Prevent deep recursions on nested COLLATE operators.
[sqlite.git] / test / analyze3.test
blob3e721a087713e0c0223e61e5ea97d2dbc57f73b1
1 # 2009 August 06
3 # The author disclaims copyright to this source code.  In place of
4 # a legal notice, here is a blessing:
6 #    May you do good and not evil.
7 #    May you find forgiveness for yourself and forgive others.
8 #    May you share freely, never taking more than you give.
10 #***********************************************************************
12 # This file implements regression tests for SQLite library. This file 
13 # implements tests for range and LIKE constraints that use bound variables
14 # instead of literal constant arguments.
17 set testdir [file dirname $argv0]
18 source $testdir/tester.tcl
19 set testprefix analyze3
21 ifcapable !stat4&&!stat3 {
22   finish_test
23   return
26 #----------------------------------------------------------------------
27 # Test Organization:
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.
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.
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.
41 # analyze3-4.*: Test that SQL or authorization callback errors occuring
42 #               within sqlite3Reprepare() are handled correctly.
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.
50 # analyze3-7.*: Test that some memory leaks discovered by fuzz testing 
51 #               have been fixed.
54 proc getvar {varname} { uplevel #0 set $varname }
55 db function var getvar
57 proc eqp {sql {db db}} {
58   uplevel execsql [list "EXPLAIN QUERY PLAN $sql"] $db
61 proc sf_execsql {sql {db db}} {
62   set ::sqlite_search_count 0
63   set r [uplevel [list execsql $sql $db]]
65   concat $::sqlite_search_count [$db status step] $r
68 #-------------------------------------------------------------------------
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.
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.
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.
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".
89 do_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   }
103   ifcapable stat4 {
104     execsql { SELECT count(*)>0 FROM sqlite_stat4; }
105   } else {
106     execsql { SELECT count(*)>0 FROM sqlite_stat3; }
107   }
108 } {1}
110 do_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}
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.
119 do_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<?)}}
122 do_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}}
126 # 2017-06-26:  Verify that the SQLITE_DBCONFIG_ENABLE_QPSG setting disables
127 # the use of bound parameters by STAT4
129 db cache flush
130 unset -nocomplain l
131 unset -nocomplain u
132 do_eqp_test analyze3-1.1.3.100 {
133   SELECT sum(y) FROM t1 WHERE x>$l AND x<$u
134 } {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?)}}
135 set l 200
136 set u 300
137 do_eqp_test analyze3-1.1.3.101 {
138   SELECT sum(y) FROM t1 WHERE x>$l AND x<$u
139 } {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?)}}
140 set l 0
141 set u 1100
142 do_eqp_test analyze3-1.1.3.102 {
143   SELECT sum(y) FROM t1 WHERE x>$l AND x<$u
144 } {0 0 0 {SCAN TABLE t1}}
145 db cache flush
146 sqlite3_db_config db ENABLE_QPSG 1
147 do_eqp_test analyze3-1.1.3.103 {
148   SELECT sum(y) FROM t1 WHERE x>$l AND x<$u
149 } {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?)}}
150 db cache flush
151 sqlite3_db_config db ENABLE_QPSG 0
152 do_eqp_test analyze3-1.1.3.104 {
153   SELECT sum(y) FROM t1 WHERE x>$l AND x<$u
154 } {0 0 0 {SCAN TABLE t1}}
156 do_test analyze3-1.1.4 {
157   sf_execsql { SELECT sum(y) FROM t1 WHERE x>200 AND x<300 }
158 } {199 0 14850}
159 do_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}
164 do_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}
169 do_test analyze3-1.1.7 {
170   sf_execsql { SELECT sum(y) FROM t1 WHERE x>0 AND x<1100 }
171 } {999 999 499500}
172 do_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}
177 do_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}
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.
188 do_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 } {}
198 do_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}
202 do_eqp_test analyze3-1.2.2 {
203   SELECT sum(y) FROM t2 WHERE x>1 AND x<2
204 } {0 0 0 {SEARCH TABLE t2 USING INDEX i2 (x>? AND x<?)}}
205 do_eqp_test analyze3-1.2.3 {
206   SELECT sum(y) FROM t2 WHERE x>0 AND x<99
207 } {0 0 0 {SCAN TABLE t2}}
209 do_test analyze3-1.2.4 {
210   sf_execsql { SELECT sum(y) FROM t2 WHERE x>12 AND x<20 }
211 } {161 0 4760}
212 do_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}
217 do_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}
222 do_test analyze3-1.2.7 {
223   sf_execsql { SELECT sum(y) FROM t2 WHERE x>0 AND x<99 }
224 } {999 999 490555}
225 do_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}
230 do_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}
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.
240 do_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 } {}
250 do_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}
254 do_eqp_test analyze3-1.3.2 {
255   SELECT sum(y) FROM t3 WHERE x>200 AND x<300
256 } {0 0 0 {SEARCH TABLE t3 USING INDEX i3 (x>? AND x<?)}}
257 do_eqp_test analyze3-1.3.3 {
258   SELECT sum(y) FROM t3 WHERE x>0 AND x<1100
259 } {0 0 0 {SCAN TABLE t3}}
261 do_test analyze3-1.3.4 {
262   sf_execsql { SELECT sum(y) FROM t3 WHERE x>200 AND x<300 }
263 } {199 0 14850}
264 do_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}
269 do_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}
274 do_test analyze3-1.3.7 {
275   sf_execsql { SELECT sum(y) FROM t3 WHERE x>0 AND x<1100 }
276 } {999 999 499500}
277 do_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}
282 do_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}
288 #-------------------------------------------------------------------------
289 # Test that the values of bound SQL variables may be used for the LIKE
290 # optimization.
292 drop_all_tables
293 do_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 } {}
309 do_eqp_test analyze3-2.2 {
310   SELECT count(a) FROM t1 WHERE b LIKE 'a%'
311 } {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (b>? AND b<?)}}
312 do_eqp_test analyze3-2.3 {
313   SELECT count(a) FROM t1 WHERE b LIKE '%a'
314 } {0 0 0 {SCAN TABLE t1}}
316 # Return the first argument if like_match_blobs is true (the default)
317 # or the second argument if not
319 proc ilmb {a b} {
320   ifcapable like_match_blobs {return $a}
321   return $b
324 do_test analyze3-2.4 {
325   sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE 'a%' }
326 } [list [ilmb 102 101] 0 100]
327 do_test analyze3-2.5 {
328   sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE '%a' }
329 } {999 999 100}
331 do_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]
335 do_test analyze3-2.7 {
336   set like "%a"
337   sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
338 } {999 999 100}
339 do_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]
343 do_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]
347 do_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]
351 do_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]
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.
362 drop_all_tables
363 db auth auth
364 proc auth {args} {
365   set ::auth 1
366   return SQLITE_OK
369 do_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 } {}
381 do_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}
385 do_test analyze3-3.2.2 {
386   sqlite3_bind_text $S 1 "abc" 3
387   sqlite3_expired $S
388 } {1}
389 do_test analyze3-3.2.4 {
390   sqlite3_finalize $S
391 } {SQLITE_OK}
393 do_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}
397 do_test analyze3-3.2.6 {
398   sqlite3_bind_text $S 1 "abc" 3
399   sqlite3_expired $S
400 } {1}
401 do_test analyze3-3.2.7 {
402   sqlite3_finalize $S
403 } {SQLITE_OK}
405 do_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}
409 do_test analyze3-3.4.2 {
410   sqlite3_bind_text $S 1 "abc" 3
411   sqlite3_expired $S
412 } {0}
413 do_test analyze3-3.4.3 {
414   sqlite3_bind_text $S 2 "def" 3
415   sqlite3_expired $S
416 } {1}
417 do_test analyze3-3.4.4 {
418   sqlite3_bind_text $S 2 "ghi" 3
419   sqlite3_expired $S
420 } {1}
421 do_test analyze3-3.4.5 {
422   sqlite3_expired $S
423 } {1}
424 do_test analyze3-3.4.6 {
425   sqlite3_finalize $S
426 } {SQLITE_OK}
428 do_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}
438 do_test analyze3-3.5.2 {
439   sqlite3_bind_text $S 31 "abc" 3
440   sqlite3_expired $S
441 } {0}
442 do_test analyze3-3.5.3 {
443   sqlite3_bind_text $S 32 "def" 3
444   sqlite3_expired $S
445 } {1}
446 do_test analyze3-3.5.5 {
447   sqlite3_finalize $S
448 } {SQLITE_OK}
450 do_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}
460 do_test analyze3-3.6.2 {
461   sqlite3_bind_text $S 32 "abc" 3
462   sqlite3_expired $S
463 } {1}
464 do_test analyze3-3.6.3 {
465   sqlite3_bind_text $S 33 "def" 3
466   sqlite3_expired $S
467 } {1}
468 do_test analyze3-3.6.5 {
469   sqlite3_finalize $S
470 } {SQLITE_OK}
472 do_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}
482 do_test analyze3-3.7.2 {
483   sqlite3_bind_text $S 32 "abc" 3
484   sqlite3_expired $S
485 } {0}
486 do_test analyze3-3.7.3 {
487   sqlite3_bind_text $S 33 "def" 3
488   sqlite3_expired $S
489 } {0}
490 do_test analyze3-3.7.4 {
491   sqlite3_bind_text $S 10 "def" 3
492   sqlite3_expired $S
493 } {1}
494 do_test analyze3-3.7.6 {
495   sqlite3_finalize $S
496 } {SQLITE_OK}
498 do_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 } {}
504 do_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}
510 do_test analyze3-3.8.3 {
511   sqlite3_bind_text $S 1 "abc" 3
512   sqlite3_expired $S
513 } {0}
514 do_test analyze3-3.8.4 {
515   sqlite3_bind_text $S 2 "def" 3
516   sqlite3_expired $S
517 } {1}
518 do_test analyze3-3.8.7 {
519   sqlite3_bind_text $S 2 "ghi%" 4
520   sqlite3_expired $S
521 } {1}
522 do_test analyze3-3.8.8 {
523   sqlite3_expired $S
524 } {1}
525 do_test analyze3-3.8.9 {
526   sqlite3_bind_text $S 2 "ghi%def" 7
527   sqlite3_expired $S
528 } {1}
529 do_test analyze3-3.8.10 {
530   sqlite3_expired $S
531 } {1}
532 do_test analyze3-3.8.11 {
533   sqlite3_bind_text $S 2 "%ab" 3
534   sqlite3_expired $S
535 } {1}
536 do_test analyze3-3.8.12 {
537   sqlite3_expired $S
538 } {1}
539 do_test analyze3-3.8.12 {
540   sqlite3_bind_text $S 2 "%de" 3
541   sqlite3_expired $S
542 } {1}
543 do_test analyze3-3.8.13 {
544   sqlite3_expired $S
545 } {1}
546 do_test analyze3-3.8.14 {
547   sqlite3_finalize $S
548 } {SQLITE_OK}
550 #-------------------------------------------------------------------------
551 # These tests check that errors encountered while repreparing an SQL
552 # statement within sqlite3Reprepare() are handled correctly.
555 # Check a schema error.
557 do_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}
561 do_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}
567 do_test analyze3-4.1.3 {
568   sqlite3_finalize $S
569 } {SQLITE_ERROR}
571 # Check an authorization error.
573 do_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}
587 db auth auth
588 proc auth {args} {
589   if {[lindex $args 0] == "SQLITE_READ"} {return SQLITE_DENY}
590   return SQLITE_OK
592 do_test analyze3-4.2.2 {
593   sqlite3_reset $S
594   sqlite3_bind_text $S 2 "abc" 3
595   sqlite3_step $S
596 } {SQLITE_AUTH}
597 do_test analyze3-4.2.4 {
598   sqlite3_finalize $S
599 } {SQLITE_AUTH}
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().
605 do_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}
612 do_test analyze3-4.3.2 {
613   sqlite3_finalize $S
614 } {SQLITE_AUTH}
615 db auth {}
617 #-------------------------------------------------------------------------
618 # Test that modifying bound variables using the clear_bindings() or
619 # transfer_bindings() APIs works.
621 #   analyze3-5.1.*: sqlite3_clear_bindings()
622 #   analyze3-5.2.*: sqlite3_transfer_bindings()
624 do_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   }
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}
645 do_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}
653 do_test analyze3-5.1.3 {
654   sqlite3_finalize $S
655 } {SQLITE_OK}
657 do_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}
667 do_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}
677 do_test analyze3-5.1.3 {
678   sqlite3_finalize $S2
679   sqlite3_finalize $S1
680 } {SQLITE_OK}
682 #-------------------------------------------------------------------------
684 do_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 } {}
699 do_eqp_test analyze3-6-3 {
700   SELECT * FROM t1 WHERE a = 5 AND c = 13;
701 } {0 0 0 {SEARCH TABLE t1 USING INDEX i2 (c=?)}}
703 do_eqp_test analyze3-6-2 {
704   SELECT * FROM t1 WHERE a = 5 AND b > 'w' AND c = 13;
705 } {0 0 0 {SEARCH TABLE t1 USING INDEX i2 (c=?)}}
707 #-----------------------------------------------------------------------------
708 # 2015-04-20.
709 # Memory leak in sqlite3Stat4ProbeFree().  (Discovered while fuzzing.)
711 do_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 } {}
720 # At one point duplicate stat1 entries were causing a memory leak.
722 reset_db
723 do_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;
733 finish_test