xref: /sqlite-3.40.0/test/analyze3.test (revision 9edb5ceb)
1# 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
13# implements tests for range and LIKE constraints that use bound variables
14# instead of literal constant arguments.
15#
16
17set testdir [file dirname $argv0]
18source $testdir/tester.tcl
19set testprefix analyze3
20
21ifcapable !stat4&&!stat3 {
22  finish_test
23  return
24}
25
26#----------------------------------------------------------------------
27# Test Organization:
28#
29# analyze3-1.*: Test that the values of bound parameters are considered
30#               in the same way as constants when planning queries that
31#               use range constraints.
32#
33# analyze3-2.*: Test that the values of bound parameters are considered
34#               in the same way as constants when planning queries that
35#               use LIKE expressions in the WHERE clause.
36#
37# analyze3-3.*: Test that binding to a variable does not invalidate the
38#               query plan when there is no way in which replanning the
39#               query may produce a superior outcome.
40#
41# analyze3-4.*: Test that SQL or authorization callback errors occuring
42#               within sqlite3Reprepare() are handled correctly.
43#
44# analyze3-5.*: Check that the query plans of applicable statements are
45#               invalidated if the values of SQL parameter are modified
46#               using the clear_bindings() or transfer_bindings() APIs.
47#
48# analyze3-6.*: Test that the problem fixed by commit [127a5b776d] is fixed.
49#
50# analyze3-7.*: Test that some memory leaks discovered by fuzz testing
51#               have been fixed.
52#
53
54proc getvar {varname} { uplevel #0 set $varname }
55db function var getvar
56
57proc eqp {sql {db db}} {
58  uplevel execsql [list "EXPLAIN QUERY PLAN $sql"] $db
59}
60
61proc sf_execsql {sql {db db}} {
62  set ::sqlite_search_count 0
63  set r [uplevel [list execsql $sql $db]]
64
65  concat $::sqlite_search_count [$db status step] $r
66}
67
68#-------------------------------------------------------------------------
69#
70# analyze3-1.1.1:
71#   Create a table with two columns. Populate the first column (affinity
72#   INTEGER) with integer values from 100 to 1100. Create an index on this
73#   column. ANALYZE the table.
74#
75# analyze3-1.1.2 - 3.1.3
76#   Show that there are two possible plans for querying the table with
77#   a range constraint on the indexed column - "full table scan" or "use
78#   the index". When the range is specified using literal values, SQLite
79#   is able to pick the best plan based on the samples in sqlite_stat3.
80#
81# analyze3-1.1.4 - 3.1.9
82#   Show that using SQL variables produces the same results as using
83#   literal values to constrain the range scan.
84#
85#   These tests also check that the compiler code considers column
86#   affinities when estimating the number of rows scanned by the "use
87#   index strategy".
88#
89do_test analyze3-1.1.1 {
90  execsql {
91    BEGIN;
92    CREATE TABLE t1(x INTEGER, y);
93    CREATE INDEX i1 ON t1(x);
94  }
95  for {set i 0} {$i < 1000} {incr i} {
96    execsql { INSERT INTO t1 VALUES($i+100, $i) }
97  }
98  execsql {
99    COMMIT;
100    ANALYZE;
101  }
102
103  ifcapable stat4 {
104    execsql { SELECT count(*)>0 FROM sqlite_stat4; }
105  } else {
106    execsql { SELECT count(*)>0 FROM sqlite_stat3; }
107  }
108} {1}
109
110do_execsql_test analyze3-1.1.x {
111  SELECT count(*) FROM t1 WHERE x>200 AND x<300;
112  SELECT count(*) FROM t1 WHERE x>0 AND x<1100;
113} {99 1000}
114
115# The first of the following two SELECT statements visits 99 rows. So
116# it is better to use the index. But the second visits every row in
117# the table (1000 in total) so it is better to do a full-table scan.
118#
119do_eqp_test analyze3-1.1.2 {
120  SELECT sum(y) FROM t1 WHERE x>200 AND x<300
121} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?)}}
122do_eqp_test analyze3-1.1.3 {
123  SELECT sum(y) FROM t1 WHERE x>0 AND x<1100
124} {0 0 0 {SCAN TABLE t1}}
125
126do_test analyze3-1.1.4 {
127  sf_execsql { SELECT sum(y) FROM t1 WHERE x>200 AND x<300 }
128} {199 0 14850}
129do_test analyze3-1.1.5 {
130  set l [string range "200" 0 end]
131  set u [string range "300" 0 end]
132  sf_execsql { SELECT sum(y) FROM t1 WHERE x>$l AND x<$u }
133} {199 0 14850}
134do_test analyze3-1.1.6 {
135  set l [expr int(200)]
136  set u [expr int(300)]
137  sf_execsql { SELECT sum(y) FROM t1 WHERE x>$l AND x<$u }
138} {199 0 14850}
139do_test analyze3-1.1.7 {
140  sf_execsql { SELECT sum(y) FROM t1 WHERE x>0 AND x<1100 }
141} {999 999 499500}
142do_test analyze3-1.1.8 {
143  set l [string range "0" 0 end]
144  set u [string range "1100" 0 end]
145  sf_execsql { SELECT sum(y) FROM t1 WHERE x>$l AND x<$u }
146} {999 999 499500}
147do_test analyze3-1.1.9 {
148  set l [expr int(0)]
149  set u [expr int(1100)]
150  sf_execsql { SELECT sum(y) FROM t1 WHERE x>$l AND x<$u }
151} {999 999 499500}
152
153
154# The following tests are similar to the block above. The difference is
155# that the indexed column has TEXT affinity in this case. In the tests
156# above the affinity is INTEGER.
157#
158do_test analyze3-1.2.1 {
159  execsql {
160    BEGIN;
161      CREATE TABLE t2(x TEXT, y);
162      INSERT INTO t2 SELECT * FROM t1;
163      CREATE INDEX i2 ON t2(x);
164    COMMIT;
165    ANALYZE;
166  }
167} {}
168do_execsql_test analyze3-2.1.x {
169  SELECT count(*) FROM t2 WHERE x>1 AND x<2;
170  SELECT count(*) FROM t2 WHERE x>0 AND x<99;
171} {200 990}
172do_eqp_test analyze3-1.2.2 {
173  SELECT sum(y) FROM t2 WHERE x>1 AND x<2
174} {0 0 0 {SEARCH TABLE t2 USING INDEX i2 (x>? AND x<?)}}
175do_eqp_test analyze3-1.2.3 {
176  SELECT sum(y) FROM t2 WHERE x>0 AND x<99
177} {0 0 0 {SCAN TABLE t2}}
178
179do_test analyze3-1.2.4 {
180  sf_execsql { SELECT sum(y) FROM t2 WHERE x>12 AND x<20 }
181} {161 0 4760}
182do_test analyze3-1.2.5 {
183  set l [string range "12" 0 end]
184  set u [string range "20" 0 end]
185  sf_execsql {SELECT typeof($l), typeof($u), sum(y) FROM t2 WHERE x>$l AND x<$u}
186} {161 0 text text 4760}
187do_test analyze3-1.2.6 {
188  set l [expr int(12)]
189  set u [expr int(20)]
190  sf_execsql {SELECT typeof($l), typeof($u), sum(y) FROM t2 WHERE x>$l AND x<$u}
191} {161 0 integer integer 4760}
192do_test analyze3-1.2.7 {
193  sf_execsql { SELECT sum(y) FROM t2 WHERE x>0 AND x<99 }
194} {999 999 490555}
195do_test analyze3-1.2.8 {
196  set l [string range "0" 0 end]
197  set u [string range "99" 0 end]
198  sf_execsql {SELECT typeof($l), typeof($u), sum(y) FROM t2 WHERE x>$l AND x<$u}
199} {999 999 text text 490555}
200do_test analyze3-1.2.9 {
201  set l [expr int(0)]
202  set u [expr int(99)]
203  sf_execsql {SELECT typeof($l), typeof($u), sum(y) FROM t2 WHERE x>$l AND x<$u}
204} {999 999 integer integer 490555}
205
206# Same tests a third time. This time, column x has INTEGER affinity and
207# is not the leftmost column of the table. This triggered a bug causing
208# SQLite to use sub-optimal query plans in 3.6.18 and earlier.
209#
210do_test analyze3-1.3.1 {
211  execsql {
212    BEGIN;
213      CREATE TABLE t3(y TEXT, x INTEGER);
214      INSERT INTO t3 SELECT y, x FROM t1;
215      CREATE INDEX i3 ON t3(x);
216    COMMIT;
217    ANALYZE;
218  }
219} {}
220do_execsql_test analyze3-1.3.x {
221  SELECT count(*) FROM t3 WHERE x>200 AND x<300;
222  SELECT count(*) FROM t3 WHERE x>0 AND x<1100
223} {99 1000}
224do_eqp_test analyze3-1.3.2 {
225  SELECT sum(y) FROM t3 WHERE x>200 AND x<300
226} {0 0 0 {SEARCH TABLE t3 USING INDEX i3 (x>? AND x<?)}}
227do_eqp_test analyze3-1.3.3 {
228  SELECT sum(y) FROM t3 WHERE x>0 AND x<1100
229} {0 0 0 {SCAN TABLE t3}}
230
231do_test analyze3-1.3.4 {
232  sf_execsql { SELECT sum(y) FROM t3 WHERE x>200 AND x<300 }
233} {199 0 14850}
234do_test analyze3-1.3.5 {
235  set l [string range "200" 0 end]
236  set u [string range "300" 0 end]
237  sf_execsql { SELECT sum(y) FROM t3 WHERE x>$l AND x<$u }
238} {199 0 14850}
239do_test analyze3-1.3.6 {
240  set l [expr int(200)]
241  set u [expr int(300)]
242  sf_execsql { SELECT sum(y) FROM t3 WHERE x>$l AND x<$u }
243} {199 0 14850}
244do_test analyze3-1.3.7 {
245  sf_execsql { SELECT sum(y) FROM t3 WHERE x>0 AND x<1100 }
246} {999 999 499500}
247do_test analyze3-1.3.8 {
248  set l [string range "0" 0 end]
249  set u [string range "1100" 0 end]
250  sf_execsql { SELECT sum(y) FROM t3 WHERE x>$l AND x<$u }
251} {999 999 499500}
252do_test analyze3-1.3.9 {
253  set l [expr int(0)]
254  set u [expr int(1100)]
255  sf_execsql { SELECT sum(y) FROM t3 WHERE x>$l AND x<$u }
256} {999 999 499500}
257
258#-------------------------------------------------------------------------
259# Test that the values of bound SQL variables may be used for the LIKE
260# optimization.
261#
262drop_all_tables
263do_test analyze3-2.1 {
264  execsql {
265    PRAGMA case_sensitive_like=off;
266    BEGIN;
267    CREATE TABLE t1(a, b TEXT COLLATE nocase);
268    CREATE INDEX i1 ON t1(b);
269  }
270  for {set i 0} {$i < 1000} {incr i} {
271    set t ""
272    append t [lindex {a b c d e f g h i j} [expr $i/100]]
273    append t [lindex {a b c d e f g h i j} [expr ($i/10)%10]]
274    append t [lindex {a b c d e f g h i j} [expr ($i%10)]]
275    execsql { INSERT INTO t1 VALUES($i, $t) }
276  }
277  execsql COMMIT
278} {}
279do_eqp_test analyze3-2.2 {
280  SELECT count(a) FROM t1 WHERE b LIKE 'a%'
281} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (b>? AND b<?)}}
282do_eqp_test analyze3-2.3 {
283  SELECT count(a) FROM t1 WHERE b LIKE '%a'
284} {0 0 0 {SCAN TABLE t1}}
285
286do_test analyze3-2.4 {
287  sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE 'a%' }
288} {102 0 100}
289do_test analyze3-2.5 {
290  sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE '%a' }
291} {999 999 100}
292
293do_test analyze3-2.6 {
294  set like "a%"
295  sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
296} {102 0 100}
297do_test analyze3-2.7 {
298  set like "%a"
299  sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
300} {999 999 100}
301do_test analyze3-2.8 {
302  set like "a"
303  sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
304} {102 0 0}
305do_test analyze3-2.9 {
306  set like "ab"
307  sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
308} {12 0 0}
309do_test analyze3-2.10 {
310  set like "abc"
311  sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
312} {3 0 1}
313do_test analyze3-2.11 {
314  set like "a_c"
315  sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
316} {102 0 10}
317
318
319#-------------------------------------------------------------------------
320# This block of tests checks that statements are correctly marked as
321# expired when the values bound to any parameters that may affect the
322# query plan are modified.
323#
324drop_all_tables
325db auth auth
326proc auth {args} {
327  set ::auth 1
328  return SQLITE_OK
329}
330
331do_test analyze3-3.1 {
332  execsql {
333    BEGIN;
334    CREATE TABLE t1(a, b, c);
335    CREATE INDEX i1 ON t1(b);
336  }
337  for {set i 0} {$i < 100} {incr i} {
338    execsql { INSERT INTO t1 VALUES($i, $i, $i) }
339  }
340  execsql COMMIT
341  execsql ANALYZE
342} {}
343do_test analyze3-3.2.1 {
344  set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE b>?" -1 dummy]
345  sqlite3_expired $S
346} {0}
347do_test analyze3-3.2.2 {
348  sqlite3_bind_text $S 1 "abc" 3
349  sqlite3_expired $S
350} {1}
351do_test analyze3-3.2.4 {
352  sqlite3_finalize $S
353} {SQLITE_OK}
354
355do_test analyze3-3.2.5 {
356  set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE b=?" -1 dummy]
357  sqlite3_expired $S
358} {0}
359do_test analyze3-3.2.6 {
360  sqlite3_bind_text $S 1 "abc" 3
361  sqlite3_expired $S
362} {1}
363do_test analyze3-3.2.7 {
364  sqlite3_finalize $S
365} {SQLITE_OK}
366
367do_test analyze3-3.4.1 {
368  set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE a=? AND b>?" -1 dummy]
369  sqlite3_expired $S
370} {0}
371do_test analyze3-3.4.2 {
372  sqlite3_bind_text $S 1 "abc" 3
373  sqlite3_expired $S
374} {0}
375do_test analyze3-3.4.3 {
376  sqlite3_bind_text $S 2 "def" 3
377  sqlite3_expired $S
378} {1}
379do_test analyze3-3.4.4 {
380  sqlite3_bind_text $S 2 "ghi" 3
381  sqlite3_expired $S
382} {1}
383do_test analyze3-3.4.5 {
384  sqlite3_expired $S
385} {1}
386do_test analyze3-3.4.6 {
387  sqlite3_finalize $S
388} {SQLITE_OK}
389
390do_test analyze3-3.5.1 {
391  set S [sqlite3_prepare_v2 db {
392    SELECT * FROM t1 WHERE a IN (
393      ?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10,
394      ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20,
395      ?21, ?22, ?23, ?24, ?25, ?26, ?27, ?28, ?29, ?30, ?31
396    ) AND b>?32;
397  } -1 dummy]
398  sqlite3_expired $S
399} {0}
400do_test analyze3-3.5.2 {
401  sqlite3_bind_text $S 31 "abc" 3
402  sqlite3_expired $S
403} {0}
404do_test analyze3-3.5.3 {
405  sqlite3_bind_text $S 32 "def" 3
406  sqlite3_expired $S
407} {1}
408do_test analyze3-3.5.5 {
409  sqlite3_finalize $S
410} {SQLITE_OK}
411
412do_test analyze3-3.6.1 {
413  set S [sqlite3_prepare_v2 db {
414    SELECT * FROM t1 WHERE a IN (
415      ?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10,
416      ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20,
417      ?21, ?22, ?23, ?24, ?25, ?26, ?27, ?28, ?29, ?30, ?31, ?32
418    ) AND b>?33;
419  } -1 dummy]
420  sqlite3_expired $S
421} {0}
422do_test analyze3-3.6.2 {
423  sqlite3_bind_text $S 32 "abc" 3
424  sqlite3_expired $S
425} {1}
426do_test analyze3-3.6.3 {
427  sqlite3_bind_text $S 33 "def" 3
428  sqlite3_expired $S
429} {1}
430do_test analyze3-3.6.5 {
431  sqlite3_finalize $S
432} {SQLITE_OK}
433
434do_test analyze3-3.7.1 {
435  set S [sqlite3_prepare_v2 db {
436    SELECT * FROM t1 WHERE a IN (
437      ?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?33,
438      ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20,
439      ?21, ?22, ?23, ?24, ?25, ?26, ?27, ?28, ?29, ?30, ?31, ?32
440    ) AND b>?10;
441  } -1 dummy]
442  sqlite3_expired $S
443} {0}
444do_test analyze3-3.7.2 {
445  sqlite3_bind_text $S 32 "abc" 3
446  sqlite3_expired $S
447} {0}
448do_test analyze3-3.7.3 {
449  sqlite3_bind_text $S 33 "def" 3
450  sqlite3_expired $S
451} {0}
452do_test analyze3-3.7.4 {
453  sqlite3_bind_text $S 10 "def" 3
454  sqlite3_expired $S
455} {1}
456do_test analyze3-3.7.6 {
457  sqlite3_finalize $S
458} {SQLITE_OK}
459
460do_test analyze3-3.8.1 {
461  execsql {
462    CREATE TABLE t4(x, y TEXT COLLATE NOCASE);
463    CREATE INDEX i4 ON t4(y);
464  }
465} {}
466do_test analyze3-3.8.2 {
467  set S [sqlite3_prepare_v2 db {
468    SELECT * FROM t4 WHERE x != ? AND y LIKE ?
469  } -1 dummy]
470  sqlite3_expired $S
471} {0}
472do_test analyze3-3.8.3 {
473  sqlite3_bind_text $S 1 "abc" 3
474  sqlite3_expired $S
475} {0}
476do_test analyze3-3.8.4 {
477  sqlite3_bind_text $S 2 "def" 3
478  sqlite3_expired $S
479} {1}
480do_test analyze3-3.8.7 {
481  sqlite3_bind_text $S 2 "ghi%" 4
482  sqlite3_expired $S
483} {1}
484do_test analyze3-3.8.8 {
485  sqlite3_expired $S
486} {1}
487do_test analyze3-3.8.9 {
488  sqlite3_bind_text $S 2 "ghi%def" 7
489  sqlite3_expired $S
490} {1}
491do_test analyze3-3.8.10 {
492  sqlite3_expired $S
493} {1}
494do_test analyze3-3.8.11 {
495  sqlite3_bind_text $S 2 "%ab" 3
496  sqlite3_expired $S
497} {1}
498do_test analyze3-3.8.12 {
499  sqlite3_expired $S
500} {1}
501do_test analyze3-3.8.12 {
502  sqlite3_bind_text $S 2 "%de" 3
503  sqlite3_expired $S
504} {1}
505do_test analyze3-3.8.13 {
506  sqlite3_expired $S
507} {1}
508do_test analyze3-3.8.14 {
509  sqlite3_finalize $S
510} {SQLITE_OK}
511
512#-------------------------------------------------------------------------
513# These tests check that errors encountered while repreparing an SQL
514# statement within sqlite3Reprepare() are handled correctly.
515#
516
517# Check a schema error.
518#
519do_test analyze3-4.1.1 {
520  set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE a=? AND b>?" -1 dummy]
521  sqlite3_step $S
522} {SQLITE_DONE}
523do_test analyze3-4.1.2 {
524  sqlite3_reset $S
525  sqlite3_bind_text $S 2 "abc" 3
526  execsql { DROP TABLE t1 }
527  sqlite3_step $S
528} {SQLITE_ERROR}
529do_test analyze3-4.1.3 {
530  sqlite3_finalize $S
531} {SQLITE_ERROR}
532
533# Check an authorization error.
534#
535do_test analyze3-4.2.1 {
536  execsql {
537    BEGIN;
538    CREATE TABLE t1(a, b, c);
539    CREATE INDEX i1 ON t1(b);
540  }
541  for {set i 0} {$i < 100} {incr i} {
542    execsql { INSERT INTO t1 VALUES($i, $i, $i) }
543  }
544  execsql COMMIT
545  execsql ANALYZE
546  set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE a=? AND b>?" -1 dummy]
547  sqlite3_step $S
548} {SQLITE_DONE}
549db auth auth
550proc auth {args} {
551  if {[lindex $args 0] == "SQLITE_READ"} {return SQLITE_DENY}
552  return SQLITE_OK
553}
554do_test analyze3-4.2.2 {
555  sqlite3_reset $S
556  sqlite3_bind_text $S 2 "abc" 3
557  sqlite3_step $S
558} {SQLITE_AUTH}
559do_test analyze3-4.2.4 {
560  sqlite3_finalize $S
561} {SQLITE_AUTH}
562
563# Check the effect of an authorization error that occurs in a re-prepare
564# performed by sqlite3_step() is the same as one that occurs within
565# sqlite3Reprepare().
566#
567do_test analyze3-4.3.1 {
568  db auth {}
569  set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE a=? AND b>?" -1 dummy]
570  execsql { CREATE TABLE t2(d, e, f) }
571  db auth auth
572  sqlite3_step $S
573} {SQLITE_AUTH}
574do_test analyze3-4.3.2 {
575  sqlite3_finalize $S
576} {SQLITE_AUTH}
577db auth {}
578
579#-------------------------------------------------------------------------
580# Test that modifying bound variables using the clear_bindings() or
581# transfer_bindings() APIs works.
582#
583#   analyze3-5.1.*: sqlite3_clear_bindings()
584#   analyze3-5.2.*: sqlite3_transfer_bindings()
585#
586do_test analyze3-5.1.1 {
587  drop_all_tables
588  execsql {
589    CREATE TABLE t1(x TEXT COLLATE NOCASE);
590    CREATE INDEX i1 ON t1(x);
591    INSERT INTO t1 VALUES('aaa');
592    INSERT INTO t1 VALUES('abb');
593    INSERT INTO t1 VALUES('acc');
594    INSERT INTO t1 VALUES('baa');
595    INSERT INTO t1 VALUES('bbb');
596    INSERT INTO t1 VALUES('bcc');
597  }
598
599  set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE x LIKE ?" -1 dummy]
600  sqlite3_bind_text $S 1 "a%" 2
601  set R [list]
602  while { "SQLITE_ROW" == [sqlite3_step $S] } {
603    lappend R [sqlite3_column_text $S 0]
604  }
605  concat [sqlite3_reset $S] $R
606} {SQLITE_OK aaa abb acc}
607do_test analyze3-5.1.2 {
608  sqlite3_clear_bindings $S
609  set R [list]
610  while { "SQLITE_ROW" == [sqlite3_step $S] } {
611    lappend R [sqlite3_column_text $S 0]
612  }
613  concat [sqlite3_reset $S] $R
614} {SQLITE_OK}
615do_test analyze3-5.1.3 {
616  sqlite3_finalize $S
617} {SQLITE_OK}
618
619do_test analyze3-5.1.1 {
620  set S1 [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE x LIKE ?" -1 dummy]
621  sqlite3_bind_text $S1 1 "b%" 2
622  set R [list]
623  while { "SQLITE_ROW" == [sqlite3_step $S1] } {
624    lappend R [sqlite3_column_text $S1 0]
625  }
626  concat [sqlite3_reset $S1] $R
627} {SQLITE_OK baa bbb bcc}
628
629do_test analyze3-5.1.2 {
630  set S2 [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE x = ?" -1 dummy]
631  sqlite3_bind_text $S2 1 "a%" 2
632  sqlite3_transfer_bindings $S2 $S1
633  set R [list]
634  while { "SQLITE_ROW" == [sqlite3_step $S1] } {
635    lappend R [sqlite3_column_text $S1 0]
636  }
637  concat [sqlite3_reset $S1] $R
638} {SQLITE_OK aaa abb acc}
639do_test analyze3-5.1.3 {
640  sqlite3_finalize $S2
641  sqlite3_finalize $S1
642} {SQLITE_OK}
643
644#-------------------------------------------------------------------------
645
646do_test analyze3-6.1 {
647  execsql { DROP TABLE IF EXISTS t1 }
648  execsql BEGIN
649  execsql { CREATE TABLE t1(a, b, c) }
650  for {set i 0} {$i < 1000} {incr i} {
651    execsql "INSERT INTO t1 VALUES([expr $i/100], 'x', [expr $i/10])"
652  }
653  execsql {
654    CREATE INDEX i1 ON t1(a, b);
655    CREATE INDEX i2 ON t1(c);
656  }
657  execsql COMMIT
658  execsql ANALYZE
659} {}
660
661do_eqp_test analyze3-6-3 {
662  SELECT * FROM t1 WHERE a = 5 AND c = 13;
663} {0 0 0 {SEARCH TABLE t1 USING INDEX i2 (c=?)}}
664
665do_eqp_test analyze3-6-2 {
666  SELECT * FROM t1 WHERE a = 5 AND b > 'w' AND c = 13;
667} {0 0 0 {SEARCH TABLE t1 USING INDEX i2 (c=?)}}
668
669#-----------------------------------------------------------------------------
670# 2015-04-20.
671# Memory leak in sqlite3Stat4ProbeFree().  (Discovered while fuzzing.)
672#
673do_execsql_test analyze-7.1 {
674  DROP TABLE IF EXISTS t1;
675  CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
676  INSERT INTO t1 VALUES(1,1,'0000');
677  CREATE INDEX t0b ON t1(b);
678  ANALYZE;
679  SELECT c FROM t1 WHERE b=3 AND a BETWEEN 30 AND hex(1);
680} {}
681
682# At one point duplicate stat1 entries were causing a memory leak.
683#
684reset_db
685do_execsql_test 7.2 {
686  CREATE TABLE t1(a,b,c);
687  CREATE INDEX t1a ON t1(a);
688  ANALYZE;
689  SELECT * FROM sqlite_stat1;
690  INSERT INTO sqlite_stat1(tbl,idx,stat) VALUES('t1','t1a','12000');
691  INSERT INTO sqlite_stat1(tbl,idx,stat) VALUES('t1','t1a','12000');
692  ANALYZE sqlite_master;
693}
694
695finish_test
696