3 # The author disclaims copyright to this source code. In place of
4 # a legal notice, here is a blessing:
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.
10 #***********************************************************************
12 # This file implements regression tests for SQLite library. This file
13 # implements tests for range and LIKE constraints that use bound variables
14 # instead of literal constant arguments.
17 set testdir [file dirname $argv0]
18 source $testdir/tester.tcl
25 #----------------------------------------------------------------------
28 # analyze3-1.*: Test that the values of bound parameters are considered
29 # in the same way as constants when planning queries that
30 # use range constraints.
32 # analyze3-2.*: Test that the values of bound parameters are considered
33 # in the same way as constants when planning queries that
34 # use LIKE expressions in the WHERE clause.
36 # analyze3-3.*: Test that binding to a variable does not invalidate the
37 # query plan when there is no way in which replanning the
38 # query may produce a superior outcome.
40 # analyze3-4.*: Test that SQL or authorization callback errors occuring
41 # within sqlite3Reprepare() are handled correctly.
43 # analyze3-5.*: Check that the query plans of applicable statements are
44 # invalidated if the values of SQL parameter are modified
45 # using the clear_bindings() or transfer_bindings() APIs.
48 proc getvar {varname} { uplevel #0 set $varname }
49 db function var getvar
51 proc eqp {sql {db db}} {
52 uplevel execsql [list "EXPLAIN QUERY PLAN $sql"] $db
55 proc sf_execsql {sql {db db}} {
56 set ::sqlite_search_count 0
57 set r [uplevel [list execsql $sql $db]]
59 concat $::sqlite_search_count [$db status step] $r
62 #-------------------------------------------------------------------------
65 # Create a table with two columns. Populate the first column (affinity
66 # INTEGER) with integer values from 100 to 1100. Create an index on this
67 # column. ANALYZE the table.
69 # analyze3-1.1.2 - 3.1.3
70 # Show that there are two possible plans for querying the table with
71 # a range constraint on the indexed column - "full table scan" or "use
72 # the index". When the range is specified using literal values, SQLite
73 # is able to pick the best plan based on the samples in sqlite_stat3.
75 # analyze3-1.1.4 - 3.1.9
76 # Show that using SQL variables produces the same results as using
77 # literal values to constrain the range scan.
79 # These tests also check that the compiler code considers column
80 # affinities when estimating the number of rows scanned by the "use
83 do_test analyze3-1.1.1 {
86 CREATE TABLE t1(x INTEGER, y);
87 CREATE INDEX i1 ON t1(x);
89 for {set i 0} {$i < 1000} {incr i} {
90 execsql { INSERT INTO t1 VALUES($i+100, $i) }
98 do_eqp_test analyze3-1.1.2 {
99 SELECT sum(y) FROM t1 WHERE x>200 AND x<300
100 } {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?) (~179 rows)}}
101 do_eqp_test analyze3-1.1.3 {
102 SELECT sum(y) FROM t1 WHERE x>0 AND x<1100
103 } {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?) (~959 rows)}}
105 do_test analyze3-1.1.4 {
106 sf_execsql { SELECT sum(y) FROM t1 WHERE x>200 AND x<300 }
108 do_test analyze3-1.1.5 {
109 set l [string range "200" 0 end]
110 set u [string range "300" 0 end]
111 sf_execsql { SELECT sum(y) FROM t1 WHERE x>$l AND x<$u }
113 do_test analyze3-1.1.6 {
114 set l [expr int(200)]
115 set u [expr int(300)]
116 sf_execsql { SELECT sum(y) FROM t1 WHERE x>$l AND x<$u }
118 do_test analyze3-1.1.7 {
119 sf_execsql { SELECT sum(y) FROM t1 WHERE x>0 AND x<1100 }
121 do_test analyze3-1.1.8 {
122 set l [string range "0" 0 end]
123 set u [string range "1100" 0 end]
124 sf_execsql { SELECT sum(y) FROM t1 WHERE x>$l AND x<$u }
126 do_test analyze3-1.1.9 {
128 set u [expr int(1100)]
129 sf_execsql { SELECT sum(y) FROM t1 WHERE x>$l AND x<$u }
133 # The following tests are similar to the block above. The difference is
134 # that the indexed column has TEXT affinity in this case. In the tests
135 # above the affinity is INTEGER.
137 do_test analyze3-1.2.1 {
140 CREATE TABLE t2(x TEXT, y);
141 INSERT INTO t2 SELECT * FROM t1;
142 CREATE INDEX i2 ON t2(x);
147 do_eqp_test analyze3-1.2.2 {
148 SELECT sum(y) FROM t2 WHERE x>1 AND x<2
149 } {0 0 0 {SEARCH TABLE t2 USING INDEX i2 (x>? AND x<?) (~196 rows)}}
150 do_eqp_test analyze3-1.2.3 {
151 SELECT sum(y) FROM t2 WHERE x>0 AND x<99
152 } {0 0 0 {SEARCH TABLE t2 USING INDEX i2 (x>? AND x<?) (~968 rows)}}
153 do_test analyze3-1.2.4 {
154 sf_execsql { SELECT sum(y) FROM t2 WHERE x>12 AND x<20 }
156 do_test analyze3-1.2.5 {
157 set l [string range "12" 0 end]
158 set u [string range "20" 0 end]
159 sf_execsql {SELECT typeof($l), typeof($u), sum(y) FROM t2 WHERE x>$l AND x<$u}
160 } {161 0 text text 4760}
161 do_test analyze3-1.2.6 {
164 sf_execsql {SELECT typeof($l), typeof($u), sum(y) FROM t2 WHERE x>$l AND x<$u}
165 } {161 0 integer integer 4760}
166 do_test analyze3-1.2.7 {
167 sf_execsql { SELECT sum(y) FROM t2 WHERE x>0 AND x<99 }
169 do_test analyze3-1.2.8 {
170 set l [string range "0" 0 end]
171 set u [string range "99" 0 end]
172 sf_execsql {SELECT typeof($l), typeof($u), sum(y) FROM t2 WHERE x>$l AND x<$u}
173 } {1981 0 text text 490555}
174 do_test analyze3-1.2.9 {
177 sf_execsql {SELECT typeof($l), typeof($u), sum(y) FROM t2 WHERE x>$l AND x<$u}
178 } {1981 0 integer integer 490555}
180 # Same tests a third time. This time, column x has INTEGER affinity and
181 # is not the leftmost column of the table. This triggered a bug causing
182 # SQLite to use sub-optimal query plans in 3.6.18 and earlier.
184 do_test analyze3-1.3.1 {
187 CREATE TABLE t3(y TEXT, x INTEGER);
188 INSERT INTO t3 SELECT y, x FROM t1;
189 CREATE INDEX i3 ON t3(x);
194 do_eqp_test analyze3-1.3.2 {
195 SELECT sum(y) FROM t3 WHERE x>200 AND x<300
196 } {0 0 0 {SEARCH TABLE t3 USING INDEX i3 (x>? AND x<?) (~156 rows)}}
197 do_eqp_test analyze3-1.3.3 {
198 SELECT sum(y) FROM t3 WHERE x>0 AND x<1100
199 } {0 0 0 {SEARCH TABLE t3 USING INDEX i3 (x>? AND x<?) (~989 rows)}}
201 do_test analyze3-1.3.4 {
202 sf_execsql { SELECT sum(y) FROM t3 WHERE x>200 AND x<300 }
204 do_test analyze3-1.3.5 {
205 set l [string range "200" 0 end]
206 set u [string range "300" 0 end]
207 sf_execsql { SELECT sum(y) FROM t3 WHERE x>$l AND x<$u }
209 do_test analyze3-1.3.6 {
210 set l [expr int(200)]
211 set u [expr int(300)]
212 sf_execsql { SELECT sum(y) FROM t3 WHERE x>$l AND x<$u }
214 do_test analyze3-1.3.7 {
215 sf_execsql { SELECT sum(y) FROM t3 WHERE x>0 AND x<1100 }
217 do_test analyze3-1.3.8 {
218 set l [string range "0" 0 end]
219 set u [string range "1100" 0 end]
220 sf_execsql { SELECT sum(y) FROM t3 WHERE x>$l AND x<$u }
222 do_test analyze3-1.3.9 {
224 set u [expr int(1100)]
225 sf_execsql { SELECT sum(y) FROM t3 WHERE x>$l AND x<$u }
228 #-------------------------------------------------------------------------
229 # Test that the values of bound SQL variables may be used for the LIKE
233 do_test analyze3-2.1 {
235 PRAGMA case_sensitive_like=off;
237 CREATE TABLE t1(a, b TEXT COLLATE nocase);
238 CREATE INDEX i1 ON t1(b);
240 for {set i 0} {$i < 1000} {incr i} {
242 append t [lindex {a b c d e f g h i j} [expr $i/100]]
243 append t [lindex {a b c d e f g h i j} [expr ($i/10)%10]]
244 append t [lindex {a b c d e f g h i j} [expr ($i%10)]]
245 execsql { INSERT INTO t1 VALUES($i, $t) }
249 do_eqp_test analyze3-2.2 {
250 SELECT count(a) FROM t1 WHERE b LIKE 'a%'
251 } {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (b>? AND b<?) (~31250 rows)}}
252 do_eqp_test analyze3-2.3 {
253 SELECT count(a) FROM t1 WHERE b LIKE '%a'
254 } {0 0 0 {SCAN TABLE t1 (~500000 rows)}}
256 do_test analyze3-2.4 {
257 sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE 'a%' }
259 do_test analyze3-2.5 {
260 sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE '%a' }
263 do_test analyze3-2.4 {
265 sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
267 do_test analyze3-2.5 {
269 sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
271 do_test analyze3-2.6 {
273 sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
275 do_test analyze3-2.7 {
277 sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
279 do_test analyze3-2.8 {
281 sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
283 do_test analyze3-2.9 {
285 sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
289 #-------------------------------------------------------------------------
290 # This block of tests checks that statements are correctly marked as
291 # expired when the values bound to any parameters that may affect the
292 # query plan are modified.
301 do_test analyze3-3.1 {
304 CREATE TABLE t1(a, b, c);
305 CREATE INDEX i1 ON t1(b);
307 for {set i 0} {$i < 100} {incr i} {
308 execsql { INSERT INTO t1 VALUES($i, $i, $i) }
314 do_test analyze3-3.2.1 {
315 set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE b>?" -1 dummy]
318 do_test analyze3-3.2.2 {
319 sqlite3_bind_text $S 1 "abc" 3
322 do_test analyze3-3.2.4 {
326 do_test analyze3-3.2.5 {
327 set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE b=?" -1 dummy]
330 do_test analyze3-3.2.6 {
331 sqlite3_bind_text $S 1 "abc" 3
334 do_test analyze3-3.2.7 {
338 do_test analyze3-3.4.1 {
339 set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE a=? AND b>?" -1 dummy]
342 do_test analyze3-3.4.2 {
343 sqlite3_bind_text $S 1 "abc" 3
346 do_test analyze3-3.4.3 {
347 sqlite3_bind_text $S 2 "def" 3
350 do_test analyze3-3.4.4 {
351 sqlite3_bind_text $S 2 "ghi" 3
354 do_test analyze3-3.4.5 {
357 do_test analyze3-3.4.6 {
361 do_test analyze3-3.5.1 {
362 set S [sqlite3_prepare_v2 db {
363 SELECT * FROM t1 WHERE a IN (
364 ?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10,
365 ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20,
366 ?21, ?22, ?23, ?24, ?25, ?26, ?27, ?28, ?29, ?30, ?31
371 do_test analyze3-3.5.2 {
372 sqlite3_bind_text $S 31 "abc" 3
375 do_test analyze3-3.5.3 {
376 sqlite3_bind_text $S 32 "def" 3
379 do_test analyze3-3.5.5 {
383 do_test analyze3-3.6.1 {
384 set S [sqlite3_prepare_v2 db {
385 SELECT * FROM t1 WHERE a IN (
386 ?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10,
387 ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20,
388 ?21, ?22, ?23, ?24, ?25, ?26, ?27, ?28, ?29, ?30, ?31, ?32
393 do_test analyze3-3.6.2 {
394 sqlite3_bind_text $S 32 "abc" 3
397 do_test analyze3-3.6.3 {
398 sqlite3_bind_text $S 33 "def" 3
401 do_test analyze3-3.6.5 {
405 do_test analyze3-3.7.1 {
406 set S [sqlite3_prepare_v2 db {
407 SELECT * FROM t1 WHERE a IN (
408 ?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?33,
409 ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20,
410 ?21, ?22, ?23, ?24, ?25, ?26, ?27, ?28, ?29, ?30, ?31, ?32
415 do_test analyze3-3.7.2 {
416 sqlite3_bind_text $S 32 "abc" 3
419 do_test analyze3-3.7.3 {
420 sqlite3_bind_text $S 33 "def" 3
423 do_test analyze3-3.7.4 {
424 sqlite3_bind_text $S 10 "def" 3
427 do_test analyze3-3.7.6 {
431 do_test analyze3-3.8.1 {
433 CREATE TABLE t4(x, y TEXT COLLATE NOCASE);
434 CREATE INDEX i4 ON t4(y);
437 do_test analyze3-3.8.2 {
438 set S [sqlite3_prepare_v2 db {
439 SELECT * FROM t4 WHERE x != ? AND y LIKE ?
443 do_test analyze3-3.8.3 {
444 sqlite3_bind_text $S 1 "abc" 3
447 do_test analyze3-3.8.4 {
448 sqlite3_bind_text $S 2 "def" 3
451 do_test analyze3-3.8.7 {
452 sqlite3_bind_text $S 2 "ghi%" 4
455 do_test analyze3-3.8.8 {
458 do_test analyze3-3.8.9 {
459 sqlite3_bind_text $S 2 "ghi%def" 7
462 do_test analyze3-3.8.10 {
465 do_test analyze3-3.8.11 {
466 sqlite3_bind_text $S 2 "%ab" 3
469 do_test analyze3-3.8.12 {
472 do_test analyze3-3.8.12 {
473 sqlite3_bind_text $S 2 "%de" 3
476 do_test analyze3-3.8.13 {
479 do_test analyze3-3.8.14 {
483 #-------------------------------------------------------------------------
484 # These tests check that errors encountered while repreparing an SQL
485 # statement within sqlite3Reprepare() are handled correctly.
488 # Check a schema error.
490 do_test analyze3-4.1.1 {
491 set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE a=? AND b>?" -1 dummy]
494 do_test analyze3-4.1.2 {
496 sqlite3_bind_text $S 2 "abc" 3
497 execsql { DROP TABLE t1 }
500 do_test analyze3-4.1.3 {
504 # Check an authorization error.
506 do_test analyze3-4.2.1 {
509 CREATE TABLE t1(a, b, c);
510 CREATE INDEX i1 ON t1(b);
512 for {set i 0} {$i < 100} {incr i} {
513 execsql { INSERT INTO t1 VALUES($i, $i, $i) }
517 set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE a=? AND b>?" -1 dummy]
522 if {[lindex $args 0] == "SQLITE_READ"} {return SQLITE_DENY}
525 do_test analyze3-4.2.2 {
527 sqlite3_bind_text $S 2 "abc" 3
530 do_test analyze3-4.2.4 {
534 # Check the effect of an authorization error that occurs in a re-prepare
535 # performed by sqlite3_step() is the same as one that occurs within
536 # sqlite3Reprepare().
538 do_test analyze3-4.3.1 {
540 set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE a=? AND b>?" -1 dummy]
541 execsql { CREATE TABLE t2(d, e, f) }
545 do_test analyze3-4.3.2 {
550 #-------------------------------------------------------------------------
551 # Test that modifying bound variables using the clear_bindings() or
552 # transfer_bindings() APIs works.
554 # analyze3-5.1.*: sqlite3_clear_bindings()
555 # analyze3-5.2.*: sqlite3_transfer_bindings()
557 do_test analyze3-5.1.1 {
560 CREATE TABLE t1(x TEXT COLLATE NOCASE);
561 CREATE INDEX i1 ON t1(x);
562 INSERT INTO t1 VALUES('aaa');
563 INSERT INTO t1 VALUES('abb');
564 INSERT INTO t1 VALUES('acc');
565 INSERT INTO t1 VALUES('baa');
566 INSERT INTO t1 VALUES('bbb');
567 INSERT INTO t1 VALUES('bcc');
570 set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE x LIKE ?" -1 dummy]
571 sqlite3_bind_text $S 1 "a%" 2
573 while { "SQLITE_ROW" == [sqlite3_step $S] } {
574 lappend R [sqlite3_column_text $S 0]
576 concat [sqlite3_reset $S] $R
577 } {SQLITE_OK aaa abb acc}
578 do_test analyze3-5.1.2 {
579 sqlite3_clear_bindings $S
581 while { "SQLITE_ROW" == [sqlite3_step $S] } {
582 lappend R [sqlite3_column_text $S 0]
584 concat [sqlite3_reset $S] $R
586 do_test analyze3-5.1.3 {
590 do_test analyze3-5.1.1 {
591 set S1 [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE x LIKE ?" -1 dummy]
592 sqlite3_bind_text $S1 1 "b%" 2
594 while { "SQLITE_ROW" == [sqlite3_step $S1] } {
595 lappend R [sqlite3_column_text $S1 0]
597 concat [sqlite3_reset $S1] $R
598 } {SQLITE_OK baa bbb bcc}
600 do_test analyze3-5.1.2 {
601 set S2 [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE x = ?" -1 dummy]
602 sqlite3_bind_text $S2 1 "a%" 2
603 sqlite3_transfer_bindings $S2 $S1
605 while { "SQLITE_ROW" == [sqlite3_step $S1] } {
606 lappend R [sqlite3_column_text $S1 0]
608 concat [sqlite3_reset $S1] $R
609 } {SQLITE_OK aaa abb acc}
610 do_test analyze3-5.1.3 {