xref: /sqlite-3.40.0/test/analyze3.test (revision 8210233c)
1937d0deaSdan# 2009 August 06
2937d0deaSdan#
3937d0deaSdan# The author disclaims copyright to this source code.  In place of
4937d0deaSdan# a legal notice, here is a blessing:
5937d0deaSdan#
6937d0deaSdan#    May you do good and not evil.
7937d0deaSdan#    May you find forgiveness for yourself and forgive others.
8937d0deaSdan#    May you share freely, never taking more than you give.
9937d0deaSdan#
10937d0deaSdan#***********************************************************************
11937d0deaSdan#
12937d0deaSdan# This file implements regression tests for SQLite library. This file
131d2ce4f8Sdan# implements tests for range and LIKE constraints that use bound variables
141d2ce4f8Sdan# instead of literal constant arguments.
15937d0deaSdan#
16937d0deaSdan
17937d0deaSdanset testdir [file dirname $argv0]
18937d0deaSdansource $testdir/tester.tcl
194eed0534Sdanset testprefix analyze3
20937d0deaSdan
21175b8f06Sdrhifcapable !stat4 {
22937d0deaSdan  finish_test
23937d0deaSdan  return
24937d0deaSdan}
25937d0deaSdan
26ca3ee7e1Sdan# This test cannot be run with the sqlite3_prepare() permutation, as it
27ca3ee7e1Sdan# tests that stat4 data can be used to influence the plans of queries
28ca3ee7e1Sdan# based on bound variable values. And this is not possible when using
29ca3ee7e1Sdan# sqlite3_prepare() - as queries cannot be internally re-prepared after
30ca3ee7e1Sdan# binding values are available.
31ca3ee7e1Sdanif {[permutation]=="prepare"} {
32ca3ee7e1Sdan  finish_test
33ca3ee7e1Sdan  return
34ca3ee7e1Sdan}
35ca3ee7e1Sdan
36937d0deaSdan#----------------------------------------------------------------------
37937d0deaSdan# Test Organization:
38937d0deaSdan#
39937d0deaSdan# analyze3-1.*: Test that the values of bound parameters are considered
40937d0deaSdan#               in the same way as constants when planning queries that
41937d0deaSdan#               use range constraints.
42937d0deaSdan#
43937d0deaSdan# analyze3-2.*: Test that the values of bound parameters are considered
44937d0deaSdan#               in the same way as constants when planning queries that
45937d0deaSdan#               use LIKE expressions in the WHERE clause.
46937d0deaSdan#
471d2ce4f8Sdan# analyze3-3.*: Test that binding to a variable does not invalidate the
481d2ce4f8Sdan#               query plan when there is no way in which replanning the
491d2ce4f8Sdan#               query may produce a superior outcome.
50937d0deaSdan#
51937d0deaSdan# analyze3-4.*: Test that SQL or authorization callback errors occuring
521d2ce4f8Sdan#               within sqlite3Reprepare() are handled correctly.
53937d0deaSdan#
54c94b8595Sdan# analyze3-5.*: Check that the query plans of applicable statements are
55c94b8595Sdan#               invalidated if the values of SQL parameter are modified
56c94b8595Sdan#               using the clear_bindings() or transfer_bindings() APIs.
57c94b8595Sdan#
582acbc0ddSdan# analyze3-6.*: Test that the problem fixed by commit [127a5b776d] is fixed.
592acbc0ddSdan#
604eed0534Sdan# analyze3-7.*: Test that some memory leaks discovered by fuzz testing
614eed0534Sdan#               have been fixed.
624eed0534Sdan#
63937d0deaSdan
64937d0deaSdanproc getvar {varname} { uplevel #0 set $varname }
65937d0deaSdandb function var getvar
66937d0deaSdan
67937d0deaSdanproc eqp {sql {db db}} {
68937d0deaSdan  uplevel execsql [list "EXPLAIN QUERY PLAN $sql"] $db
69937d0deaSdan}
70937d0deaSdan
71937d0deaSdanproc sf_execsql {sql {db db}} {
72937d0deaSdan  set ::sqlite_search_count 0
73937d0deaSdan  set r [uplevel [list execsql $sql $db]]
74937d0deaSdan
75937d0deaSdan  concat $::sqlite_search_count [$db status step] $r
76937d0deaSdan}
77937d0deaSdan
78937d0deaSdan#-------------------------------------------------------------------------
79937d0deaSdan#
80937d0deaSdan# analyze3-1.1.1:
81937d0deaSdan#   Create a table with two columns. Populate the first column (affinity
82937d0deaSdan#   INTEGER) with integer values from 100 to 1100. Create an index on this
83937d0deaSdan#   column. ANALYZE the table.
84937d0deaSdan#
85937d0deaSdan# analyze3-1.1.2 - 3.1.3
86937d0deaSdan#   Show that there are two possible plans for querying the table with
87937d0deaSdan#   a range constraint on the indexed column - "full table scan" or "use
88937d0deaSdan#   the index". When the range is specified using literal values, SQLite
8974e7c8f5Sdrh#   is able to pick the best plan based on the samples in sqlite_stat3.
90937d0deaSdan#
91937d0deaSdan# analyze3-1.1.4 - 3.1.9
92937d0deaSdan#   Show that using SQL variables produces the same results as using
931d2ce4f8Sdan#   literal values to constrain the range scan.
94937d0deaSdan#
95937d0deaSdan#   These tests also check that the compiler code considers column
96937d0deaSdan#   affinities when estimating the number of rows scanned by the "use
97937d0deaSdan#   index strategy".
98937d0deaSdan#
99937d0deaSdando_test analyze3-1.1.1 {
100937d0deaSdan  execsql {
101937d0deaSdan    BEGIN;
102937d0deaSdan    CREATE TABLE t1(x INTEGER, y);
103937d0deaSdan    CREATE INDEX i1 ON t1(x);
104937d0deaSdan  }
105937d0deaSdan  for {set i 0} {$i < 1000} {incr i} {
106937d0deaSdan    execsql { INSERT INTO t1 VALUES($i+100, $i) }
107937d0deaSdan  }
108937d0deaSdan  execsql {
109937d0deaSdan    COMMIT;
110937d0deaSdan    ANALYZE;
111937d0deaSdan  }
1128ad169abSdan
1138ad169abSdan  execsql { SELECT count(*)>0 FROM sqlite_stat4; }
114dd6e1f19Sdan} {1}
115937d0deaSdan
116b51926e6Sdando_execsql_test analyze3-1.1.x {
117b51926e6Sdan  SELECT count(*) FROM t1 WHERE x>200 AND x<300;
118b51926e6Sdan  SELECT count(*) FROM t1 WHERE x>0 AND x<1100;
119b51926e6Sdan} {99 1000}
120b51926e6Sdan
121b51926e6Sdan# The first of the following two SELECT statements visits 99 rows. So
122b51926e6Sdan# it is better to use the index. But the second visits every row in
123b51926e6Sdan# the table (1000 in total) so it is better to do a full-table scan.
124b51926e6Sdan#
1253985479bSdando_eqp_test analyze3-1.1.2 {
1263985479bSdan  SELECT sum(y) FROM t1 WHERE x>200 AND x<300
127*8210233cSdrh} {SEARCH t1 USING INDEX i1 (x>? AND x<?)}
1283985479bSdando_eqp_test analyze3-1.1.3 {
1293985479bSdan  SELECT sum(y) FROM t1 WHERE x>0 AND x<1100
130*8210233cSdrh} {SCAN t1}
131937d0deaSdan
132169dd928Sdrh# 2017-06-26:  Verify that the SQLITE_DBCONFIG_ENABLE_QPSG setting disables
133169dd928Sdrh# the use of bound parameters by STAT4
134169dd928Sdrh#
135169dd928Sdrhdb cache flush
136169dd928Sdrhunset -nocomplain l
137169dd928Sdrhunset -nocomplain u
138169dd928Sdrhdo_eqp_test analyze3-1.1.3.100 {
139169dd928Sdrh  SELECT sum(y) FROM t1 WHERE x>$l AND x<$u
140*8210233cSdrh} {SEARCH t1 USING INDEX i1 (x>? AND x<?)}
141169dd928Sdrhset l 200
142169dd928Sdrhset u 300
143169dd928Sdrhdo_eqp_test analyze3-1.1.3.101 {
144169dd928Sdrh  SELECT sum(y) FROM t1 WHERE x>$l AND x<$u
145*8210233cSdrh} {SEARCH t1 USING INDEX i1 (x>? AND x<?)}
146169dd928Sdrhset l 0
147169dd928Sdrhset u 1100
148169dd928Sdrhdo_eqp_test analyze3-1.1.3.102 {
149169dd928Sdrh  SELECT sum(y) FROM t1 WHERE x>$l AND x<$u
150*8210233cSdrh} {SCAN t1}
151169dd928Sdrhdb cache flush
152169dd928Sdrhsqlite3_db_config db ENABLE_QPSG 1
153169dd928Sdrhdo_eqp_test analyze3-1.1.3.103 {
154169dd928Sdrh  SELECT sum(y) FROM t1 WHERE x>$l AND x<$u
155*8210233cSdrh} {SEARCH t1 USING INDEX i1 (x>? AND x<?)}
156169dd928Sdrhdb cache flush
157169dd928Sdrhsqlite3_db_config db ENABLE_QPSG 0
158169dd928Sdrhdo_eqp_test analyze3-1.1.3.104 {
159169dd928Sdrh  SELECT sum(y) FROM t1 WHERE x>$l AND x<$u
160*8210233cSdrh} {SCAN t1}
161169dd928Sdrh
162937d0deaSdando_test analyze3-1.1.4 {
163937d0deaSdan  sf_execsql { SELECT sum(y) FROM t1 WHERE x>200 AND x<300 }
164937d0deaSdan} {199 0 14850}
165937d0deaSdando_test analyze3-1.1.5 {
166937d0deaSdan  set l [string range "200" 0 end]
167937d0deaSdan  set u [string range "300" 0 end]
168937d0deaSdan  sf_execsql { SELECT sum(y) FROM t1 WHERE x>$l AND x<$u }
169937d0deaSdan} {199 0 14850}
170937d0deaSdando_test analyze3-1.1.6 {
171937d0deaSdan  set l [expr int(200)]
172937d0deaSdan  set u [expr int(300)]
173937d0deaSdan  sf_execsql { SELECT sum(y) FROM t1 WHERE x>$l AND x<$u }
174937d0deaSdan} {199 0 14850}
175937d0deaSdando_test analyze3-1.1.7 {
176937d0deaSdan  sf_execsql { SELECT sum(y) FROM t1 WHERE x>0 AND x<1100 }
177b51926e6Sdan} {999 999 499500}
178937d0deaSdando_test analyze3-1.1.8 {
179937d0deaSdan  set l [string range "0" 0 end]
180937d0deaSdan  set u [string range "1100" 0 end]
181937d0deaSdan  sf_execsql { SELECT sum(y) FROM t1 WHERE x>$l AND x<$u }
182b51926e6Sdan} {999 999 499500}
183937d0deaSdando_test analyze3-1.1.9 {
184937d0deaSdan  set l [expr int(0)]
185937d0deaSdan  set u [expr int(1100)]
186937d0deaSdan  sf_execsql { SELECT sum(y) FROM t1 WHERE x>$l AND x<$u }
187b51926e6Sdan} {999 999 499500}
188937d0deaSdan
189937d0deaSdan
190937d0deaSdan# The following tests are similar to the block above. The difference is
191937d0deaSdan# that the indexed column has TEXT affinity in this case. In the tests
192937d0deaSdan# above the affinity is INTEGER.
193937d0deaSdan#
194937d0deaSdando_test analyze3-1.2.1 {
195937d0deaSdan  execsql {
196937d0deaSdan    BEGIN;
197937d0deaSdan      CREATE TABLE t2(x TEXT, y);
198937d0deaSdan      INSERT INTO t2 SELECT * FROM t1;
199937d0deaSdan      CREATE INDEX i2 ON t2(x);
200937d0deaSdan    COMMIT;
201937d0deaSdan    ANALYZE;
202937d0deaSdan  }
203937d0deaSdan} {}
204b51926e6Sdando_execsql_test analyze3-2.1.x {
205b51926e6Sdan  SELECT count(*) FROM t2 WHERE x>1 AND x<2;
206b51926e6Sdan  SELECT count(*) FROM t2 WHERE x>0 AND x<99;
207b51926e6Sdan} {200 990}
2083985479bSdando_eqp_test analyze3-1.2.2 {
2093985479bSdan  SELECT sum(y) FROM t2 WHERE x>1 AND x<2
210*8210233cSdrh} {SEARCH t2 USING INDEX i2 (x>? AND x<?)}
2113985479bSdando_eqp_test analyze3-1.2.3 {
2123985479bSdan  SELECT sum(y) FROM t2 WHERE x>0 AND x<99
213*8210233cSdrh} {SCAN t2}
214b51926e6Sdan
215937d0deaSdando_test analyze3-1.2.4 {
216937d0deaSdan  sf_execsql { SELECT sum(y) FROM t2 WHERE x>12 AND x<20 }
217937d0deaSdan} {161 0 4760}
218937d0deaSdando_test analyze3-1.2.5 {
219937d0deaSdan  set l [string range "12" 0 end]
220937d0deaSdan  set u [string range "20" 0 end]
221937d0deaSdan  sf_execsql {SELECT typeof($l), typeof($u), sum(y) FROM t2 WHERE x>$l AND x<$u}
222937d0deaSdan} {161 0 text text 4760}
223937d0deaSdando_test analyze3-1.2.6 {
224937d0deaSdan  set l [expr int(12)]
225937d0deaSdan  set u [expr int(20)]
226937d0deaSdan  sf_execsql {SELECT typeof($l), typeof($u), sum(y) FROM t2 WHERE x>$l AND x<$u}
227937d0deaSdan} {161 0 integer integer 4760}
228937d0deaSdando_test analyze3-1.2.7 {
229937d0deaSdan  sf_execsql { SELECT sum(y) FROM t2 WHERE x>0 AND x<99 }
230b51926e6Sdan} {999 999 490555}
231937d0deaSdando_test analyze3-1.2.8 {
232937d0deaSdan  set l [string range "0" 0 end]
233937d0deaSdan  set u [string range "99" 0 end]
234937d0deaSdan  sf_execsql {SELECT typeof($l), typeof($u), sum(y) FROM t2 WHERE x>$l AND x<$u}
235b51926e6Sdan} {999 999 text text 490555}
236937d0deaSdando_test analyze3-1.2.9 {
237937d0deaSdan  set l [expr int(0)]
238937d0deaSdan  set u [expr int(99)]
239937d0deaSdan  sf_execsql {SELECT typeof($l), typeof($u), sum(y) FROM t2 WHERE x>$l AND x<$u}
240b51926e6Sdan} {999 999 integer integer 490555}
241937d0deaSdan
242937d0deaSdan# Same tests a third time. This time, column x has INTEGER affinity and
243937d0deaSdan# is not the leftmost column of the table. This triggered a bug causing
244937d0deaSdan# SQLite to use sub-optimal query plans in 3.6.18 and earlier.
245937d0deaSdan#
246937d0deaSdando_test analyze3-1.3.1 {
247937d0deaSdan  execsql {
248937d0deaSdan    BEGIN;
249937d0deaSdan      CREATE TABLE t3(y TEXT, x INTEGER);
250937d0deaSdan      INSERT INTO t3 SELECT y, x FROM t1;
251937d0deaSdan      CREATE INDEX i3 ON t3(x);
252937d0deaSdan    COMMIT;
253937d0deaSdan    ANALYZE;
254937d0deaSdan  }
255937d0deaSdan} {}
256b51926e6Sdando_execsql_test analyze3-1.3.x {
257b51926e6Sdan  SELECT count(*) FROM t3 WHERE x>200 AND x<300;
258b51926e6Sdan  SELECT count(*) FROM t3 WHERE x>0 AND x<1100
259b51926e6Sdan} {99 1000}
2603985479bSdando_eqp_test analyze3-1.3.2 {
2613985479bSdan  SELECT sum(y) FROM t3 WHERE x>200 AND x<300
262*8210233cSdrh} {SEARCH t3 USING INDEX i3 (x>? AND x<?)}
2633985479bSdando_eqp_test analyze3-1.3.3 {
2643985479bSdan  SELECT sum(y) FROM t3 WHERE x>0 AND x<1100
265*8210233cSdrh} {SCAN t3}
266937d0deaSdan
267937d0deaSdando_test analyze3-1.3.4 {
268937d0deaSdan  sf_execsql { SELECT sum(y) FROM t3 WHERE x>200 AND x<300 }
269937d0deaSdan} {199 0 14850}
270937d0deaSdando_test analyze3-1.3.5 {
271937d0deaSdan  set l [string range "200" 0 end]
272937d0deaSdan  set u [string range "300" 0 end]
273937d0deaSdan  sf_execsql { SELECT sum(y) FROM t3 WHERE x>$l AND x<$u }
274937d0deaSdan} {199 0 14850}
275937d0deaSdando_test analyze3-1.3.6 {
276937d0deaSdan  set l [expr int(200)]
277937d0deaSdan  set u [expr int(300)]
278937d0deaSdan  sf_execsql { SELECT sum(y) FROM t3 WHERE x>$l AND x<$u }
279937d0deaSdan} {199 0 14850}
280937d0deaSdando_test analyze3-1.3.7 {
281937d0deaSdan  sf_execsql { SELECT sum(y) FROM t3 WHERE x>0 AND x<1100 }
282b51926e6Sdan} {999 999 499500}
283937d0deaSdando_test analyze3-1.3.8 {
284937d0deaSdan  set l [string range "0" 0 end]
285937d0deaSdan  set u [string range "1100" 0 end]
286937d0deaSdan  sf_execsql { SELECT sum(y) FROM t3 WHERE x>$l AND x<$u }
287b51926e6Sdan} {999 999 499500}
288937d0deaSdando_test analyze3-1.3.9 {
289937d0deaSdan  set l [expr int(0)]
290937d0deaSdan  set u [expr int(1100)]
291937d0deaSdan  sf_execsql { SELECT sum(y) FROM t3 WHERE x>$l AND x<$u }
292b51926e6Sdan} {999 999 499500}
293937d0deaSdan
294937d0deaSdan#-------------------------------------------------------------------------
295937d0deaSdan# Test that the values of bound SQL variables may be used for the LIKE
296937d0deaSdan# optimization.
297937d0deaSdan#
298937d0deaSdandrop_all_tables
299937d0deaSdando_test analyze3-2.1 {
300937d0deaSdan  execsql {
301937d0deaSdan    PRAGMA case_sensitive_like=off;
302937d0deaSdan    BEGIN;
303937d0deaSdan    CREATE TABLE t1(a, b TEXT COLLATE nocase);
304937d0deaSdan    CREATE INDEX i1 ON t1(b);
305937d0deaSdan  }
306937d0deaSdan  for {set i 0} {$i < 1000} {incr i} {
307937d0deaSdan    set t ""
308937d0deaSdan    append t [lindex {a b c d e f g h i j} [expr $i/100]]
309937d0deaSdan    append t [lindex {a b c d e f g h i j} [expr ($i/10)%10]]
310937d0deaSdan    append t [lindex {a b c d e f g h i j} [expr ($i%10)]]
311937d0deaSdan    execsql { INSERT INTO t1 VALUES($i, $t) }
312937d0deaSdan  }
313937d0deaSdan  execsql COMMIT
314937d0deaSdan} {}
3153985479bSdando_eqp_test analyze3-2.2 {
3163985479bSdan  SELECT count(a) FROM t1 WHERE b LIKE 'a%'
317*8210233cSdrh} {SEARCH t1 USING INDEX i1 (b>? AND b<?)}
3183985479bSdando_eqp_test analyze3-2.3 {
3193985479bSdan  SELECT count(a) FROM t1 WHERE b LIKE '%a'
320*8210233cSdrh} {SCAN t1}
321937d0deaSdan
32241d2e66eSdrh# Return the first argument if like_match_blobs is true (the default)
32341d2e66eSdrh# or the second argument if not
32441d2e66eSdrh#
32541d2e66eSdrhproc ilmb {a b} {
32641d2e66eSdrh  ifcapable like_match_blobs {return $a}
32741d2e66eSdrh  return $b
32841d2e66eSdrh}
32941d2e66eSdrh
330937d0deaSdando_test analyze3-2.4 {
331937d0deaSdan  sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE 'a%' }
33241d2e66eSdrh} [list [ilmb 102 101] 0 100]
333937d0deaSdando_test analyze3-2.5 {
334937d0deaSdan  sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE '%a' }
335937d0deaSdan} {999 999 100}
336937d0deaSdan
337a9c18a90Sdrhdo_test analyze3-2.6 {
338937d0deaSdan  set like "a%"
339937d0deaSdan  sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
34041d2e66eSdrh} [list [ilmb 102 101] 0 100]
341a9c18a90Sdrhdo_test analyze3-2.7 {
342937d0deaSdan  set like "%a"
343937d0deaSdan  sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
344937d0deaSdan} {999 999 100}
345a9c18a90Sdrhdo_test analyze3-2.8 {
34693ee23ccSdrh  set like "a"
34793ee23ccSdrh  sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
34841d2e66eSdrh} [list [ilmb 102 101] 0 0]
349a9c18a90Sdrhdo_test analyze3-2.9 {
35093ee23ccSdrh  set like "ab"
35193ee23ccSdrh  sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
35241d2e66eSdrh} [list [ilmb 12 11] 0 0]
353a9c18a90Sdrhdo_test analyze3-2.10 {
35493ee23ccSdrh  set like "abc"
35593ee23ccSdrh  sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
35641d2e66eSdrh} [list [ilmb 3 2] 0 1]
357a9c18a90Sdrhdo_test analyze3-2.11 {
35893ee23ccSdrh  set like "a_c"
35993ee23ccSdrh  sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
36041d2e66eSdrh} [list [ilmb 102 101] 0 10]
361937d0deaSdan
362937d0deaSdan
363937d0deaSdan#-------------------------------------------------------------------------
3641d2ce4f8Sdan# This block of tests checks that statements are correctly marked as
3651d2ce4f8Sdan# expired when the values bound to any parameters that may affect the
3661d2ce4f8Sdan# query plan are modified.
367937d0deaSdan#
368937d0deaSdandrop_all_tables
369937d0deaSdandb auth auth
370937d0deaSdanproc auth {args} {
371937d0deaSdan  set ::auth 1
372937d0deaSdan  return SQLITE_OK
373937d0deaSdan}
374937d0deaSdan
375937d0deaSdando_test analyze3-3.1 {
376937d0deaSdan  execsql {
377937d0deaSdan    BEGIN;
378937d0deaSdan    CREATE TABLE t1(a, b, c);
379937d0deaSdan    CREATE INDEX i1 ON t1(b);
380937d0deaSdan  }
381937d0deaSdan  for {set i 0} {$i < 100} {incr i} {
382937d0deaSdan    execsql { INSERT INTO t1 VALUES($i, $i, $i) }
383937d0deaSdan  }
384937d0deaSdan  execsql COMMIT
385937d0deaSdan  execsql ANALYZE
386937d0deaSdan} {}
387937d0deaSdando_test analyze3-3.2.1 {
388937d0deaSdan  set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE b>?" -1 dummy]
3891d2ce4f8Sdan  sqlite3_expired $S
390937d0deaSdan} {0}
391937d0deaSdando_test analyze3-3.2.2 {
392d893ed8eSdan  sqlite3_bind_text $S 1 "abc" 3
3931d2ce4f8Sdan  sqlite3_expired $S
394937d0deaSdan} {1}
395937d0deaSdando_test analyze3-3.2.4 {
396937d0deaSdan  sqlite3_finalize $S
397937d0deaSdan} {SQLITE_OK}
398937d0deaSdan
3991d2ce4f8Sdando_test analyze3-3.2.5 {
400937d0deaSdan  set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE b=?" -1 dummy]
4011d2ce4f8Sdan  sqlite3_expired $S
402937d0deaSdan} {0}
4031d2ce4f8Sdando_test analyze3-3.2.6 {
404d893ed8eSdan  sqlite3_bind_text $S 1 "abc" 3
4051d2ce4f8Sdan  sqlite3_expired $S
4065822d6feSdrh} {1}
4071d2ce4f8Sdando_test analyze3-3.2.7 {
408937d0deaSdan  sqlite3_finalize $S
409937d0deaSdan} {SQLITE_OK}
410937d0deaSdan
411937d0deaSdando_test analyze3-3.4.1 {
412937d0deaSdan  set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE a=? AND b>?" -1 dummy]
4131d2ce4f8Sdan  sqlite3_expired $S
414937d0deaSdan} {0}
415937d0deaSdando_test analyze3-3.4.2 {
416d893ed8eSdan  sqlite3_bind_text $S 1 "abc" 3
4171d2ce4f8Sdan  sqlite3_expired $S
418937d0deaSdan} {0}
419937d0deaSdando_test analyze3-3.4.3 {
420d893ed8eSdan  sqlite3_bind_text $S 2 "def" 3
4211d2ce4f8Sdan  sqlite3_expired $S
422937d0deaSdan} {1}
423937d0deaSdando_test analyze3-3.4.4 {
424d893ed8eSdan  sqlite3_bind_text $S 2 "ghi" 3
4251d2ce4f8Sdan  sqlite3_expired $S
426937d0deaSdan} {1}
427937d0deaSdando_test analyze3-3.4.5 {
4281d2ce4f8Sdan  sqlite3_expired $S
4291d2ce4f8Sdan} {1}
430937d0deaSdando_test analyze3-3.4.6 {
431937d0deaSdan  sqlite3_finalize $S
432937d0deaSdan} {SQLITE_OK}
433937d0deaSdan
434937d0deaSdando_test analyze3-3.5.1 {
435937d0deaSdan  set S [sqlite3_prepare_v2 db {
436937d0deaSdan    SELECT * FROM t1 WHERE a IN (
437937d0deaSdan      ?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10,
438937d0deaSdan      ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20,
439937d0deaSdan      ?21, ?22, ?23, ?24, ?25, ?26, ?27, ?28, ?29, ?30, ?31
440937d0deaSdan    ) AND b>?32;
441937d0deaSdan  } -1 dummy]
4421d2ce4f8Sdan  sqlite3_expired $S
443937d0deaSdan} {0}
444937d0deaSdando_test analyze3-3.5.2 {
445d893ed8eSdan  sqlite3_bind_text $S 31 "abc" 3
4461d2ce4f8Sdan  sqlite3_expired $S
447937d0deaSdan} {0}
448937d0deaSdando_test analyze3-3.5.3 {
449d893ed8eSdan  sqlite3_bind_text $S 32 "def" 3
4501d2ce4f8Sdan  sqlite3_expired $S
451937d0deaSdan} {1}
452937d0deaSdando_test analyze3-3.5.5 {
453937d0deaSdan  sqlite3_finalize $S
454937d0deaSdan} {SQLITE_OK}
455937d0deaSdan
456937d0deaSdando_test analyze3-3.6.1 {
457937d0deaSdan  set S [sqlite3_prepare_v2 db {
458937d0deaSdan    SELECT * FROM t1 WHERE a IN (
459937d0deaSdan      ?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10,
460937d0deaSdan      ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20,
461937d0deaSdan      ?21, ?22, ?23, ?24, ?25, ?26, ?27, ?28, ?29, ?30, ?31, ?32
462937d0deaSdan    ) AND b>?33;
463937d0deaSdan  } -1 dummy]
4641d2ce4f8Sdan  sqlite3_expired $S
465937d0deaSdan} {0}
466937d0deaSdando_test analyze3-3.6.2 {
467d893ed8eSdan  sqlite3_bind_text $S 32 "abc" 3
4681d2ce4f8Sdan  sqlite3_expired $S
469937d0deaSdan} {1}
470937d0deaSdando_test analyze3-3.6.3 {
471d893ed8eSdan  sqlite3_bind_text $S 33 "def" 3
4721d2ce4f8Sdan  sqlite3_expired $S
473937d0deaSdan} {1}
474937d0deaSdando_test analyze3-3.6.5 {
475937d0deaSdan  sqlite3_finalize $S
476937d0deaSdan} {SQLITE_OK}
477937d0deaSdan
478937d0deaSdando_test analyze3-3.7.1 {
479937d0deaSdan  set S [sqlite3_prepare_v2 db {
480937d0deaSdan    SELECT * FROM t1 WHERE a IN (
481937d0deaSdan      ?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?33,
482937d0deaSdan      ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20,
483937d0deaSdan      ?21, ?22, ?23, ?24, ?25, ?26, ?27, ?28, ?29, ?30, ?31, ?32
484937d0deaSdan    ) AND b>?10;
485937d0deaSdan  } -1 dummy]
4861d2ce4f8Sdan  sqlite3_expired $S
487937d0deaSdan} {0}
488937d0deaSdando_test analyze3-3.7.2 {
489d893ed8eSdan  sqlite3_bind_text $S 32 "abc" 3
4901d2ce4f8Sdan  sqlite3_expired $S
491937d0deaSdan} {0}
492937d0deaSdando_test analyze3-3.7.3 {
493d893ed8eSdan  sqlite3_bind_text $S 33 "def" 3
4941d2ce4f8Sdan  sqlite3_expired $S
495937d0deaSdan} {0}
496937d0deaSdando_test analyze3-3.7.4 {
497d893ed8eSdan  sqlite3_bind_text $S 10 "def" 3
4981d2ce4f8Sdan  sqlite3_expired $S
499937d0deaSdan} {1}
500937d0deaSdando_test analyze3-3.7.6 {
501937d0deaSdan  sqlite3_finalize $S
502937d0deaSdan} {SQLITE_OK}
503937d0deaSdan
504937d0deaSdando_test analyze3-3.8.1 {
505937d0deaSdan  execsql {
506937d0deaSdan    CREATE TABLE t4(x, y TEXT COLLATE NOCASE);
507937d0deaSdan    CREATE INDEX i4 ON t4(y);
508937d0deaSdan  }
509937d0deaSdan} {}
510937d0deaSdando_test analyze3-3.8.2 {
511937d0deaSdan  set S [sqlite3_prepare_v2 db {
512937d0deaSdan    SELECT * FROM t4 WHERE x != ? AND y LIKE ?
513937d0deaSdan  } -1 dummy]
5141d2ce4f8Sdan  sqlite3_expired $S
515937d0deaSdan} {0}
516937d0deaSdando_test analyze3-3.8.3 {
517d893ed8eSdan  sqlite3_bind_text $S 1 "abc" 3
5181d2ce4f8Sdan  sqlite3_expired $S
519937d0deaSdan} {0}
520937d0deaSdando_test analyze3-3.8.4 {
521d893ed8eSdan  sqlite3_bind_text $S 2 "def" 3
522937d0deaSdan  sqlite3_expired $S
5231d2ce4f8Sdan} {1}
524937d0deaSdando_test analyze3-3.8.7 {
525d893ed8eSdan  sqlite3_bind_text $S 2 "ghi%" 4
526937d0deaSdan  sqlite3_expired $S
5271d2ce4f8Sdan} {1}
528937d0deaSdando_test analyze3-3.8.8 {
5291d2ce4f8Sdan  sqlite3_expired $S
530937d0deaSdan} {1}
531937d0deaSdando_test analyze3-3.8.9 {
532d893ed8eSdan  sqlite3_bind_text $S 2 "ghi%def" 7
533937d0deaSdan  sqlite3_expired $S
534937d0deaSdan} {1}
535937d0deaSdando_test analyze3-3.8.10 {
5361d2ce4f8Sdan  sqlite3_expired $S
537937d0deaSdan} {1}
538937d0deaSdando_test analyze3-3.8.11 {
539d893ed8eSdan  sqlite3_bind_text $S 2 "%ab" 3
540937d0deaSdan  sqlite3_expired $S
541937d0deaSdan} {1}
542937d0deaSdando_test analyze3-3.8.12 {
5431d2ce4f8Sdan  sqlite3_expired $S
544937d0deaSdan} {1}
545937d0deaSdando_test analyze3-3.8.12 {
546d893ed8eSdan  sqlite3_bind_text $S 2 "%de" 3
547937d0deaSdan  sqlite3_expired $S
5481d2ce4f8Sdan} {1}
549937d0deaSdando_test analyze3-3.8.13 {
5501d2ce4f8Sdan  sqlite3_expired $S
551937d0deaSdan} {1}
552937d0deaSdando_test analyze3-3.8.14 {
553937d0deaSdan  sqlite3_finalize $S
554937d0deaSdan} {SQLITE_OK}
555937d0deaSdan
556937d0deaSdan#-------------------------------------------------------------------------
557937d0deaSdan# These tests check that errors encountered while repreparing an SQL
5581d2ce4f8Sdan# statement within sqlite3Reprepare() are handled correctly.
559937d0deaSdan#
560937d0deaSdan
5611d2ce4f8Sdan# Check a schema error.
562937d0deaSdan#
563937d0deaSdando_test analyze3-4.1.1 {
564937d0deaSdan  set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE a=? AND b>?" -1 dummy]
5651d2ce4f8Sdan  sqlite3_step $S
5661d2ce4f8Sdan} {SQLITE_DONE}
567937d0deaSdando_test analyze3-4.1.2 {
5681d2ce4f8Sdan  sqlite3_reset $S
569d893ed8eSdan  sqlite3_bind_text $S 2 "abc" 3
570937d0deaSdan  execsql { DROP TABLE t1 }
571937d0deaSdan  sqlite3_step $S
572cda455b7Sdrh} {SQLITE_ERROR}
5731d2ce4f8Sdando_test analyze3-4.1.3 {
574937d0deaSdan  sqlite3_finalize $S
575cda455b7Sdrh} {SQLITE_ERROR}
576937d0deaSdan
577937d0deaSdan# Check an authorization error.
578937d0deaSdan#
579937d0deaSdando_test analyze3-4.2.1 {
580937d0deaSdan  execsql {
581937d0deaSdan    BEGIN;
582937d0deaSdan    CREATE TABLE t1(a, b, c);
583937d0deaSdan    CREATE INDEX i1 ON t1(b);
584937d0deaSdan  }
585937d0deaSdan  for {set i 0} {$i < 100} {incr i} {
586937d0deaSdan    execsql { INSERT INTO t1 VALUES($i, $i, $i) }
587937d0deaSdan  }
588937d0deaSdan  execsql COMMIT
589937d0deaSdan  execsql ANALYZE
590937d0deaSdan  set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE a=? AND b>?" -1 dummy]
5911d2ce4f8Sdan  sqlite3_step $S
5921d2ce4f8Sdan} {SQLITE_DONE}
593937d0deaSdandb auth auth
594937d0deaSdanproc auth {args} {
595937d0deaSdan  if {[lindex $args 0] == "SQLITE_READ"} {return SQLITE_DENY}
596937d0deaSdan  return SQLITE_OK
597937d0deaSdan}
598937d0deaSdando_test analyze3-4.2.2 {
5991d2ce4f8Sdan  sqlite3_reset $S
600d893ed8eSdan  sqlite3_bind_text $S 2 "abc" 3
601937d0deaSdan  sqlite3_step $S
602cda455b7Sdrh} {SQLITE_AUTH}
603937d0deaSdando_test analyze3-4.2.4 {
604937d0deaSdan  sqlite3_finalize $S
605cda455b7Sdrh} {SQLITE_AUTH}
606937d0deaSdan
607937d0deaSdan# Check the effect of an authorization error that occurs in a re-prepare
608937d0deaSdan# performed by sqlite3_step() is the same as one that occurs within
6091d2ce4f8Sdan# sqlite3Reprepare().
610937d0deaSdan#
611937d0deaSdando_test analyze3-4.3.1 {
612937d0deaSdan  db auth {}
613937d0deaSdan  set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE a=? AND b>?" -1 dummy]
614937d0deaSdan  execsql { CREATE TABLE t2(d, e, f) }
615937d0deaSdan  db auth auth
616937d0deaSdan  sqlite3_step $S
617cda455b7Sdrh} {SQLITE_AUTH}
618937d0deaSdando_test analyze3-4.3.2 {
619937d0deaSdan  sqlite3_finalize $S
620cda455b7Sdrh} {SQLITE_AUTH}
621c94b8595Sdandb auth {}
622c94b8595Sdan
623c94b8595Sdan#-------------------------------------------------------------------------
624c94b8595Sdan# Test that modifying bound variables using the clear_bindings() or
625c94b8595Sdan# transfer_bindings() APIs works.
626c94b8595Sdan#
627c94b8595Sdan#   analyze3-5.1.*: sqlite3_clear_bindings()
628c94b8595Sdan#   analyze3-5.2.*: sqlite3_transfer_bindings()
629c94b8595Sdan#
630c94b8595Sdando_test analyze3-5.1.1 {
631c94b8595Sdan  drop_all_tables
632c94b8595Sdan  execsql {
633c94b8595Sdan    CREATE TABLE t1(x TEXT COLLATE NOCASE);
634c94b8595Sdan    CREATE INDEX i1 ON t1(x);
635c94b8595Sdan    INSERT INTO t1 VALUES('aaa');
636c94b8595Sdan    INSERT INTO t1 VALUES('abb');
637c94b8595Sdan    INSERT INTO t1 VALUES('acc');
638c94b8595Sdan    INSERT INTO t1 VALUES('baa');
639c94b8595Sdan    INSERT INTO t1 VALUES('bbb');
640c94b8595Sdan    INSERT INTO t1 VALUES('bcc');
641c94b8595Sdan  }
642c94b8595Sdan
643c94b8595Sdan  set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE x LIKE ?" -1 dummy]
644c94b8595Sdan  sqlite3_bind_text $S 1 "a%" 2
645c94b8595Sdan  set R [list]
646c94b8595Sdan  while { "SQLITE_ROW" == [sqlite3_step $S] } {
647c94b8595Sdan    lappend R [sqlite3_column_text $S 0]
648c94b8595Sdan  }
649c94b8595Sdan  concat [sqlite3_reset $S] $R
650c94b8595Sdan} {SQLITE_OK aaa abb acc}
651c94b8595Sdando_test analyze3-5.1.2 {
652c94b8595Sdan  sqlite3_clear_bindings $S
653c94b8595Sdan  set R [list]
654c94b8595Sdan  while { "SQLITE_ROW" == [sqlite3_step $S] } {
655c94b8595Sdan    lappend R [sqlite3_column_text $S 0]
656c94b8595Sdan  }
657c94b8595Sdan  concat [sqlite3_reset $S] $R
658c94b8595Sdan} {SQLITE_OK}
659c94b8595Sdando_test analyze3-5.1.3 {
660c94b8595Sdan  sqlite3_finalize $S
661c94b8595Sdan} {SQLITE_OK}
662c94b8595Sdan
663c94b8595Sdando_test analyze3-5.1.1 {
664c94b8595Sdan  set S1 [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE x LIKE ?" -1 dummy]
665c94b8595Sdan  sqlite3_bind_text $S1 1 "b%" 2
666c94b8595Sdan  set R [list]
667c94b8595Sdan  while { "SQLITE_ROW" == [sqlite3_step $S1] } {
668c94b8595Sdan    lappend R [sqlite3_column_text $S1 0]
669c94b8595Sdan  }
670c94b8595Sdan  concat [sqlite3_reset $S1] $R
671c94b8595Sdan} {SQLITE_OK baa bbb bcc}
672c94b8595Sdan
673c94b8595Sdando_test analyze3-5.1.2 {
674c94b8595Sdan  set S2 [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE x = ?" -1 dummy]
675c94b8595Sdan  sqlite3_bind_text $S2 1 "a%" 2
676c94b8595Sdan  sqlite3_transfer_bindings $S2 $S1
677c94b8595Sdan  set R [list]
678c94b8595Sdan  while { "SQLITE_ROW" == [sqlite3_step $S1] } {
679c94b8595Sdan    lappend R [sqlite3_column_text $S1 0]
680c94b8595Sdan  }
681c94b8595Sdan  concat [sqlite3_reset $S1] $R
682c94b8595Sdan} {SQLITE_OK aaa abb acc}
683c94b8595Sdando_test analyze3-5.1.3 {
684c94b8595Sdan  sqlite3_finalize $S2
685c94b8595Sdan  sqlite3_finalize $S1
686c94b8595Sdan} {SQLITE_OK}
687937d0deaSdan
6882acbc0ddSdan#-------------------------------------------------------------------------
6892acbc0ddSdan
6902acbc0ddSdando_test analyze3-6.1 {
6912acbc0ddSdan  execsql { DROP TABLE IF EXISTS t1 }
6922acbc0ddSdan  execsql BEGIN
6932acbc0ddSdan  execsql { CREATE TABLE t1(a, b, c) }
6942acbc0ddSdan  for {set i 0} {$i < 1000} {incr i} {
6952acbc0ddSdan    execsql "INSERT INTO t1 VALUES([expr $i/100], 'x', [expr $i/10])"
6962acbc0ddSdan  }
6972acbc0ddSdan  execsql {
6982acbc0ddSdan    CREATE INDEX i1 ON t1(a, b);
6992acbc0ddSdan    CREATE INDEX i2 ON t1(c);
7002acbc0ddSdan  }
7012acbc0ddSdan  execsql COMMIT
7022acbc0ddSdan  execsql ANALYZE
7032acbc0ddSdan} {}
7042acbc0ddSdan
7052acbc0ddSdando_eqp_test analyze3-6-3 {
7062acbc0ddSdan  SELECT * FROM t1 WHERE a = 5 AND c = 13;
707*8210233cSdrh} {SEARCH t1 USING INDEX i2 (c=?)}
7082acbc0ddSdan
7092acbc0ddSdando_eqp_test analyze3-6-2 {
7102acbc0ddSdan  SELECT * FROM t1 WHERE a = 5 AND b > 'w' AND c = 13;
711*8210233cSdrh} {SEARCH t1 USING INDEX i2 (c=?)}
7122acbc0ddSdan
713cef25843Sdrh#-----------------------------------------------------------------------------
714cef25843Sdrh# 2015-04-20.
715cef25843Sdrh# Memory leak in sqlite3Stat4ProbeFree().  (Discovered while fuzzing.)
716cef25843Sdrh#
717cef25843Sdrhdo_execsql_test analyze-7.1 {
718cef25843Sdrh  DROP TABLE IF EXISTS t1;
719cef25843Sdrh  CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
720cef25843Sdrh  INSERT INTO t1 VALUES(1,1,'0000');
721cef25843Sdrh  CREATE INDEX t0b ON t1(b);
722cef25843Sdrh  ANALYZE;
723cef25843Sdrh  SELECT c FROM t1 WHERE b=3 AND a BETWEEN 30 AND hex(1);
724cef25843Sdrh} {}
725cef25843Sdrh
7264eed0534Sdan# At one point duplicate stat1 entries were causing a memory leak.
7274eed0534Sdan#
7284eed0534Sdanreset_db
7294eed0534Sdando_execsql_test 7.2 {
7304eed0534Sdan  CREATE TABLE t1(a,b,c);
7314eed0534Sdan  CREATE INDEX t1a ON t1(a);
7324eed0534Sdan  ANALYZE;
7334eed0534Sdan  SELECT * FROM sqlite_stat1;
7344eed0534Sdan  INSERT INTO sqlite_stat1(tbl,idx,stat) VALUES('t1','t1a','12000');
7354eed0534Sdan  INSERT INTO sqlite_stat1(tbl,idx,stat) VALUES('t1','t1a','12000');
7364eed0534Sdan  ANALYZE sqlite_master;
7374eed0534Sdan}
7384eed0534Sdan
739937d0deaSdanfinish_test
740