Skip to content

Commit d847f6e

Browse files
committed
sql: add CITEXT column data type
Fixes: #22463 Epic: CRDB-5855 Release note (sql change): The CITEXT datatype is now a supported feature which allows case-insensitive row comparisons for CITEXT columns. The CITEXT column type is equivalent to applying the undetermined level 2 collation, 'und-u-ks-level2'. For example, under CITEXT, 'test' = 'TEST' returns true.
1 parent 0418d73 commit d847f6e

File tree

40 files changed

+993
-220
lines changed

40 files changed

+993
-220
lines changed

pkg/ccl/logictestccl/tests/3node-tenant/generated_test.go

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/ccl/logictestccl/tests/local-read-committed/generated_test.go

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/ccl/logictestccl/tests/local-repeatable-read/generated_test.go

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/cli/clisqlshell/testdata/describe

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2425,6 +2425,7 @@ bit varying,bit,NULL,yes
24252425
bit varying,bit varying,NULL,yes
24262426
boolean,character,NULL,in assignment
24272427
boolean,character varying,NULL,in assignment
2428+
boolean,citext,NULL,in assignment
24282429
boolean,integer,NULL,no
24292430
boolean,text,NULL,in assignment
24302431
box2d,geometry,NULL,yes
@@ -2433,14 +2434,19 @@ bytea,geometry,NULL,yes
24332434
character,"""char""",NULL,in assignment
24342435
character,character,NULL,yes
24352436
character,character varying,NULL,yes
2437+
character,citext,NULL,in assignment
24362438
character,name,NULL,yes
24372439
character,text,NULL,yes
24382440
character varying,"""char""",NULL,in assignment
24392441
character varying,character,NULL,yes
24402442
character varying,character varying,NULL,yes
2443+
character varying,citext,NULL,in assignment
24412444
character varying,name,NULL,yes
24422445
character varying,regclass,NULL,yes
24432446
character varying,text,NULL,yes
2447+
citext,character,NULL,in assignment
2448+
citext,character varying,NULL,yes
2449+
citext,text,NULL,yes
24442450
date,timestamp with time zone,NULL,yes
24452451
date,timestamp without time zone,NULL,yes
24462452
double precision,bigint,NULL,in assignment
@@ -2459,6 +2465,7 @@ geometry,jsonb,NULL,no
24592465
geometry,text,NULL,yes
24602466
inet,character,NULL,in assignment
24612467
inet,character varying,NULL,in assignment
2468+
inet,citext,NULL,in assignment
24622469
inet,text,NULL,in assignment
24632470
integer,"""char""",NULL,no
24642471
integer,bigint,NULL,yes
@@ -2541,6 +2548,7 @@ smallint,regtype,NULL,yes
25412548
text,"""char""",NULL,in assignment
25422549
text,character,NULL,yes
25432550
text,character varying,NULL,yes
2551+
text,citext,NULL,in assignment
25442552
text,geometry,NULL,yes
25452553
text,name,NULL,yes
25462554
text,regclass,NULL,yes
Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
query T
2+
SELECT pg_typeof(CITEXT 'Foo')
3+
----
4+
citext
5+
6+
query T
7+
SELECT pg_typeof('Foo'::CITEXT)
8+
----
9+
citext
10+
11+
query T
12+
SELECT pg_typeof('Foo'::CITEXT::TEXT::CITEXT)
13+
----
14+
citext
15+
16+
query T
17+
SELECT 'Foo'::CITEXT
18+
----
19+
Foo
20+
21+
statement ok
22+
CREATE TABLE t (
23+
c CITEXT
24+
)
25+
26+
onlyif config schema-locked-disabled
27+
query TT colnames
28+
SHOW CREATE TABLE t
29+
----
30+
table_name create_statement
31+
t CREATE TABLE public.t (
32+
c CITEXT NULL,
33+
rowid INT8 NOT VISIBLE NOT NULL DEFAULT unique_rowid(),
34+
CONSTRAINT t_pkey PRIMARY KEY (rowid ASC)
35+
);
36+
37+
statement ok
38+
INSERT INTO t VALUES ('test')
39+
40+
query T
41+
SELECT pg_typeof(c) FROM t LIMIT 1;
42+
----
43+
citext
44+
45+
query T
46+
SELECT c FROM t WHERE c = 'tEsT';
47+
----
48+
test
49+
50+
statement ok
51+
CREATE TABLE r (
52+
c CITEXT[]
53+
)
54+
55+
onlyif config schema-locked-disabled
56+
query TT colnames
57+
SHOW CREATE TABLE r
58+
----
59+
table_name create_statement
60+
r CREATE TABLE public.r (
61+
c CITEXT[] NULL,
62+
rowid INT8 NOT VISIBLE NOT NULL DEFAULT unique_rowid(),
63+
CONSTRAINT r_pkey PRIMARY KEY (rowid ASC)
64+
);
65+
66+
statement ok
67+
INSERT INTO r VALUES (ARRAY['test', 'TESTER'])
68+
69+
query T
70+
SELECT pg_typeof(c) FROM r LIMIT 1;
71+
----
72+
citext[]
73+
74+
query error unsupported comparison operator: <citext\[\]> = <string\[\]>
75+
SELECT c FROM r WHERE c = ARRAY['test', 'TESTER'];
76+
77+
query T
78+
SELECT c FROM r WHERE c = ARRAY['tEsT', 'tEsTeR']::CITEXT[];
79+
----
80+
{test,TESTER}
81+
82+
query error multiple COLLATE declarations
83+
CREATE TABLE s (c CITEXT COLLATE "en_US");
84+
85+
query B
86+
SELECT 'test'::CITEXT = 'TEST'::CITEXT;
87+
----
88+
true
89+
90+
query B
91+
SELECT 'test'::CITEXT = 'TEST';
92+
----
93+
true
94+
95+
query B
96+
SELECT 'test' = 'TEST'::CITEXT;
97+
----
98+
true
99+
100+
query B
101+
SELECT 'test'::CITEXT = 'TESTER';
102+
----
103+
false
104+
105+
# \u047D is the uppercase of \u047C, which are unicode characters.
106+
query B
107+
SELECT e'\u047D'::CITEXT = e'\u047C'::CITEXT;
108+
----
109+
true
110+
111+
# \u00E9 is the lowercase 'e' with acute accent, while \u00E8 is the lowercase 'e' with grave accent.
112+
query B
113+
SELECT e'\u00E9'::CITEXT = e'\u00E8'::CITEXT;
114+
----
115+
false
116+
117+
# \u0065\u0301 is the lowercase 'e' with acute accent in legacy unicode encoding, which is equivalent to \u00E9.
118+
query B
119+
SELECT e'\u00E9'::CITEXT = e'\u0065\u0301'::CITEXT;
120+
----
121+
true
122+
123+
# The same as above, but comparing with \u00E9's uppercase equivalent which is \u00C9.
124+
query B
125+
SELECT e'\u00C9'::CITEXT = e'\u0065\u0301'::CITEXT;
126+
----
127+
true
128+
129+
# The same as above, but comparing with \u00C9's legacy unicode equivalent which is \u0045\u0301.
130+
query B
131+
SELECT e'\u0065\u0301'::CITEXT = e'\u0045\u0301'::CITEXT;
132+
----
133+
true
134+
135+
# The same as above, but directly comparing \u00E9 and \u00C9.
136+
query B
137+
SELECT e'\u00E9'::CITEXT = e'\u00C9'::CITEXT;
138+
----
139+
true
140+
141+
# This should be false as the case insensitive locale is an 'undeterministic' language locale.
142+
# In the turkish case insensitive locale, "tr_TR-u-ks-level2", this would be true,
143+
# but CITEXT assumes an 'undeterministic' language locale.
144+
query B
145+
SELECT 'I'::CITEXT = 'ı'::CITEXT;
146+
----
147+
false
148+
149+
query B
150+
SELECT 'ß'::CITEXT = 'SS'::CITEXT;
151+
----
152+
false
153+
154+
query B
155+
SELECT NULL::CITEXT = NULL::CITEXT IS NULL
156+
----
157+
true
158+
159+
query B
160+
SELECT 'A'::CITEXT < 'a'::CITEXT;
161+
----
162+
false
163+
164+
query B
165+
SELECT 'a'::CITEXT < 'A'::CITEXT;
166+
----
167+
false
168+
169+
query error nondeterministic collations are not supported for LIKE
170+
SELECT 'test'::CITEXT LIKE 'TEST';
171+
172+
query error unsupported comparison operator: <citext> ILIKE <citext>
173+
SELECT 'test'::CITEXT ILIKE 'TEST'::CITEXT;
174+
175+
query B
176+
SELECT ARRAY['test', 'TESTER']::CITEXT[] = ARRAY['tEsT', 'tEsTeR']::CITEXT[];
177+
----
178+
true
179+
180+
query B
181+
SELECT ARRAY['test', 'TESTER']::CITEXT[] = ARRAY['TESTING', 'TESTER']::CITEXT[];
182+
----
183+
false
184+
185+
query B
186+
SELECT ARRAY[]::CITEXT[] = ARRAY['TESTING', 'TESTER']::CITEXT[];
187+
----
188+
false
189+
190+
statement ok
191+
CREATE TYPE IF NOT EXISTS ctype AS (id INT, c CITEXT);
192+
193+
statement ok
194+
CREATE TABLE composite_citext_tbl (a ctype);
195+
196+
statement ok
197+
INSERT INTO composite_citext_tbl VALUES (ROW(1, 'TeSt')), (ROW(2, 'TESTER')), (ROW(3, 'tEsT'));
198+
199+
query T
200+
SELECT (a).c FROM composite_citext_tbl WHERE (a).c = 'test' ORDER BY (a).id;
201+
----
202+
TeSt
203+
tEsT
204+
205+
query T
206+
SELECT pg_typeof((a).c) FROM composite_citext_tbl LIMIT 1;
207+
----
208+
citext
209+
210+
query error syntax error
211+
CREATE TABLE citext_with_width_tbl (a CITEXT(10));

pkg/sql/logictest/testdata/logic_test/grant_table

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,12 @@ test pg_catalog bytes type
161161
test pg_catalog bytes[] type admin ALL false
162162
test pg_catalog bytes[] type public USAGE false
163163
test pg_catalog bytes[] type root ALL false
164+
test pg_catalog citext type admin ALL false
165+
test pg_catalog citext type public USAGE false
166+
test pg_catalog citext type root ALL false
167+
test pg_catalog citext[] type admin ALL false
168+
test pg_catalog citext[] type public USAGE false
169+
test pg_catalog citext[] type root ALL false
164170
test pg_catalog date type admin ALL false
165171
test pg_catalog date type public USAGE false
166172
test pg_catalog date type root ALL false
@@ -566,6 +572,10 @@ test pg_catalog bytes type admin ALL
566572
test pg_catalog bytes type root ALL false
567573
test pg_catalog bytes[] type admin ALL false
568574
test pg_catalog bytes[] type root ALL false
575+
test pg_catalog citext type admin ALL false
576+
test pg_catalog citext type root ALL false
577+
test pg_catalog citext[] type admin ALL false
578+
test pg_catalog citext[] type root ALL false
569579
test pg_catalog date type admin ALL false
570580
test pg_catalog date type root ALL false
571581
test pg_catalog date[] type admin ALL false
@@ -818,6 +828,10 @@ a pg_catalog bytes type admin ALL
818828
a pg_catalog bytes type root ALL false
819829
a pg_catalog bytes[] type admin ALL false
820830
a pg_catalog bytes[] type root ALL false
831+
a pg_catalog citext type admin ALL false
832+
a pg_catalog citext type root ALL false
833+
a pg_catalog citext[] type admin ALL false
834+
a pg_catalog citext[] type root ALL false
821835
a pg_catalog date type admin ALL false
822836
a pg_catalog date type root ALL false
823837
a pg_catalog date[] type admin ALL false
@@ -1008,6 +1022,10 @@ defaultdb pg_catalog bytes type admin ALL
10081022
defaultdb pg_catalog bytes type root ALL false
10091023
defaultdb pg_catalog bytes[] type admin ALL false
10101024
defaultdb pg_catalog bytes[] type root ALL false
1025+
defaultdb pg_catalog citext type admin ALL false
1026+
defaultdb pg_catalog citext type root ALL false
1027+
defaultdb pg_catalog citext[] type admin ALL false
1028+
defaultdb pg_catalog citext[] type root ALL false
10111029
defaultdb pg_catalog date type admin ALL false
10121030
defaultdb pg_catalog date type root ALL false
10131031
defaultdb pg_catalog date[] type admin ALL false
@@ -1198,6 +1216,10 @@ postgres pg_catalog bytes type admin ALL
11981216
postgres pg_catalog bytes type root ALL false
11991217
postgres pg_catalog bytes[] type admin ALL false
12001218
postgres pg_catalog bytes[] type root ALL false
1219+
postgres pg_catalog citext type admin ALL false
1220+
postgres pg_catalog citext type root ALL false
1221+
postgres pg_catalog citext[] type admin ALL false
1222+
postgres pg_catalog citext[] type root ALL false
12011223
postgres pg_catalog date type admin ALL false
12021224
postgres pg_catalog date type root ALL false
12031225
postgres pg_catalog date[] type admin ALL false
@@ -1396,6 +1418,10 @@ test pg_catalog bytes type admin ALL
13961418
test pg_catalog bytes type root ALL false
13971419
test pg_catalog bytes[] type admin ALL false
13981420
test pg_catalog bytes[] type root ALL false
1421+
test pg_catalog citext type admin ALL false
1422+
test pg_catalog citext type root ALL false
1423+
test pg_catalog citext[] type admin ALL false
1424+
test pg_catalog citext[] type root ALL false
13991425
test pg_catalog date type admin ALL false
14001426
test pg_catalog date type root ALL false
14011427
test pg_catalog date[] type admin ALL false

0 commit comments

Comments
 (0)