xref: /sqlite-3.40.0/test/like3.test (revision 8210233c)
1a9c18a90Sdrh# 2015-03-06
2a9c18a90Sdrh#
3a9c18a90Sdrh# The author disclaims copyright to this source code.  In place of
4a9c18a90Sdrh# a legal notice, here is a blessing:
5a9c18a90Sdrh#
6a9c18a90Sdrh#    May you do good and not evil.
7a9c18a90Sdrh#    May you find forgiveness for yourself and forgive others.
8a9c18a90Sdrh#    May you share freely, never taking more than you give.
9a9c18a90Sdrh#
10a9c18a90Sdrh#***********************************************************************
11a9c18a90Sdrh#
12a9c18a90Sdrh# This file implements regression tests for SQLite library.  The
13a9c18a90Sdrh# focus of this file is testing the LIKE and GLOB operators and
14a9c18a90Sdrh# in particular the optimizations that occur to help those operators
15a9c18a90Sdrh# run faster and that those optimizations work correctly when there
16a9c18a90Sdrh# are both strings and blobs being tested.
17a9c18a90Sdrh#
18a9c18a90Sdrh# Ticket 05f43be8fdda9fbd948d374319b99b054140bc36 shows that the following
19a9c18a90Sdrh# SQL was not working correctly:
20a9c18a90Sdrh#
21a9c18a90Sdrh#     CREATE TABLE t1(x TEXT UNIQUE COLLATE nocase);
22a9c18a90Sdrh#     INSERT INTO t1(x) VALUES(x'616263');
23a9c18a90Sdrh#     SELECT 'query-1', x FROM t1 WHERE x LIKE 'a%';
24a9c18a90Sdrh#     SELECT 'query-2', x FROM t1 WHERE +x LIKE 'a%';
25a9c18a90Sdrh#
26a9c18a90Sdrh# This script verifies that it works right now.
27a9c18a90Sdrh#
28a9c18a90Sdrh
29a9c18a90Sdrhset testdir [file dirname $argv0]
30a9c18a90Sdrhsource $testdir/tester.tcl
31a9c18a90Sdrh
3241d2e66eSdrhifcapable !like_match_blobs {
3341d2e66eSdrh  finish_test
3441d2e66eSdrh  return
3541d2e66eSdrh}
3641d2e66eSdrh
37a9c18a90Sdrhdo_execsql_test like3-1.1 {
38a9c18a90Sdrh  PRAGMA encoding=UTF8;
39a9c18a90Sdrh  CREATE TABLE t1(a,b TEXT COLLATE nocase);
40a9c18a90Sdrh  INSERT INTO t1(a,b)
41a9c18a90Sdrh     VALUES(1,'abc'),
42a9c18a90Sdrh           (2,'ABX'),
43a9c18a90Sdrh           (3,'BCD'),
44a9c18a90Sdrh           (4,x'616263'),
45a9c18a90Sdrh           (5,x'414258'),
46a9c18a90Sdrh           (6,x'424344');
47a9c18a90Sdrh  CREATE INDEX t1ba ON t1(b,a);
48a9c18a90Sdrh
49a9c18a90Sdrh  SELECT a, b FROM t1 WHERE b LIKE 'aB%' ORDER BY +a;
50a9c18a90Sdrh} {1 abc 2 ABX 4 abc 5 ABX}
51a9c18a90Sdrhdo_execsql_test like3-1.2 {
52a9c18a90Sdrh  SELECT a, b FROM t1 WHERE +b LIKE 'aB%' ORDER BY +a;
53a9c18a90Sdrh} {1 abc 2 ABX 4 abc 5 ABX}
54a9c18a90Sdrh
55560b7c72Sdrhdo_execsql_test like3-2.0 {
56a9c18a90Sdrh  CREATE TABLE t2(a, b TEXT);
57a9c18a90Sdrh  INSERT INTO t2 SELECT a, b FROM t1;
58a9c18a90Sdrh  CREATE INDEX t2ba ON t2(b,a);
59a9c18a90Sdrh  SELECT a, b FROM t2 WHERE b GLOB 'ab*' ORDER BY +a;
60a9c18a90Sdrh} {1 abc 4 abc}
61560b7c72Sdrhdo_execsql_test like3-2.1 {
62a9c18a90Sdrh  SELECT a, b FROM t2 WHERE +b GLOB 'ab*' ORDER BY +a;
63a9c18a90Sdrh} {1 abc 4 abc}
64560b7c72Sdrhdo_execsql_test like3-2.2 {
65560b7c72Sdrh  SELECT a, b FROM t2 WHERE b>=x'6162' AND b GLOB 'ab*'
66560b7c72Sdrh} {4 abc}
67560b7c72Sdrhdo_execsql_test like3-2.3 {
68560b7c72Sdrh  SELECT a, b FROM t2 WHERE +b>=x'6162' AND +b GLOB 'ab*'
69560b7c72Sdrh} {4 abc}
70560b7c72Sdrhdo_execsql_test like3-2.4 {
71560b7c72Sdrh  SELECT a, b FROM t2 WHERE b GLOB 'ab*' AND b>=x'6162'
72560b7c72Sdrh} {4 abc}
73560b7c72Sdrhdo_execsql_test like3-2.5 {
74560b7c72Sdrh  SELECT a, b FROM t2 WHERE +b GLOB 'ab*' AND +b>=x'6162'
75560b7c72Sdrh} {4 abc}
76a9c18a90Sdrh
7716897072Sdrhdo_execsql_test like3-3.0 {
7816897072Sdrh  CREATE TABLE t3(x TEXT PRIMARY KEY COLLATE nocase);
7916897072Sdrh  INSERT INTO t3(x) VALUES('aaa'),('abc'),('abd'),('abe'),('acz');
8016897072Sdrh  INSERT INTO t3(x) SELECT CAST(x AS blob) FROM t3;
8116897072Sdrh  SELECT quote(x) FROM t3 WHERE x LIKE 'ab%' ORDER BY x;
8216897072Sdrh} {'abc' 'abd' 'abe' X'616263' X'616264' X'616265'}
8316897072Sdrhdo_execsql_test like3-3.1 {
8416897072Sdrh  SELECT quote(x) FROM t3 WHERE x LIKE 'ab%' ORDER BY x DESC;
8516897072Sdrh} {X'616265' X'616264' X'616263' 'abe' 'abd' 'abc'}
8616897072Sdrhdo_execsql_test like3-3.1ck {
8716897072Sdrh  SELECT quote(x) FROM t3 WHERE x LIKE 'ab%' ORDER BY +x DESC;
8816897072Sdrh} {X'616265' X'616264' X'616263' 'abe' 'abd' 'abc'}
89b7c60ba6Sdrhdo_execsql_test like3-3.2 {
90b7c60ba6Sdrh  SELECT quote(x) FROM t3 WHERE x LIKE 'ab%' ORDER BY x ASC;
91b7c60ba6Sdrh} {'abc' 'abd' 'abe' X'616263' X'616264' X'616265'}
92b7c60ba6Sdrhdo_execsql_test like3-3.2ck {
93b7c60ba6Sdrh  SELECT quote(x) FROM t3 WHERE x LIKE 'ab%' ORDER BY +x ASC;
94b7c60ba6Sdrh} {'abc' 'abd' 'abe' X'616263' X'616264' X'616265'}
95b7c60ba6Sdrh
96b7c60ba6Sdrhdo_execsql_test like3-4.0 {
97b7c60ba6Sdrh  CREATE TABLE t4(x TEXT COLLATE nocase);
98b7c60ba6Sdrh  CREATE INDEX t4x ON t4(x DESC);
99b7c60ba6Sdrh  INSERT INTO t4(x) SELECT x FROM t3;
100b7c60ba6Sdrh  SELECT quote(x) FROM t4 WHERE x LIKE 'ab%' ORDER BY x;
101b7c60ba6Sdrh} {'abc' 'abd' 'abe' X'616263' X'616264' X'616265'}
102b7c60ba6Sdrhdo_execsql_test like3-4.1 {
103b7c60ba6Sdrh  SELECT quote(x) FROM t4 WHERE x LIKE 'ab%' ORDER BY x DESC;
104b7c60ba6Sdrh} {X'616265' X'616264' X'616263' 'abe' 'abd' 'abc'}
105b7c60ba6Sdrhdo_execsql_test like3-4.1ck {
106b7c60ba6Sdrh  SELECT quote(x) FROM t4 WHERE x LIKE 'ab%' ORDER BY +x DESC;
107b7c60ba6Sdrh} {X'616265' X'616264' X'616263' 'abe' 'abd' 'abc'}
108b7c60ba6Sdrhdo_execsql_test like3-4.2 {
109b7c60ba6Sdrh  SELECT quote(x) FROM t4 WHERE x LIKE 'ab%' ORDER BY x ASC;
110b7c60ba6Sdrh} {'abc' 'abd' 'abe' X'616263' X'616264' X'616265'}
111b7c60ba6Sdrhdo_execsql_test like3-4.2ck {
112b7c60ba6Sdrh  SELECT quote(x) FROM t4 WHERE x LIKE 'ab%' ORDER BY +x ASC;
113b7c60ba6Sdrh} {'abc' 'abd' 'abe' X'616263' X'616264' X'616265'}
114b7c60ba6Sdrh
115b7a002f8Sdrh# 2018-09-10 ticket https://www.sqlite.org/src/tktview/c94369cae9b561b1f996
116b7a002f8Sdrh# The like optimization fails for a column with numeric affinity if
117b7a002f8Sdrh# the pattern '/%' or begins with the escape character.
118b7a002f8Sdrh#
119b7a002f8Sdrhdo_execsql_test like3-5.100 {
120b7a002f8Sdrh  CREATE TABLE t5a(x INT UNIQUE COLLATE nocase);
121b7a002f8Sdrh  INSERT INTO t5a(x) VALUES('/abc'),(123),(-234);
122b7a002f8Sdrh  SELECT x FROM t5a WHERE x LIKE '/%';
123b7a002f8Sdrh} {/abc}
124b7a002f8Sdrhdo_eqp_test like3-5.101 {
125b7a002f8Sdrh  SELECT x FROM t5a WHERE x LIKE '/%';
126b7a002f8Sdrh} {
127b7a002f8Sdrh  QUERY PLAN
128*8210233cSdrh  `--SCAN t5a
129b7a002f8Sdrh}
130b7a002f8Sdrhdo_execsql_test like3-5.110 {
131b7a002f8Sdrh  SELECT x FROM t5a WHERE x LIKE '/a%';
132b7a002f8Sdrh} {/abc}
133ca9a5fafSdrhifcapable !icu {
134b7a002f8Sdrhdo_eqp_test like3-5.111 {
135b7a002f8Sdrh  SELECT x FROM t5a WHERE x LIKE '/a%';
136b7a002f8Sdrh} {
137b7a002f8Sdrh  QUERY PLAN
138*8210233cSdrh  `--SEARCH t5a USING COVERING INDEX sqlite_autoindex_t5a_1 (x>? AND x<?)
139b7a002f8Sdrh}
140ca9a5fafSdrh}
141b7a002f8Sdrhdo_execsql_test like3-5.120 {
142b7a002f8Sdrh  SELECT x FROM t5a WHERE x LIKE '^12%' ESCAPE '^';
143b7a002f8Sdrh} {123}
144b7a002f8Sdrhdo_eqp_test like3-5.121 {
145b7a002f8Sdrh  SELECT x FROM t5a WHERE x LIKE '^12%' ESCAPE '^';
146b7a002f8Sdrh} {
147b7a002f8Sdrh  QUERY PLAN
148*8210233cSdrh  `--SCAN t5a
149b7a002f8Sdrh}
150b7a002f8Sdrhdo_execsql_test like3-5.122 {
151b7a002f8Sdrh  SELECT x FROM t5a WHERE x LIKE '^-2%' ESCAPE '^';
152b7a002f8Sdrh} {-234}
153b7a002f8Sdrhdo_eqp_test like3-5.123 {
154b7a002f8Sdrh  SELECT x FROM t5a WHERE x LIKE '^12%' ESCAPE '^';
155b7a002f8Sdrh} {
156b7a002f8Sdrh  QUERY PLAN
157*8210233cSdrh  `--SCAN t5a
158b7a002f8Sdrh}
159b7a002f8Sdrh
160b7a002f8Sdrhdo_execsql_test like3-5.200 {
161b7a002f8Sdrh  CREATE TABLE t5b(x INT UNIQUE COLLATE binary);
162b7a002f8Sdrh  INSERT INTO t5b(x) VALUES('/abc'),(123),(-234);
163b7a002f8Sdrh  SELECT x FROM t5b WHERE x GLOB '/*';
164b7a002f8Sdrh} {/abc}
165b7a002f8Sdrhdo_eqp_test like3-5.201 {
166b7a002f8Sdrh  SELECT x FROM t5b WHERE x GLOB '/*';
167b7a002f8Sdrh} {
168b7a002f8Sdrh  QUERY PLAN
169*8210233cSdrh  `--SCAN t5b
170b7a002f8Sdrh}
171b7a002f8Sdrhdo_execsql_test like3-5.210 {
172b7a002f8Sdrh  SELECT x FROM t5b WHERE x GLOB '/a*';
173b7a002f8Sdrh} {/abc}
174b7a002f8Sdrhdo_eqp_test like3-5.211 {
175b7a002f8Sdrh  SELECT x FROM t5b WHERE x GLOB '/a*';
176b7a002f8Sdrh} {
177b7a002f8Sdrh  QUERY PLAN
178*8210233cSdrh  `--SEARCH t5b USING COVERING INDEX sqlite_autoindex_t5b_1 (x>? AND x<?)
179b7a002f8Sdrh}
180b7a002f8Sdrh
181cf1747b7Sdrh# 2019-05-01
18297afa309Sdrh# another case of the above reported on the mailing list by Manuel Rigger.
183cf1747b7Sdrh#
184cf1747b7Sdrhdo_execsql_test like3-5.300 {
185cf1747b7Sdrh  CREATE TABLE t5c (c0 REAL);
186cf1747b7Sdrh  CREATE INDEX t5c_0 ON t5c(c0 COLLATE NOCASE);
187cf1747b7Sdrh  INSERT INTO t5c(rowid, c0) VALUES (99,'+/');
188cf1747b7Sdrh  SELECT * FROM t5c WHERE (c0 LIKE '+/');
189cf1747b7Sdrh} {+/}
190cf1747b7Sdrh
19197afa309Sdrh# 2019-05-08
19297afa309Sdrh# Yet another case for the above from Manuel Rigger.
19397afa309Sdrh#
19497afa309Sdrhdo_execsql_test like3-5.400 {
19597afa309Sdrh  DROP TABLE IF EXISTS t0;
19697afa309Sdrh  CREATE TABLE t0(c0 INT UNIQUE COLLATE NOCASE);
19797afa309Sdrh  INSERT INTO t0(c0) VALUES ('./');
19897afa309Sdrh  SELECT * FROM t0 WHERE t0.c0 LIKE './';
19997afa309Sdrh} {./}
20097afa309Sdrh
201060b7fa9Sdrh# 2019-06-14
202060b7fa9Sdrh# Ticket https://www.sqlite.org/src/info/ce8717f0885af975
203060b7fa9Sdrhdo_execsql_test like3-5.410 {
204060b7fa9Sdrh  DROP TABLE IF EXISTS t0;
205060b7fa9Sdrh  CREATE TABLE t0(c0 INT UNIQUE COLLATE NOCASE);
206060b7fa9Sdrh  INSERT INTO t0(c0) VALUES ('.1%');
207060b7fa9Sdrh  SELECT * FROM t0 WHERE t0.c0 LIKE '.1%';
208060b7fa9Sdrh} {.1%}
209060b7fa9Sdrh
21091f473b5Sdrh# 2019-09-03
21191f473b5Sdrh# Ticket https://www.sqlite.org/src/info/0f0428096f
21291f473b5Sdrhdo_execsql_test like3-5.420 {
21391f473b5Sdrh  DROP TABLE IF EXISTS t0;
21491f473b5Sdrh  CREATE TABLE t0(c0 UNIQUE);
21591f473b5Sdrh  INSERT INTO t0(c0) VALUES(-1);
21691f473b5Sdrh  SELECT * FROM t0 WHERE t0.c0 GLOB '-*';
21791f473b5Sdrh} {-1}
21891f473b5Sdrhdo_execsql_test like3-5.421 {
21991f473b5Sdrh  SELECT t0.c0 GLOB '-*' FROM t0;
22091f473b5Sdrh} {1}
22191f473b5Sdrh
22291f473b5Sdrh
22397afa309Sdrh
2248e0f794dSdrh# 2019-02-27
2258e0f794dSdrh# Verify that the LIKE optimization works with an ESCAPE clause when
2268e0f794dSdrh# using PRAGMA case_sensitive_like=ON.
2278e0f794dSdrh#
228db5ba5c3Sdanifcapable !icu {
2298e0f794dSdrhdo_execsql_test like3-6.100 {
2308e0f794dSdrh  DROP TABLE IF EXISTS t1;
2318e0f794dSdrh  CREATE TABLE t1(path TEXT COLLATE nocase PRIMARY KEY,a,b,c) WITHOUT ROWID;
2328e0f794dSdrh}
2338e0f794dSdrhdo_eqp_test like3-6.110 {
2348e0f794dSdrh  SELECT * FROM t1 WHERE path LIKE 'a%';
2358e0f794dSdrh} {
2368e0f794dSdrh  QUERY PLAN
237*8210233cSdrh  `--SEARCH t1 USING PRIMARY KEY (path>? AND path<?)
2388e0f794dSdrh}
2398e0f794dSdrhdo_eqp_test like3-6.120 {
240589c7876Sdrh  SELECT * FROM t1 WHERE path LIKE 'a%' ESCAPE 'x';
2418e0f794dSdrh} {
2428e0f794dSdrh  QUERY PLAN
243*8210233cSdrh  `--SEARCH t1 USING PRIMARY KEY (path>? AND path<?)
2448e0f794dSdrh}
2458e0f794dSdrhdo_execsql_test like3-6.200 {
2468e0f794dSdrh  DROP TABLE IF EXISTS t2;
2478e0f794dSdrh  CREATE TABLE t2(path TEXT,x,y,z);
2488e0f794dSdrh  CREATE INDEX t2path ON t2(path COLLATE nocase);
2498e0f794dSdrh  CREATE INDEX t2path2 ON t2(path);
2508e0f794dSdrh}
2518e0f794dSdrhdo_eqp_test like3-6.210 {
2528e0f794dSdrh  SELECT * FROM t2 WHERE path LIKE 'a%';
2538e0f794dSdrh} {
2548e0f794dSdrh  QUERY PLAN
255*8210233cSdrh  `--SEARCH t2 USING INDEX t2path (path>? AND path<?)
2568e0f794dSdrh}
2578e0f794dSdrhdo_eqp_test like3-6.220 {
258589c7876Sdrh  SELECT * FROM t2 WHERE path LIKE 'a%' ESCAPE '\';
2598e0f794dSdrh} {
2608e0f794dSdrh  QUERY PLAN
261*8210233cSdrh  `--SEARCH t2 USING INDEX t2path (path>? AND path<?)
2628e0f794dSdrh}
2638e0f794dSdrhdb eval {PRAGMA case_sensitive_like=ON}
2648e0f794dSdrhdo_eqp_test like3-6.230 {
2658e0f794dSdrh  SELECT * FROM t2 WHERE path LIKE 'a%';
2668e0f794dSdrh} {
2678e0f794dSdrh  QUERY PLAN
268*8210233cSdrh  `--SEARCH t2 USING INDEX t2path2 (path>? AND path<?)
2698e0f794dSdrh}
2708e0f794dSdrhdo_eqp_test like3-6.240 {
271589c7876Sdrh  SELECT * FROM t2 WHERE path LIKE 'a%' ESCAPE '\';
2728e0f794dSdrh} {
2738e0f794dSdrh  QUERY PLAN
274*8210233cSdrh  `--SEARCH t2 USING INDEX t2path2 (path>? AND path<?)
2758e0f794dSdrh}
276db5ba5c3Sdan}
2778e0f794dSdrh
278a9c18a90Sdrhfinish_test
279