like.test 22 KB

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