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