blob: 8ea7cff782b545b138a3efc6447c1ac0e9bd0bb4 [file] [log] [blame]
drh55ef4d92005-08-14 01:20:37 +00001# 2005 August 13
2#
3# The author disclaims copyright to this source code. In place of
4# a legal notice, here is a blessing:
5#
6# May you do good and not evil.
7# May you find forgiveness for yourself and forgive others.
8# May you share freely, never taking more than you give.
9#
10#***********************************************************************
11# This file implements regression tests for SQLite library. The
12# focus of this file is testing the LIKE and GLOB operators and
13# in particular the optimizations that occur to help those operators
14# run faster.
15#
drhc4ac22e2009-06-07 23:45:10 +000016# $Id: like.test,v 1.13 2009/06/07 23:45:11 drh Exp $
drh55ef4d92005-08-14 01:20:37 +000017
18set testdir [file dirname $argv0]
19source $testdir/tester.tcl
dan32d0f642019-06-10 13:46:42 +000020set testprefix like
drh55ef4d92005-08-14 01:20:37 +000021
22# Create some sample data to work with.
23#
24do_test like-1.0 {
25 execsql {
26 CREATE TABLE t1(x TEXT);
27 }
28 foreach str {
29 a
30 ab
31 abc
32 abcd
33
34 acd
35 abd
36 bc
37 bcd
38
39 xyz
40 ABC
41 CDE
42 {ABC abc xyz}
43 } {
danielk19773bdca9c2006-01-17 09:35:01 +000044 db eval {INSERT INTO t1 VALUES(:str)}
drh55ef4d92005-08-14 01:20:37 +000045 }
46 execsql {
47 SELECT count(*) FROM t1;
48 }
49} {12}
50
51# Test that both case sensitive and insensitive version of LIKE work.
52#
53do_test like-1.1 {
54 execsql {
55 SELECT x FROM t1 WHERE x LIKE 'abc' ORDER BY 1;
56 }
57} {ABC abc}
58do_test like-1.2 {
59 execsql {
60 SELECT x FROM t1 WHERE x GLOB 'abc' ORDER BY 1;
61 }
62} {abc}
63do_test like-1.3 {
64 execsql {
65 SELECT x FROM t1 WHERE x LIKE 'ABC' ORDER BY 1;
66 }
67} {ABC abc}
68do_test like-1.4 {
69 execsql {
70 SELECT x FROM t1 WHERE x LIKE 'aBc' ORDER BY 1;
71 }
72} {ABC abc}
drhd2cb50b2009-01-09 21:41:17 +000073do_test like-1.5.1 {
drhc7060c42011-06-26 23:44:35 +000074 # Use sqlite3_exec() to verify fix for ticket [25ee81271091] 2011-06-26
75 sqlite3_exec db {PRAGMA case_sensitive_like=on}
76} {0 {}}
77do_test like-1.5.2 {
drh55ef4d92005-08-14 01:20:37 +000078 execsql {
drh55ef4d92005-08-14 01:20:37 +000079 SELECT x FROM t1 WHERE x LIKE 'abc' ORDER BY 1;
80 }
81} {abc}
drhc7060c42011-06-26 23:44:35 +000082do_test like-1.5.3 {
drhd2cb50b2009-01-09 21:41:17 +000083 execsql {
84 PRAGMA case_sensitive_like; -- no argument; does not change setting
85 SELECT x FROM t1 WHERE x LIKE 'abc' ORDER BY 1;
86 }
87} {abc}
drh55ef4d92005-08-14 01:20:37 +000088do_test like-1.6 {
89 execsql {
90 SELECT x FROM t1 WHERE x GLOB 'abc' ORDER BY 1;
91 }
92} {abc}
93do_test like-1.7 {
94 execsql {
95 SELECT x FROM t1 WHERE x LIKE 'ABC' ORDER BY 1;
96 }
97} {ABC}
98do_test like-1.8 {
99 execsql {
100 SELECT x FROM t1 WHERE x LIKE 'aBc' ORDER BY 1;
101 }
102} {}
103do_test like-1.9 {
104 execsql {
105 PRAGMA case_sensitive_like=off;
106 SELECT x FROM t1 WHERE x LIKE 'abc' ORDER BY 1;
107 }
108} {ABC abc}
drhd2cb50b2009-01-09 21:41:17 +0000109do_test like-1.10 {
110 execsql {
111 PRAGMA case_sensitive_like; -- No argument, does not change setting.
112 SELECT x FROM t1 WHERE x LIKE 'abc' ORDER BY 1;
113 }
114} {ABC abc}
drh55ef4d92005-08-14 01:20:37 +0000115
116# Tests of the REGEXP operator
117#
118do_test like-2.1 {
119 proc test_regexp {a b} {
120 return [regexp $a $b]
121 }
dan6bd2c732010-11-01 05:42:26 +0000122 db function regexp -argcount 2 test_regexp
drh55ef4d92005-08-14 01:20:37 +0000123 execsql {
124 SELECT x FROM t1 WHERE x REGEXP 'abc' ORDER BY 1;
125 }
126} {{ABC abc xyz} abc abcd}
127do_test like-2.2 {
128 execsql {
129 SELECT x FROM t1 WHERE x REGEXP '^abc' ORDER BY 1;
130 }
131} {abc abcd}
132
danielk1977619a3692006-06-14 08:48:25 +0000133# Tests of the MATCH operator
134#
135do_test like-2.3 {
136 proc test_match {a b} {
137 return [string match $a $b]
138 }
drhe3602be2008-09-09 12:31:33 +0000139 db function match -argcount 2 test_match
danielk1977619a3692006-06-14 08:48:25 +0000140 execsql {
141 SELECT x FROM t1 WHERE x MATCH '*abc*' ORDER BY 1;
142 }
143} {{ABC abc xyz} abc abcd}
144do_test like-2.4 {
145 execsql {
146 SELECT x FROM t1 WHERE x MATCH 'abc*' ORDER BY 1;
147 }
148} {abc abcd}
149
drh55ef4d92005-08-14 01:20:37 +0000150# For the remaining tests, we need to have the like optimizations
151# enabled.
152#
153ifcapable !like_opt {
154 finish_test
155 return
156}
157
158# This procedure executes the SQL. Then it appends to the result the
159# "sort" or "nosort" keyword (as in the cksort procedure above) then
drh7c171092013-06-03 22:08:20 +0000160# it appends the names of the table and index used.
drh55ef4d92005-08-14 01:20:37 +0000161#
162proc queryplan {sql} {
163 set ::sqlite_sort_count 0
drh169dd922017-06-26 13:57:49 +0000164 db cache flush
drh55ef4d92005-08-14 01:20:37 +0000165 set data [execsql $sql]
166 if {$::sqlite_sort_count} {set x sort} {set x nosort}
167 lappend data $x
drh7c171092013-06-03 22:08:20 +0000168 set eqp [execsql "EXPLAIN QUERY PLAN $sql"]
169 # puts eqp=$eqp
170 foreach {a b c x} $eqp {
drh8a4380d2013-06-11 02:32:50 +0000171 if {[regexp { TABLE (\w+ AS )?(\w+) USING COVERING INDEX (\w+)\y} \
drh7c171092013-06-03 22:08:20 +0000172 $x all as tab idx]} {
173 lappend data {} $idx
drh8a4380d2013-06-11 02:32:50 +0000174 } elseif {[regexp { TABLE (\w+ AS )?(\w+) USING.* INDEX (\w+)\y} \
drh7c171092013-06-03 22:08:20 +0000175 $x all as tab idx]} {
176 lappend data $tab $idx
drh8a4380d2013-06-11 02:32:50 +0000177 } elseif {[regexp { TABLE (\w+ AS )?(\w+)\y} $x all as tab]} {
drh7c171092013-06-03 22:08:20 +0000178 lappend data $tab *
179 }
180 }
181 return $data
drh55ef4d92005-08-14 01:20:37 +0000182}
183
184# Perform tests on the like optimization.
185#
186# With no index on t1.x and with case sensitivity turned off, no optimization
187# is performed.
188#
189do_test like-3.1 {
190 set sqlite_like_count 0
191 queryplan {
192 SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1;
193 }
drh7c171092013-06-03 22:08:20 +0000194} {ABC {ABC abc xyz} abc abcd sort t1 *}
drh55ef4d92005-08-14 01:20:37 +0000195do_test like-3.2 {
196 set sqlite_like_count
197} {12}
198
199# With an index on t1.x and case sensitivity on, optimize completely.
200#
drh169dd922017-06-26 13:57:49 +0000201do_test like-3.3.100 {
drh55ef4d92005-08-14 01:20:37 +0000202 set sqlite_like_count 0
203 execsql {
204 PRAGMA case_sensitive_like=on;
205 CREATE INDEX i1 ON t1(x);
206 }
207 queryplan {
208 SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1;
209 }
210} {abc abcd nosort {} i1}
drh1d42ea72017-07-27 20:24:29 +0000211do_test like-3.3.100.cnt {
drh55ef4d92005-08-14 01:20:37 +0000212 set sqlite_like_count
213} 0
214
drh169dd922017-06-26 13:57:49 +0000215# The like optimization works even when the pattern is a bound parameter
216#
dana50b3092017-07-15 06:35:15 +0000217# Exception: It does not work if sqlite3_prepare() is used instead of
218# sqlite3_prepare_v2(), as in that case the statement cannot be reprepared
219# after the parameter is bound.
220#
dancb0d3ba2017-07-15 08:02:10 +0000221unset -nocomplain ::likepat
dana50b3092017-07-15 06:35:15 +0000222set ::likepat abc%
223if {[permutation]!="prepare"} {
224 do_test like-3.3.102 {
225 set sqlite_like_count 0
dana50b3092017-07-15 06:35:15 +0000226 queryplan {
227 SELECT x FROM t1 WHERE x LIKE $::likepat ORDER BY 1;
228 }
229 } {abc abcd nosort {} i1}
230 do_test like-3.3.103 {
231 set sqlite_like_count
232 } 0
233}
drh169dd922017-06-26 13:57:49 +0000234
235# Except, the like optimization does not work for bound parameters if
236# the query planner stability guarantee is active.
237#
238do_test like-3.3.104 {
239 set sqlite_like_count 0
240 sqlite3_db_config db QPSG 1
241 queryplan {
242 SELECT x FROM t1 WHERE x LIKE $::likepat ORDER BY 1;
243 }
244} {abc abcd nosort {} i1}
245do_test like-3.3.105 {
246 set sqlite_like_count
247} 12
248
249# The query planner stability guarantee does not disrupt explicit patterns
250#
251do_test like-3.3.105 {
252 set sqlite_like_count 0
253 queryplan {
254 SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1;
255 }
256} {abc abcd nosort {} i1}
257do_test like-3.3.106 {
258 set sqlite_like_count
259} 0
260sqlite3_db_config db QPSG 0
261
drh93ee23c2010-07-22 12:33:57 +0000262# The LIKE optimization still works when the RHS is a string with no
263# wildcard. Ticket [e090183531fc2747]
264#
265do_test like-3.4.2 {
266 queryplan {
267 SELECT x FROM t1 WHERE x LIKE 'a' ORDER BY 1;
268 }
269} {a nosort {} i1}
270do_test like-3.4.3 {
271 queryplan {
272 SELECT x FROM t1 WHERE x LIKE 'ab' ORDER BY 1;
273 }
274} {ab nosort {} i1}
275do_test like-3.4.4 {
276 queryplan {
277 SELECT x FROM t1 WHERE x LIKE 'abcd' ORDER BY 1;
278 }
279} {abcd nosort {} i1}
280do_test like-3.4.5 {
281 queryplan {
282 SELECT x FROM t1 WHERE x LIKE 'abcde' ORDER BY 1;
283 }
284} {nosort {} i1}
285
286
drh55ef4d92005-08-14 01:20:37 +0000287# Partial optimization when the pattern does not end in '%'
288#
289do_test like-3.5 {
290 set sqlite_like_count 0
291 queryplan {
292 SELECT x FROM t1 WHERE x LIKE 'a_c' ORDER BY 1;
293 }
294} {abc nosort {} i1}
295do_test like-3.6 {
296 set sqlite_like_count
297} 6
298do_test like-3.7 {
299 set sqlite_like_count 0
300 queryplan {
301 SELECT x FROM t1 WHERE x LIKE 'ab%d' ORDER BY 1;
302 }
303} {abcd abd nosort {} i1}
304do_test like-3.8 {
305 set sqlite_like_count
306} 4
307do_test like-3.9 {
308 set sqlite_like_count 0
309 queryplan {
310 SELECT x FROM t1 WHERE x LIKE 'a_c%' ORDER BY 1;
311 }
312} {abc abcd nosort {} i1}
313do_test like-3.10 {
314 set sqlite_like_count
315} 6
316
317# No optimization when the pattern begins with a wildcard.
318# Note that the index is still used but only for sorting.
319#
320do_test like-3.11 {
321 set sqlite_like_count 0
322 queryplan {
323 SELECT x FROM t1 WHERE x LIKE '%bcd' ORDER BY 1;
324 }
325} {abcd bcd nosort {} i1}
326do_test like-3.12 {
327 set sqlite_like_count
328} 12
329
330# No optimization for case insensitive LIKE
331#
332do_test like-3.13 {
333 set sqlite_like_count 0
drh7c171092013-06-03 22:08:20 +0000334 db eval {PRAGMA case_sensitive_like=off;}
drh55ef4d92005-08-14 01:20:37 +0000335 queryplan {
drh55ef4d92005-08-14 01:20:37 +0000336 SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1;
337 }
338} {ABC {ABC abc xyz} abc abcd nosort {} i1}
339do_test like-3.14 {
340 set sqlite_like_count
341} 12
342
343# No optimization without an index.
344#
345do_test like-3.15 {
346 set sqlite_like_count 0
drh7c171092013-06-03 22:08:20 +0000347 db eval {
drh55ef4d92005-08-14 01:20:37 +0000348 PRAGMA case_sensitive_like=on;
349 DROP INDEX i1;
drh7c171092013-06-03 22:08:20 +0000350 }
351 queryplan {
drh55ef4d92005-08-14 01:20:37 +0000352 SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1;
353 }
drh7c171092013-06-03 22:08:20 +0000354} {abc abcd sort t1 *}
drh55ef4d92005-08-14 01:20:37 +0000355do_test like-3.16 {
356 set sqlite_like_count
357} 12
358
359# No GLOB optimization without an index.
360#
361do_test like-3.17 {
362 set sqlite_like_count 0
363 queryplan {
364 SELECT x FROM t1 WHERE x GLOB 'abc*' ORDER BY 1;
365 }
drh7c171092013-06-03 22:08:20 +0000366} {abc abcd sort t1 *}
drh55ef4d92005-08-14 01:20:37 +0000367do_test like-3.18 {
368 set sqlite_like_count
369} 12
370
371# GLOB is optimized regardless of the case_sensitive_like setting.
372#
373do_test like-3.19 {
374 set sqlite_like_count 0
drh9da058b2011-08-17 00:40:58 +0000375 db eval {CREATE INDEX i1 ON t1(x);}
drh55ef4d92005-08-14 01:20:37 +0000376 queryplan {
drh55ef4d92005-08-14 01:20:37 +0000377 SELECT x FROM t1 WHERE x GLOB 'abc*' ORDER BY 1;
378 }
379} {abc abcd nosort {} i1}
380do_test like-3.20 {
381 set sqlite_like_count
382} 0
383do_test like-3.21 {
384 set sqlite_like_count 0
drh7c171092013-06-03 22:08:20 +0000385 db eval {PRAGMA case_sensitive_like=on;}
drh55ef4d92005-08-14 01:20:37 +0000386 queryplan {
drh55ef4d92005-08-14 01:20:37 +0000387 SELECT x FROM t1 WHERE x GLOB 'abc*' ORDER BY 1;
388 }
389} {abc abcd nosort {} i1}
390do_test like-3.22 {
391 set sqlite_like_count
392} 0
393do_test like-3.23 {
394 set sqlite_like_count 0
drh7c171092013-06-03 22:08:20 +0000395 db eval {PRAGMA case_sensitive_like=off;}
drh55ef4d92005-08-14 01:20:37 +0000396 queryplan {
drh55ef4d92005-08-14 01:20:37 +0000397 SELECT x FROM t1 WHERE x GLOB 'a[bc]d' ORDER BY 1;
398 }
399} {abd acd nosort {} i1}
400do_test like-3.24 {
401 set sqlite_like_count
402} 6
403
drh93ee23c2010-07-22 12:33:57 +0000404# GLOB optimization when there is no wildcard. Ticket [e090183531fc2747]
405#
406do_test like-3.25 {
407 queryplan {
408 SELECT x FROM t1 WHERE x GLOB 'a' ORDER BY 1;
409 }
410} {a nosort {} i1}
411do_test like-3.26 {
412 queryplan {
413 SELECT x FROM t1 WHERE x GLOB 'abcd' ORDER BY 1;
414 }
415} {abcd nosort {} i1}
416do_test like-3.27 {
417 queryplan {
418 SELECT x FROM t1 WHERE x GLOB 'abcde' ORDER BY 1;
419 }
420} {nosort {} i1}
421
422
423
drh8b3d9902005-08-19 00:14:42 +0000424# No optimization if the LHS of the LIKE is not a column name or
425# if the RHS is not a string.
426#
427do_test like-4.1 {
428 execsql {PRAGMA case_sensitive_like=on}
429 set sqlite_like_count 0
430 queryplan {
431 SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1
432 }
433} {abc abcd nosort {} i1}
434do_test like-4.2 {
435 set sqlite_like_count
436} 0
437do_test like-4.3 {
438 set sqlite_like_count 0
439 queryplan {
440 SELECT x FROM t1 WHERE +x LIKE 'abc%' ORDER BY 1
441 }
442} {abc abcd nosort {} i1}
443do_test like-4.4 {
444 set sqlite_like_count
445} 12
446do_test like-4.5 {
447 set sqlite_like_count 0
448 queryplan {
449 SELECT x FROM t1 WHERE x LIKE ('ab' || 'c%') ORDER BY 1
450 }
451} {abc abcd nosort {} i1}
452do_test like-4.6 {
453 set sqlite_like_count
454} 12
455
drhd64fe2f2005-08-28 17:00:23 +0000456# Collating sequences on the index disable the LIKE optimization.
457# Or if the NOCASE collating sequence is used, the LIKE optimization
458# is enabled when case_sensitive_like is OFF.
459#
460do_test like-5.1 {
461 execsql {PRAGMA case_sensitive_like=off}
462 set sqlite_like_count 0
463 queryplan {
464 SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1
465 }
466} {ABC {ABC abc xyz} abc abcd nosort {} i1}
467do_test like-5.2 {
468 set sqlite_like_count
469} 12
470do_test like-5.3 {
471 execsql {
drhc4ac22e2009-06-07 23:45:10 +0000472 CREATE TABLE t2(x TEXT COLLATE NOCASE);
drh3f4d1d12012-09-15 18:45:54 +0000473 INSERT INTO t2 SELECT * FROM t1 ORDER BY rowid;
drhd64fe2f2005-08-28 17:00:23 +0000474 CREATE INDEX i2 ON t2(x COLLATE NOCASE);
475 }
476 set sqlite_like_count 0
477 queryplan {
478 SELECT x FROM t2 WHERE x LIKE 'abc%' ORDER BY 1
479 }
480} {abc ABC {ABC abc xyz} abcd nosort {} i2}
481do_test like-5.4 {
482 set sqlite_like_count
483} 0
484do_test like-5.5 {
485 execsql {
486 PRAGMA case_sensitive_like=on;
487 }
488 set sqlite_like_count 0
489 queryplan {
490 SELECT x FROM t2 WHERE x LIKE 'abc%' ORDER BY 1
491 }
492} {abc abcd nosort {} i2}
493do_test like-5.6 {
494 set sqlite_like_count
495} 12
496do_test like-5.7 {
497 execsql {
498 PRAGMA case_sensitive_like=off;
499 }
500 set sqlite_like_count 0
501 queryplan {
502 SELECT x FROM t2 WHERE x GLOB 'abc*' ORDER BY 1
503 }
504} {abc abcd nosort {} i2}
505do_test like-5.8 {
506 set sqlite_like_count
507} 12
drh9f504ea2008-02-23 21:55:39 +0000508do_test like-5.11 {
509 execsql {PRAGMA case_sensitive_like=off}
510 set sqlite_like_count 0
511 queryplan {
512 SELECT x FROM t1 WHERE x LIKE 'ABC%' ORDER BY 1
513 }
514} {ABC {ABC abc xyz} abc abcd nosort {} i1}
515do_test like-5.12 {
516 set sqlite_like_count
517} 12
518do_test like-5.13 {
519 set sqlite_like_count 0
520 queryplan {
521 SELECT x FROM t2 WHERE x LIKE 'ABC%' ORDER BY 1
522 }
523} {abc ABC {ABC abc xyz} abcd nosort {} i2}
524do_test like-5.14 {
525 set sqlite_like_count
526} 0
527do_test like-5.15 {
528 execsql {
529 PRAGMA case_sensitive_like=on;
530 }
531 set sqlite_like_count 0
532 queryplan {
533 SELECT x FROM t2 WHERE x LIKE 'ABC%' ORDER BY 1
534 }
535} {ABC {ABC abc xyz} nosort {} i2}
536do_test like-5.16 {
537 set sqlite_like_count
538} 12
539do_test like-5.17 {
540 execsql {
541 PRAGMA case_sensitive_like=off;
542 }
543 set sqlite_like_count 0
544 queryplan {
545 SELECT x FROM t2 WHERE x GLOB 'ABC*' ORDER BY 1
546 }
547} {ABC {ABC abc xyz} nosort {} i2}
548do_test like-5.18 {
549 set sqlite_like_count
550} 12
551
552# Boundary case. The prefix for a LIKE comparison is rounded up
553# when constructing the comparison. Example: "ab" becomes "ac".
554# In other words, the last character is increased by one.
555#
556# Make sure this happens correctly when the last character is a
557# "z" and we are doing case-insensitive comparisons.
558#
559# Ticket #2959
560#
561do_test like-5.21 {
562 execsql {
563 PRAGMA case_sensitive_like=off;
564 INSERT INTO t2 VALUES('ZZ-upper-upper');
565 INSERT INTO t2 VALUES('zZ-lower-upper');
566 INSERT INTO t2 VALUES('Zz-upper-lower');
567 INSERT INTO t2 VALUES('zz-lower-lower');
568 }
569 queryplan {
570 SELECT x FROM t2 WHERE x LIKE 'zz%';
571 }
572} {zz-lower-lower zZ-lower-upper Zz-upper-lower ZZ-upper-upper nosort {} i2}
573do_test like-5.22 {
574 queryplan {
575 SELECT x FROM t2 WHERE x LIKE 'zZ%';
576 }
577} {zz-lower-lower zZ-lower-upper Zz-upper-lower ZZ-upper-upper nosort {} i2}
578do_test like-5.23 {
579 queryplan {
580 SELECT x FROM t2 WHERE x LIKE 'Zz%';
581 }
582} {zz-lower-lower zZ-lower-upper Zz-upper-lower ZZ-upper-upper nosort {} i2}
583do_test like-5.24 {
584 queryplan {
585 SELECT x FROM t2 WHERE x LIKE 'ZZ%';
586 }
587} {zz-lower-lower zZ-lower-upper Zz-upper-lower ZZ-upper-upper nosort {} i2}
588do_test like-5.25 {
drh9da058b2011-08-17 00:40:58 +0000589 db eval {
drh9f504ea2008-02-23 21:55:39 +0000590 PRAGMA case_sensitive_like=on;
drhc4ac22e2009-06-07 23:45:10 +0000591 CREATE TABLE t3(x TEXT);
drh9f504ea2008-02-23 21:55:39 +0000592 CREATE INDEX i3 ON t3(x);
593 INSERT INTO t3 VALUES('ZZ-upper-upper');
594 INSERT INTO t3 VALUES('zZ-lower-upper');
595 INSERT INTO t3 VALUES('Zz-upper-lower');
596 INSERT INTO t3 VALUES('zz-lower-lower');
drh9da058b2011-08-17 00:40:58 +0000597 }
598 queryplan {
drh9f504ea2008-02-23 21:55:39 +0000599 SELECT x FROM t3 WHERE x LIKE 'zz%';
600 }
601} {zz-lower-lower nosort {} i3}
602do_test like-5.26 {
603 queryplan {
604 SELECT x FROM t3 WHERE x LIKE 'zZ%';
605 }
606} {zZ-lower-upper nosort {} i3}
607do_test like-5.27 {
608 queryplan {
609 SELECT x FROM t3 WHERE x LIKE 'Zz%';
610 }
611} {Zz-upper-lower nosort {} i3}
612do_test like-5.28 {
613 queryplan {
614 SELECT x FROM t3 WHERE x LIKE 'ZZ%';
615 }
616} {ZZ-upper-upper nosort {} i3}
617
drhd64fe2f2005-08-28 17:00:23 +0000618
drh9c86df52007-06-11 12:56:15 +0000619# ticket #2407
620#
621# Make sure the LIKE prefix optimization does not strip off leading
622# characters of the like pattern that happen to be quote characters.
623#
624do_test like-6.1 {
625 foreach x { 'abc 'bcd 'def 'ax } {
danielk19774152e672007-09-12 17:01:45 +0000626 set x2 '[string map {' ''} $x]'
627 db eval "INSERT INTO t2 VALUES($x2)"
drh9c86df52007-06-11 12:56:15 +0000628 }
629 execsql {
630 SELECT * FROM t2 WHERE x LIKE '''a%'
631 }
632} {'abc 'ax}
drh8b3d9902005-08-19 00:14:42 +0000633
drh01495b92008-01-23 12:52:40 +0000634do_test like-7.1 {
635 execsql {
drhc4ac22e2009-06-07 23:45:10 +0000636 SELECT rowid, * FROM t1 WHERE rowid GLOB '1*' ORDER BY rowid;
drh01495b92008-01-23 12:52:40 +0000637 }
drhc4ac22e2009-06-07 23:45:10 +0000638} {1 a 10 ABC 11 CDE 12 {ABC abc xyz}}
drh01495b92008-01-23 12:52:40 +0000639
drhe3602be2008-09-09 12:31:33 +0000640# ticket #3345.
641#
642# Overloading the LIKE function with -1 for the number of arguments
643# will overload both the 2-argument and the 3-argument LIKE.
644#
645do_test like-8.1 {
646 db eval {
647 CREATE TABLE t8(x);
648 INSERT INTO t8 VALUES('abcdef');
649 INSERT INTO t8 VALUES('ghijkl');
650 INSERT INTO t8 VALUES('mnopqr');
651 SELECT 1, x FROM t8 WHERE x LIKE '%h%';
652 SELECT 2, x FROM t8 WHERE x LIKE '%h%' ESCAPE 'x';
653 }
654} {1 ghijkl 2 ghijkl}
655do_test like-8.2 {
656 proc newlike {args} {return 1} ;# Alternative LIKE is always return TRUE
657 db function like newlike ;# Uses -1 for nArg in sqlite3_create_function
658 db cache flush
659 db eval {
660 SELECT 1, x FROM t8 WHERE x LIKE '%h%';
661 SELECT 2, x FROM t8 WHERE x LIKE '%h%' ESCAPE 'x';
662 }
663} {1 ghijkl 2 ghijkl}
664do_test like-8.3 {
665 db function like -argcount 2 newlike
666 db eval {
667 SELECT 1, x FROM t8 WHERE x LIKE '%h%';
668 SELECT 2, x FROM t8 WHERE x LIKE '%h%' ESCAPE 'x';
669 }
670} {1 abcdef 1 ghijkl 1 mnopqr 2 ghijkl}
671do_test like-8.4 {
672 db function like -argcount 3 newlike
673 db eval {
674 SELECT 1, x FROM t8 WHERE x LIKE '%h%';
675 SELECT 2, x FROM t8 WHERE x LIKE '%h%' ESCAPE 'x';
676 }
677} {1 abcdef 1 ghijkl 1 mnopqr 2 abcdef 2 ghijkl 2 mnopqr}
678
679
dan6bd2c732010-11-01 05:42:26 +0000680ifcapable like_opt&&!icu {
drh5bd98ae2009-01-07 18:24:03 +0000681 # Evaluate SQL. Return the result set followed by the
682 # and the number of full-scan steps.
683 #
684 db close
685 sqlite3 db test.db
686 proc count_steps {sql} {
687 set r [db eval $sql]
688 lappend r scan [db status step] sort [db status sort]
689 }
690 do_test like-9.1 {
691 count_steps {
692 SELECT x FROM t2 WHERE x LIKE 'x%'
693 }
694 } {xyz scan 0 sort 0}
695 do_test like-9.2 {
696 count_steps {
697 SELECT x FROM t2 WHERE x LIKE '_y%'
698 }
699 } {xyz scan 19 sort 0}
700 do_test like-9.3.1 {
701 set res [sqlite3_exec_hex db {
702 SELECT x FROM t2 WHERE x LIKE '%78%25'
703 }]
704 } {0 {x xyz}}
705 ifcapable explain {
706 do_test like-9.3.2 {
707 set res [sqlite3_exec_hex db {
708 EXPLAIN QUERY PLAN SELECT x FROM t2 WHERE x LIKE '%78%25'
709 }]
710 regexp {INDEX i2} $res
711 } {1}
712 }
713 do_test like-9.4.1 {
714 sqlite3_exec_hex db {INSERT INTO t2 VALUES('%ffhello')}
715 set res [sqlite3_exec_hex db {
716 SELECT substr(x,2) AS x FROM t2 WHERE +x LIKE '%ff%25'
717 }]
718 } {0 {x hello}}
719 do_test like-9.4.2 {
720 set res [sqlite3_exec_hex db {
721 SELECT substr(x,2) AS x FROM t2 WHERE x LIKE '%ff%25'
722 }]
723 } {0 {x hello}}
724 ifcapable explain {
725 do_test like-9.4.3 {
726 set res [sqlite3_exec_hex db {
727 EXPLAIN QUERY PLAN SELECT x FROM t2 WHERE x LIKE '%ff%25'
728 }]
drh3f4d1d12012-09-15 18:45:54 +0000729 regexp {SCAN TABLE t2} $res
730 } {1}
drh5bd98ae2009-01-07 18:24:03 +0000731 }
732 do_test like-9.5.1 {
733 set res [sqlite3_exec_hex db {
734 SELECT x FROM t2 WHERE x LIKE '%fe%25'
735 }]
736 } {0 {}}
737 ifcapable explain {
738 do_test like-9.5.2 {
739 set res [sqlite3_exec_hex db {
740 EXPLAIN QUERY PLAN SELECT x FROM t2 WHERE x LIKE '%fe%25'
741 }]
742 regexp {INDEX i2} $res
743 } {1}
744 }
drh5bd98ae2009-01-07 18:24:03 +0000745
dan6bd2c732010-11-01 05:42:26 +0000746 # Do an SQL statement. Append the search count to the end of the result.
747 #
748 proc count sql {
749 set ::sqlite_search_count 0
750 set ::sqlite_like_count 0
751 return [concat [execsql $sql] scan $::sqlite_search_count \
752 like $::sqlite_like_count]
753 }
drhc4ac22e2009-06-07 23:45:10 +0000754
dan6bd2c732010-11-01 05:42:26 +0000755 # The LIKE and GLOB optimizations do not work on columns with
756 # affinity other than TEXT.
757 # Ticket #3901
758 #
759 do_test like-10.1 {
760 db close
761 sqlite3 db test.db
762 execsql {
763 CREATE TABLE t10(
764 a INTEGER PRIMARY KEY,
765 b INTEGER COLLATE nocase UNIQUE,
766 c NUMBER COLLATE nocase UNIQUE,
767 d BLOB COLLATE nocase UNIQUE,
768 e COLLATE nocase UNIQUE,
769 f TEXT COLLATE nocase UNIQUE
770 );
771 INSERT INTO t10 VALUES(1,1,1,1,1,1);
772 INSERT INTO t10 VALUES(12,12,12,12,12,12);
773 INSERT INTO t10 VALUES(123,123,123,123,123,123);
774 INSERT INTO t10 VALUES(234,234,234,234,234,234);
775 INSERT INTO t10 VALUES(345,345,345,345,345,345);
776 INSERT INTO t10 VALUES(45,45,45,45,45,45);
777 }
778 count {
drh083310d2011-01-28 01:57:41 +0000779 SELECT a FROM t10 WHERE b LIKE '12%' ORDER BY +a;
dan6bd2c732010-11-01 05:42:26 +0000780 }
781 } {12 123 scan 5 like 6}
782 do_test like-10.2 {
783 count {
drh083310d2011-01-28 01:57:41 +0000784 SELECT a FROM t10 WHERE c LIKE '12%' ORDER BY +a;
dan6bd2c732010-11-01 05:42:26 +0000785 }
786 } {12 123 scan 5 like 6}
787 do_test like-10.3 {
788 count {
drh083310d2011-01-28 01:57:41 +0000789 SELECT a FROM t10 WHERE d LIKE '12%' ORDER BY +a;
dan6bd2c732010-11-01 05:42:26 +0000790 }
791 } {12 123 scan 5 like 6}
792 do_test like-10.4 {
793 count {
drh083310d2011-01-28 01:57:41 +0000794 SELECT a FROM t10 WHERE e LIKE '12%' ORDER BY +a;
dan6bd2c732010-11-01 05:42:26 +0000795 }
796 } {12 123 scan 5 like 6}
drh41d2e662015-12-01 21:23:07 +0000797 ifcapable like_match_blobs {
798 do_test like-10.5a {
799 count {
800 SELECT a FROM t10 WHERE f LIKE '12%' ORDER BY +a;
801 }
802 } {12 123 scan 4 like 0}
803 } else {
804 do_test like-10.5b {
805 count {
806 SELECT a FROM t10 WHERE f LIKE '12%' ORDER BY +a;
807 }
808 } {12 123 scan 3 like 0}
809 }
dan6bd2c732010-11-01 05:42:26 +0000810 do_test like-10.6 {
811 count {
drh083310d2011-01-28 01:57:41 +0000812 SELECT a FROM t10 WHERE a LIKE '12%' ORDER BY +a;
dan6bd2c732010-11-01 05:42:26 +0000813 }
814 } {12 123 scan 5 like 6}
815 do_test like-10.10 {
816 execsql {
817 CREATE TABLE t10b(
818 a INTEGER PRIMARY KEY,
819 b INTEGER UNIQUE,
820 c NUMBER UNIQUE,
821 d BLOB UNIQUE,
822 e UNIQUE,
823 f TEXT UNIQUE
824 );
825 INSERT INTO t10b SELECT * FROM t10;
826 }
827 count {
drh083310d2011-01-28 01:57:41 +0000828 SELECT a FROM t10b WHERE b GLOB '12*' ORDER BY +a;
dan6bd2c732010-11-01 05:42:26 +0000829 }
830 } {12 123 scan 5 like 6}
831 do_test like-10.11 {
832 count {
drh083310d2011-01-28 01:57:41 +0000833 SELECT a FROM t10b WHERE c GLOB '12*' ORDER BY +a;
dan6bd2c732010-11-01 05:42:26 +0000834 }
835 } {12 123 scan 5 like 6}
836 do_test like-10.12 {
837 count {
drh083310d2011-01-28 01:57:41 +0000838 SELECT a FROM t10b WHERE d GLOB '12*' ORDER BY +a;
dan6bd2c732010-11-01 05:42:26 +0000839 }
840 } {12 123 scan 5 like 6}
841 do_test like-10.13 {
842 count {
drh083310d2011-01-28 01:57:41 +0000843 SELECT a FROM t10b WHERE e GLOB '12*' ORDER BY +a;
dan6bd2c732010-11-01 05:42:26 +0000844 }
845 } {12 123 scan 5 like 6}
drh41d2e662015-12-01 21:23:07 +0000846 ifcapable like_match_blobs {
847 do_test like-10.14 {
848 count {
849 SELECT a FROM t10b WHERE f GLOB '12*' ORDER BY +a;
850 }
851 } {12 123 scan 4 like 0}
852 } else {
853 do_test like-10.14 {
854 count {
855 SELECT a FROM t10b WHERE f GLOB '12*' ORDER BY +a;
856 }
857 } {12 123 scan 3 like 0}
858 }
dan6bd2c732010-11-01 05:42:26 +0000859 do_test like-10.15 {
860 count {
drh083310d2011-01-28 01:57:41 +0000861 SELECT a FROM t10b WHERE a GLOB '12*' ORDER BY +a;
dan6bd2c732010-11-01 05:42:26 +0000862 }
863 } {12 123 scan 5 like 6}
864}
drhc4ac22e2009-06-07 23:45:10 +0000865
drh8342e492010-07-22 17:49:52 +0000866# LIKE and GLOB where the default collating sequence is not appropriate
867# but an index with the appropriate collating sequence exists.
868#
869do_test like-11.0 {
870 execsql {
871 CREATE TABLE t11(
872 a INTEGER PRIMARY KEY,
873 b TEXT COLLATE nocase,
874 c TEXT COLLATE binary
875 );
876 INSERT INTO t11 VALUES(1, 'a','a');
877 INSERT INTO t11 VALUES(2, 'ab','ab');
878 INSERT INTO t11 VALUES(3, 'abc','abc');
879 INSERT INTO t11 VALUES(4, 'abcd','abcd');
880 INSERT INTO t11 VALUES(5, 'A','A');
881 INSERT INTO t11 VALUES(6, 'AB','AB');
882 INSERT INTO t11 VALUES(7, 'ABC','ABC');
883 INSERT INTO t11 VALUES(8, 'ABCD','ABCD');
884 INSERT INTO t11 VALUES(9, 'x','x');
885 INSERT INTO t11 VALUES(10, 'yz','yz');
886 INSERT INTO t11 VALUES(11, 'X','X');
887 INSERT INTO t11 VALUES(12, 'YZ','YZ');
888 SELECT count(*) FROM t11;
889 }
890} {12}
891do_test like-11.1 {
drh7c171092013-06-03 22:08:20 +0000892 db eval {PRAGMA case_sensitive_like=OFF;}
drh8342e492010-07-22 17:49:52 +0000893 queryplan {
drh8342e492010-07-22 17:49:52 +0000894 SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY a;
895 }
896} {abc abcd ABC ABCD nosort t11 *}
897do_test like-11.2 {
drh7c171092013-06-03 22:08:20 +0000898 db eval {PRAGMA case_sensitive_like=ON;}
drh8342e492010-07-22 17:49:52 +0000899 queryplan {
drh8342e492010-07-22 17:49:52 +0000900 SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY a;
901 }
902} {abc abcd nosort t11 *}
903do_test like-11.3 {
drh7c171092013-06-03 22:08:20 +0000904 db eval {
drh8342e492010-07-22 17:49:52 +0000905 PRAGMA case_sensitive_like=OFF;
906 CREATE INDEX t11b ON t11(b);
drh7c171092013-06-03 22:08:20 +0000907 }
908 queryplan {
drh083310d2011-01-28 01:57:41 +0000909 SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY +a;
drh8342e492010-07-22 17:49:52 +0000910 }
911} {abc abcd ABC ABCD sort {} t11b}
912do_test like-11.4 {
drh7c171092013-06-03 22:08:20 +0000913 db eval {PRAGMA case_sensitive_like=ON;}
drh8342e492010-07-22 17:49:52 +0000914 queryplan {
drh8342e492010-07-22 17:49:52 +0000915 SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY a;
916 }
917} {abc abcd nosort t11 *}
918do_test like-11.5 {
drh7c171092013-06-03 22:08:20 +0000919 db eval {
drh8342e492010-07-22 17:49:52 +0000920 PRAGMA case_sensitive_like=OFF;
921 DROP INDEX t11b;
922 CREATE INDEX t11bnc ON t11(b COLLATE nocase);
drh7c171092013-06-03 22:08:20 +0000923 }
924 queryplan {
drh083310d2011-01-28 01:57:41 +0000925 SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY +a;
drh8342e492010-07-22 17:49:52 +0000926 }
927} {abc abcd ABC ABCD sort {} t11bnc}
928do_test like-11.6 {
drh7c171092013-06-03 22:08:20 +0000929 db eval {CREATE INDEX t11bb ON t11(b COLLATE binary);}
drh8342e492010-07-22 17:49:52 +0000930 queryplan {
drh083310d2011-01-28 01:57:41 +0000931 SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY +a;
drh8342e492010-07-22 17:49:52 +0000932 }
933} {abc abcd ABC ABCD sort {} t11bnc}
934do_test like-11.7 {
drh7c171092013-06-03 22:08:20 +0000935 db eval {PRAGMA case_sensitive_like=ON;}
drh8342e492010-07-22 17:49:52 +0000936 queryplan {
drh083310d2011-01-28 01:57:41 +0000937 SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY +a;
drh8342e492010-07-22 17:49:52 +0000938 }
939} {abc abcd sort {} t11bb}
940do_test like-11.8 {
drh7c171092013-06-03 22:08:20 +0000941 db eval {PRAGMA case_sensitive_like=OFF;}
drh8342e492010-07-22 17:49:52 +0000942 queryplan {
drh083310d2011-01-28 01:57:41 +0000943 SELECT b FROM t11 WHERE b GLOB 'abc*' ORDER BY +a;
drh8342e492010-07-22 17:49:52 +0000944 }
945} {abc abcd sort {} t11bb}
946do_test like-11.9 {
drh7c171092013-06-03 22:08:20 +0000947 db eval {
drh8342e492010-07-22 17:49:52 +0000948 CREATE INDEX t11cnc ON t11(c COLLATE nocase);
949 CREATE INDEX t11cb ON t11(c COLLATE binary);
drh7c171092013-06-03 22:08:20 +0000950 }
951 queryplan {
drh083310d2011-01-28 01:57:41 +0000952 SELECT c FROM t11 WHERE c LIKE 'abc%' ORDER BY +a;
drh8342e492010-07-22 17:49:52 +0000953 }
954} {abc abcd ABC ABCD sort {} t11cnc}
955do_test like-11.10 {
956 queryplan {
drh083310d2011-01-28 01:57:41 +0000957 SELECT c FROM t11 WHERE c GLOB 'abc*' ORDER BY +a;
drh8342e492010-07-22 17:49:52 +0000958 }
959} {abc abcd sort {} t11cb}
960
drh6ade4532014-01-16 15:31:41 +0000961# A COLLATE clause on the pattern does not change the result of a
962# LIKE operator.
963#
964do_execsql_test like-12.1 {
965 CREATE TABLE t12nc(id INTEGER, x TEXT UNIQUE COLLATE nocase);
966 INSERT INTO t12nc VALUES(1,'abcde'),(2,'uvwxy'),(3,'ABCDEF');
967 CREATE TABLE t12b(id INTEGER, x TEXT UNIQUE COLLATE binary);
968 INSERT INTO t12b VALUES(1,'abcde'),(2,'uvwxy'),(3,'ABCDEF');
969 SELECT id FROM t12nc WHERE x LIKE 'abc%' ORDER BY +id;
970} {1 3}
971do_execsql_test like-12.2 {
972 SELECT id FROM t12b WHERE x LIKE 'abc%' ORDER BY +id;
973} {1 3}
974do_execsql_test like-12.3 {
975 SELECT id FROM t12nc WHERE x LIKE 'abc%' COLLATE binary ORDER BY +id;
976} {1 3}
977do_execsql_test like-12.4 {
978 SELECT id FROM t12b WHERE x LIKE 'abc%' COLLATE binary ORDER BY +id;
979} {1 3}
980do_execsql_test like-12.5 {
981 SELECT id FROM t12nc WHERE x LIKE 'abc%' COLLATE nocase ORDER BY +id;
982} {1 3}
983do_execsql_test like-12.6 {
984 SELECT id FROM t12b WHERE x LIKE 'abc%' COLLATE nocase ORDER BY +id;
985} {1 3}
986
987# Adding a COLLATE clause to the pattern of a LIKE operator does nothing
988# to change the suitability of using an index to satisfy that LIKE
989# operator.
990#
991do_execsql_test like-12.11 {
992 EXPLAIN QUERY PLAN
993 SELECT id FROM t12nc WHERE x LIKE 'abc%' ORDER BY +id;
994} {/SEARCH/}
995do_execsql_test like-12.12 {
996 EXPLAIN QUERY PLAN
997 SELECT id FROM t12b WHERE x LIKE 'abc%' ORDER BY +id;
998} {/SCAN/}
999do_execsql_test like-12.13 {
1000 EXPLAIN QUERY PLAN
1001 SELECT id FROM t12nc WHERE x LIKE 'abc%' COLLATE nocase ORDER BY +id;
1002} {/SEARCH/}
1003do_execsql_test like-12.14 {
1004 EXPLAIN QUERY PLAN
1005 SELECT id FROM t12b WHERE x LIKE 'abc%' COLLATE nocase ORDER BY +id;
1006} {/SCAN/}
1007do_execsql_test like-12.15 {
1008 EXPLAIN QUERY PLAN
1009 SELECT id FROM t12nc WHERE x LIKE 'abc%' COLLATE binary ORDER BY +id;
1010} {/SEARCH/}
1011do_execsql_test like-12.16 {
1012 EXPLAIN QUERY PLAN
1013 SELECT id FROM t12b WHERE x LIKE 'abc%' COLLATE binary ORDER BY +id;
1014} {/SCAN/}
1015
drhfb397262016-01-20 14:22:41 +00001016# Ticket [https://www.sqlite.org/src/tktview/80369eddd5c94d49f7fbbcf5]
1017# 2016-01-20
1018#
1019do_execsql_test like-13.1 {
1020 SELECT char(0x304d) LIKE char(0x306d);
1021} {0}
1022do_execsql_test like-13.2 {
1023 SELECT char(0x4d) LIKE char(0x306d);
1024} {0}
1025do_execsql_test like-13.3 {
1026 SELECT char(0x304d) LIKE char(0x6d);
1027} {0}
1028do_execsql_test like-13.4 {
1029 SELECT char(0x4d) LIKE char(0x6d);
1030} {1}
1031
drh7a407072016-12-02 02:19:24 +00001032# Performance testing for patterns with many wildcards. These LIKE and GLOB
1033# patterns were quite slow with SQLite 3.15.2 and earlier.
1034#
1035do_test like-14.1 {
1036 set x [lindex [time {
1037 db one {SELECT 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaz'GLOB'*a*a*a*a*a*a*a*a*y'}
1038 }] 0]
1039 puts -nonewline " ($x ms - want less than 1000) "
1040 expr {$x<1000}
1041} {1}
1042ifcapable !icu {
1043 do_test like-14.2 {
1044 set x [lindex [time {
1045 db one {SELECT 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaz'LIKE'%a%a%a%a%a%a%a%a%y'}
1046 }] 0]
1047 puts -nonewline " ($x ms - want less than 1000) "
1048 expr {$x<1000}
1049 } {1}
1050}
drh5bd98ae2009-01-07 18:24:03 +00001051
drh9325c872017-09-27 16:51:00 +00001052ifcapable !icu {
drh1d42ea72017-07-27 20:24:29 +00001053# As of 2017-07-27 (3.21.0) the LIKE optimization works with ESCAPE as
1054# long as the ESCAPE is a single-byte literal.
1055#
1056db close
1057sqlite3 db :memory:
1058do_execsql_test like-15.100 {
1059 CREATE TABLE t15(x TEXT COLLATE nocase, y, PRIMARY KEY(x));
1060 INSERT INTO t15(x,y) VALUES
1061 ('abcde',1), ('ab%de',2), ('a_cde',3),
1062 ('uvwxy',11),('uvwx%',12),('uvwx_',13),
1063 ('_bcde',21),('%bcde',22),
1064 ('abcd_',31),('abcd%',32),
1065 ('ab%xy',41);
1066 SELECT y FROM t15 WHERE x LIKE 'ab/%d%' ESCAPE '/';
1067} {2}
1068do_execsql_test like-15.101 {
1069 EXPLAIN QUERY PLAN
1070 SELECT y FROM t15 WHERE x LIKE 'ab/%d%' ESCAPE '/';
1071} {/SEARCH/}
1072do_execsql_test like-15.102 {
1073 EXPLAIN QUERY PLAN
1074 SELECT y FROM t15 WHERE x LIKE 'ab/%d%' ESCAPE '//';
1075} {/SCAN/}
1076do_execsql_test like-15.103 {
1077 EXPLAIN QUERY PLAN
1078 SELECT y FROM t15 WHERE x LIKE 'ab/%d%' ESCAPE '';
1079} {/SCAN/}
1080do_execsql_test like-15.110 {
1081 SELECT y FROM t15 WHERE x LIKE 'abcdx%%' ESCAPE 'x';
1082} {32}
1083do_execsql_test like-15.111 {
1084 SELECT y FROM t15 WHERE x LIKE 'abx%%' ESCAPE 'x' ORDER BY +y
1085} {2 41}
1086do_execsql_test like-15.112 {
1087 EXPLAIN QUERY PLAN
1088 SELECT y FROM t15 WHERE x LIKE 'abx%%' ESCAPE 'x' ORDER BY +y
1089} {/SEARCH/}
1090do_execsql_test like-15.120 {
1091 SELECT y FROM t15 WHERE x LIKE '/%bc%' ESCAPE '/';
1092} {22}
1093do_execsql_test like-15.121 {
1094 EXPLAIN QUERY PLAN
1095 SELECT y FROM t15 WHERE x LIKE '/%bc%' ESCAPE '/';
1096} {/SEARCH/}
drh9325c872017-09-27 16:51:00 +00001097}
drh1d42ea72017-07-27 20:24:29 +00001098
dan32d0f642019-06-10 13:46:42 +00001099#-------------------------------------------------------------------------
1100# Tests for ticket [b1d8c79314].
1101#
1102reset_db
1103do_execsql_test 16.0 {
1104 CREATE TABLE t1(a INTEGER COLLATE NOCASE);
1105 CREATE INDEX i1 ON t1(a);
1106 INSERT INTO t1 VALUES(' 1x');
1107 INSERT INTO t1 VALUES(' 1-');
1108}
1109do_execsql_test 16.1 {
1110 SELECT * FROM t1 WHERE a LIKE ' 1%';
1111} {{ 1x} { 1-}}
1112do_execsql_test 16.2 {
1113 SELECT * FROM t1 WHERE a LIKE ' 1-';
1114} {{ 1-}}
1115
drh589c7872020-03-19 18:13:28 +00001116# 2020-03-19
1117# The ESCAPE clause on LIKE takes precedence over wildcards
1118#
1119do_execsql_test 17.0 {
1120 DROP TABLE IF EXISTS t1;
1121 CREATE TABLE t1(id INTEGER PRIMARY KEY, x TEXT);
1122 INSERT INTO t1 VALUES
1123 (1,'abcde'),
1124 (2,'abc_'),
1125 (3,'abc__'),
1126 (4,'abc%'),
1127 (5,'abc%%');
1128 SELECT id FROM t1 WHERE x LIKE 'abc%%' ESCAPE '%';
1129} {4}
1130do_execsql_test 17.1 {
1131 SELECT id FROM t1 WHERE x LIKE 'abc__' ESCAPE '_';
1132} {2}
1133
drh33941692021-02-15 17:02:01 +00001134# 2021-02-15 ticket c0aeea67d58ae0fd
1135#
1136do_execsql_test 17.1 {
1137 SELECT 'x' LIKE '%' ESCAPE '_';
1138} {1}
1139
1140
drh55ef4d92005-08-14 01:20:37 +00001141finish_test