xref: /sqlite-3.40.0/test/analyze3.test (revision b80bb6ce)
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} {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} {SCAN TABLE t1}
125
126# 2017-06-26:  Verify that the SQLITE_DBCONFIG_ENABLE_QPSG setting disables
127# the use of bound parameters by STAT4
128#
129db cache flush
130unset -nocomplain l
131unset -nocomplain u
132do_eqp_test analyze3-1.1.3.100 {
133  SELECT sum(y) FROM t1 WHERE x>$l AND x<$u
134} {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?)}
135set l 200
136set u 300
137do_eqp_test analyze3-1.1.3.101 {
138  SELECT sum(y) FROM t1 WHERE x>$l AND x<$u
139} {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?)}
140set l 0
141set u 1100
142do_eqp_test analyze3-1.1.3.102 {
143  SELECT sum(y) FROM t1 WHERE x>$l AND x<$u
144} {SCAN TABLE t1}
145db cache flush
146sqlite3_db_config db ENABLE_QPSG 1
147do_eqp_test analyze3-1.1.3.103 {
148  SELECT sum(y) FROM t1 WHERE x>$l AND x<$u
149} {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?)}
150db cache flush
151sqlite3_db_config db ENABLE_QPSG 0
152do_eqp_test analyze3-1.1.3.104 {
153  SELECT sum(y) FROM t1 WHERE x>$l AND x<$u
154} {SCAN TABLE t1}
155
156do_test analyze3-1.1.4 {
157  sf_execsql { SELECT sum(y) FROM t1 WHERE x>200 AND x<300 }
158} {199 0 14850}
159do_test analyze3-1.1.5 {
160  set l [string range "200" 0 end]
161  set u [string range "300" 0 end]
162  sf_execsql { SELECT sum(y) FROM t1 WHERE x>$l AND x<$u }
163} {199 0 14850}
164do_test analyze3-1.1.6 {
165  set l [expr int(200)]
166  set u [expr int(300)]
167  sf_execsql { SELECT sum(y) FROM t1 WHERE x>$l AND x<$u }
168} {199 0 14850}
169do_test analyze3-1.1.7 {
170  sf_execsql { SELECT sum(y) FROM t1 WHERE x>0 AND x<1100 }
171} {999 999 499500}
172do_test analyze3-1.1.8 {
173  set l [string range "0" 0 end]
174  set u [string range "1100" 0 end]
175  sf_execsql { SELECT sum(y) FROM t1 WHERE x>$l AND x<$u }
176} {999 999 499500}
177do_test analyze3-1.1.9 {
178  set l [expr int(0)]
179  set u [expr int(1100)]
180  sf_execsql { SELECT sum(y) FROM t1 WHERE x>$l AND x<$u }
181} {999 999 499500}
182
183
184# The following tests are similar to the block above. The difference is
185# that the indexed column has TEXT affinity in this case. In the tests
186# above the affinity is INTEGER.
187#
188do_test analyze3-1.2.1 {
189  execsql {
190    BEGIN;
191      CREATE TABLE t2(x TEXT, y);
192      INSERT INTO t2 SELECT * FROM t1;
193      CREATE INDEX i2 ON t2(x);
194    COMMIT;
195    ANALYZE;
196  }
197} {}
198do_execsql_test analyze3-2.1.x {
199  SELECT count(*) FROM t2 WHERE x>1 AND x<2;
200  SELECT count(*) FROM t2 WHERE x>0 AND x<99;
201} {200 990}
202do_eqp_test analyze3-1.2.2 {
203  SELECT sum(y) FROM t2 WHERE x>1 AND x<2
204} {SEARCH TABLE t2 USING INDEX i2 (x>? AND x<?)}
205do_eqp_test analyze3-1.2.3 {
206  SELECT sum(y) FROM t2 WHERE x>0 AND x<99
207} {SCAN TABLE t2}
208
209do_test analyze3-1.2.4 {
210  sf_execsql { SELECT sum(y) FROM t2 WHERE x>12 AND x<20 }
211} {161 0 4760}
212do_test analyze3-1.2.5 {
213  set l [string range "12" 0 end]
214  set u [string range "20" 0 end]
215  sf_execsql {SELECT typeof($l), typeof($u), sum(y) FROM t2 WHERE x>$l AND x<$u}
216} {161 0 text text 4760}
217do_test analyze3-1.2.6 {
218  set l [expr int(12)]
219  set u [expr int(20)]
220  sf_execsql {SELECT typeof($l), typeof($u), sum(y) FROM t2 WHERE x>$l AND x<$u}
221} {161 0 integer integer 4760}
222do_test analyze3-1.2.7 {
223  sf_execsql { SELECT sum(y) FROM t2 WHERE x>0 AND x<99 }
224} {999 999 490555}
225do_test analyze3-1.2.8 {
226  set l [string range "0" 0 end]
227  set u [string range "99" 0 end]
228  sf_execsql {SELECT typeof($l), typeof($u), sum(y) FROM t2 WHERE x>$l AND x<$u}
229} {999 999 text text 490555}
230do_test analyze3-1.2.9 {
231  set l [expr int(0)]
232  set u [expr int(99)]
233  sf_execsql {SELECT typeof($l), typeof($u), sum(y) FROM t2 WHERE x>$l AND x<$u}
234} {999 999 integer integer 490555}
235
236# Same tests a third time. This time, column x has INTEGER affinity and
237# is not the leftmost column of the table. This triggered a bug causing
238# SQLite to use sub-optimal query plans in 3.6.18 and earlier.
239#
240do_test analyze3-1.3.1 {
241  execsql {
242    BEGIN;
243      CREATE TABLE t3(y TEXT, x INTEGER);
244      INSERT INTO t3 SELECT y, x FROM t1;
245      CREATE INDEX i3 ON t3(x);
246    COMMIT;
247    ANALYZE;
248  }
249} {}
250do_execsql_test analyze3-1.3.x {
251  SELECT count(*) FROM t3 WHERE x>200 AND x<300;
252  SELECT count(*) FROM t3 WHERE x>0 AND x<1100
253} {99 1000}
254do_eqp_test analyze3-1.3.2 {
255  SELECT sum(y) FROM t3 WHERE x>200 AND x<300
256} {SEARCH TABLE t3 USING INDEX i3 (x>? AND x<?)}
257do_eqp_test analyze3-1.3.3 {
258  SELECT sum(y) FROM t3 WHERE x>0 AND x<1100
259} {SCAN TABLE t3}
260
261do_test analyze3-1.3.4 {
262  sf_execsql { SELECT sum(y) FROM t3 WHERE x>200 AND x<300 }
263} {199 0 14850}
264do_test analyze3-1.3.5 {
265  set l [string range "200" 0 end]
266  set u [string range "300" 0 end]
267  sf_execsql { SELECT sum(y) FROM t3 WHERE x>$l AND x<$u }
268} {199 0 14850}
269do_test analyze3-1.3.6 {
270  set l [expr int(200)]
271  set u [expr int(300)]
272  sf_execsql { SELECT sum(y) FROM t3 WHERE x>$l AND x<$u }
273} {199 0 14850}
274do_test analyze3-1.3.7 {
275  sf_execsql { SELECT sum(y) FROM t3 WHERE x>0 AND x<1100 }
276} {999 999 499500}
277do_test analyze3-1.3.8 {
278  set l [string range "0" 0 end]
279  set u [string range "1100" 0 end]
280  sf_execsql { SELECT sum(y) FROM t3 WHERE x>$l AND x<$u }
281} {999 999 499500}
282do_test analyze3-1.3.9 {
283  set l [expr int(0)]
284  set u [expr int(1100)]
285  sf_execsql { SELECT sum(y) FROM t3 WHERE x>$l AND x<$u }
286} {999 999 499500}
287
288#-------------------------------------------------------------------------
289# Test that the values of bound SQL variables may be used for the LIKE
290# optimization.
291#
292drop_all_tables
293do_test analyze3-2.1 {
294  execsql {
295    PRAGMA case_sensitive_like=off;
296    BEGIN;
297    CREATE TABLE t1(a, b TEXT COLLATE nocase);
298    CREATE INDEX i1 ON t1(b);
299  }
300  for {set i 0} {$i < 1000} {incr i} {
301    set t ""
302    append t [lindex {a b c d e f g h i j} [expr $i/100]]
303    append t [lindex {a b c d e f g h i j} [expr ($i/10)%10]]
304    append t [lindex {a b c d e f g h i j} [expr ($i%10)]]
305    execsql { INSERT INTO t1 VALUES($i, $t) }
306  }
307  execsql COMMIT
308} {}
309do_eqp_test analyze3-2.2 {
310  SELECT count(a) FROM t1 WHERE b LIKE 'a%'
311} {SEARCH TABLE t1 USING INDEX i1 (b>? AND b<?)}
312do_eqp_test analyze3-2.3 {
313  SELECT count(a) FROM t1 WHERE b LIKE '%a'
314} {SCAN TABLE t1}
315
316# Return the first argument if like_match_blobs is true (the default)
317# or the second argument if not
318#
319proc ilmb {a b} {
320  ifcapable like_match_blobs {return $a}
321  return $b
322}
323
324do_test analyze3-2.4 {
325  sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE 'a%' }
326} [list [ilmb 102 101] 0 100]
327do_test analyze3-2.5 {
328  sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE '%a' }
329} {999 999 100}
330
331do_test analyze3-2.6 {
332  set like "a%"
333  sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
334} [list [ilmb 102 101] 0 100]
335do_test analyze3-2.7 {
336  set like "%a"
337  sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
338} {999 999 100}
339do_test analyze3-2.8 {
340  set like "a"
341  sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
342} [list [ilmb 102 101] 0 0]
343do_test analyze3-2.9 {
344  set like "ab"
345  sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
346} [list [ilmb 12 11] 0 0]
347do_test analyze3-2.10 {
348  set like "abc"
349  sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
350} [list [ilmb 3 2] 0 1]
351do_test analyze3-2.11 {
352  set like "a_c"
353  sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
354} [list [ilmb 102 101] 0 10]
355
356
357#-------------------------------------------------------------------------
358# This block of tests checks that statements are correctly marked as
359# expired when the values bound to any parameters that may affect the
360# query plan are modified.
361#
362drop_all_tables
363db auth auth
364proc auth {args} {
365  set ::auth 1
366  return SQLITE_OK
367}
368
369do_test analyze3-3.1 {
370  execsql {
371    BEGIN;
372    CREATE TABLE t1(a, b, c);
373    CREATE INDEX i1 ON t1(b);
374  }
375  for {set i 0} {$i < 100} {incr i} {
376    execsql { INSERT INTO t1 VALUES($i, $i, $i) }
377  }
378  execsql COMMIT
379  execsql ANALYZE
380} {}
381do_test analyze3-3.2.1 {
382  set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE b>?" -1 dummy]
383  sqlite3_expired $S
384} {0}
385do_test analyze3-3.2.2 {
386  sqlite3_bind_text $S 1 "abc" 3
387  sqlite3_expired $S
388} {1}
389do_test analyze3-3.2.4 {
390  sqlite3_finalize $S
391} {SQLITE_OK}
392
393do_test analyze3-3.2.5 {
394  set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE b=?" -1 dummy]
395  sqlite3_expired $S
396} {0}
397do_test analyze3-3.2.6 {
398  sqlite3_bind_text $S 1 "abc" 3
399  sqlite3_expired $S
400} {1}
401do_test analyze3-3.2.7 {
402  sqlite3_finalize $S
403} {SQLITE_OK}
404
405do_test analyze3-3.4.1 {
406  set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE a=? AND b>?" -1 dummy]
407  sqlite3_expired $S
408} {0}
409do_test analyze3-3.4.2 {
410  sqlite3_bind_text $S 1 "abc" 3
411  sqlite3_expired $S
412} {0}
413do_test analyze3-3.4.3 {
414  sqlite3_bind_text $S 2 "def" 3
415  sqlite3_expired $S
416} {1}
417do_test analyze3-3.4.4 {
418  sqlite3_bind_text $S 2 "ghi" 3
419  sqlite3_expired $S
420} {1}
421do_test analyze3-3.4.5 {
422  sqlite3_expired $S
423} {1}
424do_test analyze3-3.4.6 {
425  sqlite3_finalize $S
426} {SQLITE_OK}
427
428do_test analyze3-3.5.1 {
429  set S [sqlite3_prepare_v2 db {
430    SELECT * FROM t1 WHERE a IN (
431      ?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10,
432      ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20,
433      ?21, ?22, ?23, ?24, ?25, ?26, ?27, ?28, ?29, ?30, ?31
434    ) AND b>?32;
435  } -1 dummy]
436  sqlite3_expired $S
437} {0}
438do_test analyze3-3.5.2 {
439  sqlite3_bind_text $S 31 "abc" 3
440  sqlite3_expired $S
441} {0}
442do_test analyze3-3.5.3 {
443  sqlite3_bind_text $S 32 "def" 3
444  sqlite3_expired $S
445} {1}
446do_test analyze3-3.5.5 {
447  sqlite3_finalize $S
448} {SQLITE_OK}
449
450do_test analyze3-3.6.1 {
451  set S [sqlite3_prepare_v2 db {
452    SELECT * FROM t1 WHERE a IN (
453      ?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10,
454      ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20,
455      ?21, ?22, ?23, ?24, ?25, ?26, ?27, ?28, ?29, ?30, ?31, ?32
456    ) AND b>?33;
457  } -1 dummy]
458  sqlite3_expired $S
459} {0}
460do_test analyze3-3.6.2 {
461  sqlite3_bind_text $S 32 "abc" 3
462  sqlite3_expired $S
463} {1}
464do_test analyze3-3.6.3 {
465  sqlite3_bind_text $S 33 "def" 3
466  sqlite3_expired $S
467} {1}
468do_test analyze3-3.6.5 {
469  sqlite3_finalize $S
470} {SQLITE_OK}
471
472do_test analyze3-3.7.1 {
473  set S [sqlite3_prepare_v2 db {
474    SELECT * FROM t1 WHERE a IN (
475      ?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?33,
476      ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20,
477      ?21, ?22, ?23, ?24, ?25, ?26, ?27, ?28, ?29, ?30, ?31, ?32
478    ) AND b>?10;
479  } -1 dummy]
480  sqlite3_expired $S
481} {0}
482do_test analyze3-3.7.2 {
483  sqlite3_bind_text $S 32 "abc" 3
484  sqlite3_expired $S
485} {0}
486do_test analyze3-3.7.3 {
487  sqlite3_bind_text $S 33 "def" 3
488  sqlite3_expired $S
489} {0}
490do_test analyze3-3.7.4 {
491  sqlite3_bind_text $S 10 "def" 3
492  sqlite3_expired $S
493} {1}
494do_test analyze3-3.7.6 {
495  sqlite3_finalize $S
496} {SQLITE_OK}
497
498do_test analyze3-3.8.1 {
499  execsql {
500    CREATE TABLE t4(x, y TEXT COLLATE NOCASE);
501    CREATE INDEX i4 ON t4(y);
502  }
503} {}
504do_test analyze3-3.8.2 {
505  set S [sqlite3_prepare_v2 db {
506    SELECT * FROM t4 WHERE x != ? AND y LIKE ?
507  } -1 dummy]
508  sqlite3_expired $S
509} {0}
510do_test analyze3-3.8.3 {
511  sqlite3_bind_text $S 1 "abc" 3
512  sqlite3_expired $S
513} {0}
514do_test analyze3-3.8.4 {
515  sqlite3_bind_text $S 2 "def" 3
516  sqlite3_expired $S
517} {1}
518do_test analyze3-3.8.7 {
519  sqlite3_bind_text $S 2 "ghi%" 4
520  sqlite3_expired $S
521} {1}
522do_test analyze3-3.8.8 {
523  sqlite3_expired $S
524} {1}
525do_test analyze3-3.8.9 {
526  sqlite3_bind_text $S 2 "ghi%def" 7
527  sqlite3_expired $S
528} {1}
529do_test analyze3-3.8.10 {
530  sqlite3_expired $S
531} {1}
532do_test analyze3-3.8.11 {
533  sqlite3_bind_text $S 2 "%ab" 3
534  sqlite3_expired $S
535} {1}
536do_test analyze3-3.8.12 {
537  sqlite3_expired $S
538} {1}
539do_test analyze3-3.8.12 {
540  sqlite3_bind_text $S 2 "%de" 3
541  sqlite3_expired $S
542} {1}
543do_test analyze3-3.8.13 {
544  sqlite3_expired $S
545} {1}
546do_test analyze3-3.8.14 {
547  sqlite3_finalize $S
548} {SQLITE_OK}
549
550#-------------------------------------------------------------------------
551# These tests check that errors encountered while repreparing an SQL
552# statement within sqlite3Reprepare() are handled correctly.
553#
554
555# Check a schema error.
556#
557do_test analyze3-4.1.1 {
558  set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE a=? AND b>?" -1 dummy]
559  sqlite3_step $S
560} {SQLITE_DONE}
561do_test analyze3-4.1.2 {
562  sqlite3_reset $S
563  sqlite3_bind_text $S 2 "abc" 3
564  execsql { DROP TABLE t1 }
565  sqlite3_step $S
566} {SQLITE_ERROR}
567do_test analyze3-4.1.3 {
568  sqlite3_finalize $S
569} {SQLITE_ERROR}
570
571# Check an authorization error.
572#
573do_test analyze3-4.2.1 {
574  execsql {
575    BEGIN;
576    CREATE TABLE t1(a, b, c);
577    CREATE INDEX i1 ON t1(b);
578  }
579  for {set i 0} {$i < 100} {incr i} {
580    execsql { INSERT INTO t1 VALUES($i, $i, $i) }
581  }
582  execsql COMMIT
583  execsql ANALYZE
584  set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE a=? AND b>?" -1 dummy]
585  sqlite3_step $S
586} {SQLITE_DONE}
587db auth auth
588proc auth {args} {
589  if {[lindex $args 0] == "SQLITE_READ"} {return SQLITE_DENY}
590  return SQLITE_OK
591}
592do_test analyze3-4.2.2 {
593  sqlite3_reset $S
594  sqlite3_bind_text $S 2 "abc" 3
595  sqlite3_step $S
596} {SQLITE_AUTH}
597do_test analyze3-4.2.4 {
598  sqlite3_finalize $S
599} {SQLITE_AUTH}
600
601# Check the effect of an authorization error that occurs in a re-prepare
602# performed by sqlite3_step() is the same as one that occurs within
603# sqlite3Reprepare().
604#
605do_test analyze3-4.3.1 {
606  db auth {}
607  set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE a=? AND b>?" -1 dummy]
608  execsql { CREATE TABLE t2(d, e, f) }
609  db auth auth
610  sqlite3_step $S
611} {SQLITE_AUTH}
612do_test analyze3-4.3.2 {
613  sqlite3_finalize $S
614} {SQLITE_AUTH}
615db auth {}
616
617#-------------------------------------------------------------------------
618# Test that modifying bound variables using the clear_bindings() or
619# transfer_bindings() APIs works.
620#
621#   analyze3-5.1.*: sqlite3_clear_bindings()
622#   analyze3-5.2.*: sqlite3_transfer_bindings()
623#
624do_test analyze3-5.1.1 {
625  drop_all_tables
626  execsql {
627    CREATE TABLE t1(x TEXT COLLATE NOCASE);
628    CREATE INDEX i1 ON t1(x);
629    INSERT INTO t1 VALUES('aaa');
630    INSERT INTO t1 VALUES('abb');
631    INSERT INTO t1 VALUES('acc');
632    INSERT INTO t1 VALUES('baa');
633    INSERT INTO t1 VALUES('bbb');
634    INSERT INTO t1 VALUES('bcc');
635  }
636
637  set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE x LIKE ?" -1 dummy]
638  sqlite3_bind_text $S 1 "a%" 2
639  set R [list]
640  while { "SQLITE_ROW" == [sqlite3_step $S] } {
641    lappend R [sqlite3_column_text $S 0]
642  }
643  concat [sqlite3_reset $S] $R
644} {SQLITE_OK aaa abb acc}
645do_test analyze3-5.1.2 {
646  sqlite3_clear_bindings $S
647  set R [list]
648  while { "SQLITE_ROW" == [sqlite3_step $S] } {
649    lappend R [sqlite3_column_text $S 0]
650  }
651  concat [sqlite3_reset $S] $R
652} {SQLITE_OK}
653do_test analyze3-5.1.3 {
654  sqlite3_finalize $S
655} {SQLITE_OK}
656
657do_test analyze3-5.1.1 {
658  set S1 [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE x LIKE ?" -1 dummy]
659  sqlite3_bind_text $S1 1 "b%" 2
660  set R [list]
661  while { "SQLITE_ROW" == [sqlite3_step $S1] } {
662    lappend R [sqlite3_column_text $S1 0]
663  }
664  concat [sqlite3_reset $S1] $R
665} {SQLITE_OK baa bbb bcc}
666
667do_test analyze3-5.1.2 {
668  set S2 [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE x = ?" -1 dummy]
669  sqlite3_bind_text $S2 1 "a%" 2
670  sqlite3_transfer_bindings $S2 $S1
671  set R [list]
672  while { "SQLITE_ROW" == [sqlite3_step $S1] } {
673    lappend R [sqlite3_column_text $S1 0]
674  }
675  concat [sqlite3_reset $S1] $R
676} {SQLITE_OK aaa abb acc}
677do_test analyze3-5.1.3 {
678  sqlite3_finalize $S2
679  sqlite3_finalize $S1
680} {SQLITE_OK}
681
682#-------------------------------------------------------------------------
683
684do_test analyze3-6.1 {
685  execsql { DROP TABLE IF EXISTS t1 }
686  execsql BEGIN
687  execsql { CREATE TABLE t1(a, b, c) }
688  for {set i 0} {$i < 1000} {incr i} {
689    execsql "INSERT INTO t1 VALUES([expr $i/100], 'x', [expr $i/10])"
690  }
691  execsql {
692    CREATE INDEX i1 ON t1(a, b);
693    CREATE INDEX i2 ON t1(c);
694  }
695  execsql COMMIT
696  execsql ANALYZE
697} {}
698
699do_eqp_test analyze3-6-3 {
700  SELECT * FROM t1 WHERE a = 5 AND c = 13;
701} {SEARCH TABLE t1 USING INDEX i2 (c=?)}
702
703do_eqp_test analyze3-6-2 {
704  SELECT * FROM t1 WHERE a = 5 AND b > 'w' AND c = 13;
705} {SEARCH TABLE t1 USING INDEX i2 (c=?)}
706
707#-----------------------------------------------------------------------------
708# 2015-04-20.
709# Memory leak in sqlite3Stat4ProbeFree().  (Discovered while fuzzing.)
710#
711do_execsql_test analyze-7.1 {
712  DROP TABLE IF EXISTS t1;
713  CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
714  INSERT INTO t1 VALUES(1,1,'0000');
715  CREATE INDEX t0b ON t1(b);
716  ANALYZE;
717  SELECT c FROM t1 WHERE b=3 AND a BETWEEN 30 AND hex(1);
718} {}
719
720# At one point duplicate stat1 entries were causing a memory leak.
721#
722reset_db
723do_execsql_test 7.2 {
724  CREATE TABLE t1(a,b,c);
725  CREATE INDEX t1a ON t1(a);
726  ANALYZE;
727  SELECT * FROM sqlite_stat1;
728  INSERT INTO sqlite_stat1(tbl,idx,stat) VALUES('t1','t1a','12000');
729  INSERT INTO sqlite_stat1(tbl,idx,stat) VALUES('t1','t1a','12000');
730  ANALYZE sqlite_master;
731}
732
733finish_test
734