Compute the correct column name even if the column identifier is the
[sqlite.git] / test / like.test
blobe5324aee252aa3c007fedd0a0fe295711b7e4677
1 # 2005 August 13
3 # The author disclaims copyright to this source code.  In place of
4 # a legal notice, here is a blessing:
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.
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.
16 # $Id: like.test,v 1.13 2009/06/07 23:45:11 drh Exp $
18 set testdir [file dirname $argv0]
19 source $testdir/tester.tcl
21 # Create some sample data to work with.
23 do_test like-1.0 {
24   execsql {
25     CREATE TABLE t1(x TEXT);
26   }
27   foreach str {
28     a
29     ab
30     abc
31     abcd
33     acd
34     abd
35     bc
36     bcd
38     xyz
39     ABC
40     CDE
41     {ABC abc xyz}
42   } {
43     db eval {INSERT INTO t1 VALUES(:str)}
44   }
45   execsql {
46     SELECT count(*) FROM t1;
47   }
48 } {12}
50 # Test that both case sensitive and insensitive version of LIKE work.
52 do_test like-1.1 {
53   execsql {
54     SELECT x FROM t1 WHERE x LIKE 'abc' ORDER BY 1;
55   }
56 } {ABC abc}
57 do_test like-1.2 {
58   execsql {
59     SELECT x FROM t1 WHERE x GLOB 'abc' ORDER BY 1;
60   }
61 } {abc}
62 do_test like-1.3 {
63   execsql {
64     SELECT x FROM t1 WHERE x LIKE 'ABC' ORDER BY 1;
65   }
66 } {ABC abc}
67 do_test like-1.4 {
68   execsql {
69     SELECT x FROM t1 WHERE x LIKE 'aBc' ORDER BY 1;
70   }
71 } {ABC abc}
72 do_test like-1.5.1 {
73   # Use sqlite3_exec() to verify fix for ticket [25ee81271091] 2011-06-26
74   sqlite3_exec db {PRAGMA case_sensitive_like=on}
75 } {0 {}}
76 do_test like-1.5.2 {
77   execsql {
78     SELECT x FROM t1 WHERE x LIKE 'abc' ORDER BY 1;
79   }
80 } {abc}
81 do_test like-1.5.3 {
82   execsql {
83     PRAGMA case_sensitive_like; -- no argument; does not change setting
84     SELECT x FROM t1 WHERE x LIKE 'abc' ORDER BY 1;
85   }
86 } {abc}
87 do_test like-1.6 {
88   execsql {
89     SELECT x FROM t1 WHERE x GLOB 'abc' ORDER BY 1;
90   }
91 } {abc}
92 do_test like-1.7 {
93   execsql {
94     SELECT x FROM t1 WHERE x LIKE 'ABC' ORDER BY 1;
95   }
96 } {ABC}
97 do_test like-1.8 {
98   execsql {
99     SELECT x FROM t1 WHERE x LIKE 'aBc' ORDER BY 1;
100   }
101 } {}
102 do_test like-1.9 {
103   execsql {
104     PRAGMA case_sensitive_like=off;
105     SELECT x FROM t1 WHERE x LIKE 'abc' ORDER BY 1;
106   }
107 } {ABC abc}
108 do_test like-1.10 {
109   execsql {
110     PRAGMA case_sensitive_like;  -- No argument, does not change setting.
111     SELECT x FROM t1 WHERE x LIKE 'abc' ORDER BY 1;
112   }
113 } {ABC abc}
115 # Tests of the REGEXP operator
117 do_test like-2.1 {
118   proc test_regexp {a b} {
119     return [regexp $a $b]
120   }
121   db function regexp -argcount 2 test_regexp
122   execsql {
123     SELECT x FROM t1 WHERE x REGEXP 'abc' ORDER BY 1;
124   }
125 } {{ABC abc xyz} abc abcd}
126 do_test like-2.2 {
127   execsql {
128     SELECT x FROM t1 WHERE x REGEXP '^abc' ORDER BY 1;
129   }
130 } {abc abcd}
132 # Tests of the MATCH operator
134 do_test like-2.3 {
135   proc test_match {a b} {
136     return [string match $a $b]
137   }
138   db function match -argcount 2 test_match
139   execsql {
140     SELECT x FROM t1 WHERE x MATCH '*abc*' ORDER BY 1;
141   }
142 } {{ABC abc xyz} abc abcd}
143 do_test like-2.4 {
144   execsql {
145     SELECT x FROM t1 WHERE x MATCH 'abc*' ORDER BY 1;
146   }
147 } {abc abcd}
149 # For the remaining tests, we need to have the like optimizations
150 # enabled.
152 ifcapable !like_opt {
153   finish_test
154   return
157 # This procedure executes the SQL.  Then it appends to the result the
158 # "sort" or "nosort" keyword (as in the cksort procedure above) then
159 # it appends the names of the table and index used.
161 proc queryplan {sql} {
162   set ::sqlite_sort_count 0
163   db cache flush
164   set data [execsql $sql]
165   if {$::sqlite_sort_count} {set x sort} {set x nosort}
166   lappend data $x
167   set eqp [execsql "EXPLAIN QUERY PLAN $sql"]
168   # puts eqp=$eqp
169   foreach {a b c x} $eqp {
170     if {[regexp { TABLE (\w+ AS )?(\w+) USING COVERING INDEX (\w+)\y} \
171         $x all as tab idx]} {
172       lappend data {} $idx
173     } elseif {[regexp { TABLE (\w+ AS )?(\w+) USING.* INDEX (\w+)\y} \
174         $x all as tab idx]} {
175       lappend data $tab $idx
176     } elseif {[regexp { TABLE (\w+ AS )?(\w+)\y} $x all as tab]} {
177       lappend data $tab *
178     }
179   }
180   return $data   
183 # Perform tests on the like optimization.
185 # With no index on t1.x and with case sensitivity turned off, no optimization
186 # is performed.
188 do_test like-3.1 {
189   set sqlite_like_count 0
190   queryplan {
191     SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1;
192   }
193 } {ABC {ABC abc xyz} abc abcd sort t1 *}
194 do_test like-3.2 {
195   set sqlite_like_count
196 } {12}
198 # With an index on t1.x and case sensitivity on, optimize completely.
200 do_test like-3.3.100 {
201   set sqlite_like_count 0
202   execsql {
203     PRAGMA case_sensitive_like=on;
204     CREATE INDEX i1 ON t1(x);
205   }
206   queryplan {
207     SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1;
208   }
209 } {abc abcd nosort {} i1}
210 do_test like-3.3.100.cnt {
211   set sqlite_like_count
212 } 0
214 # The like optimization works even when the pattern is a bound parameter
216 # Exception: It does not work if sqlite3_prepare() is used instead of
217 # sqlite3_prepare_v2(), as in that case the statement cannot be reprepared
218 # after the parameter is bound.
220 unset -nocomplain ::likepat
221 set ::likepat abc%
222 if {[permutation]!="prepare"} {
223   do_test like-3.3.102 {
224     set sqlite_like_count 0
225     queryplan {
226       SELECT x FROM t1 WHERE x LIKE $::likepat ORDER BY 1;
227     }
228   } {abc abcd nosort {} i1}
229   do_test like-3.3.103 {
230     set sqlite_like_count
231   } 0
234 # Except, the like optimization does not work for bound parameters if
235 # the query planner stability guarantee is active.
237 do_test like-3.3.104 {
238   set sqlite_like_count 0
239   sqlite3_db_config db QPSG 1
240   queryplan {
241     SELECT x FROM t1 WHERE x LIKE $::likepat ORDER BY 1;
242   }
243 } {abc abcd nosort {} i1}
244 do_test like-3.3.105 {
245   set sqlite_like_count
246 } 12
248 # The query planner stability guarantee does not disrupt explicit patterns
250 do_test like-3.3.105 {
251   set sqlite_like_count 0
252   queryplan {
253     SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1;
254   }
255 } {abc abcd nosort {} i1}
256 do_test like-3.3.106 {
257   set sqlite_like_count
258 } 0
259 sqlite3_db_config db QPSG 0
261 # The LIKE optimization still works when the RHS is a string with no
262 # wildcard.  Ticket [e090183531fc2747]
264 do_test like-3.4.2 {
265   queryplan {
266     SELECT x FROM t1 WHERE x LIKE 'a' ORDER BY 1;
267   }
268 } {a nosort {} i1}
269 do_test like-3.4.3 {
270   queryplan {
271     SELECT x FROM t1 WHERE x LIKE 'ab' ORDER BY 1;
272   }
273 } {ab nosort {} i1}
274 do_test like-3.4.4 {
275   queryplan {
276     SELECT x FROM t1 WHERE x LIKE 'abcd' ORDER BY 1;
277   }
278 } {abcd nosort {} i1}
279 do_test like-3.4.5 {
280   queryplan {
281     SELECT x FROM t1 WHERE x LIKE 'abcde' ORDER BY 1;
282   }
283 } {nosort {} i1}
286 # Partial optimization when the pattern does not end in '%'
288 do_test like-3.5 {
289   set sqlite_like_count 0
290   queryplan {
291     SELECT x FROM t1 WHERE x LIKE 'a_c' ORDER BY 1;
292   }
293 } {abc nosort {} i1}
294 do_test like-3.6 {
295   set sqlite_like_count
296 } 6
297 do_test like-3.7 {
298   set sqlite_like_count 0
299   queryplan {
300     SELECT x FROM t1 WHERE x LIKE 'ab%d' ORDER BY 1;
301   }
302 } {abcd abd nosort {} i1}
303 do_test like-3.8 {
304   set sqlite_like_count
305 } 4
306 do_test like-3.9 {
307   set sqlite_like_count 0
308   queryplan {
309     SELECT x FROM t1 WHERE x LIKE 'a_c%' ORDER BY 1;
310   }
311 } {abc abcd nosort {} i1}
312 do_test like-3.10 {
313   set sqlite_like_count
314 } 6
316 # No optimization when the pattern begins with a wildcard.
317 # Note that the index is still used but only for sorting.
319 do_test like-3.11 {
320   set sqlite_like_count 0
321   queryplan {
322     SELECT x FROM t1 WHERE x LIKE '%bcd' ORDER BY 1;
323   }
324 } {abcd bcd nosort {} i1}
325 do_test like-3.12 {
326   set sqlite_like_count
327 } 12
329 # No optimization for case insensitive LIKE
331 do_test like-3.13 {
332   set sqlite_like_count 0
333   db eval {PRAGMA case_sensitive_like=off;}
334   queryplan {
335     SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1;
336   }
337 } {ABC {ABC abc xyz} abc abcd nosort {} i1}
338 do_test like-3.14 {
339   set sqlite_like_count
340 } 12
342 # No optimization without an index.
344 do_test like-3.15 {
345   set sqlite_like_count 0
346   db eval {
347     PRAGMA case_sensitive_like=on;
348     DROP INDEX i1;
349   }
350   queryplan {
351     SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1;
352   }
353 } {abc abcd sort t1 *}
354 do_test like-3.16 {
355   set sqlite_like_count
356 } 12
358 # No GLOB optimization without an index.
360 do_test like-3.17 {
361   set sqlite_like_count 0
362   queryplan {
363     SELECT x FROM t1 WHERE x GLOB 'abc*' ORDER BY 1;
364   }
365 } {abc abcd sort t1 *}
366 do_test like-3.18 {
367   set sqlite_like_count
368 } 12
370 # GLOB is optimized regardless of the case_sensitive_like setting.
372 do_test like-3.19 {
373   set sqlite_like_count 0
374   db eval {CREATE INDEX i1 ON t1(x);}
375   queryplan {
376     SELECT x FROM t1 WHERE x GLOB 'abc*' ORDER BY 1;
377   }
378 } {abc abcd nosort {} i1}
379 do_test like-3.20 {
380   set sqlite_like_count
381 } 0
382 do_test like-3.21 {
383   set sqlite_like_count 0
384   db eval {PRAGMA case_sensitive_like=on;}
385   queryplan {
386     SELECT x FROM t1 WHERE x GLOB 'abc*' ORDER BY 1;
387   }
388 } {abc abcd nosort {} i1}
389 do_test like-3.22 {
390   set sqlite_like_count
391 } 0
392 do_test like-3.23 {
393   set sqlite_like_count 0
394   db eval {PRAGMA case_sensitive_like=off;}
395   queryplan {
396     SELECT x FROM t1 WHERE x GLOB 'a[bc]d' ORDER BY 1;
397   }
398 } {abd acd nosort {} i1}
399 do_test like-3.24 {
400   set sqlite_like_count
401 } 6
403 # GLOB optimization when there is no wildcard.  Ticket [e090183531fc2747]
405 do_test like-3.25 {
406   queryplan {
407     SELECT x FROM t1 WHERE x GLOB 'a' ORDER BY 1;
408   }
409 } {a nosort {} i1}
410 do_test like-3.26 {
411   queryplan {
412     SELECT x FROM t1 WHERE x GLOB 'abcd' ORDER BY 1;
413   }
414 } {abcd nosort {} i1}
415 do_test like-3.27 {
416   queryplan {
417     SELECT x FROM t1 WHERE x GLOB 'abcde' ORDER BY 1;
418   }
419 } {nosort {} i1}
423 # No optimization if the LHS of the LIKE is not a column name or
424 # if the RHS is not a string.
426 do_test like-4.1 {
427   execsql {PRAGMA case_sensitive_like=on}
428   set sqlite_like_count 0
429   queryplan {
430     SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1
431   }
432 } {abc abcd nosort {} i1}
433 do_test like-4.2 {
434   set sqlite_like_count
435 } 0
436 do_test like-4.3 {
437   set sqlite_like_count 0
438   queryplan {
439     SELECT x FROM t1 WHERE +x LIKE 'abc%' ORDER BY 1
440   }
441 } {abc abcd nosort {} i1}
442 do_test like-4.4 {
443   set sqlite_like_count
444 } 12
445 do_test like-4.5 {
446   set sqlite_like_count 0
447   queryplan {
448     SELECT x FROM t1 WHERE x LIKE ('ab' || 'c%') ORDER BY 1
449   }
450 } {abc abcd nosort {} i1}
451 do_test like-4.6 {
452   set sqlite_like_count
453 } 12
455 # Collating sequences on the index disable the LIKE optimization.
456 # Or if the NOCASE collating sequence is used, the LIKE optimization
457 # is enabled when case_sensitive_like is OFF.
459 do_test like-5.1 {
460   execsql {PRAGMA case_sensitive_like=off}
461   set sqlite_like_count 0
462   queryplan {
463     SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1
464   }
465 } {ABC {ABC abc xyz} abc abcd nosort {} i1}
466 do_test like-5.2 {
467   set sqlite_like_count
468 } 12
469 do_test like-5.3 {
470   execsql {
471     CREATE TABLE t2(x TEXT COLLATE NOCASE);
472     INSERT INTO t2 SELECT * FROM t1 ORDER BY rowid;
473     CREATE INDEX i2 ON t2(x COLLATE NOCASE);
474   }
475   set sqlite_like_count 0
476   queryplan {
477     SELECT x FROM t2 WHERE x LIKE 'abc%' ORDER BY 1
478   }
479 } {abc ABC {ABC abc xyz} abcd nosort {} i2}
480 do_test like-5.4 {
481   set sqlite_like_count
482 } 0
483 do_test like-5.5 {
484   execsql {
485     PRAGMA case_sensitive_like=on;
486   }
487   set sqlite_like_count 0
488   queryplan {
489     SELECT x FROM t2 WHERE x LIKE 'abc%' ORDER BY 1
490   }
491 } {abc abcd nosort {} i2}
492 do_test like-5.6 {
493   set sqlite_like_count
494 } 12
495 do_test like-5.7 {
496   execsql {
497     PRAGMA case_sensitive_like=off;
498   }
499   set sqlite_like_count 0
500   queryplan {
501     SELECT x FROM t2 WHERE x GLOB 'abc*' ORDER BY 1
502   }
503 } {abc abcd nosort {} i2}
504 do_test like-5.8 {
505   set sqlite_like_count
506 } 12
507 do_test like-5.11 {
508   execsql {PRAGMA case_sensitive_like=off}
509   set sqlite_like_count 0
510   queryplan {
511     SELECT x FROM t1 WHERE x LIKE 'ABC%' ORDER BY 1
512   }
513 } {ABC {ABC abc xyz} abc abcd nosort {} i1}
514 do_test like-5.12 {
515   set sqlite_like_count
516 } 12
517 do_test like-5.13 {
518   set sqlite_like_count 0
519   queryplan {
520     SELECT x FROM t2 WHERE x LIKE 'ABC%' ORDER BY 1
521   }
522 } {abc ABC {ABC abc xyz} abcd nosort {} i2}
523 do_test like-5.14 {
524   set sqlite_like_count
525 } 0
526 do_test like-5.15 {
527   execsql {
528     PRAGMA case_sensitive_like=on;
529   }
530   set sqlite_like_count 0
531   queryplan {
532     SELECT x FROM t2 WHERE x LIKE 'ABC%' ORDER BY 1
533   }
534 } {ABC {ABC abc xyz} nosort {} i2}
535 do_test like-5.16 {
536   set sqlite_like_count
537 } 12
538 do_test like-5.17 {
539   execsql {
540     PRAGMA case_sensitive_like=off;
541   }
542   set sqlite_like_count 0
543   queryplan {
544     SELECT x FROM t2 WHERE x GLOB 'ABC*' ORDER BY 1
545   }
546 } {ABC {ABC abc xyz} nosort {} i2}
547 do_test like-5.18 {
548   set sqlite_like_count
549 } 12
551 # Boundary case.  The prefix for a LIKE comparison is rounded up
552 # when constructing the comparison.  Example:  "ab" becomes "ac".
553 # In other words, the last character is increased by one.
555 # Make sure this happens correctly when the last character is a 
556 # "z" and we are doing case-insensitive comparisons.
558 # Ticket #2959
560 do_test like-5.21 {
561   execsql {
562     PRAGMA case_sensitive_like=off;
563     INSERT INTO t2 VALUES('ZZ-upper-upper');
564     INSERT INTO t2 VALUES('zZ-lower-upper');
565     INSERT INTO t2 VALUES('Zz-upper-lower');
566     INSERT INTO t2 VALUES('zz-lower-lower');
567   }
568   queryplan {
569     SELECT x FROM t2 WHERE x LIKE 'zz%';
570   }
571 } {zz-lower-lower zZ-lower-upper Zz-upper-lower ZZ-upper-upper nosort {} i2}
572 do_test like-5.22 {
573   queryplan {
574     SELECT x FROM t2 WHERE x LIKE 'zZ%';
575   }
576 } {zz-lower-lower zZ-lower-upper Zz-upper-lower ZZ-upper-upper nosort {} i2}
577 do_test like-5.23 {
578   queryplan {
579     SELECT x FROM t2 WHERE x LIKE 'Zz%';
580   }
581 } {zz-lower-lower zZ-lower-upper Zz-upper-lower ZZ-upper-upper nosort {} i2}
582 do_test like-5.24 {
583   queryplan {
584     SELECT x FROM t2 WHERE x LIKE 'ZZ%';
585   }
586 } {zz-lower-lower zZ-lower-upper Zz-upper-lower ZZ-upper-upper nosort {} i2}
587 do_test like-5.25 {
588   db eval {
589     PRAGMA case_sensitive_like=on;
590     CREATE TABLE t3(x TEXT);
591     CREATE INDEX i3 ON t3(x);
592     INSERT INTO t3 VALUES('ZZ-upper-upper');
593     INSERT INTO t3 VALUES('zZ-lower-upper');
594     INSERT INTO t3 VALUES('Zz-upper-lower');
595     INSERT INTO t3 VALUES('zz-lower-lower');
596   }
597   queryplan {
598     SELECT x FROM t3 WHERE x LIKE 'zz%';
599   }
600 } {zz-lower-lower nosort {} i3}
601 do_test like-5.26 {
602   queryplan {
603     SELECT x FROM t3 WHERE x LIKE 'zZ%';
604   }
605 } {zZ-lower-upper nosort {} i3}
606 do_test like-5.27 {
607   queryplan {
608     SELECT x FROM t3 WHERE x LIKE 'Zz%';
609   }
610 } {Zz-upper-lower nosort {} i3}
611 do_test like-5.28 {
612   queryplan {
613     SELECT x FROM t3 WHERE x LIKE 'ZZ%';
614   }
615 } {ZZ-upper-upper nosort {} i3}
618 # ticket #2407
620 # Make sure the LIKE prefix optimization does not strip off leading
621 # characters of the like pattern that happen to be quote characters.
623 do_test like-6.1 {
624   foreach x { 'abc 'bcd 'def 'ax } {
625     set x2 '[string map {' ''} $x]'
626     db eval "INSERT INTO t2 VALUES($x2)"
627   }
628   execsql {
629     SELECT * FROM t2 WHERE x LIKE '''a%'
630   }
631 } {'abc 'ax}
633 do_test like-7.1 {
634   execsql {
635     SELECT rowid, * FROM t1 WHERE rowid GLOB '1*' ORDER BY rowid;
636   }
637 } {1 a 10 ABC 11 CDE 12 {ABC abc xyz}}
639 # ticket #3345.
641 # Overloading the LIKE function with -1 for the number of arguments
642 # will overload both the 2-argument and the 3-argument LIKE.
644 do_test like-8.1 {
645   db eval {
646     CREATE TABLE t8(x);
647     INSERT INTO t8 VALUES('abcdef');
648     INSERT INTO t8 VALUES('ghijkl');
649     INSERT INTO t8 VALUES('mnopqr');
650     SELECT 1, x FROM t8 WHERE x LIKE '%h%';
651     SELECT 2, x FROM t8 WHERE x LIKE '%h%' ESCAPE 'x';
652   }
653 } {1 ghijkl 2 ghijkl}
654 do_test like-8.2 {
655   proc newlike {args} {return 1} ;# Alternative LIKE is always return TRUE
656   db function like newlike       ;# Uses -1 for nArg in sqlite3_create_function
657   db cache flush
658   db eval {
659     SELECT 1, x FROM t8 WHERE x LIKE '%h%';
660     SELECT 2, x FROM t8 WHERE x LIKE '%h%' ESCAPE 'x';
661   }
662 } {1 ghijkl 2 ghijkl}
663 do_test like-8.3 {
664   db function like -argcount 2 newlike
665   db eval {
666     SELECT 1, x FROM t8 WHERE x LIKE '%h%';
667     SELECT 2, x FROM t8 WHERE x LIKE '%h%' ESCAPE 'x';
668   }
669 } {1 abcdef 1 ghijkl 1 mnopqr 2 ghijkl}
670 do_test like-8.4 {
671   db function like -argcount 3 newlike
672   db eval {
673     SELECT 1, x FROM t8 WHERE x LIKE '%h%';
674     SELECT 2, x FROM t8 WHERE x LIKE '%h%' ESCAPE 'x';
675   }
676 } {1 abcdef 1 ghijkl 1 mnopqr 2 abcdef 2 ghijkl 2 mnopqr}
679 ifcapable like_opt&&!icu {
680   # Evaluate SQL.  Return the result set followed by the
681   # and the number of full-scan steps.
682   #
683   db close
684   sqlite3 db test.db
685   proc count_steps {sql} {
686     set r [db eval $sql]
687     lappend r scan [db status step] sort [db status sort]
688   }
689   do_test like-9.1 {
690     count_steps {
691        SELECT x FROM t2 WHERE x LIKE 'x%'
692     }
693   } {xyz scan 0 sort 0}
694   do_test like-9.2 {
695     count_steps {
696        SELECT x FROM t2 WHERE x LIKE '_y%'
697     }
698   } {xyz scan 19 sort 0}
699   do_test like-9.3.1 {
700     set res [sqlite3_exec_hex db {
701        SELECT x FROM t2 WHERE x LIKE '%78%25'
702     }]
703   } {0 {x xyz}}
704   ifcapable explain {
705     do_test like-9.3.2 {
706       set res [sqlite3_exec_hex db {
707          EXPLAIN QUERY PLAN SELECT x FROM t2 WHERE x LIKE '%78%25'
708       }]
709       regexp {INDEX i2} $res
710     } {1}
711   }
712   do_test like-9.4.1 {
713     sqlite3_exec_hex db {INSERT INTO t2 VALUES('%ffhello')}
714     set res [sqlite3_exec_hex db {
715        SELECT substr(x,2) AS x FROM t2 WHERE +x LIKE '%ff%25'
716     }]
717   } {0 {x hello}}
718   do_test like-9.4.2 {
719     set res [sqlite3_exec_hex db {
720        SELECT substr(x,2) AS x FROM t2 WHERE x LIKE '%ff%25'
721     }]
722   } {0 {x hello}}
723   ifcapable explain {
724     do_test like-9.4.3 {
725       set res [sqlite3_exec_hex db {
726          EXPLAIN QUERY PLAN SELECT x FROM t2 WHERE x LIKE '%ff%25'
727       }]
728       regexp {SCAN TABLE t2} $res
729     } {1}
730   }
731   do_test like-9.5.1 {
732     set res [sqlite3_exec_hex db {
733        SELECT x FROM t2 WHERE x LIKE '%fe%25'
734     }]
735   } {0 {}}
736   ifcapable explain {
737     do_test like-9.5.2 {
738       set res [sqlite3_exec_hex db {
739          EXPLAIN QUERY PLAN SELECT x FROM t2 WHERE x LIKE '%fe%25'
740       }]
741       regexp {INDEX i2} $res
742     } {1}
743   }
745   # Do an SQL statement.  Append the search count to the end of the result.
746   #
747   proc count sql {
748     set ::sqlite_search_count 0
749     set ::sqlite_like_count 0
750     return [concat [execsql $sql] scan $::sqlite_search_count \
751              like $::sqlite_like_count]
752   }
754   # The LIKE and GLOB optimizations do not work on columns with
755   # affinity other than TEXT.
756   # Ticket #3901
757   #
758   do_test like-10.1 {
759     db close
760     sqlite3 db test.db
761     execsql {
762       CREATE TABLE t10(
763         a INTEGER PRIMARY KEY,
764         b INTEGER COLLATE nocase UNIQUE,
765         c NUMBER COLLATE nocase UNIQUE,
766         d BLOB COLLATE nocase UNIQUE,
767         e COLLATE nocase UNIQUE,
768         f TEXT COLLATE nocase UNIQUE
769       );
770       INSERT INTO t10 VALUES(1,1,1,1,1,1);
771       INSERT INTO t10 VALUES(12,12,12,12,12,12);
772       INSERT INTO t10 VALUES(123,123,123,123,123,123);
773       INSERT INTO t10 VALUES(234,234,234,234,234,234);
774       INSERT INTO t10 VALUES(345,345,345,345,345,345);
775       INSERT INTO t10 VALUES(45,45,45,45,45,45);
776     }
777     count {
778       SELECT a FROM t10 WHERE b LIKE '12%' ORDER BY +a;
779     }
780   } {12 123 scan 5 like 6}
781   do_test like-10.2 {
782     count {
783       SELECT a FROM t10 WHERE c LIKE '12%' ORDER BY +a;
784     }
785   } {12 123 scan 5 like 6}
786   do_test like-10.3 {
787     count {
788       SELECT a FROM t10 WHERE d LIKE '12%' ORDER BY +a;
789     }
790   } {12 123 scan 5 like 6}
791   do_test like-10.4 {
792     count {
793       SELECT a FROM t10 WHERE e LIKE '12%' ORDER BY +a;
794     }
795   } {12 123 scan 5 like 6}
796   ifcapable like_match_blobs {
797     do_test like-10.5a {
798       count {
799         SELECT a FROM t10 WHERE f LIKE '12%' ORDER BY +a;
800       }
801     } {12 123 scan 4 like 0}
802   } else {
803     do_test like-10.5b {
804       count {
805         SELECT a FROM t10 WHERE f LIKE '12%' ORDER BY +a;
806       }
807     } {12 123 scan 3 like 0}
808   }
809   do_test like-10.6 {
810     count {
811       SELECT a FROM t10 WHERE a LIKE '12%' ORDER BY +a;
812     }
813   } {12 123 scan 5 like 6}
814   do_test like-10.10 {
815     execsql {
816       CREATE TABLE t10b(
817         a INTEGER PRIMARY KEY,
818         b INTEGER UNIQUE,
819         c NUMBER UNIQUE,
820         d BLOB UNIQUE,
821         e UNIQUE,
822         f TEXT UNIQUE
823       );
824       INSERT INTO t10b SELECT * FROM t10;
825     }
826     count {
827       SELECT a FROM t10b WHERE b GLOB '12*' ORDER BY +a;
828     }
829   } {12 123 scan 5 like 6}
830   do_test like-10.11 {
831     count {
832       SELECT a FROM t10b WHERE c GLOB '12*' ORDER BY +a;
833     }
834   } {12 123 scan 5 like 6}
835   do_test like-10.12 {
836     count {
837       SELECT a FROM t10b WHERE d GLOB '12*' ORDER BY +a;
838     }
839   } {12 123 scan 5 like 6}
840   do_test like-10.13 {
841     count {
842       SELECT a FROM t10b WHERE e GLOB '12*' ORDER BY +a;
843     }
844   } {12 123 scan 5 like 6}
845   ifcapable like_match_blobs {
846     do_test like-10.14 {
847       count {
848         SELECT a FROM t10b WHERE f GLOB '12*' ORDER BY +a;
849       }
850     } {12 123 scan 4 like 0}
851   } else {
852     do_test like-10.14 {
853       count {
854         SELECT a FROM t10b WHERE f GLOB '12*' ORDER BY +a;
855       }
856     } {12 123 scan 3 like 0}
857   }
858   do_test like-10.15 {
859     count {
860       SELECT a FROM t10b WHERE a GLOB '12*' ORDER BY +a;
861     }
862   } {12 123 scan 5 like 6}
865 # LIKE and GLOB where the default collating sequence is not appropriate
866 # but an index with the appropriate collating sequence exists.
868 do_test like-11.0 {
869   execsql {
870     CREATE TABLE t11(
871       a INTEGER PRIMARY KEY,
872       b TEXT COLLATE nocase,
873       c TEXT COLLATE binary
874     );
875     INSERT INTO t11 VALUES(1, 'a','a');
876     INSERT INTO t11 VALUES(2, 'ab','ab');
877     INSERT INTO t11 VALUES(3, 'abc','abc');
878     INSERT INTO t11 VALUES(4, 'abcd','abcd');
879     INSERT INTO t11 VALUES(5, 'A','A');
880     INSERT INTO t11 VALUES(6, 'AB','AB');
881     INSERT INTO t11 VALUES(7, 'ABC','ABC');
882     INSERT INTO t11 VALUES(8, 'ABCD','ABCD');
883     INSERT INTO t11 VALUES(9, 'x','x');
884     INSERT INTO t11 VALUES(10, 'yz','yz');
885     INSERT INTO t11 VALUES(11, 'X','X');
886     INSERT INTO t11 VALUES(12, 'YZ','YZ');
887     SELECT count(*) FROM t11;
888   }
889 } {12}
890 do_test like-11.1 {
891   db eval {PRAGMA case_sensitive_like=OFF;}
892   queryplan {
893     SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY a;
894   }
895 } {abc abcd ABC ABCD nosort t11 *}
896 do_test like-11.2 {
897   db eval {PRAGMA case_sensitive_like=ON;}
898   queryplan {
899     SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY a;
900   }
901 } {abc abcd nosort t11 *}
902 do_test like-11.3 {
903   db eval {
904     PRAGMA case_sensitive_like=OFF;
905     CREATE INDEX t11b ON t11(b);
906   }
907   queryplan {
908     SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY +a;
909   }
910 } {abc abcd ABC ABCD sort {} t11b}
911 do_test like-11.4 {
912   db eval {PRAGMA case_sensitive_like=ON;}
913   queryplan {
914     SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY a;
915   }
916 } {abc abcd nosort t11 *}
917 do_test like-11.5 {
918   db eval {
919     PRAGMA case_sensitive_like=OFF;
920     DROP INDEX t11b;
921     CREATE INDEX t11bnc ON t11(b COLLATE nocase);
922   }
923   queryplan {
924     SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY +a;
925   }
926 } {abc abcd ABC ABCD sort {} t11bnc}
927 do_test like-11.6 {
928   db eval {CREATE INDEX t11bb ON t11(b COLLATE binary);}
929   queryplan {
930     SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY +a;
931   }
932 } {abc abcd ABC ABCD sort {} t11bnc}
933 do_test like-11.7 {
934   db eval {PRAGMA case_sensitive_like=ON;}
935   queryplan {
936     SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY +a;
937   }
938 } {abc abcd sort {} t11bb}
939 do_test like-11.8 {
940   db eval {PRAGMA case_sensitive_like=OFF;}
941   queryplan {
942     SELECT b FROM t11 WHERE b GLOB 'abc*' ORDER BY +a;
943   }
944 } {abc abcd sort {} t11bb}
945 do_test like-11.9 {
946   db eval {
947     CREATE INDEX t11cnc ON t11(c COLLATE nocase);
948     CREATE INDEX t11cb ON t11(c COLLATE binary);
949   }
950   queryplan {
951     SELECT c FROM t11 WHERE c LIKE 'abc%' ORDER BY +a;
952   }
953 } {abc abcd ABC ABCD sort {} t11cnc}
954 do_test like-11.10 {
955   queryplan {
956     SELECT c FROM t11 WHERE c GLOB 'abc*' ORDER BY +a;
957   }
958 } {abc abcd sort {} t11cb}
960 # A COLLATE clause on the pattern does not change the result of a
961 # LIKE operator.
963 do_execsql_test like-12.1 {
964   CREATE TABLE t12nc(id INTEGER, x TEXT UNIQUE COLLATE nocase);
965   INSERT INTO t12nc VALUES(1,'abcde'),(2,'uvwxy'),(3,'ABCDEF');
966   CREATE TABLE t12b(id INTEGER, x TEXT UNIQUE COLLATE binary);
967   INSERT INTO t12b VALUES(1,'abcde'),(2,'uvwxy'),(3,'ABCDEF');
968   SELECT id FROM t12nc WHERE x LIKE 'abc%' ORDER BY +id;
969 } {1 3}
970 do_execsql_test like-12.2 {
971   SELECT id FROM t12b WHERE x LIKE 'abc%' ORDER BY +id;
972 } {1 3}
973 do_execsql_test like-12.3 {
974   SELECT id FROM t12nc WHERE x LIKE 'abc%' COLLATE binary ORDER BY +id;
975 } {1 3}
976 do_execsql_test like-12.4 {
977   SELECT id FROM t12b WHERE x LIKE 'abc%' COLLATE binary ORDER BY +id;
978 } {1 3}
979 do_execsql_test like-12.5 {
980   SELECT id FROM t12nc WHERE x LIKE 'abc%' COLLATE nocase ORDER BY +id;
981 } {1 3}
982 do_execsql_test like-12.6 {
983   SELECT id FROM t12b WHERE x LIKE 'abc%' COLLATE nocase ORDER BY +id;
984 } {1 3}
986 # Adding a COLLATE clause to the pattern of a LIKE operator does nothing
987 # to change the suitability of using an index to satisfy that LIKE
988 # operator.
990 do_execsql_test like-12.11 {
991   EXPLAIN QUERY PLAN
992   SELECT id FROM t12nc WHERE x LIKE 'abc%' ORDER BY +id;
993 } {/SEARCH/}
994 do_execsql_test like-12.12 {
995   EXPLAIN QUERY PLAN
996   SELECT id FROM t12b WHERE x LIKE 'abc%' ORDER BY +id;
997 } {/SCAN/}
998 do_execsql_test like-12.13 {
999   EXPLAIN QUERY PLAN
1000   SELECT id FROM t12nc WHERE x LIKE 'abc%' COLLATE nocase ORDER BY +id;
1001 } {/SEARCH/}
1002 do_execsql_test like-12.14 {
1003   EXPLAIN QUERY PLAN
1004   SELECT id FROM t12b WHERE x LIKE 'abc%' COLLATE nocase ORDER BY +id;
1005 } {/SCAN/}
1006 do_execsql_test like-12.15 {
1007   EXPLAIN QUERY PLAN
1008   SELECT id FROM t12nc WHERE x LIKE 'abc%' COLLATE binary ORDER BY +id;
1009 } {/SEARCH/}
1010 do_execsql_test like-12.16 {
1011   EXPLAIN QUERY PLAN
1012   SELECT id FROM t12b WHERE x LIKE 'abc%' COLLATE binary ORDER BY +id;
1013 } {/SCAN/}
1015 # Ticket [https://www.sqlite.org/src/tktview/80369eddd5c94d49f7fbbcf5]
1016 # 2016-01-20
1018 do_execsql_test like-13.1 {
1019   SELECT char(0x304d) LIKE char(0x306d);
1020 } {0}
1021 do_execsql_test like-13.2 {
1022   SELECT char(0x4d) LIKE char(0x306d);
1023 } {0}
1024 do_execsql_test like-13.3 {
1025   SELECT char(0x304d) LIKE char(0x6d);
1026 } {0}
1027 do_execsql_test like-13.4 {
1028   SELECT char(0x4d) LIKE char(0x6d);
1029 } {1}
1031 # Performance testing for patterns with many wildcards.  These LIKE and GLOB
1032 # patterns were quite slow with SQLite 3.15.2 and earlier.
1034 do_test like-14.1 {
1035   set x [lindex [time {
1036     db one {SELECT 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaz'GLOB'*a*a*a*a*a*a*a*a*y'}
1037   }] 0]
1038   puts -nonewline " ($x ms - want less than 1000) "
1039   expr {$x<1000}
1040 } {1}
1041 ifcapable !icu {
1042   do_test like-14.2 {
1043     set x [lindex [time {
1044       db one {SELECT 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaz'LIKE'%a%a%a%a%a%a%a%a%y'}
1045     }] 0]
1046     puts -nonewline " ($x ms - want less than 1000) "
1047     expr {$x<1000}
1048   } {1}
1051 ifcapable !icu {
1052 # As of 2017-07-27 (3.21.0) the LIKE optimization works with ESCAPE as
1053 # long as the ESCAPE is a single-byte literal.
1055 db close
1056 sqlite3 db :memory:
1057 do_execsql_test like-15.100 {
1058   CREATE TABLE t15(x TEXT COLLATE nocase, y, PRIMARY KEY(x));
1059   INSERT INTO t15(x,y) VALUES
1060     ('abcde',1), ('ab%de',2), ('a_cde',3),
1061     ('uvwxy',11),('uvwx%',12),('uvwx_',13),
1062     ('_bcde',21),('%bcde',22),
1063     ('abcd_',31),('abcd%',32),
1064     ('ab%xy',41);
1065   SELECT y FROM t15 WHERE x LIKE 'ab/%d%' ESCAPE '/';
1066 } {2}
1067 do_execsql_test like-15.101 {
1068   EXPLAIN QUERY PLAN
1069   SELECT y FROM t15 WHERE x LIKE 'ab/%d%' ESCAPE '/';
1070 } {/SEARCH/}
1071 do_execsql_test like-15.102 {
1072   EXPLAIN QUERY PLAN
1073   SELECT y FROM t15 WHERE x LIKE 'ab/%d%' ESCAPE '//';
1074 } {/SCAN/}
1075 do_execsql_test like-15.103 {
1076   EXPLAIN QUERY PLAN
1077   SELECT y FROM t15 WHERE x LIKE 'ab/%d%' ESCAPE '';
1078 } {/SCAN/}
1079 do_execsql_test like-15.110 {
1080   SELECT y FROM t15 WHERE x LIKE 'abcdx%%' ESCAPE 'x';
1081 } {32}
1082 do_execsql_test like-15.111 {
1083   SELECT y FROM t15 WHERE x LIKE 'abx%%' ESCAPE 'x' ORDER BY +y
1084 } {2 41}
1085 do_execsql_test like-15.112 {
1086   EXPLAIN QUERY PLAN
1087   SELECT y FROM t15 WHERE x LIKE 'abx%%' ESCAPE 'x' ORDER BY +y
1088 } {/SEARCH/}
1089 do_execsql_test like-15.120 {
1090   SELECT y FROM t15 WHERE x LIKE '/%bc%' ESCAPE '/';
1091 } {22}
1092 do_execsql_test like-15.121 {
1093   EXPLAIN QUERY PLAN
1094   SELECT y FROM t15 WHERE x LIKE '/%bc%' ESCAPE '/';
1095 } {/SEARCH/}
1098 finish_test