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>