blob: d22387dcc3a17fdda730d2ac83aff281e1455937 [file] [log] [blame]
dan937d0de2009-10-15 18:35:38 +00001# 2009 August 06
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#
12# This file implements regression tests for SQLite library. This file
dan1d2ce4f2009-10-19 18:11:09 +000013# implements tests for range and LIKE constraints that use bound variables
14# instead of literal constant arguments.
dan937d0de2009-10-15 18:35:38 +000015#
16
17set testdir [file dirname $argv0]
18source $testdir/tester.tcl
19
dan8ad169a2013-08-12 20:14:04 +000020ifcapable !stat4&&!stat3 {
dan937d0de2009-10-15 18:35:38 +000021 finish_test
22 return
23}
24
25#----------------------------------------------------------------------
26# Test Organization:
27#
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.
31#
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.
35#
dan1d2ce4f2009-10-19 18:11:09 +000036# 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.
dan937d0de2009-10-15 18:35:38 +000039#
40# analyze3-4.*: Test that SQL or authorization callback errors occuring
dan1d2ce4f2009-10-19 18:11:09 +000041# within sqlite3Reprepare() are handled correctly.
dan937d0de2009-10-15 18:35:38 +000042#
danc94b8592009-10-20 07:01:24 +000043# 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.
dan2acbc0d2013-08-01 17:43:35 +000046#
47# analyze3-6.*: Test that the problem fixed by commit [127a5b776d] is fixed.
danc94b8592009-10-20 07:01:24 +000048#
dan937d0de2009-10-15 18:35:38 +000049
50proc getvar {varname} { uplevel #0 set $varname }
51db function var getvar
52
53proc eqp {sql {db db}} {
54 uplevel execsql [list "EXPLAIN QUERY PLAN $sql"] $db
55}
56
57proc sf_execsql {sql {db db}} {
58 set ::sqlite_search_count 0
59 set r [uplevel [list execsql $sql $db]]
60
61 concat $::sqlite_search_count [$db status step] $r
62}
63
64#-------------------------------------------------------------------------
65#
66# analyze3-1.1.1:
67# Create a table with two columns. Populate the first column (affinity
68# INTEGER) with integer values from 100 to 1100. Create an index on this
69# column. ANALYZE the table.
70#
71# analyze3-1.1.2 - 3.1.3
72# Show that there are two possible plans for querying the table with
73# a range constraint on the indexed column - "full table scan" or "use
74# the index". When the range is specified using literal values, SQLite
drh74e7c8f2011-10-21 19:06:32 +000075# is able to pick the best plan based on the samples in sqlite_stat3.
dan937d0de2009-10-15 18:35:38 +000076#
77# analyze3-1.1.4 - 3.1.9
78# Show that using SQL variables produces the same results as using
dan1d2ce4f2009-10-19 18:11:09 +000079# literal values to constrain the range scan.
dan937d0de2009-10-15 18:35:38 +000080#
81# These tests also check that the compiler code considers column
82# affinities when estimating the number of rows scanned by the "use
83# index strategy".
84#
85do_test analyze3-1.1.1 {
86 execsql {
87 BEGIN;
88 CREATE TABLE t1(x INTEGER, y);
89 CREATE INDEX i1 ON t1(x);
90 }
91 for {set i 0} {$i < 1000} {incr i} {
92 execsql { INSERT INTO t1 VALUES($i+100, $i) }
93 }
94 execsql {
95 COMMIT;
96 ANALYZE;
97 }
dan8ad169a2013-08-12 20:14:04 +000098
99 ifcapable stat4 {
100 execsql { SELECT count(*)>0 FROM sqlite_stat4; }
101 } else {
102 execsql { SELECT count(*)>0 FROM sqlite_stat3; }
dandd6e1f12013-08-10 19:08:30 +0000103 }
104} {1}
dan937d0de2009-10-15 18:35:38 +0000105
danb51926e2014-04-28 10:00:59 +0000106do_execsql_test analyze3-1.1.x {
107 SELECT count(*) FROM t1 WHERE x>200 AND x<300;
108 SELECT count(*) FROM t1 WHERE x>0 AND x<1100;
109} {99 1000}
110
111# The first of the following two SELECT statements visits 99 rows. So
112# it is better to use the index. But the second visits every row in
113# the table (1000 in total) so it is better to do a full-table scan.
114#
dan39854792010-11-15 16:12:58 +0000115do_eqp_test analyze3-1.1.2 {
116 SELECT sum(y) FROM t1 WHERE x>200 AND x<300
drh5822d6f2013-06-10 23:30:09 +0000117} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?)}}
dan39854792010-11-15 16:12:58 +0000118do_eqp_test analyze3-1.1.3 {
119 SELECT sum(y) FROM t1 WHERE x>0 AND x<1100
danb51926e2014-04-28 10:00:59 +0000120} {0 0 0 {SCAN TABLE t1}}
dan937d0de2009-10-15 18:35:38 +0000121
122do_test analyze3-1.1.4 {
123 sf_execsql { SELECT sum(y) FROM t1 WHERE x>200 AND x<300 }
124} {199 0 14850}
125do_test analyze3-1.1.5 {
126 set l [string range "200" 0 end]
127 set u [string range "300" 0 end]
128 sf_execsql { SELECT sum(y) FROM t1 WHERE x>$l AND x<$u }
129} {199 0 14850}
130do_test analyze3-1.1.6 {
131 set l [expr int(200)]
132 set u [expr int(300)]
133 sf_execsql { SELECT sum(y) FROM t1 WHERE x>$l AND x<$u }
134} {199 0 14850}
135do_test analyze3-1.1.7 {
136 sf_execsql { SELECT sum(y) FROM t1 WHERE x>0 AND x<1100 }
danb51926e2014-04-28 10:00:59 +0000137} {999 999 499500}
dan937d0de2009-10-15 18:35:38 +0000138do_test analyze3-1.1.8 {
139 set l [string range "0" 0 end]
140 set u [string range "1100" 0 end]
141 sf_execsql { SELECT sum(y) FROM t1 WHERE x>$l AND x<$u }
danb51926e2014-04-28 10:00:59 +0000142} {999 999 499500}
dan937d0de2009-10-15 18:35:38 +0000143do_test analyze3-1.1.9 {
144 set l [expr int(0)]
145 set u [expr int(1100)]
146 sf_execsql { SELECT sum(y) FROM t1 WHERE x>$l AND x<$u }
danb51926e2014-04-28 10:00:59 +0000147} {999 999 499500}
dan937d0de2009-10-15 18:35:38 +0000148
149
150# The following tests are similar to the block above. The difference is
151# that the indexed column has TEXT affinity in this case. In the tests
152# above the affinity is INTEGER.
153#
154do_test analyze3-1.2.1 {
155 execsql {
156 BEGIN;
157 CREATE TABLE t2(x TEXT, y);
158 INSERT INTO t2 SELECT * FROM t1;
159 CREATE INDEX i2 ON t2(x);
160 COMMIT;
161 ANALYZE;
162 }
163} {}
danb51926e2014-04-28 10:00:59 +0000164do_execsql_test analyze3-2.1.x {
165 SELECT count(*) FROM t2 WHERE x>1 AND x<2;
166 SELECT count(*) FROM t2 WHERE x>0 AND x<99;
167} {200 990}
dan39854792010-11-15 16:12:58 +0000168do_eqp_test analyze3-1.2.2 {
169 SELECT sum(y) FROM t2 WHERE x>1 AND x<2
drh5822d6f2013-06-10 23:30:09 +0000170} {0 0 0 {SEARCH TABLE t2 USING INDEX i2 (x>? AND x<?)}}
dan39854792010-11-15 16:12:58 +0000171do_eqp_test analyze3-1.2.3 {
172 SELECT sum(y) FROM t2 WHERE x>0 AND x<99
danb51926e2014-04-28 10:00:59 +0000173} {0 0 0 {SCAN TABLE t2}}
174
dan937d0de2009-10-15 18:35:38 +0000175do_test analyze3-1.2.4 {
176 sf_execsql { SELECT sum(y) FROM t2 WHERE x>12 AND x<20 }
177} {161 0 4760}
178do_test analyze3-1.2.5 {
179 set l [string range "12" 0 end]
180 set u [string range "20" 0 end]
181 sf_execsql {SELECT typeof($l), typeof($u), sum(y) FROM t2 WHERE x>$l AND x<$u}
182} {161 0 text text 4760}
183do_test analyze3-1.2.6 {
184 set l [expr int(12)]
185 set u [expr int(20)]
186 sf_execsql {SELECT typeof($l), typeof($u), sum(y) FROM t2 WHERE x>$l AND x<$u}
187} {161 0 integer integer 4760}
188do_test analyze3-1.2.7 {
189 sf_execsql { SELECT sum(y) FROM t2 WHERE x>0 AND x<99 }
danb51926e2014-04-28 10:00:59 +0000190} {999 999 490555}
dan937d0de2009-10-15 18:35:38 +0000191do_test analyze3-1.2.8 {
192 set l [string range "0" 0 end]
193 set u [string range "99" 0 end]
194 sf_execsql {SELECT typeof($l), typeof($u), sum(y) FROM t2 WHERE x>$l AND x<$u}
danb51926e2014-04-28 10:00:59 +0000195} {999 999 text text 490555}
dan937d0de2009-10-15 18:35:38 +0000196do_test analyze3-1.2.9 {
197 set l [expr int(0)]
198 set u [expr int(99)]
199 sf_execsql {SELECT typeof($l), typeof($u), sum(y) FROM t2 WHERE x>$l AND x<$u}
danb51926e2014-04-28 10:00:59 +0000200} {999 999 integer integer 490555}
dan937d0de2009-10-15 18:35:38 +0000201
202# Same tests a third time. This time, column x has INTEGER affinity and
203# is not the leftmost column of the table. This triggered a bug causing
204# SQLite to use sub-optimal query plans in 3.6.18 and earlier.
205#
206do_test analyze3-1.3.1 {
207 execsql {
208 BEGIN;
209 CREATE TABLE t3(y TEXT, x INTEGER);
210 INSERT INTO t3 SELECT y, x FROM t1;
211 CREATE INDEX i3 ON t3(x);
212 COMMIT;
213 ANALYZE;
214 }
215} {}
danb51926e2014-04-28 10:00:59 +0000216do_execsql_test analyze3-1.3.x {
217 SELECT count(*) FROM t3 WHERE x>200 AND x<300;
218 SELECT count(*) FROM t3 WHERE x>0 AND x<1100
219} {99 1000}
dan39854792010-11-15 16:12:58 +0000220do_eqp_test analyze3-1.3.2 {
221 SELECT sum(y) FROM t3 WHERE x>200 AND x<300
drh5822d6f2013-06-10 23:30:09 +0000222} {0 0 0 {SEARCH TABLE t3 USING INDEX i3 (x>? AND x<?)}}
dan39854792010-11-15 16:12:58 +0000223do_eqp_test analyze3-1.3.3 {
224 SELECT sum(y) FROM t3 WHERE x>0 AND x<1100
danb51926e2014-04-28 10:00:59 +0000225} {0 0 0 {SCAN TABLE t3}}
dan937d0de2009-10-15 18:35:38 +0000226
227do_test analyze3-1.3.4 {
228 sf_execsql { SELECT sum(y) FROM t3 WHERE x>200 AND x<300 }
229} {199 0 14850}
230do_test analyze3-1.3.5 {
231 set l [string range "200" 0 end]
232 set u [string range "300" 0 end]
233 sf_execsql { SELECT sum(y) FROM t3 WHERE x>$l AND x<$u }
234} {199 0 14850}
235do_test analyze3-1.3.6 {
236 set l [expr int(200)]
237 set u [expr int(300)]
238 sf_execsql { SELECT sum(y) FROM t3 WHERE x>$l AND x<$u }
239} {199 0 14850}
240do_test analyze3-1.3.7 {
241 sf_execsql { SELECT sum(y) FROM t3 WHERE x>0 AND x<1100 }
danb51926e2014-04-28 10:00:59 +0000242} {999 999 499500}
dan937d0de2009-10-15 18:35:38 +0000243do_test analyze3-1.3.8 {
244 set l [string range "0" 0 end]
245 set u [string range "1100" 0 end]
246 sf_execsql { SELECT sum(y) FROM t3 WHERE x>$l AND x<$u }
danb51926e2014-04-28 10:00:59 +0000247} {999 999 499500}
dan937d0de2009-10-15 18:35:38 +0000248do_test analyze3-1.3.9 {
249 set l [expr int(0)]
250 set u [expr int(1100)]
251 sf_execsql { SELECT sum(y) FROM t3 WHERE x>$l AND x<$u }
danb51926e2014-04-28 10:00:59 +0000252} {999 999 499500}
dan937d0de2009-10-15 18:35:38 +0000253
254#-------------------------------------------------------------------------
255# Test that the values of bound SQL variables may be used for the LIKE
256# optimization.
257#
258drop_all_tables
259do_test analyze3-2.1 {
260 execsql {
261 PRAGMA case_sensitive_like=off;
262 BEGIN;
263 CREATE TABLE t1(a, b TEXT COLLATE nocase);
264 CREATE INDEX i1 ON t1(b);
265 }
266 for {set i 0} {$i < 1000} {incr i} {
267 set t ""
268 append t [lindex {a b c d e f g h i j} [expr $i/100]]
269 append t [lindex {a b c d e f g h i j} [expr ($i/10)%10]]
270 append t [lindex {a b c d e f g h i j} [expr ($i%10)]]
271 execsql { INSERT INTO t1 VALUES($i, $t) }
272 }
273 execsql COMMIT
274} {}
dan39854792010-11-15 16:12:58 +0000275do_eqp_test analyze3-2.2 {
276 SELECT count(a) FROM t1 WHERE b LIKE 'a%'
drh5822d6f2013-06-10 23:30:09 +0000277} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (b>? AND b<?)}}
dan39854792010-11-15 16:12:58 +0000278do_eqp_test analyze3-2.3 {
279 SELECT count(a) FROM t1 WHERE b LIKE '%a'
drh5822d6f2013-06-10 23:30:09 +0000280} {0 0 0 {SCAN TABLE t1}}
dan937d0de2009-10-15 18:35:38 +0000281
282do_test analyze3-2.4 {
283 sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE 'a%' }
drha9c18a92015-03-06 20:49:52 +0000284} {102 0 100}
dan937d0de2009-10-15 18:35:38 +0000285do_test analyze3-2.5 {
286 sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE '%a' }
287} {999 999 100}
288
drha9c18a92015-03-06 20:49:52 +0000289do_test analyze3-2.6 {
dan937d0de2009-10-15 18:35:38 +0000290 set like "a%"
291 sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
drha9c18a92015-03-06 20:49:52 +0000292} {102 0 100}
293do_test analyze3-2.7 {
dan937d0de2009-10-15 18:35:38 +0000294 set like "%a"
295 sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
296} {999 999 100}
drha9c18a92015-03-06 20:49:52 +0000297do_test analyze3-2.8 {
drh93ee23c2010-07-22 12:33:57 +0000298 set like "a"
299 sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
drha9c18a92015-03-06 20:49:52 +0000300} {102 0 0}
301do_test analyze3-2.9 {
drh93ee23c2010-07-22 12:33:57 +0000302 set like "ab"
303 sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
drha9c18a92015-03-06 20:49:52 +0000304} {12 0 0}
305do_test analyze3-2.10 {
drh93ee23c2010-07-22 12:33:57 +0000306 set like "abc"
307 sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
drha9c18a92015-03-06 20:49:52 +0000308} {3 0 1}
309do_test analyze3-2.11 {
drh93ee23c2010-07-22 12:33:57 +0000310 set like "a_c"
311 sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
drha9c18a92015-03-06 20:49:52 +0000312} {102 0 10}
dan937d0de2009-10-15 18:35:38 +0000313
314
315#-------------------------------------------------------------------------
dan1d2ce4f2009-10-19 18:11:09 +0000316# This block of tests checks that statements are correctly marked as
317# expired when the values bound to any parameters that may affect the
318# query plan are modified.
dan937d0de2009-10-15 18:35:38 +0000319#
320drop_all_tables
321db auth auth
322proc auth {args} {
323 set ::auth 1
324 return SQLITE_OK
325}
326
dan937d0de2009-10-15 18:35:38 +0000327do_test analyze3-3.1 {
328 execsql {
329 BEGIN;
330 CREATE TABLE t1(a, b, c);
331 CREATE INDEX i1 ON t1(b);
332 }
333 for {set i 0} {$i < 100} {incr i} {
334 execsql { INSERT INTO t1 VALUES($i, $i, $i) }
335 }
336 execsql COMMIT
337 execsql ANALYZE
338} {}
dan937d0de2009-10-15 18:35:38 +0000339do_test analyze3-3.2.1 {
340 set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE b>?" -1 dummy]
dan1d2ce4f2009-10-19 18:11:09 +0000341 sqlite3_expired $S
dan937d0de2009-10-15 18:35:38 +0000342} {0}
343do_test analyze3-3.2.2 {
dand893ed82009-10-16 15:59:35 +0000344 sqlite3_bind_text $S 1 "abc" 3
dan1d2ce4f2009-10-19 18:11:09 +0000345 sqlite3_expired $S
dan937d0de2009-10-15 18:35:38 +0000346} {1}
dan937d0de2009-10-15 18:35:38 +0000347do_test analyze3-3.2.4 {
348 sqlite3_finalize $S
349} {SQLITE_OK}
350
dan1d2ce4f2009-10-19 18:11:09 +0000351do_test analyze3-3.2.5 {
dan937d0de2009-10-15 18:35:38 +0000352 set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE b=?" -1 dummy]
dan1d2ce4f2009-10-19 18:11:09 +0000353 sqlite3_expired $S
dan937d0de2009-10-15 18:35:38 +0000354} {0}
dan1d2ce4f2009-10-19 18:11:09 +0000355do_test analyze3-3.2.6 {
dand893ed82009-10-16 15:59:35 +0000356 sqlite3_bind_text $S 1 "abc" 3
dan1d2ce4f2009-10-19 18:11:09 +0000357 sqlite3_expired $S
drh5822d6f2013-06-10 23:30:09 +0000358} {1}
dan1d2ce4f2009-10-19 18:11:09 +0000359do_test analyze3-3.2.7 {
dan937d0de2009-10-15 18:35:38 +0000360 sqlite3_finalize $S
361} {SQLITE_OK}
362
363do_test analyze3-3.4.1 {
364 set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE a=? AND b>?" -1 dummy]
dan1d2ce4f2009-10-19 18:11:09 +0000365 sqlite3_expired $S
dan937d0de2009-10-15 18:35:38 +0000366} {0}
367do_test analyze3-3.4.2 {
dand893ed82009-10-16 15:59:35 +0000368 sqlite3_bind_text $S 1 "abc" 3
dan1d2ce4f2009-10-19 18:11:09 +0000369 sqlite3_expired $S
dan937d0de2009-10-15 18:35:38 +0000370} {0}
371do_test analyze3-3.4.3 {
dand893ed82009-10-16 15:59:35 +0000372 sqlite3_bind_text $S 2 "def" 3
dan1d2ce4f2009-10-19 18:11:09 +0000373 sqlite3_expired $S
dan937d0de2009-10-15 18:35:38 +0000374} {1}
375do_test analyze3-3.4.4 {
dand893ed82009-10-16 15:59:35 +0000376 sqlite3_bind_text $S 2 "ghi" 3
dan1d2ce4f2009-10-19 18:11:09 +0000377 sqlite3_expired $S
dan937d0de2009-10-15 18:35:38 +0000378} {1}
379do_test analyze3-3.4.5 {
dan1d2ce4f2009-10-19 18:11:09 +0000380 sqlite3_expired $S
381} {1}
dan937d0de2009-10-15 18:35:38 +0000382do_test analyze3-3.4.6 {
383 sqlite3_finalize $S
384} {SQLITE_OK}
385
386do_test analyze3-3.5.1 {
387 set S [sqlite3_prepare_v2 db {
388 SELECT * FROM t1 WHERE a IN (
389 ?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10,
390 ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20,
391 ?21, ?22, ?23, ?24, ?25, ?26, ?27, ?28, ?29, ?30, ?31
392 ) AND b>?32;
393 } -1 dummy]
dan1d2ce4f2009-10-19 18:11:09 +0000394 sqlite3_expired $S
dan937d0de2009-10-15 18:35:38 +0000395} {0}
396do_test analyze3-3.5.2 {
dand893ed82009-10-16 15:59:35 +0000397 sqlite3_bind_text $S 31 "abc" 3
dan1d2ce4f2009-10-19 18:11:09 +0000398 sqlite3_expired $S
dan937d0de2009-10-15 18:35:38 +0000399} {0}
400do_test analyze3-3.5.3 {
dand893ed82009-10-16 15:59:35 +0000401 sqlite3_bind_text $S 32 "def" 3
dan1d2ce4f2009-10-19 18:11:09 +0000402 sqlite3_expired $S
dan937d0de2009-10-15 18:35:38 +0000403} {1}
dan937d0de2009-10-15 18:35:38 +0000404do_test analyze3-3.5.5 {
405 sqlite3_finalize $S
406} {SQLITE_OK}
407
408do_test analyze3-3.6.1 {
409 set S [sqlite3_prepare_v2 db {
410 SELECT * FROM t1 WHERE a IN (
411 ?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10,
412 ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20,
413 ?21, ?22, ?23, ?24, ?25, ?26, ?27, ?28, ?29, ?30, ?31, ?32
414 ) AND b>?33;
415 } -1 dummy]
dan1d2ce4f2009-10-19 18:11:09 +0000416 sqlite3_expired $S
dan937d0de2009-10-15 18:35:38 +0000417} {0}
418do_test analyze3-3.6.2 {
dand893ed82009-10-16 15:59:35 +0000419 sqlite3_bind_text $S 32 "abc" 3
dan1d2ce4f2009-10-19 18:11:09 +0000420 sqlite3_expired $S
dan937d0de2009-10-15 18:35:38 +0000421} {1}
422do_test analyze3-3.6.3 {
dand893ed82009-10-16 15:59:35 +0000423 sqlite3_bind_text $S 33 "def" 3
dan1d2ce4f2009-10-19 18:11:09 +0000424 sqlite3_expired $S
dan937d0de2009-10-15 18:35:38 +0000425} {1}
dan937d0de2009-10-15 18:35:38 +0000426do_test analyze3-3.6.5 {
427 sqlite3_finalize $S
428} {SQLITE_OK}
429
430do_test analyze3-3.7.1 {
dan937d0de2009-10-15 18:35:38 +0000431 set S [sqlite3_prepare_v2 db {
432 SELECT * FROM t1 WHERE a IN (
433 ?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?33,
434 ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20,
435 ?21, ?22, ?23, ?24, ?25, ?26, ?27, ?28, ?29, ?30, ?31, ?32
436 ) AND b>?10;
437 } -1 dummy]
dan1d2ce4f2009-10-19 18:11:09 +0000438 sqlite3_expired $S
dan937d0de2009-10-15 18:35:38 +0000439} {0}
440do_test analyze3-3.7.2 {
dand893ed82009-10-16 15:59:35 +0000441 sqlite3_bind_text $S 32 "abc" 3
dan1d2ce4f2009-10-19 18:11:09 +0000442 sqlite3_expired $S
dan937d0de2009-10-15 18:35:38 +0000443} {0}
444do_test analyze3-3.7.3 {
dand893ed82009-10-16 15:59:35 +0000445 sqlite3_bind_text $S 33 "def" 3
dan1d2ce4f2009-10-19 18:11:09 +0000446 sqlite3_expired $S
dan937d0de2009-10-15 18:35:38 +0000447} {0}
448do_test analyze3-3.7.4 {
dand893ed82009-10-16 15:59:35 +0000449 sqlite3_bind_text $S 10 "def" 3
dan1d2ce4f2009-10-19 18:11:09 +0000450 sqlite3_expired $S
dan937d0de2009-10-15 18:35:38 +0000451} {1}
dan937d0de2009-10-15 18:35:38 +0000452do_test analyze3-3.7.6 {
453 sqlite3_finalize $S
454} {SQLITE_OK}
455
456do_test analyze3-3.8.1 {
457 execsql {
458 CREATE TABLE t4(x, y TEXT COLLATE NOCASE);
459 CREATE INDEX i4 ON t4(y);
460 }
461} {}
462do_test analyze3-3.8.2 {
463 set S [sqlite3_prepare_v2 db {
464 SELECT * FROM t4 WHERE x != ? AND y LIKE ?
465 } -1 dummy]
dan1d2ce4f2009-10-19 18:11:09 +0000466 sqlite3_expired $S
dan937d0de2009-10-15 18:35:38 +0000467} {0}
468do_test analyze3-3.8.3 {
dand893ed82009-10-16 15:59:35 +0000469 sqlite3_bind_text $S 1 "abc" 3
dan1d2ce4f2009-10-19 18:11:09 +0000470 sqlite3_expired $S
dan937d0de2009-10-15 18:35:38 +0000471} {0}
472do_test analyze3-3.8.4 {
dand893ed82009-10-16 15:59:35 +0000473 sqlite3_bind_text $S 2 "def" 3
dan937d0de2009-10-15 18:35:38 +0000474 sqlite3_expired $S
dan1d2ce4f2009-10-19 18:11:09 +0000475} {1}
dan937d0de2009-10-15 18:35:38 +0000476do_test analyze3-3.8.7 {
dand893ed82009-10-16 15:59:35 +0000477 sqlite3_bind_text $S 2 "ghi%" 4
dan937d0de2009-10-15 18:35:38 +0000478 sqlite3_expired $S
dan1d2ce4f2009-10-19 18:11:09 +0000479} {1}
dan937d0de2009-10-15 18:35:38 +0000480do_test analyze3-3.8.8 {
dan1d2ce4f2009-10-19 18:11:09 +0000481 sqlite3_expired $S
dan937d0de2009-10-15 18:35:38 +0000482} {1}
483do_test analyze3-3.8.9 {
dand893ed82009-10-16 15:59:35 +0000484 sqlite3_bind_text $S 2 "ghi%def" 7
dan937d0de2009-10-15 18:35:38 +0000485 sqlite3_expired $S
486} {1}
487do_test analyze3-3.8.10 {
dan1d2ce4f2009-10-19 18:11:09 +0000488 sqlite3_expired $S
dan937d0de2009-10-15 18:35:38 +0000489} {1}
490do_test analyze3-3.8.11 {
dand893ed82009-10-16 15:59:35 +0000491 sqlite3_bind_text $S 2 "%ab" 3
dan937d0de2009-10-15 18:35:38 +0000492 sqlite3_expired $S
493} {1}
494do_test analyze3-3.8.12 {
dan1d2ce4f2009-10-19 18:11:09 +0000495 sqlite3_expired $S
dan937d0de2009-10-15 18:35:38 +0000496} {1}
497do_test analyze3-3.8.12 {
dand893ed82009-10-16 15:59:35 +0000498 sqlite3_bind_text $S 2 "%de" 3
dan937d0de2009-10-15 18:35:38 +0000499 sqlite3_expired $S
dan1d2ce4f2009-10-19 18:11:09 +0000500} {1}
dan937d0de2009-10-15 18:35:38 +0000501do_test analyze3-3.8.13 {
dan1d2ce4f2009-10-19 18:11:09 +0000502 sqlite3_expired $S
dan937d0de2009-10-15 18:35:38 +0000503} {1}
504do_test analyze3-3.8.14 {
505 sqlite3_finalize $S
506} {SQLITE_OK}
507
508#-------------------------------------------------------------------------
509# These tests check that errors encountered while repreparing an SQL
dan1d2ce4f2009-10-19 18:11:09 +0000510# statement within sqlite3Reprepare() are handled correctly.
dan937d0de2009-10-15 18:35:38 +0000511#
512
dan1d2ce4f2009-10-19 18:11:09 +0000513# Check a schema error.
dan937d0de2009-10-15 18:35:38 +0000514#
515do_test analyze3-4.1.1 {
516 set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE a=? AND b>?" -1 dummy]
dan1d2ce4f2009-10-19 18:11:09 +0000517 sqlite3_step $S
518} {SQLITE_DONE}
dan937d0de2009-10-15 18:35:38 +0000519do_test analyze3-4.1.2 {
dan1d2ce4f2009-10-19 18:11:09 +0000520 sqlite3_reset $S
dand893ed82009-10-16 15:59:35 +0000521 sqlite3_bind_text $S 2 "abc" 3
dan937d0de2009-10-15 18:35:38 +0000522 execsql { DROP TABLE t1 }
dan937d0de2009-10-15 18:35:38 +0000523 sqlite3_step $S
drhcda455b2010-02-24 19:23:56 +0000524} {SQLITE_ERROR}
dan1d2ce4f2009-10-19 18:11:09 +0000525do_test analyze3-4.1.3 {
dan937d0de2009-10-15 18:35:38 +0000526 sqlite3_finalize $S
drhcda455b2010-02-24 19:23:56 +0000527} {SQLITE_ERROR}
dan937d0de2009-10-15 18:35:38 +0000528
529# Check an authorization error.
530#
531do_test analyze3-4.2.1 {
532 execsql {
533 BEGIN;
534 CREATE TABLE t1(a, b, c);
535 CREATE INDEX i1 ON t1(b);
536 }
537 for {set i 0} {$i < 100} {incr i} {
538 execsql { INSERT INTO t1 VALUES($i, $i, $i) }
539 }
540 execsql COMMIT
541 execsql ANALYZE
542 set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE a=? AND b>?" -1 dummy]
dan1d2ce4f2009-10-19 18:11:09 +0000543 sqlite3_step $S
544} {SQLITE_DONE}
dan937d0de2009-10-15 18:35:38 +0000545db auth auth
546proc auth {args} {
547 if {[lindex $args 0] == "SQLITE_READ"} {return SQLITE_DENY}
548 return SQLITE_OK
549}
550do_test analyze3-4.2.2 {
dan1d2ce4f2009-10-19 18:11:09 +0000551 sqlite3_reset $S
dand893ed82009-10-16 15:59:35 +0000552 sqlite3_bind_text $S 2 "abc" 3
dan937d0de2009-10-15 18:35:38 +0000553 sqlite3_step $S
drhcda455b2010-02-24 19:23:56 +0000554} {SQLITE_AUTH}
dan937d0de2009-10-15 18:35:38 +0000555do_test analyze3-4.2.4 {
556 sqlite3_finalize $S
drhcda455b2010-02-24 19:23:56 +0000557} {SQLITE_AUTH}
dan937d0de2009-10-15 18:35:38 +0000558
559# Check the effect of an authorization error that occurs in a re-prepare
560# performed by sqlite3_step() is the same as one that occurs within
dan1d2ce4f2009-10-19 18:11:09 +0000561# sqlite3Reprepare().
dan937d0de2009-10-15 18:35:38 +0000562#
563do_test analyze3-4.3.1 {
564 db auth {}
565 set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE a=? AND b>?" -1 dummy]
566 execsql { CREATE TABLE t2(d, e, f) }
567 db auth auth
568 sqlite3_step $S
drhcda455b2010-02-24 19:23:56 +0000569} {SQLITE_AUTH}
dan937d0de2009-10-15 18:35:38 +0000570do_test analyze3-4.3.2 {
571 sqlite3_finalize $S
drhcda455b2010-02-24 19:23:56 +0000572} {SQLITE_AUTH}
danc94b8592009-10-20 07:01:24 +0000573db auth {}
574
575#-------------------------------------------------------------------------
576# Test that modifying bound variables using the clear_bindings() or
577# transfer_bindings() APIs works.
578#
579# analyze3-5.1.*: sqlite3_clear_bindings()
580# analyze3-5.2.*: sqlite3_transfer_bindings()
581#
582do_test analyze3-5.1.1 {
583 drop_all_tables
584 execsql {
585 CREATE TABLE t1(x TEXT COLLATE NOCASE);
586 CREATE INDEX i1 ON t1(x);
587 INSERT INTO t1 VALUES('aaa');
588 INSERT INTO t1 VALUES('abb');
589 INSERT INTO t1 VALUES('acc');
590 INSERT INTO t1 VALUES('baa');
591 INSERT INTO t1 VALUES('bbb');
592 INSERT INTO t1 VALUES('bcc');
593 }
594
595 set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE x LIKE ?" -1 dummy]
596 sqlite3_bind_text $S 1 "a%" 2
597 set R [list]
598 while { "SQLITE_ROW" == [sqlite3_step $S] } {
599 lappend R [sqlite3_column_text $S 0]
600 }
601 concat [sqlite3_reset $S] $R
602} {SQLITE_OK aaa abb acc}
603do_test analyze3-5.1.2 {
604 sqlite3_clear_bindings $S
605 set R [list]
606 while { "SQLITE_ROW" == [sqlite3_step $S] } {
607 lappend R [sqlite3_column_text $S 0]
608 }
609 concat [sqlite3_reset $S] $R
610} {SQLITE_OK}
611do_test analyze3-5.1.3 {
612 sqlite3_finalize $S
613} {SQLITE_OK}
614
615do_test analyze3-5.1.1 {
616 set S1 [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE x LIKE ?" -1 dummy]
617 sqlite3_bind_text $S1 1 "b%" 2
618 set R [list]
619 while { "SQLITE_ROW" == [sqlite3_step $S1] } {
620 lappend R [sqlite3_column_text $S1 0]
621 }
622 concat [sqlite3_reset $S1] $R
623} {SQLITE_OK baa bbb bcc}
624
625do_test analyze3-5.1.2 {
626 set S2 [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE x = ?" -1 dummy]
627 sqlite3_bind_text $S2 1 "a%" 2
628 sqlite3_transfer_bindings $S2 $S1
629 set R [list]
630 while { "SQLITE_ROW" == [sqlite3_step $S1] } {
631 lappend R [sqlite3_column_text $S1 0]
632 }
633 concat [sqlite3_reset $S1] $R
634} {SQLITE_OK aaa abb acc}
635do_test analyze3-5.1.3 {
636 sqlite3_finalize $S2
637 sqlite3_finalize $S1
638} {SQLITE_OK}
dan937d0de2009-10-15 18:35:38 +0000639
dan2acbc0d2013-08-01 17:43:35 +0000640#-------------------------------------------------------------------------
641
642do_test analyze3-6.1 {
643 execsql { DROP TABLE IF EXISTS t1 }
644 execsql BEGIN
645 execsql { CREATE TABLE t1(a, b, c) }
646 for {set i 0} {$i < 1000} {incr i} {
647 execsql "INSERT INTO t1 VALUES([expr $i/100], 'x', [expr $i/10])"
648 }
649 execsql {
650 CREATE INDEX i1 ON t1(a, b);
651 CREATE INDEX i2 ON t1(c);
652 }
653 execsql COMMIT
654 execsql ANALYZE
655} {}
656
657do_eqp_test analyze3-6-3 {
658 SELECT * FROM t1 WHERE a = 5 AND c = 13;
659} {0 0 0 {SEARCH TABLE t1 USING INDEX i2 (c=?)}}
660
661do_eqp_test analyze3-6-2 {
662 SELECT * FROM t1 WHERE a = 5 AND b > 'w' AND c = 13;
663} {0 0 0 {SEARCH TABLE t1 USING INDEX i2 (c=?)}}
664
dan937d0de2009-10-15 18:35:38 +0000665finish_test