xref: /sqlite-3.40.0/test/like.test (revision 9da058bb)
1# 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#
16# $Id: like.test,v 1.13 2009/06/07 23:45:11 drh Exp $
17
18set testdir [file dirname $argv0]
19source $testdir/tester.tcl
20
21# Create some sample data to work with.
22#
23do_test like-1.0 {
24  execsql {
25    CREATE TABLE t1(x TEXT);
26  }
27  foreach str {
28    a
29    ab
30    abc
31    abcd
32
33    acd
34    abd
35    bc
36    bcd
37
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}
49
50# Test that both case sensitive and insensitive version of LIKE work.
51#
52do_test like-1.1 {
53  execsql {
54    SELECT x FROM t1 WHERE x LIKE 'abc' ORDER BY 1;
55  }
56} {ABC abc}
57do_test like-1.2 {
58  execsql {
59    SELECT x FROM t1 WHERE x GLOB 'abc' ORDER BY 1;
60  }
61} {abc}
62do_test like-1.3 {
63  execsql {
64    SELECT x FROM t1 WHERE x LIKE 'ABC' ORDER BY 1;
65  }
66} {ABC abc}
67do_test like-1.4 {
68  execsql {
69    SELECT x FROM t1 WHERE x LIKE 'aBc' ORDER BY 1;
70  }
71} {ABC abc}
72do_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 {}}
76do_test like-1.5.2 {
77  execsql {
78    SELECT x FROM t1 WHERE x LIKE 'abc' ORDER BY 1;
79  }
80} {abc}
81do_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}
87do_test like-1.6 {
88  execsql {
89    SELECT x FROM t1 WHERE x GLOB 'abc' ORDER BY 1;
90  }
91} {abc}
92do_test like-1.7 {
93  execsql {
94    SELECT x FROM t1 WHERE x LIKE 'ABC' ORDER BY 1;
95  }
96} {ABC}
97do_test like-1.8 {
98  execsql {
99    SELECT x FROM t1 WHERE x LIKE 'aBc' ORDER BY 1;
100  }
101} {}
102do_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}
108do_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}
114
115# Tests of the REGEXP operator
116#
117do_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}
126do_test like-2.2 {
127  execsql {
128    SELECT x FROM t1 WHERE x REGEXP '^abc' ORDER BY 1;
129  }
130} {abc abcd}
131
132# Tests of the MATCH operator
133#
134do_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}
143do_test like-2.4 {
144  execsql {
145    SELECT x FROM t1 WHERE x MATCH 'abc*' ORDER BY 1;
146  }
147} {abc abcd}
148
149# For the remaining tests, we need to have the like optimizations
150# enabled.
151#
152ifcapable !like_opt {
153  finish_test
154  return
155}
156
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 ::sqlite_query_plan variable.
160#
161proc queryplan {sql} {
162  set ::sqlite_sort_count 0
163  set data [execsql $sql]
164  if {$::sqlite_sort_count} {set x sort} {set x nosort}
165  lappend data $x
166  return [concat $data $::sqlite_query_plan]
167}
168
169# Perform tests on the like optimization.
170#
171# With no index on t1.x and with case sensitivity turned off, no optimization
172# is performed.
173#
174do_test like-3.1 {
175  set sqlite_like_count 0
176  queryplan {
177    SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1;
178  }
179} {ABC {ABC abc xyz} abc abcd sort t1 {}}
180do_test like-3.2 {
181  set sqlite_like_count
182} {12}
183
184# With an index on t1.x and case sensitivity on, optimize completely.
185#
186do_test like-3.3 {
187  set sqlite_like_count 0
188  execsql {
189    PRAGMA case_sensitive_like=on;
190    CREATE INDEX i1 ON t1(x);
191  }
192  queryplan {
193    SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1;
194  }
195} {abc abcd nosort {} i1}
196do_test like-3.4 {
197  set sqlite_like_count
198} 0
199
200# The LIKE optimization still works when the RHS is a string with no
201# wildcard.  Ticket [e090183531fc2747]
202#
203do_test like-3.4.2 {
204  queryplan {
205    SELECT x FROM t1 WHERE x LIKE 'a' ORDER BY 1;
206  }
207} {a nosort {} i1}
208do_test like-3.4.3 {
209  queryplan {
210    SELECT x FROM t1 WHERE x LIKE 'ab' ORDER BY 1;
211  }
212} {ab nosort {} i1}
213do_test like-3.4.4 {
214  queryplan {
215    SELECT x FROM t1 WHERE x LIKE 'abcd' ORDER BY 1;
216  }
217} {abcd nosort {} i1}
218do_test like-3.4.5 {
219  queryplan {
220    SELECT x FROM t1 WHERE x LIKE 'abcde' ORDER BY 1;
221  }
222} {nosort {} i1}
223
224
225# Partial optimization when the pattern does not end in '%'
226#
227do_test like-3.5 {
228  set sqlite_like_count 0
229  queryplan {
230    SELECT x FROM t1 WHERE x LIKE 'a_c' ORDER BY 1;
231  }
232} {abc nosort {} i1}
233do_test like-3.6 {
234  set sqlite_like_count
235} 6
236do_test like-3.7 {
237  set sqlite_like_count 0
238  queryplan {
239    SELECT x FROM t1 WHERE x LIKE 'ab%d' ORDER BY 1;
240  }
241} {abcd abd nosort {} i1}
242do_test like-3.8 {
243  set sqlite_like_count
244} 4
245do_test like-3.9 {
246  set sqlite_like_count 0
247  queryplan {
248    SELECT x FROM t1 WHERE x LIKE 'a_c%' ORDER BY 1;
249  }
250} {abc abcd nosort {} i1}
251do_test like-3.10 {
252  set sqlite_like_count
253} 6
254
255# No optimization when the pattern begins with a wildcard.
256# Note that the index is still used but only for sorting.
257#
258do_test like-3.11 {
259  set sqlite_like_count 0
260  queryplan {
261    SELECT x FROM t1 WHERE x LIKE '%bcd' ORDER BY 1;
262  }
263} {abcd bcd nosort {} i1}
264do_test like-3.12 {
265  set sqlite_like_count
266} 12
267
268# No optimization for case insensitive LIKE
269#
270do_test like-3.13 {
271  set sqlite_like_count 0
272  queryplan {
273    PRAGMA case_sensitive_like=off;
274    SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1;
275  }
276} {ABC {ABC abc xyz} abc abcd nosort {} i1}
277do_test like-3.14 {
278  set sqlite_like_count
279} 12
280
281# No optimization without an index.
282#
283do_test like-3.15 {
284  set sqlite_like_count 0
285  queryplan {
286    PRAGMA case_sensitive_like=on;
287    DROP INDEX i1;
288    SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1;
289  }
290} {abc abcd sort t1 {}}
291do_test like-3.16 {
292  set sqlite_like_count
293} 12
294
295# No GLOB optimization without an index.
296#
297do_test like-3.17 {
298  set sqlite_like_count 0
299  queryplan {
300    SELECT x FROM t1 WHERE x GLOB 'abc*' ORDER BY 1;
301  }
302} {abc abcd sort t1 {}}
303do_test like-3.18 {
304  set sqlite_like_count
305} 12
306
307# GLOB is optimized regardless of the case_sensitive_like setting.
308#
309do_test like-3.19 {
310  set sqlite_like_count 0
311  db eval {CREATE INDEX i1 ON t1(x);}
312  queryplan {
313    SELECT x FROM t1 WHERE x GLOB 'abc*' ORDER BY 1;
314  }
315} {abc abcd nosort {} i1}
316do_test like-3.20 {
317  set sqlite_like_count
318} 0
319do_test like-3.21 {
320  set sqlite_like_count 0
321  queryplan {
322    PRAGMA case_sensitive_like=on;
323    SELECT x FROM t1 WHERE x GLOB 'abc*' ORDER BY 1;
324  }
325} {abc abcd nosort {} i1}
326do_test like-3.22 {
327  set sqlite_like_count
328} 0
329do_test like-3.23 {
330  set sqlite_like_count 0
331  queryplan {
332    PRAGMA case_sensitive_like=off;
333    SELECT x FROM t1 WHERE x GLOB 'a[bc]d' ORDER BY 1;
334  }
335} {abd acd nosort {} i1}
336do_test like-3.24 {
337  set sqlite_like_count
338} 6
339
340# GLOB optimization when there is no wildcard.  Ticket [e090183531fc2747]
341#
342do_test like-3.25 {
343  queryplan {
344    SELECT x FROM t1 WHERE x GLOB 'a' ORDER BY 1;
345  }
346} {a nosort {} i1}
347do_test like-3.26 {
348  queryplan {
349    SELECT x FROM t1 WHERE x GLOB 'abcd' ORDER BY 1;
350  }
351} {abcd nosort {} i1}
352do_test like-3.27 {
353  queryplan {
354    SELECT x FROM t1 WHERE x GLOB 'abcde' ORDER BY 1;
355  }
356} {nosort {} i1}
357
358
359
360# No optimization if the LHS of the LIKE is not a column name or
361# if the RHS is not a string.
362#
363do_test like-4.1 {
364  execsql {PRAGMA case_sensitive_like=on}
365  set sqlite_like_count 0
366  queryplan {
367    SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1
368  }
369} {abc abcd nosort {} i1}
370do_test like-4.2 {
371  set sqlite_like_count
372} 0
373do_test like-4.3 {
374  set sqlite_like_count 0
375  queryplan {
376    SELECT x FROM t1 WHERE +x LIKE 'abc%' ORDER BY 1
377  }
378} {abc abcd nosort {} i1}
379do_test like-4.4 {
380  set sqlite_like_count
381} 12
382do_test like-4.5 {
383  set sqlite_like_count 0
384  queryplan {
385    SELECT x FROM t1 WHERE x LIKE ('ab' || 'c%') ORDER BY 1
386  }
387} {abc abcd nosort {} i1}
388do_test like-4.6 {
389  set sqlite_like_count
390} 12
391
392# Collating sequences on the index disable the LIKE optimization.
393# Or if the NOCASE collating sequence is used, the LIKE optimization
394# is enabled when case_sensitive_like is OFF.
395#
396do_test like-5.1 {
397  execsql {PRAGMA case_sensitive_like=off}
398  set sqlite_like_count 0
399  queryplan {
400    SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1
401  }
402} {ABC {ABC abc xyz} abc abcd nosort {} i1}
403do_test like-5.2 {
404  set sqlite_like_count
405} 12
406do_test like-5.3 {
407  execsql {
408    CREATE TABLE t2(x TEXT COLLATE NOCASE);
409    INSERT INTO t2 SELECT * FROM t1;
410    CREATE INDEX i2 ON t2(x COLLATE NOCASE);
411  }
412  set sqlite_like_count 0
413  queryplan {
414    SELECT x FROM t2 WHERE x LIKE 'abc%' ORDER BY 1
415  }
416} {abc ABC {ABC abc xyz} abcd nosort {} i2}
417do_test like-5.4 {
418  set sqlite_like_count
419} 0
420do_test like-5.5 {
421  execsql {
422    PRAGMA case_sensitive_like=on;
423  }
424  set sqlite_like_count 0
425  queryplan {
426    SELECT x FROM t2 WHERE x LIKE 'abc%' ORDER BY 1
427  }
428} {abc abcd nosort {} i2}
429do_test like-5.6 {
430  set sqlite_like_count
431} 12
432do_test like-5.7 {
433  execsql {
434    PRAGMA case_sensitive_like=off;
435  }
436  set sqlite_like_count 0
437  queryplan {
438    SELECT x FROM t2 WHERE x GLOB 'abc*' ORDER BY 1
439  }
440} {abc abcd nosort {} i2}
441do_test like-5.8 {
442  set sqlite_like_count
443} 12
444do_test like-5.11 {
445  execsql {PRAGMA case_sensitive_like=off}
446  set sqlite_like_count 0
447  queryplan {
448    SELECT x FROM t1 WHERE x LIKE 'ABC%' ORDER BY 1
449  }
450} {ABC {ABC abc xyz} abc abcd nosort {} i1}
451do_test like-5.12 {
452  set sqlite_like_count
453} 12
454do_test like-5.13 {
455  set sqlite_like_count 0
456  queryplan {
457    SELECT x FROM t2 WHERE x LIKE 'ABC%' ORDER BY 1
458  }
459} {abc ABC {ABC abc xyz} abcd nosort {} i2}
460do_test like-5.14 {
461  set sqlite_like_count
462} 0
463do_test like-5.15 {
464  execsql {
465    PRAGMA case_sensitive_like=on;
466  }
467  set sqlite_like_count 0
468  queryplan {
469    SELECT x FROM t2 WHERE x LIKE 'ABC%' ORDER BY 1
470  }
471} {ABC {ABC abc xyz} nosort {} i2}
472do_test like-5.16 {
473  set sqlite_like_count
474} 12
475do_test like-5.17 {
476  execsql {
477    PRAGMA case_sensitive_like=off;
478  }
479  set sqlite_like_count 0
480  queryplan {
481    SELECT x FROM t2 WHERE x GLOB 'ABC*' ORDER BY 1
482  }
483} {ABC {ABC abc xyz} nosort {} i2}
484do_test like-5.18 {
485  set sqlite_like_count
486} 12
487
488# Boundary case.  The prefix for a LIKE comparison is rounded up
489# when constructing the comparison.  Example:  "ab" becomes "ac".
490# In other words, the last character is increased by one.
491#
492# Make sure this happens correctly when the last character is a
493# "z" and we are doing case-insensitive comparisons.
494#
495# Ticket #2959
496#
497do_test like-5.21 {
498  execsql {
499    PRAGMA case_sensitive_like=off;
500    INSERT INTO t2 VALUES('ZZ-upper-upper');
501    INSERT INTO t2 VALUES('zZ-lower-upper');
502    INSERT INTO t2 VALUES('Zz-upper-lower');
503    INSERT INTO t2 VALUES('zz-lower-lower');
504  }
505  queryplan {
506    SELECT x FROM t2 WHERE x LIKE 'zz%';
507  }
508} {zz-lower-lower zZ-lower-upper Zz-upper-lower ZZ-upper-upper nosort {} i2}
509do_test like-5.22 {
510  queryplan {
511    SELECT x FROM t2 WHERE x LIKE 'zZ%';
512  }
513} {zz-lower-lower zZ-lower-upper Zz-upper-lower ZZ-upper-upper nosort {} i2}
514do_test like-5.23 {
515  queryplan {
516    SELECT x FROM t2 WHERE x LIKE 'Zz%';
517  }
518} {zz-lower-lower zZ-lower-upper Zz-upper-lower ZZ-upper-upper nosort {} i2}
519do_test like-5.24 {
520  queryplan {
521    SELECT x FROM t2 WHERE x LIKE 'ZZ%';
522  }
523} {zz-lower-lower zZ-lower-upper Zz-upper-lower ZZ-upper-upper nosort {} i2}
524do_test like-5.25 {
525  db eval {
526    PRAGMA case_sensitive_like=on;
527    CREATE TABLE t3(x TEXT);
528    CREATE INDEX i3 ON t3(x);
529    INSERT INTO t3 VALUES('ZZ-upper-upper');
530    INSERT INTO t3 VALUES('zZ-lower-upper');
531    INSERT INTO t3 VALUES('Zz-upper-lower');
532    INSERT INTO t3 VALUES('zz-lower-lower');
533  }
534  queryplan {
535    SELECT x FROM t3 WHERE x LIKE 'zz%';
536  }
537} {zz-lower-lower nosort {} i3}
538do_test like-5.26 {
539  queryplan {
540    SELECT x FROM t3 WHERE x LIKE 'zZ%';
541  }
542} {zZ-lower-upper nosort {} i3}
543do_test like-5.27 {
544  queryplan {
545    SELECT x FROM t3 WHERE x LIKE 'Zz%';
546  }
547} {Zz-upper-lower nosort {} i3}
548do_test like-5.28 {
549  queryplan {
550    SELECT x FROM t3 WHERE x LIKE 'ZZ%';
551  }
552} {ZZ-upper-upper nosort {} i3}
553
554
555# ticket #2407
556#
557# Make sure the LIKE prefix optimization does not strip off leading
558# characters of the like pattern that happen to be quote characters.
559#
560do_test like-6.1 {
561  foreach x { 'abc 'bcd 'def 'ax } {
562    set x2 '[string map {' ''} $x]'
563    db eval "INSERT INTO t2 VALUES($x2)"
564  }
565  execsql {
566    SELECT * FROM t2 WHERE x LIKE '''a%'
567  }
568} {'abc 'ax}
569
570do_test like-7.1 {
571  execsql {
572    SELECT rowid, * FROM t1 WHERE rowid GLOB '1*' ORDER BY rowid;
573  }
574} {1 a 10 ABC 11 CDE 12 {ABC abc xyz}}
575
576# ticket #3345.
577#
578# Overloading the LIKE function with -1 for the number of arguments
579# will overload both the 2-argument and the 3-argument LIKE.
580#
581do_test like-8.1 {
582  db eval {
583    CREATE TABLE t8(x);
584    INSERT INTO t8 VALUES('abcdef');
585    INSERT INTO t8 VALUES('ghijkl');
586    INSERT INTO t8 VALUES('mnopqr');
587    SELECT 1, x FROM t8 WHERE x LIKE '%h%';
588    SELECT 2, x FROM t8 WHERE x LIKE '%h%' ESCAPE 'x';
589  }
590} {1 ghijkl 2 ghijkl}
591do_test like-8.2 {
592  proc newlike {args} {return 1} ;# Alternative LIKE is always return TRUE
593  db function like newlike       ;# Uses -1 for nArg in sqlite3_create_function
594  db cache flush
595  db eval {
596    SELECT 1, x FROM t8 WHERE x LIKE '%h%';
597    SELECT 2, x FROM t8 WHERE x LIKE '%h%' ESCAPE 'x';
598  }
599} {1 ghijkl 2 ghijkl}
600do_test like-8.3 {
601  db function like -argcount 2 newlike
602  db eval {
603    SELECT 1, x FROM t8 WHERE x LIKE '%h%';
604    SELECT 2, x FROM t8 WHERE x LIKE '%h%' ESCAPE 'x';
605  }
606} {1 abcdef 1 ghijkl 1 mnopqr 2 ghijkl}
607do_test like-8.4 {
608  db function like -argcount 3 newlike
609  db eval {
610    SELECT 1, x FROM t8 WHERE x LIKE '%h%';
611    SELECT 2, x FROM t8 WHERE x LIKE '%h%' ESCAPE 'x';
612  }
613} {1 abcdef 1 ghijkl 1 mnopqr 2 abcdef 2 ghijkl 2 mnopqr}
614
615
616ifcapable like_opt&&!icu {
617  # Evaluate SQL.  Return the result set followed by the
618  # and the number of full-scan steps.
619  #
620  db close
621  sqlite3 db test.db
622  proc count_steps {sql} {
623    set r [db eval $sql]
624    lappend r scan [db status step] sort [db status sort]
625  }
626  do_test like-9.1 {
627    count_steps {
628       SELECT x FROM t2 WHERE x LIKE 'x%'
629    }
630  } {xyz scan 0 sort 0}
631  do_test like-9.2 {
632    count_steps {
633       SELECT x FROM t2 WHERE x LIKE '_y%'
634    }
635  } {xyz scan 19 sort 0}
636  do_test like-9.3.1 {
637    set res [sqlite3_exec_hex db {
638       SELECT x FROM t2 WHERE x LIKE '%78%25'
639    }]
640  } {0 {x xyz}}
641  ifcapable explain {
642    do_test like-9.3.2 {
643      set res [sqlite3_exec_hex db {
644         EXPLAIN QUERY PLAN SELECT x FROM t2 WHERE x LIKE '%78%25'
645      }]
646      regexp {INDEX i2} $res
647    } {1}
648  }
649  do_test like-9.4.1 {
650    sqlite3_exec_hex db {INSERT INTO t2 VALUES('%ffhello')}
651    set res [sqlite3_exec_hex db {
652       SELECT substr(x,2) AS x FROM t2 WHERE +x LIKE '%ff%25'
653    }]
654  } {0 {x hello}}
655  do_test like-9.4.2 {
656    set res [sqlite3_exec_hex db {
657       SELECT substr(x,2) AS x FROM t2 WHERE x LIKE '%ff%25'
658    }]
659  } {0 {x hello}}
660  ifcapable explain {
661    do_test like-9.4.3 {
662      set res [sqlite3_exec_hex db {
663         EXPLAIN QUERY PLAN SELECT x FROM t2 WHERE x LIKE '%ff%25'
664      }]
665      regexp {INDEX i2} $res
666    } {0}
667  }
668  do_test like-9.5.1 {
669    set res [sqlite3_exec_hex db {
670       SELECT x FROM t2 WHERE x LIKE '%fe%25'
671    }]
672  } {0 {}}
673  ifcapable explain {
674    do_test like-9.5.2 {
675      set res [sqlite3_exec_hex db {
676         EXPLAIN QUERY PLAN SELECT x FROM t2 WHERE x LIKE '%fe%25'
677      }]
678      regexp {INDEX i2} $res
679    } {1}
680  }
681
682  # Do an SQL statement.  Append the search count to the end of the result.
683  #
684  proc count sql {
685    set ::sqlite_search_count 0
686    set ::sqlite_like_count 0
687    return [concat [execsql $sql] scan $::sqlite_search_count \
688             like $::sqlite_like_count]
689  }
690
691  # The LIKE and GLOB optimizations do not work on columns with
692  # affinity other than TEXT.
693  # Ticket #3901
694  #
695  do_test like-10.1 {
696    db close
697    sqlite3 db test.db
698    execsql {
699      CREATE TABLE t10(
700        a INTEGER PRIMARY KEY,
701        b INTEGER COLLATE nocase UNIQUE,
702        c NUMBER COLLATE nocase UNIQUE,
703        d BLOB COLLATE nocase UNIQUE,
704        e COLLATE nocase UNIQUE,
705        f TEXT COLLATE nocase UNIQUE
706      );
707      INSERT INTO t10 VALUES(1,1,1,1,1,1);
708      INSERT INTO t10 VALUES(12,12,12,12,12,12);
709      INSERT INTO t10 VALUES(123,123,123,123,123,123);
710      INSERT INTO t10 VALUES(234,234,234,234,234,234);
711      INSERT INTO t10 VALUES(345,345,345,345,345,345);
712      INSERT INTO t10 VALUES(45,45,45,45,45,45);
713    }
714    count {
715      SELECT a FROM t10 WHERE b LIKE '12%' ORDER BY +a;
716    }
717  } {12 123 scan 5 like 6}
718  do_test like-10.2 {
719    count {
720      SELECT a FROM t10 WHERE c LIKE '12%' ORDER BY +a;
721    }
722  } {12 123 scan 5 like 6}
723  do_test like-10.3 {
724    count {
725      SELECT a FROM t10 WHERE d LIKE '12%' ORDER BY +a;
726    }
727  } {12 123 scan 5 like 6}
728  do_test like-10.4 {
729    count {
730      SELECT a FROM t10 WHERE e LIKE '12%' ORDER BY +a;
731    }
732  } {12 123 scan 5 like 6}
733  do_test like-10.5 {
734    count {
735      SELECT a FROM t10 WHERE f LIKE '12%' ORDER BY +a;
736    }
737  } {12 123 scan 3 like 0}
738  do_test like-10.6 {
739    count {
740      SELECT a FROM t10 WHERE a LIKE '12%' ORDER BY +a;
741    }
742  } {12 123 scan 5 like 6}
743  do_test like-10.10 {
744    execsql {
745      CREATE TABLE t10b(
746        a INTEGER PRIMARY KEY,
747        b INTEGER UNIQUE,
748        c NUMBER UNIQUE,
749        d BLOB UNIQUE,
750        e UNIQUE,
751        f TEXT UNIQUE
752      );
753      INSERT INTO t10b SELECT * FROM t10;
754    }
755    count {
756      SELECT a FROM t10b WHERE b GLOB '12*' ORDER BY +a;
757    }
758  } {12 123 scan 5 like 6}
759  do_test like-10.11 {
760    count {
761      SELECT a FROM t10b WHERE c GLOB '12*' ORDER BY +a;
762    }
763  } {12 123 scan 5 like 6}
764  do_test like-10.12 {
765    count {
766      SELECT a FROM t10b WHERE d GLOB '12*' ORDER BY +a;
767    }
768  } {12 123 scan 5 like 6}
769  do_test like-10.13 {
770    count {
771      SELECT a FROM t10b WHERE e GLOB '12*' ORDER BY +a;
772    }
773  } {12 123 scan 5 like 6}
774  do_test like-10.14 {
775    count {
776      SELECT a FROM t10b WHERE f GLOB '12*' ORDER BY +a;
777    }
778  } {12 123 scan 3 like 0}
779  do_test like-10.15 {
780    count {
781      SELECT a FROM t10b WHERE a GLOB '12*' ORDER BY +a;
782    }
783  } {12 123 scan 5 like 6}
784}
785
786# LIKE and GLOB where the default collating sequence is not appropriate
787# but an index with the appropriate collating sequence exists.
788#
789do_test like-11.0 {
790  execsql {
791    CREATE TABLE t11(
792      a INTEGER PRIMARY KEY,
793      b TEXT COLLATE nocase,
794      c TEXT COLLATE binary
795    );
796    INSERT INTO t11 VALUES(1, 'a','a');
797    INSERT INTO t11 VALUES(2, 'ab','ab');
798    INSERT INTO t11 VALUES(3, 'abc','abc');
799    INSERT INTO t11 VALUES(4, 'abcd','abcd');
800    INSERT INTO t11 VALUES(5, 'A','A');
801    INSERT INTO t11 VALUES(6, 'AB','AB');
802    INSERT INTO t11 VALUES(7, 'ABC','ABC');
803    INSERT INTO t11 VALUES(8, 'ABCD','ABCD');
804    INSERT INTO t11 VALUES(9, 'x','x');
805    INSERT INTO t11 VALUES(10, 'yz','yz');
806    INSERT INTO t11 VALUES(11, 'X','X');
807    INSERT INTO t11 VALUES(12, 'YZ','YZ');
808    SELECT count(*) FROM t11;
809  }
810} {12}
811do_test like-11.1 {
812  queryplan {
813    PRAGMA case_sensitive_like=OFF;
814    SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY a;
815  }
816} {abc abcd ABC ABCD nosort t11 *}
817do_test like-11.2 {
818  queryplan {
819    PRAGMA case_sensitive_like=ON;
820    SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY a;
821  }
822} {abc abcd nosort t11 *}
823do_test like-11.3 {
824  queryplan {
825    PRAGMA case_sensitive_like=OFF;
826    CREATE INDEX t11b ON t11(b);
827    SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY +a;
828  }
829} {abc abcd ABC ABCD sort {} t11b}
830do_test like-11.4 {
831  queryplan {
832    PRAGMA case_sensitive_like=ON;
833    SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY a;
834  }
835} {abc abcd nosort t11 *}
836do_test like-11.5 {
837  queryplan {
838    PRAGMA case_sensitive_like=OFF;
839    DROP INDEX t11b;
840    CREATE INDEX t11bnc ON t11(b COLLATE nocase);
841    SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY +a;
842  }
843} {abc abcd ABC ABCD sort {} t11bnc}
844do_test like-11.6 {
845  queryplan {
846    CREATE INDEX t11bb ON t11(b COLLATE binary);
847    SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY +a;
848  }
849} {abc abcd ABC ABCD sort {} t11bnc}
850do_test like-11.7 {
851  queryplan {
852    PRAGMA case_sensitive_like=ON;
853    SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY +a;
854  }
855} {abc abcd sort {} t11bb}
856do_test like-11.8 {
857  queryplan {
858    PRAGMA case_sensitive_like=OFF;
859    SELECT b FROM t11 WHERE b GLOB 'abc*' ORDER BY +a;
860  }
861} {abc abcd sort {} t11bb}
862do_test like-11.9 {
863  queryplan {
864    CREATE INDEX t11cnc ON t11(c COLLATE nocase);
865    CREATE INDEX t11cb ON t11(c COLLATE binary);
866    SELECT c FROM t11 WHERE c LIKE 'abc%' ORDER BY +a;
867  }
868} {abc abcd ABC ABCD sort {} t11cnc}
869do_test like-11.10 {
870  queryplan {
871    SELECT c FROM t11 WHERE c GLOB 'abc*' ORDER BY +a;
872  }
873} {abc abcd sort {} t11cb}
874
875
876finish_test
877