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