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