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