Annotation of embedaddon/sqlite3/test/like.test, revision 1.1
1.1 ! misho 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:
! 18: set testdir [file dirname $argv0]
! 19: source $testdir/tester.tcl
! 20:
! 21: # Create some sample data to work with.
! 22: #
! 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
! 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: #
! 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}
! 114:
! 115: # Tests of the REGEXP operator
! 116: #
! 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}
! 131:
! 132: # Tests of the MATCH operator
! 133: #
! 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}
! 148:
! 149: # For the remaining tests, we need to have the like optimizations
! 150: # enabled.
! 151: #
! 152: ifcapable !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: #
! 161: proc 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: #
! 174: do_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 {}}
! 180: do_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: #
! 186: do_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}
! 196: do_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: #
! 203: do_test like-3.4.2 {
! 204: queryplan {
! 205: SELECT x FROM t1 WHERE x LIKE 'a' ORDER BY 1;
! 206: }
! 207: } {a nosort {} i1}
! 208: do_test like-3.4.3 {
! 209: queryplan {
! 210: SELECT x FROM t1 WHERE x LIKE 'ab' ORDER BY 1;
! 211: }
! 212: } {ab nosort {} i1}
! 213: do_test like-3.4.4 {
! 214: queryplan {
! 215: SELECT x FROM t1 WHERE x LIKE 'abcd' ORDER BY 1;
! 216: }
! 217: } {abcd nosort {} i1}
! 218: do_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: #
! 227: do_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}
! 233: do_test like-3.6 {
! 234: set sqlite_like_count
! 235: } 6
! 236: do_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}
! 242: do_test like-3.8 {
! 243: set sqlite_like_count
! 244: } 4
! 245: do_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}
! 251: do_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: #
! 258: do_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}
! 264: do_test like-3.12 {
! 265: set sqlite_like_count
! 266: } 12
! 267:
! 268: # No optimization for case insensitive LIKE
! 269: #
! 270: do_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}
! 277: do_test like-3.14 {
! 278: set sqlite_like_count
! 279: } 12
! 280:
! 281: # No optimization without an index.
! 282: #
! 283: do_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 {}}
! 291: do_test like-3.16 {
! 292: set sqlite_like_count
! 293: } 12
! 294:
! 295: # No GLOB optimization without an index.
! 296: #
! 297: do_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 {}}
! 303: do_test like-3.18 {
! 304: set sqlite_like_count
! 305: } 12
! 306:
! 307: # GLOB is optimized regardless of the case_sensitive_like setting.
! 308: #
! 309: do_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}
! 316: do_test like-3.20 {
! 317: set sqlite_like_count
! 318: } 0
! 319: do_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}
! 326: do_test like-3.22 {
! 327: set sqlite_like_count
! 328: } 0
! 329: do_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}
! 336: do_test like-3.24 {
! 337: set sqlite_like_count
! 338: } 6
! 339:
! 340: # GLOB optimization when there is no wildcard. Ticket [e090183531fc2747]
! 341: #
! 342: do_test like-3.25 {
! 343: queryplan {
! 344: SELECT x FROM t1 WHERE x GLOB 'a' ORDER BY 1;
! 345: }
! 346: } {a nosort {} i1}
! 347: do_test like-3.26 {
! 348: queryplan {
! 349: SELECT x FROM t1 WHERE x GLOB 'abcd' ORDER BY 1;
! 350: }
! 351: } {abcd nosort {} i1}
! 352: do_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: #
! 363: do_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}
! 370: do_test like-4.2 {
! 371: set sqlite_like_count
! 372: } 0
! 373: do_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}
! 379: do_test like-4.4 {
! 380: set sqlite_like_count
! 381: } 12
! 382: do_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}
! 388: do_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: #
! 396: do_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}
! 403: do_test like-5.2 {
! 404: set sqlite_like_count
! 405: } 12
! 406: do_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}
! 417: do_test like-5.4 {
! 418: set sqlite_like_count
! 419: } 0
! 420: do_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}
! 429: do_test like-5.6 {
! 430: set sqlite_like_count
! 431: } 12
! 432: do_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}
! 441: do_test like-5.8 {
! 442: set sqlite_like_count
! 443: } 12
! 444: do_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}
! 451: do_test like-5.12 {
! 452: set sqlite_like_count
! 453: } 12
! 454: do_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}
! 460: do_test like-5.14 {
! 461: set sqlite_like_count
! 462: } 0
! 463: do_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}
! 472: do_test like-5.16 {
! 473: set sqlite_like_count
! 474: } 12
! 475: do_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}
! 484: do_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: #
! 497: do_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}
! 509: do_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}
! 514: do_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}
! 519: do_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}
! 524: do_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}
! 538: do_test like-5.26 {
! 539: queryplan {
! 540: SELECT x FROM t3 WHERE x LIKE 'zZ%';
! 541: }
! 542: } {zZ-lower-upper nosort {} i3}
! 543: do_test like-5.27 {
! 544: queryplan {
! 545: SELECT x FROM t3 WHERE x LIKE 'Zz%';
! 546: }
! 547: } {Zz-upper-lower nosort {} i3}
! 548: do_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: #
! 560: do_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:
! 570: do_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: #
! 581: do_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}
! 591: do_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}
! 600: do_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}
! 607: do_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:
! 616: ifcapable 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: #
! 789: do_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}
! 811: do_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 *}
! 817: do_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 *}
! 823: do_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}
! 830: do_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 *}
! 836: do_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}
! 844: do_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}
! 850: do_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}
! 856: do_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}
! 862: do_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}
! 869: do_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:
! 876: finish_test
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>