CoolFace
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 9mo agoView on Hugging Face
0likes
like.test1164 linesDownload Raw Back to test
1# 2005 August 132#3# The author disclaims copyright to this source code.  In place of4# 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.  The12# focus of this file is testing the LIKE and GLOB operators and13# in particular the optimizations that occur to help those operators14# 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.tcl20set testprefix like21 22# Create some sample data to work with.23#24do_test like-1.0 {25  execsql {26    CREATE TABLE t1(x TEXT);27  }28  foreach str {29    a30    ab31    abc32    abcd33 34    acd35    abd36    bc37    bcd38 39    xyz40    ABC41    CDE42    {ABC abc xyz}43  } {44    db eval {INSERT INTO t1 VALUES(:str)}45  }46  execsql {47    SELECT count(*) FROM t1;48  }49} {12}50 51# Test that both case sensitive and insensitive version of LIKE work.52#53do_test like-1.1 {54  execsql {55    SELECT x FROM t1 WHERE x LIKE 'abc' ORDER BY 1;56  }57} {ABC abc}58do_test like-1.2 {59  execsql {60    SELECT x FROM t1 WHERE x GLOB 'abc' ORDER BY 1;61  }62} {abc}63do_test like-1.3 {64  execsql {65    SELECT x FROM t1 WHERE x LIKE 'ABC' ORDER BY 1;66  }67} {ABC abc}68do_test like-1.4 {69  execsql {70    SELECT x FROM t1 WHERE x LIKE 'aBc' ORDER BY 1;71  }72} {ABC abc}73do_test like-1.5.1 {74  # Use sqlite3_exec() to verify fix for ticket [25ee81271091] 2011-06-2675  sqlite3_exec db {PRAGMA case_sensitive_like=on}76} {0 {}}77do_test like-1.5.2 {78  execsql {79    SELECT x FROM t1 WHERE x LIKE 'abc' ORDER BY 1;80  }81} {abc}82do_test like-1.5.3 {83  execsql {84    PRAGMA case_sensitive_like; -- no argument; does not change setting85    SELECT x FROM t1 WHERE x LIKE 'abc' ORDER BY 1;86  }87} {abc}88do_test like-1.6 {89  execsql {90    SELECT x FROM t1 WHERE x GLOB 'abc' ORDER BY 1;91  }92} {abc}93do_test like-1.7 {94  execsql {95    SELECT x FROM t1 WHERE x LIKE 'ABC' ORDER BY 1;96  }97} {ABC}98do_test like-1.8 {99  execsql {100    SELECT x FROM t1 WHERE x LIKE 'aBc' ORDER BY 1;101  }102} {}103do_test like-1.9 {104  execsql {105    PRAGMA case_sensitive_like=off;106    SELECT x FROM t1 WHERE x LIKE 'abc' ORDER BY 1;107  }108} {ABC abc}109do_test like-1.10 {110  execsql {111    PRAGMA case_sensitive_like;  -- No argument, does not change setting.112    SELECT x FROM t1 WHERE x LIKE 'abc' ORDER BY 1;113  }114} {ABC abc}115 116# Tests of the REGEXP operator117#118do_test like-2.1 {119  proc test_regexp {a b} {120    return [regexp $a $b]121  }122  db function regexp -argcount 2 test_regexp123  execsql {124    SELECT x FROM t1 WHERE x REGEXP 'abc' ORDER BY 1;125  }126} {{ABC abc xyz} abc abcd}127do_test like-2.2 {128  execsql {129    SELECT x FROM t1 WHERE x REGEXP '^abc' ORDER BY 1;130  }131} {abc abcd}132 133# Tests of the MATCH operator134#135do_test like-2.3 {136  proc test_match {a b} {137    return [string match $a $b]138  }139  db function match -argcount 2 test_match140  execsql {141    SELECT x FROM t1 WHERE x MATCH '*abc*' ORDER BY 1;142  }143} {{ABC abc xyz} abc abcd}144do_test like-2.4 {145  execsql {146    SELECT x FROM t1 WHERE x MATCH 'abc*' ORDER BY 1;147  }148} {abc abcd}149 150# For the remaining tests, we need to have the like optimizations151# enabled.152#153ifcapable !like_opt {154  finish_test155  return156} 157 158# This procedure executes the SQL.  Then it appends to the result the159# "sort" or "nosort" keyword (as in the cksort procedure above) then160# it appends the names of the table and index used.161#162proc queryplan {sql} {163  set ::sqlite_sort_count 0164  db cache flush165  set data [execsql $sql]166  if {$::sqlite_sort_count} {set x sort} {set x nosort}167  lappend data $x168  set eqp [execsql "EXPLAIN QUERY PLAN $sql"]169  # puts eqp=$eqp170  foreach {a b c x} $eqp {171    if {[regexp {(SCAN|SEARCH) (\w+ AS )?(\w+) USING COVERING INDEX (\w+)\y} \172        $x all ss as tab idx]} {173      lappend data {} $idx174    } elseif {[regexp {(SCAN|SEARCH) (\w+ AS )?(\w+) USING.* INDEX (\w+)\y} \175        $x all ss as tab idx]} {176      lappend data $tab $idx177    } elseif {[regexp {(SCAN|SEARCH) (\w+ AS )?(\w+)\y} $x all ss as tab]} {178      lappend data $tab *179    }180  }181  return $data   182}183 184# Perform tests on the like optimization.185#186# With no index on t1.x and with case sensitivity turned off, no optimization187# is performed.188#189do_test like-3.1 {190  set sqlite_like_count 0191  queryplan {192    SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1;193  }194} {ABC {ABC abc xyz} abc abcd sort t1 *}195do_test like-3.2 {196  set sqlite_like_count197} {12}198 199# With an index on t1.x and case sensitivity on, optimize completely.200#201do_test like-3.3.100 {202  set sqlite_like_count 0203  execsql {204    PRAGMA case_sensitive_like=on;205    CREATE INDEX i1 ON t1(x);206  }207  queryplan {208    SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1;209  }210} {abc abcd nosort {} i1}211do_test like-3.3.100.cnt {212  set sqlite_like_count213} 0214 215# The like optimization works even when the pattern is a bound parameter216#217# Exception: It does not work if sqlite3_prepare() is used instead of218# sqlite3_prepare_v2(), as in that case the statement cannot be reprepared219# after the parameter is bound.220#221unset -nocomplain ::likepat222set ::likepat abc%223if {[permutation]!="prepare"} {224  do_test like-3.3.102 {225    set sqlite_like_count 0226    queryplan {227      SELECT x FROM t1 WHERE x LIKE $::likepat ORDER BY 1;228    }229  } {abc abcd nosort {} i1}230  do_test like-3.3.103 {231    set sqlite_like_count232  } 0233}234 235# Except, the like optimization does not work for bound parameters if236# the query planner stability guarantee is active.237#238do_test like-3.3.104 {239  set sqlite_like_count 0240  sqlite3_db_config db QPSG 1241  queryplan {242    SELECT x FROM t1 WHERE x LIKE $::likepat ORDER BY 1;243  }244} {abc abcd nosort {} i1}245do_test like-3.3.105 {246  set sqlite_like_count247} 12248 249# The query planner stability guarantee does not disrupt explicit patterns250#251do_test like-3.3.105 {252  set sqlite_like_count 0253  queryplan {254    SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1;255  }256} {abc abcd nosort {} i1}257do_test like-3.3.106 {258  set sqlite_like_count259} 0260sqlite3_db_config db QPSG 0261 262# The LIKE optimization still works when the RHS is a string with no263# wildcard.  Ticket [e090183531fc2747]264#265do_test like-3.4.2 {266  queryplan {267    SELECT x FROM t1 WHERE x LIKE 'a' ORDER BY 1;268  }269} {a nosort {} i1}270do_test like-3.4.3 {271  queryplan {272    SELECT x FROM t1 WHERE x LIKE 'ab' ORDER BY 1;273  }274} {ab nosort {} i1}275do_test like-3.4.4 {276  queryplan {277    SELECT x FROM t1 WHERE x LIKE 'abcd' ORDER BY 1;278  }279} {abcd nosort {} i1}280do_test like-3.4.5 {281  queryplan {282    SELECT x FROM t1 WHERE x LIKE 'abcde' ORDER BY 1;283  }284} {nosort {} i1}285 286 287# Partial optimization when the pattern does not end in '%'288#289do_test like-3.5 {290  set sqlite_like_count 0291  queryplan {292    SELECT x FROM t1 WHERE x LIKE 'a_c' ORDER BY 1;293  }294} {abc nosort {} i1}295do_test like-3.6 {296  set sqlite_like_count297} 6298do_test like-3.7 {299  set sqlite_like_count 0300  queryplan {301    SELECT x FROM t1 WHERE x LIKE 'ab%d' ORDER BY 1;302  }303} {abcd abd nosort {} i1}304do_test like-3.8 {305  set sqlite_like_count306} 4307do_test like-3.9 {308  set sqlite_like_count 0309  queryplan {310    SELECT x FROM t1 WHERE x LIKE 'a_c%' ORDER BY 1;311  }312} {abc abcd nosort {} i1}313do_test like-3.10 {314  set sqlite_like_count315} 6316 317# No optimization when the pattern begins with a wildcard.318# Note that the index is still used but only for sorting.319#320do_test like-3.11 {321  set sqlite_like_count 0322  queryplan {323    SELECT x FROM t1 WHERE x LIKE '%bcd' ORDER BY 1;324  }325} {abcd bcd nosort {} i1}326do_test like-3.12 {327  set sqlite_like_count328} 12329 330# No optimization for case insensitive LIKE331#332do_test like-3.13 {333  set sqlite_like_count 0334  db eval {PRAGMA case_sensitive_like=off;}335  queryplan {336    SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1;337  }338} {ABC {ABC abc xyz} abc abcd nosort {} i1}339do_test like-3.14 {340  set sqlite_like_count341} 12342 343# No optimization without an index.344#345do_test like-3.15 {346  set sqlite_like_count 0347  db eval {348    PRAGMA case_sensitive_like=on;349    DROP INDEX i1;350  }351  queryplan {352    SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1;353  }354} {abc abcd sort t1 *}355do_test like-3.16 {356  set sqlite_like_count357} 12358 359# No GLOB optimization without an index.360#361do_test like-3.17 {362  set sqlite_like_count 0363  queryplan {364    SELECT x FROM t1 WHERE x GLOB 'abc*' ORDER BY 1;365  }366} {abc abcd sort t1 *}367do_test like-3.18 {368  set sqlite_like_count369} 12370 371# GLOB is optimized regardless of the case_sensitive_like setting.372#373do_test like-3.19 {374  set sqlite_like_count 0375  db eval {CREATE INDEX i1 ON t1(x);}376  queryplan {377    SELECT x FROM t1 WHERE x GLOB 'abc*' ORDER BY 1;378  }379} {abc abcd nosort {} i1}380do_test like-3.20 {381  set sqlite_like_count382} 0383do_test like-3.21 {384  set sqlite_like_count 0385  db eval {PRAGMA case_sensitive_like=on;}386  queryplan {387    SELECT x FROM t1 WHERE x GLOB 'abc*' ORDER BY 1;388  }389} {abc abcd nosort {} i1}390do_test like-3.22 {391  set sqlite_like_count392} 0393do_test like-3.23 {394  set sqlite_like_count 0395  db eval {PRAGMA case_sensitive_like=off;}396  queryplan {397    SELECT x FROM t1 WHERE x GLOB 'a[bc]d' ORDER BY 1;398  }399} {abd acd nosort {} i1}400do_test like-3.24 {401  set sqlite_like_count402} 6403 404# GLOB optimization when there is no wildcard.  Ticket [e090183531fc2747]405#406do_test like-3.25 {407  queryplan {408    SELECT x FROM t1 WHERE x GLOB 'a' ORDER BY 1;409  }410} {a nosort {} i1}411do_test like-3.26 {412  queryplan {413    SELECT x FROM t1 WHERE x GLOB 'abcd' ORDER BY 1;414  }415} {abcd nosort {} i1}416do_test like-3.27 {417  queryplan {418    SELECT x FROM t1 WHERE x GLOB 'abcde' ORDER BY 1;419  }420} {nosort {} i1}421 422 423 424# No optimization if the LHS of the LIKE is not a column name or425# if the RHS is not a string.426#427do_test like-4.1 {428  execsql {PRAGMA case_sensitive_like=on}429  set sqlite_like_count 0430  queryplan {431    SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1432  }433} {abc abcd nosort {} i1}434do_test like-4.2 {435  set sqlite_like_count436} 0437do_test like-4.3 {438  set sqlite_like_count 0439  queryplan {440    SELECT x FROM t1 WHERE +x LIKE 'abc%' ORDER BY 1441  }442} {abc abcd nosort {} i1}443do_test like-4.4 {444  set sqlite_like_count445} 12446do_test like-4.5 {447  set sqlite_like_count 0448  queryplan {449    SELECT x FROM t1 WHERE x LIKE ('ab' || 'c%') ORDER BY 1450  }451} {abc abcd nosort {} i1}452do_test like-4.6 {453  set sqlite_like_count454} 12455 456# Collating sequences on the index disable the LIKE optimization.457# Or if the NOCASE collating sequence is used, the LIKE optimization458# is enabled when case_sensitive_like is OFF.459#460do_test like-5.1 {461  execsql {PRAGMA case_sensitive_like=off}462  set sqlite_like_count 0463  queryplan {464    SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1465  }466} {ABC {ABC abc xyz} abc abcd nosort {} i1}467do_test like-5.2 {468  set sqlite_like_count469} 12470do_test like-5.3 {471  execsql {472    CREATE TABLE t2(x TEXT COLLATE NOCASE);473    INSERT INTO t2 SELECT * FROM t1 ORDER BY rowid;474    CREATE INDEX i2 ON t2(x COLLATE NOCASE);475  }476  set sqlite_like_count 0477  queryplan {478    SELECT x FROM t2 WHERE x LIKE 'abc%' ORDER BY 1479  }480} {abc ABC {ABC abc xyz} abcd nosort {} i2}481do_test like-5.4 {482  set sqlite_like_count483} 0484do_test like-5.5 {485  execsql {486    PRAGMA case_sensitive_like=on;487  }488  set sqlite_like_count 0489  queryplan {490    SELECT x FROM t2 WHERE x LIKE 'abc%' ORDER BY 1491  }492} {abc abcd nosort {} i2}493do_test like-5.6 {494  set sqlite_like_count495} 12496do_test like-5.7 {497  execsql {498    PRAGMA case_sensitive_like=off;499  }500  set sqlite_like_count 0501  queryplan {502    SELECT x FROM t2 WHERE x GLOB 'abc*' ORDER BY 1503  }504} {abc abcd nosort {} i2}505do_test like-5.8 {506  set sqlite_like_count507} 12508do_test like-5.11 {509  execsql {PRAGMA case_sensitive_like=off}510  set sqlite_like_count 0511  queryplan {512    SELECT x FROM t1 WHERE x LIKE 'ABC%' ORDER BY 1513  }514} {ABC {ABC abc xyz} abc abcd nosort {} i1}515do_test like-5.12 {516  set sqlite_like_count517} 12518do_test like-5.13 {519  set sqlite_like_count 0520  queryplan {521    SELECT x FROM t2 WHERE x LIKE 'ABC%' ORDER BY 1522  }523} {abc ABC {ABC abc xyz} abcd nosort {} i2}524do_test like-5.14 {525  set sqlite_like_count526} 0527do_test like-5.15 {528  execsql {529    PRAGMA case_sensitive_like=on;530  }531  set sqlite_like_count 0532  queryplan {533    SELECT x FROM t2 WHERE x LIKE 'ABC%' ORDER BY 1534  }535} {ABC {ABC abc xyz} nosort {} i2}536do_test like-5.16 {537  set sqlite_like_count538} 12539do_test like-5.17 {540  execsql {541    PRAGMA case_sensitive_like=off;542  }543  set sqlite_like_count 0544  queryplan {545    SELECT x FROM t2 WHERE x GLOB 'ABC*' ORDER BY 1546  }547} {ABC {ABC abc xyz} nosort {} i2}548do_test like-5.18 {549  set sqlite_like_count550} 12551 552# Boundary case.  The prefix for a LIKE comparison is rounded up553# when constructing the comparison.  Example:  "ab" becomes "ac".554# In other words, the last character is increased by one.555#556# Make sure this happens correctly when the last character is a 557# "z" and we are doing case-insensitive comparisons.558#559# Ticket #2959560#561do_test like-5.21 {562  execsql {563    PRAGMA case_sensitive_like=off;564    INSERT INTO t2 VALUES('ZZ-upper-upper');565    INSERT INTO t2 VALUES('zZ-lower-upper');566    INSERT INTO t2 VALUES('Zz-upper-lower');567    INSERT INTO t2 VALUES('zz-lower-lower');568  }569  queryplan {570    SELECT x FROM t2 WHERE x LIKE 'zz%';571  }572} {zz-lower-lower zZ-lower-upper Zz-upper-lower ZZ-upper-upper nosort {} i2}573do_test like-5.22 {574  queryplan {575    SELECT x FROM t2 WHERE x LIKE 'zZ%';576  }577} {zz-lower-lower zZ-lower-upper Zz-upper-lower ZZ-upper-upper nosort {} i2}578do_test like-5.23 {579  queryplan {580    SELECT x FROM t2 WHERE x LIKE 'Zz%';581  }582} {zz-lower-lower zZ-lower-upper Zz-upper-lower ZZ-upper-upper nosort {} i2}583do_test like-5.24 {584  queryplan {585    SELECT x FROM t2 WHERE x LIKE 'ZZ%';586  }587} {zz-lower-lower zZ-lower-upper Zz-upper-lower ZZ-upper-upper nosort {} i2}588do_test like-5.25 {589  db eval {590    PRAGMA case_sensitive_like=on;591    CREATE TABLE t3(x TEXT);592    CREATE INDEX i3 ON t3(x);593    INSERT INTO t3 VALUES('ZZ-upper-upper');594    INSERT INTO t3 VALUES('zZ-lower-upper');595    INSERT INTO t3 VALUES('Zz-upper-lower');596    INSERT INTO t3 VALUES('zz-lower-lower');597  }598  queryplan {599    SELECT x FROM t3 WHERE x LIKE 'zz%';600  }601} {zz-lower-lower nosort {} i3}602do_test like-5.26 {603  queryplan {604    SELECT x FROM t3 WHERE x LIKE 'zZ%';605  }606} {zZ-lower-upper nosort {} i3}607do_test like-5.27 {608  queryplan {609    SELECT x FROM t3 WHERE x LIKE 'Zz%';610  }611} {Zz-upper-lower nosort {} i3}612do_test like-5.28 {613  queryplan {614    SELECT x FROM t3 WHERE x LIKE 'ZZ%';615  }616} {ZZ-upper-upper nosort {} i3}617 618 619# ticket #2407620#621# Make sure the LIKE prefix optimization does not strip off leading622# characters of the like pattern that happen to be quote characters.623#624do_test like-6.1 {625  foreach x { 'abc 'bcd 'def 'ax } {626    set x2 '[string map {' ''} $x]'627    db eval "INSERT INTO t2 VALUES($x2)"628  }629  execsql {630    SELECT * FROM t2 WHERE x LIKE '''a%'631  }632} {'abc 'ax}633 634do_test like-7.1 {635  execsql {636    SELECT rowid, * FROM t1 WHERE rowid GLOB '1*' ORDER BY rowid;637  }638} {1 a 10 ABC 11 CDE 12 {ABC abc xyz}}639 640# ticket #3345.641#642# Overloading the LIKE function with -1 for the number of arguments643# will overload both the 2-argument and the 3-argument LIKE.644#645do_test like-8.1 {646  db eval {647    CREATE TABLE t8(x);648    INSERT INTO t8 VALUES('abcdef');649    INSERT INTO t8 VALUES('ghijkl');650    INSERT INTO t8 VALUES('mnopqr');651    SELECT 1, x FROM t8 WHERE x LIKE '%h%';652    SELECT 2, x FROM t8 WHERE x LIKE '%h%' ESCAPE 'x';653  }654} {1 ghijkl 2 ghijkl}655do_test like-8.2 {656  proc newlike {args} {return 1} ;# Alternative LIKE is always return TRUE657  db function like newlike       ;# Uses -1 for nArg in sqlite3_create_function658  db cache flush659  db eval {660    SELECT 1, x FROM t8 WHERE x LIKE '%h%';661    SELECT 2, x FROM t8 WHERE x LIKE '%h%' ESCAPE 'x';662  }663} {1 ghijkl 2 ghijkl}664do_test like-8.3 {665  db function like -argcount 2 newlike666  db eval {667    SELECT 1, x FROM t8 WHERE x LIKE '%h%';668    SELECT 2, x FROM t8 WHERE x LIKE '%h%' ESCAPE 'x';669  }670} {1 abcdef 1 ghijkl 1 mnopqr 2 ghijkl}671do_test like-8.4 {672  db function like -argcount 3 newlike673  db eval {674    SELECT 1, x FROM t8 WHERE x LIKE '%h%';675    SELECT 2, x FROM t8 WHERE x LIKE '%h%' ESCAPE 'x';676  }677} {1 abcdef 1 ghijkl 1 mnopqr 2 abcdef 2 ghijkl 2 mnopqr}678 679 680ifcapable like_opt&&!icu {681  # Evaluate SQL.  Return the result set followed by the682  # and the number of full-scan steps.683  #684  db close685  sqlite3 db test.db686  proc count_steps {sql} {687    set r [db eval $sql]688    lappend r scan [db status step] sort [db status sort]689  }690  do_test like-9.1 {691    count_steps {692       SELECT x FROM t2 WHERE x LIKE 'x%'693    }694  } {xyz scan 0 sort 0}695  do_test like-9.2 {696    count_steps {697       SELECT x FROM t2 WHERE x LIKE '_y%'698    }699  } {xyz scan 19 sort 0}700  do_test like-9.3.1 {701    set res [sqlite3_exec_hex db {702       SELECT x FROM t2 WHERE x LIKE '%78%25'703    }]704  } {0 {x xyz}}705  ifcapable explain {706    do_test like-9.3.2 {707      set res [sqlite3_exec_hex db {708         EXPLAIN QUERY PLAN SELECT x FROM t2 WHERE x LIKE '%78%25'709      }]710      regexp {INDEX i2} $res711    } {1}712  }713  do_test like-9.4.1 {714    sqlite3_exec_hex db {INSERT INTO t2 VALUES('%ffhello')}715    set res [sqlite3_exec_hex db {716       SELECT substr(x,2) AS x FROM t2 WHERE +x LIKE '%ff%25'717    }]718  } {0 {x hello}}719  do_test like-9.4.2 {720    set res [sqlite3_exec_hex db {721       SELECT substr(x,2) AS x FROM t2 WHERE x LIKE '%ff%25'722    }]723  } {0 {x hello}}724  ifcapable explain {725    do_test like-9.4.3 {726      set res [sqlite3_exec_hex db {727         EXPLAIN QUERY PLAN SELECT x FROM t2 WHERE x LIKE '%ff%25'728      }]729      regexp {SCAN t2} $res730    } {1}731  }732  do_test like-9.5.1 {733    set res [sqlite3_exec_hex db {734       SELECT 1 FROM t2 WHERE x LIKE '%fe%25'735    }]736  } {0 {1 1}}737  ifcapable explain {738    do_test like-9.5.2 {739      set res [sqlite3_exec_hex db {740         EXPLAIN QUERY PLAN SELECT x FROM t2 WHERE x LIKE '%fe%25'741      }]742      regexp {INDEX i2} $res743    } {0}744  }745 746  # Do an SQL statement.  Append the search count to the end of the result.747  #748  proc count sql {749    set ::sqlite_search_count 0750    set ::sqlite_like_count 0751    return [concat [execsql $sql] scan $::sqlite_search_count \752             like $::sqlite_like_count]753  }754 755  # The LIKE and GLOB optimizations do not work on columns with756  # affinity other than TEXT.757  # Ticket #3901758  #759  do_test like-10.1 {760    db close761    sqlite3 db test.db762    execsql {763      CREATE TABLE t10(764        a INTEGER PRIMARY KEY,765        b INTEGER COLLATE nocase UNIQUE,766        c NUMBER COLLATE nocase UNIQUE,767        d BLOB COLLATE nocase UNIQUE,768        e COLLATE nocase UNIQUE,769        f TEXT COLLATE nocase UNIQUE770      );771      INSERT INTO t10 VALUES(1,1,1,1,1,1);772      INSERT INTO t10 VALUES(12,12,12,12,12,12);773      INSERT INTO t10 VALUES(123,123,123,123,123,123);774      INSERT INTO t10 VALUES(234,234,234,234,234,234);775      INSERT INTO t10 VALUES(345,345,345,345,345,345);776      INSERT INTO t10 VALUES(45,45,45,45,45,45);777    }778    count {779      SELECT a FROM t10 WHERE b LIKE '12%' ORDER BY +a;780    }781  } {12 123 scan 5 like 6}782  do_test like-10.2 {783    count {784      SELECT a FROM t10 WHERE c LIKE '12%' ORDER BY +a;785    }786  } {12 123 scan 5 like 6}787  do_test like-10.3 {788    count {789      SELECT a FROM t10 WHERE d LIKE '12%' ORDER BY +a;790    }791  } {12 123 scan 5 like 6}792  do_test like-10.4 {793    count {794      SELECT a FROM t10 WHERE e LIKE '12%' ORDER BY +a;795    }796  } {12 123 scan 5 like 6}797  ifcapable like_match_blobs {798    do_test like-10.5a {799      count {800        SELECT a FROM t10 WHERE f LIKE '12%' ORDER BY +a;801      }802    } {12 123 scan 4 like 0}803  } else {804    do_test like-10.5b {805      count {806        SELECT a FROM t10 WHERE f LIKE '12%' ORDER BY +a;807      }808    } {12 123 scan 3 like 0}809  }810  do_test like-10.6 {811    count {812      SELECT a FROM t10 WHERE a LIKE '12%' ORDER BY +a;813    }814  } {12 123 scan 5 like 6}815  do_test like-10.10 {816    execsql {817      CREATE TABLE t10b(818        a INTEGER PRIMARY KEY,819        b INTEGER UNIQUE,820        c NUMBER UNIQUE,821        d BLOB UNIQUE,822        e UNIQUE,823        f TEXT UNIQUE824      );825      INSERT INTO t10b SELECT * FROM t10;826    }827    count {828      SELECT a FROM t10b WHERE b GLOB '12*' ORDER BY +a;829    }830  } {12 123 scan 5 like 6}831  do_test like-10.11 {832    count {833      SELECT a FROM t10b WHERE c GLOB '12*' ORDER BY +a;834    }835  } {12 123 scan 5 like 6}836  do_test like-10.12 {837    count {838      SELECT a FROM t10b WHERE d GLOB '12*' ORDER BY +a;839    }840  } {12 123 scan 5 like 6}841  do_test like-10.13 {842    count {843      SELECT a FROM t10b WHERE e GLOB '12*' ORDER BY +a;844    }845  } {12 123 scan 5 like 6}846  ifcapable like_match_blobs {847    do_test like-10.14 {848      count {849        SELECT a FROM t10b WHERE f GLOB '12*' ORDER BY +a;850      }851    } {12 123 scan 4 like 0}852  } else {853    do_test like-10.14 {854      count {855        SELECT a FROM t10b WHERE f GLOB '12*' ORDER BY +a;856      }857    } {12 123 scan 3 like 0}858  }859  do_test like-10.15 {860    count {861      SELECT a FROM t10b WHERE a GLOB '12*' ORDER BY +a;862    }863  } {12 123 scan 5 like 6}864}865 866# LIKE and GLOB where the default collating sequence is not appropriate867# but an index with the appropriate collating sequence exists.868#869do_test like-11.0 {870  execsql {871    CREATE TABLE t11(872      a INTEGER PRIMARY KEY,873      b TEXT COLLATE nocase,874      c TEXT COLLATE binary875    );876    INSERT INTO t11 VALUES(1, 'a','a');877    INSERT INTO t11 VALUES(2, 'ab','ab');878    INSERT INTO t11 VALUES(3, 'abc','abc');879    INSERT INTO t11 VALUES(4, 'abcd','abcd');880    INSERT INTO t11 VALUES(5, 'A','A');881    INSERT INTO t11 VALUES(6, 'AB','AB');882    INSERT INTO t11 VALUES(7, 'ABC','ABC');883    INSERT INTO t11 VALUES(8, 'ABCD','ABCD');884    INSERT INTO t11 VALUES(9, 'x','x');885    INSERT INTO t11 VALUES(10, 'yz','yz');886    INSERT INTO t11 VALUES(11, 'X','X');887    INSERT INTO t11 VALUES(12, 'YZ','YZ');888    SELECT count(*) FROM t11;889  }890} {12}891do_test like-11.1 {892  db eval {PRAGMA case_sensitive_like=OFF;}893  queryplan {894    SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY a;895  }896} {abc abcd ABC ABCD nosort t11 *}897do_test like-11.2 {898  db eval {PRAGMA case_sensitive_like=ON;}899  queryplan {900    SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY a;901  }902} {abc abcd nosort t11 *}903do_test like-11.3 {904  db eval {905    PRAGMA case_sensitive_like=OFF;906    CREATE INDEX t11b ON t11(b);907  }908  queryplan {909    SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY +a;910  }911} {abc abcd ABC ABCD sort {} t11b}912do_test like-11.4 {913  db eval {PRAGMA case_sensitive_like=ON;}914  queryplan {915    SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY a;916  }917} {abc abcd nosort t11 *}918do_test like-11.5 {919  db eval {920    PRAGMA case_sensitive_like=OFF;921    DROP INDEX t11b;922    CREATE INDEX t11bnc ON t11(b COLLATE nocase);923  }924  queryplan {925    SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY +a;926  }927} {abc abcd ABC ABCD sort {} t11bnc}928do_test like-11.6 {929  db eval {CREATE INDEX t11bb ON t11(b COLLATE binary);}930  queryplan {931    SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY +a;932  }933} {abc abcd ABC ABCD sort {} t11bnc}934do_test like-11.7 {935  db eval {PRAGMA case_sensitive_like=ON;}936  queryplan {937    SELECT b FROM t11 WHERE b LIKE 'abc%' ORDER BY +a;938  }939} {abc abcd sort {} t11bb}940do_test like-11.8 {941  db eval {PRAGMA case_sensitive_like=OFF;}942  queryplan {943    SELECT b FROM t11 WHERE b GLOB 'abc*' ORDER BY +a;944  }945} {abc abcd sort {} t11bb}946do_test like-11.9 {947  db eval {948    CREATE INDEX t11cnc ON t11(c COLLATE nocase);949    CREATE INDEX t11cb ON t11(c COLLATE binary);950  }951  queryplan {952    SELECT c FROM t11 WHERE c LIKE 'abc%' ORDER BY +a;953  }954} {abc abcd ABC ABCD sort {} t11cnc}955do_test like-11.10 {956  queryplan {957    SELECT c FROM t11 WHERE c GLOB 'abc*' ORDER BY +a;958  }959} {abc abcd sort {} t11cb}960 961# A COLLATE clause on the pattern does not change the result of a962# LIKE operator.963#964do_execsql_test like-12.1 {965  CREATE TABLE t12nc(id INTEGER, x TEXT UNIQUE COLLATE nocase);966  INSERT INTO t12nc VALUES(1,'abcde'),(2,'uvwxy'),(3,'ABCDEF');967  CREATE TABLE t12b(id INTEGER, x TEXT UNIQUE COLLATE binary);968  INSERT INTO t12b VALUES(1,'abcde'),(2,'uvwxy'),(3,'ABCDEF');969  SELECT id FROM t12nc WHERE x LIKE 'abc%' ORDER BY +id;970} {1 3}971do_execsql_test like-12.2 {972  SELECT id FROM t12b WHERE x LIKE 'abc%' ORDER BY +id;973} {1 3}974do_execsql_test like-12.3 {975  SELECT id FROM t12nc WHERE x LIKE 'abc%' COLLATE binary ORDER BY +id;976} {1 3}977do_execsql_test like-12.4 {978  SELECT id FROM t12b WHERE x LIKE 'abc%' COLLATE binary ORDER BY +id;979} {1 3}980do_execsql_test like-12.5 {981  SELECT id FROM t12nc WHERE x LIKE 'abc%' COLLATE nocase ORDER BY +id;982} {1 3}983do_execsql_test like-12.6 {984  SELECT id FROM t12b WHERE x LIKE 'abc%' COLLATE nocase ORDER BY +id;985} {1 3}986 987# Adding a COLLATE clause to the pattern of a LIKE operator does nothing988# to change the suitability of using an index to satisfy that LIKE989# operator.990#991do_execsql_test like-12.11 {992  EXPLAIN QUERY PLAN993  SELECT id FROM t12nc WHERE x LIKE 'abc%' ORDER BY +id;994} {/SEARCH/}995do_execsql_test like-12.12 {996  EXPLAIN QUERY PLAN997  SELECT id FROM t12b WHERE x LIKE 'abc%' ORDER BY +id;998} {/SCAN/}999do_execsql_test like-12.13 {1000  EXPLAIN QUERY PLAN1001  SELECT id FROM t12nc WHERE x LIKE 'abc%' COLLATE nocase ORDER BY +id;1002} {/SEARCH/}1003do_execsql_test like-12.14 {1004  EXPLAIN QUERY PLAN1005  SELECT id FROM t12b WHERE x LIKE 'abc%' COLLATE nocase ORDER BY +id;1006} {/SCAN/}1007do_execsql_test like-12.15 {1008  EXPLAIN QUERY PLAN1009  SELECT id FROM t12nc WHERE x LIKE 'abc%' COLLATE binary ORDER BY +id;1010} {/SEARCH/}1011do_execsql_test like-12.16 {1012  EXPLAIN QUERY PLAN1013  SELECT id FROM t12b WHERE x LIKE 'abc%' COLLATE binary ORDER BY +id;1014} {/SCAN/}1015 1016# Ticket [https://sqlite.org/src/tktview/80369eddd5c94d49f7fbbcf5]1017# 2016-01-201018#1019do_execsql_test like-13.1 {1020  SELECT char(0x304d) LIKE char(0x306d);1021} {0}1022do_execsql_test like-13.2 {1023  SELECT char(0x4d) LIKE char(0x306d);1024} {0}1025do_execsql_test like-13.3 {1026  SELECT char(0x304d) LIKE char(0x6d);1027} {0}1028do_execsql_test like-13.4 {1029  SELECT char(0x4d) LIKE char(0x6d);1030} {1}1031 1032# Performance testing for patterns with many wildcards.  These LIKE and GLOB1033# patterns were quite slow with SQLite 3.15.2 and earlier.1034#1035do_test like-14.1 {1036  set x [lindex [time {1037    db one {SELECT 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaz'GLOB'*a*a*a*a*a*a*a*a*y'}1038  }] 0]1039  set tlimit [expr {1000 * $::sqlite_options(configslower)}]1040  puts -nonewline " ($x ms - want less than $tlimit) "1041  expr {$x<$tlimit}1042} {1}1043ifcapable !icu {1044  do_test like-14.2 {1045    set x [lindex [time {1046      db one {SELECT 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaz'LIKE'%a%a%a%a%a%a%a%a%y'}1047    }] 0]1048  set tlimit [expr {1000 * $::sqlite_options(configslower)}]1049  puts -nonewline " ($x ms - want less than $tlimit) "1050  expr {$x<$tlimit}1051  } {1}1052}1053 1054ifcapable !icu {1055# As of 2017-07-27 (3.21.0) the LIKE optimization works with ESCAPE as1056# long as the ESCAPE is a single-byte literal.1057#1058db close1059sqlite3 db :memory:1060do_execsql_test like-15.100 {1061  CREATE TABLE t15(x TEXT COLLATE nocase, y, PRIMARY KEY(x));1062  INSERT INTO t15(x,y) VALUES1063    ('abcde',1), ('ab%de',2), ('a_cde',3),1064    ('uvwxy',11),('uvwx%',12),('uvwx_',13),1065    ('_bcde',21),('%bcde',22),1066    ('abcd_',31),('abcd%',32),1067    ('ab%xy',41);1068  SELECT y FROM t15 WHERE x LIKE 'ab/%d%' ESCAPE '/';1069} {2}1070do_execsql_test like-15.101 {1071  EXPLAIN QUERY PLAN1072  SELECT y FROM t15 WHERE x LIKE 'ab/%d%' ESCAPE '/';1073} {/SEARCH/}1074do_execsql_test like-15.102 {1075  EXPLAIN QUERY PLAN1076  SELECT y FROM t15 WHERE x LIKE 'ab/%d%' ESCAPE '//';1077} {/SCAN/}1078do_execsql_test like-15.103 {1079  EXPLAIN QUERY PLAN1080  SELECT y FROM t15 WHERE x LIKE 'ab/%d%' ESCAPE '';1081} {/SCAN/}1082do_execsql_test like-15.110 {1083  SELECT y FROM t15 WHERE x LIKE 'abcdx%%' ESCAPE 'x';1084} {32}1085do_execsql_test like-15.111 {1086  SELECT y FROM t15 WHERE x LIKE 'abx%%' ESCAPE 'x' ORDER BY +y1087} {2 41}1088do_execsql_test like-15.112 {1089  EXPLAIN QUERY PLAN1090  SELECT y FROM t15 WHERE x LIKE 'abx%%' ESCAPE 'x' ORDER BY +y1091} {/SEARCH/}1092do_execsql_test like-15.120 {1093  SELECT y FROM t15 WHERE x LIKE '/%bc%' ESCAPE '/';1094} {22}1095do_execsql_test like-15.121 {1096  EXPLAIN QUERY PLAN1097  SELECT y FROM t15 WHERE x LIKE '/%bc%' ESCAPE '/';1098} {/SEARCH/}1099}1100 1101#-------------------------------------------------------------------------1102# Tests for ticket [b1d8c79314].1103#1104reset_db1105do_execsql_test 16.0 {1106  CREATE TABLE t1(a INTEGER COLLATE NOCASE);1107  CREATE INDEX i1 ON t1(a);1108  INSERT INTO t1 VALUES(' 1x');1109  INSERT INTO t1 VALUES(' 1-');1110}1111do_execsql_test 16.1 {1112  SELECT * FROM t1 WHERE a LIKE ' 1%';1113} {{ 1x} { 1-}}1114do_execsql_test 16.2 {1115  SELECT * FROM t1 WHERE a LIKE ' 1-';1116} {{ 1-}}1117 1118# 2020-03-191119# The ESCAPE clause on LIKE takes precedence over wildcards1120#1121do_execsql_test 17.0 {1122  DROP TABLE IF EXISTS t1;1123  CREATE TABLE t1(id INTEGER PRIMARY KEY, x TEXT);1124  INSERT INTO t1 VALUES1125    (1,'abcde'),1126    (2,'abc_'),1127    (3,'abc__'),1128    (4,'abc%'),1129    (5,'abc%%');1130  SELECT id FROM t1 WHERE x LIKE 'abc%%' ESCAPE '%';1131} {4}1132do_execsql_test 17.1 {1133  SELECT id FROM t1 WHERE x LIKE 'abc__' ESCAPE '_';1134} {2}1135 1136# 2021-02-15 ticket c0aeea67d58ae0fd1137#1138do_execsql_test 17.1 {1139  SELECT 'x' LIKE '%' ESCAPE '_';1140} {1}1141 1142 1143# 2023-08-15 https://sqlite.org/forum/forumpost/925dc9f67804c5401144#1145reset_db1146sqlite3_db_config db DEFENSIVE 11147db eval {PRAGMA trusted_schema=OFF}1148do_execsql_test 18.0 {1149  CREATE TABLE t1(x INT, y TEXT);1150  INSERT INTO t1 VALUES(1,'abc'),(2,'ABC'),(3,'Abc');1151  CREATE VIEW t2 AS SELECT * FROM t1 WHERE y LIKE 'a%';1152  SELECT * FROM t2;1153} {1 abc 2 ABC 3 Abc}1154do_execsql_test 18.1 {1155  PRAGMA case_sensitive_like=OFF;1156  SELECT * FROM t2;1157} {1 abc 2 ABC 3 Abc}1158do_execsql_test 18.2 {1159  PRAGMA case_sensitive_like=ON;1160  SELECT * FROM t2;1161} {1 abc}1162 1163finish_test1164