1937d0deaSdan# 2009 August 06 2937d0deaSdan# 3937d0deaSdan# The author disclaims copyright to this source code. In place of 4937d0deaSdan# a legal notice, here is a blessing: 5937d0deaSdan# 6937d0deaSdan# May you do good and not evil. 7937d0deaSdan# May you find forgiveness for yourself and forgive others. 8937d0deaSdan# May you share freely, never taking more than you give. 9937d0deaSdan# 10937d0deaSdan#*********************************************************************** 11937d0deaSdan# 12937d0deaSdan# This file implements regression tests for SQLite library. This file 131d2ce4f8Sdan# implements tests for range and LIKE constraints that use bound variables 141d2ce4f8Sdan# instead of literal constant arguments. 15937d0deaSdan# 16937d0deaSdan 17937d0deaSdanset testdir [file dirname $argv0] 18937d0deaSdansource $testdir/tester.tcl 194eed0534Sdanset testprefix analyze3 20937d0deaSdan 21175b8f06Sdrhifcapable !stat4 { 22937d0deaSdan finish_test 23937d0deaSdan return 24937d0deaSdan} 25937d0deaSdan 26ca3ee7e1Sdan# This test cannot be run with the sqlite3_prepare() permutation, as it 27ca3ee7e1Sdan# tests that stat4 data can be used to influence the plans of queries 28ca3ee7e1Sdan# based on bound variable values. And this is not possible when using 29ca3ee7e1Sdan# sqlite3_prepare() - as queries cannot be internally re-prepared after 30ca3ee7e1Sdan# binding values are available. 31ca3ee7e1Sdanif {[permutation]=="prepare"} { 32ca3ee7e1Sdan finish_test 33ca3ee7e1Sdan return 34ca3ee7e1Sdan} 35ca3ee7e1Sdan 36937d0deaSdan#---------------------------------------------------------------------- 37937d0deaSdan# Test Organization: 38937d0deaSdan# 39937d0deaSdan# analyze3-1.*: Test that the values of bound parameters are considered 40937d0deaSdan# in the same way as constants when planning queries that 41937d0deaSdan# use range constraints. 42937d0deaSdan# 43937d0deaSdan# analyze3-2.*: Test that the values of bound parameters are considered 44937d0deaSdan# in the same way as constants when planning queries that 45937d0deaSdan# use LIKE expressions in the WHERE clause. 46937d0deaSdan# 471d2ce4f8Sdan# analyze3-3.*: Test that binding to a variable does not invalidate the 481d2ce4f8Sdan# query plan when there is no way in which replanning the 491d2ce4f8Sdan# query may produce a superior outcome. 50937d0deaSdan# 51937d0deaSdan# analyze3-4.*: Test that SQL or authorization callback errors occuring 521d2ce4f8Sdan# within sqlite3Reprepare() are handled correctly. 53937d0deaSdan# 54c94b8595Sdan# analyze3-5.*: Check that the query plans of applicable statements are 55c94b8595Sdan# invalidated if the values of SQL parameter are modified 56c94b8595Sdan# using the clear_bindings() or transfer_bindings() APIs. 57c94b8595Sdan# 582acbc0ddSdan# analyze3-6.*: Test that the problem fixed by commit [127a5b776d] is fixed. 592acbc0ddSdan# 604eed0534Sdan# analyze3-7.*: Test that some memory leaks discovered by fuzz testing 614eed0534Sdan# have been fixed. 624eed0534Sdan# 63937d0deaSdan 64937d0deaSdanproc getvar {varname} { uplevel #0 set $varname } 65937d0deaSdandb function var getvar 66937d0deaSdan 67937d0deaSdanproc eqp {sql {db db}} { 68937d0deaSdan uplevel execsql [list "EXPLAIN QUERY PLAN $sql"] $db 69937d0deaSdan} 70937d0deaSdan 71937d0deaSdanproc sf_execsql {sql {db db}} { 72937d0deaSdan set ::sqlite_search_count 0 73937d0deaSdan set r [uplevel [list execsql $sql $db]] 74937d0deaSdan 75937d0deaSdan concat $::sqlite_search_count [$db status step] $r 76937d0deaSdan} 77937d0deaSdan 78937d0deaSdan#------------------------------------------------------------------------- 79937d0deaSdan# 80937d0deaSdan# analyze3-1.1.1: 81937d0deaSdan# Create a table with two columns. Populate the first column (affinity 82937d0deaSdan# INTEGER) with integer values from 100 to 1100. Create an index on this 83937d0deaSdan# column. ANALYZE the table. 84937d0deaSdan# 85937d0deaSdan# analyze3-1.1.2 - 3.1.3 86937d0deaSdan# Show that there are two possible plans for querying the table with 87937d0deaSdan# a range constraint on the indexed column - "full table scan" or "use 88937d0deaSdan# the index". When the range is specified using literal values, SQLite 8974e7c8f5Sdrh# is able to pick the best plan based on the samples in sqlite_stat3. 90937d0deaSdan# 91937d0deaSdan# analyze3-1.1.4 - 3.1.9 92937d0deaSdan# Show that using SQL variables produces the same results as using 931d2ce4f8Sdan# literal values to constrain the range scan. 94937d0deaSdan# 95937d0deaSdan# These tests also check that the compiler code considers column 96937d0deaSdan# affinities when estimating the number of rows scanned by the "use 97937d0deaSdan# index strategy". 98937d0deaSdan# 99937d0deaSdando_test analyze3-1.1.1 { 100937d0deaSdan execsql { 101937d0deaSdan BEGIN; 102937d0deaSdan CREATE TABLE t1(x INTEGER, y); 103937d0deaSdan CREATE INDEX i1 ON t1(x); 104937d0deaSdan } 105937d0deaSdan for {set i 0} {$i < 1000} {incr i} { 106937d0deaSdan execsql { INSERT INTO t1 VALUES($i+100, $i) } 107937d0deaSdan } 108937d0deaSdan execsql { 109937d0deaSdan COMMIT; 110937d0deaSdan ANALYZE; 111937d0deaSdan } 1128ad169abSdan 1138ad169abSdan execsql { SELECT count(*)>0 FROM sqlite_stat4; } 114dd6e1f19Sdan} {1} 115937d0deaSdan 116b51926e6Sdando_execsql_test analyze3-1.1.x { 117b51926e6Sdan SELECT count(*) FROM t1 WHERE x>200 AND x<300; 118b51926e6Sdan SELECT count(*) FROM t1 WHERE x>0 AND x<1100; 119b51926e6Sdan} {99 1000} 120b51926e6Sdan 121b51926e6Sdan# The first of the following two SELECT statements visits 99 rows. So 122b51926e6Sdan# it is better to use the index. But the second visits every row in 123b51926e6Sdan# the table (1000 in total) so it is better to do a full-table scan. 124b51926e6Sdan# 1253985479bSdando_eqp_test analyze3-1.1.2 { 1263985479bSdan SELECT sum(y) FROM t1 WHERE x>200 AND x<300 127*8210233cSdrh} {SEARCH t1 USING INDEX i1 (x>? AND x<?)} 1283985479bSdando_eqp_test analyze3-1.1.3 { 1293985479bSdan SELECT sum(y) FROM t1 WHERE x>0 AND x<1100 130*8210233cSdrh} {SCAN t1} 131937d0deaSdan 132169dd928Sdrh# 2017-06-26: Verify that the SQLITE_DBCONFIG_ENABLE_QPSG setting disables 133169dd928Sdrh# the use of bound parameters by STAT4 134169dd928Sdrh# 135169dd928Sdrhdb cache flush 136169dd928Sdrhunset -nocomplain l 137169dd928Sdrhunset -nocomplain u 138169dd928Sdrhdo_eqp_test analyze3-1.1.3.100 { 139169dd928Sdrh SELECT sum(y) FROM t1 WHERE x>$l AND x<$u 140*8210233cSdrh} {SEARCH t1 USING INDEX i1 (x>? AND x<?)} 141169dd928Sdrhset l 200 142169dd928Sdrhset u 300 143169dd928Sdrhdo_eqp_test analyze3-1.1.3.101 { 144169dd928Sdrh SELECT sum(y) FROM t1 WHERE x>$l AND x<$u 145*8210233cSdrh} {SEARCH t1 USING INDEX i1 (x>? AND x<?)} 146169dd928Sdrhset l 0 147169dd928Sdrhset u 1100 148169dd928Sdrhdo_eqp_test analyze3-1.1.3.102 { 149169dd928Sdrh SELECT sum(y) FROM t1 WHERE x>$l AND x<$u 150*8210233cSdrh} {SCAN t1} 151169dd928Sdrhdb cache flush 152169dd928Sdrhsqlite3_db_config db ENABLE_QPSG 1 153169dd928Sdrhdo_eqp_test analyze3-1.1.3.103 { 154169dd928Sdrh SELECT sum(y) FROM t1 WHERE x>$l AND x<$u 155*8210233cSdrh} {SEARCH t1 USING INDEX i1 (x>? AND x<?)} 156169dd928Sdrhdb cache flush 157169dd928Sdrhsqlite3_db_config db ENABLE_QPSG 0 158169dd928Sdrhdo_eqp_test analyze3-1.1.3.104 { 159169dd928Sdrh SELECT sum(y) FROM t1 WHERE x>$l AND x<$u 160*8210233cSdrh} {SCAN t1} 161169dd928Sdrh 162937d0deaSdando_test analyze3-1.1.4 { 163937d0deaSdan sf_execsql { SELECT sum(y) FROM t1 WHERE x>200 AND x<300 } 164937d0deaSdan} {199 0 14850} 165937d0deaSdando_test analyze3-1.1.5 { 166937d0deaSdan set l [string range "200" 0 end] 167937d0deaSdan set u [string range "300" 0 end] 168937d0deaSdan sf_execsql { SELECT sum(y) FROM t1 WHERE x>$l AND x<$u } 169937d0deaSdan} {199 0 14850} 170937d0deaSdando_test analyze3-1.1.6 { 171937d0deaSdan set l [expr int(200)] 172937d0deaSdan set u [expr int(300)] 173937d0deaSdan sf_execsql { SELECT sum(y) FROM t1 WHERE x>$l AND x<$u } 174937d0deaSdan} {199 0 14850} 175937d0deaSdando_test analyze3-1.1.7 { 176937d0deaSdan sf_execsql { SELECT sum(y) FROM t1 WHERE x>0 AND x<1100 } 177b51926e6Sdan} {999 999 499500} 178937d0deaSdando_test analyze3-1.1.8 { 179937d0deaSdan set l [string range "0" 0 end] 180937d0deaSdan set u [string range "1100" 0 end] 181937d0deaSdan sf_execsql { SELECT sum(y) FROM t1 WHERE x>$l AND x<$u } 182b51926e6Sdan} {999 999 499500} 183937d0deaSdando_test analyze3-1.1.9 { 184937d0deaSdan set l [expr int(0)] 185937d0deaSdan set u [expr int(1100)] 186937d0deaSdan sf_execsql { SELECT sum(y) FROM t1 WHERE x>$l AND x<$u } 187b51926e6Sdan} {999 999 499500} 188937d0deaSdan 189937d0deaSdan 190937d0deaSdan# The following tests are similar to the block above. The difference is 191937d0deaSdan# that the indexed column has TEXT affinity in this case. In the tests 192937d0deaSdan# above the affinity is INTEGER. 193937d0deaSdan# 194937d0deaSdando_test analyze3-1.2.1 { 195937d0deaSdan execsql { 196937d0deaSdan BEGIN; 197937d0deaSdan CREATE TABLE t2(x TEXT, y); 198937d0deaSdan INSERT INTO t2 SELECT * FROM t1; 199937d0deaSdan CREATE INDEX i2 ON t2(x); 200937d0deaSdan COMMIT; 201937d0deaSdan ANALYZE; 202937d0deaSdan } 203937d0deaSdan} {} 204b51926e6Sdando_execsql_test analyze3-2.1.x { 205b51926e6Sdan SELECT count(*) FROM t2 WHERE x>1 AND x<2; 206b51926e6Sdan SELECT count(*) FROM t2 WHERE x>0 AND x<99; 207b51926e6Sdan} {200 990} 2083985479bSdando_eqp_test analyze3-1.2.2 { 2093985479bSdan SELECT sum(y) FROM t2 WHERE x>1 AND x<2 210*8210233cSdrh} {SEARCH t2 USING INDEX i2 (x>? AND x<?)} 2113985479bSdando_eqp_test analyze3-1.2.3 { 2123985479bSdan SELECT sum(y) FROM t2 WHERE x>0 AND x<99 213*8210233cSdrh} {SCAN t2} 214b51926e6Sdan 215937d0deaSdando_test analyze3-1.2.4 { 216937d0deaSdan sf_execsql { SELECT sum(y) FROM t2 WHERE x>12 AND x<20 } 217937d0deaSdan} {161 0 4760} 218937d0deaSdando_test analyze3-1.2.5 { 219937d0deaSdan set l [string range "12" 0 end] 220937d0deaSdan set u [string range "20" 0 end] 221937d0deaSdan sf_execsql {SELECT typeof($l), typeof($u), sum(y) FROM t2 WHERE x>$l AND x<$u} 222937d0deaSdan} {161 0 text text 4760} 223937d0deaSdando_test analyze3-1.2.6 { 224937d0deaSdan set l [expr int(12)] 225937d0deaSdan set u [expr int(20)] 226937d0deaSdan sf_execsql {SELECT typeof($l), typeof($u), sum(y) FROM t2 WHERE x>$l AND x<$u} 227937d0deaSdan} {161 0 integer integer 4760} 228937d0deaSdando_test analyze3-1.2.7 { 229937d0deaSdan sf_execsql { SELECT sum(y) FROM t2 WHERE x>0 AND x<99 } 230b51926e6Sdan} {999 999 490555} 231937d0deaSdando_test analyze3-1.2.8 { 232937d0deaSdan set l [string range "0" 0 end] 233937d0deaSdan set u [string range "99" 0 end] 234937d0deaSdan sf_execsql {SELECT typeof($l), typeof($u), sum(y) FROM t2 WHERE x>$l AND x<$u} 235b51926e6Sdan} {999 999 text text 490555} 236937d0deaSdando_test analyze3-1.2.9 { 237937d0deaSdan set l [expr int(0)] 238937d0deaSdan set u [expr int(99)] 239937d0deaSdan sf_execsql {SELECT typeof($l), typeof($u), sum(y) FROM t2 WHERE x>$l AND x<$u} 240b51926e6Sdan} {999 999 integer integer 490555} 241937d0deaSdan 242937d0deaSdan# Same tests a third time. This time, column x has INTEGER affinity and 243937d0deaSdan# is not the leftmost column of the table. This triggered a bug causing 244937d0deaSdan# SQLite to use sub-optimal query plans in 3.6.18 and earlier. 245937d0deaSdan# 246937d0deaSdando_test analyze3-1.3.1 { 247937d0deaSdan execsql { 248937d0deaSdan BEGIN; 249937d0deaSdan CREATE TABLE t3(y TEXT, x INTEGER); 250937d0deaSdan INSERT INTO t3 SELECT y, x FROM t1; 251937d0deaSdan CREATE INDEX i3 ON t3(x); 252937d0deaSdan COMMIT; 253937d0deaSdan ANALYZE; 254937d0deaSdan } 255937d0deaSdan} {} 256b51926e6Sdando_execsql_test analyze3-1.3.x { 257b51926e6Sdan SELECT count(*) FROM t3 WHERE x>200 AND x<300; 258b51926e6Sdan SELECT count(*) FROM t3 WHERE x>0 AND x<1100 259b51926e6Sdan} {99 1000} 2603985479bSdando_eqp_test analyze3-1.3.2 { 2613985479bSdan SELECT sum(y) FROM t3 WHERE x>200 AND x<300 262*8210233cSdrh} {SEARCH t3 USING INDEX i3 (x>? AND x<?)} 2633985479bSdando_eqp_test analyze3-1.3.3 { 2643985479bSdan SELECT sum(y) FROM t3 WHERE x>0 AND x<1100 265*8210233cSdrh} {SCAN t3} 266937d0deaSdan 267937d0deaSdando_test analyze3-1.3.4 { 268937d0deaSdan sf_execsql { SELECT sum(y) FROM t3 WHERE x>200 AND x<300 } 269937d0deaSdan} {199 0 14850} 270937d0deaSdando_test analyze3-1.3.5 { 271937d0deaSdan set l [string range "200" 0 end] 272937d0deaSdan set u [string range "300" 0 end] 273937d0deaSdan sf_execsql { SELECT sum(y) FROM t3 WHERE x>$l AND x<$u } 274937d0deaSdan} {199 0 14850} 275937d0deaSdando_test analyze3-1.3.6 { 276937d0deaSdan set l [expr int(200)] 277937d0deaSdan set u [expr int(300)] 278937d0deaSdan sf_execsql { SELECT sum(y) FROM t3 WHERE x>$l AND x<$u } 279937d0deaSdan} {199 0 14850} 280937d0deaSdando_test analyze3-1.3.7 { 281937d0deaSdan sf_execsql { SELECT sum(y) FROM t3 WHERE x>0 AND x<1100 } 282b51926e6Sdan} {999 999 499500} 283937d0deaSdando_test analyze3-1.3.8 { 284937d0deaSdan set l [string range "0" 0 end] 285937d0deaSdan set u [string range "1100" 0 end] 286937d0deaSdan sf_execsql { SELECT sum(y) FROM t3 WHERE x>$l AND x<$u } 287b51926e6Sdan} {999 999 499500} 288937d0deaSdando_test analyze3-1.3.9 { 289937d0deaSdan set l [expr int(0)] 290937d0deaSdan set u [expr int(1100)] 291937d0deaSdan sf_execsql { SELECT sum(y) FROM t3 WHERE x>$l AND x<$u } 292b51926e6Sdan} {999 999 499500} 293937d0deaSdan 294937d0deaSdan#------------------------------------------------------------------------- 295937d0deaSdan# Test that the values of bound SQL variables may be used for the LIKE 296937d0deaSdan# optimization. 297937d0deaSdan# 298937d0deaSdandrop_all_tables 299937d0deaSdando_test analyze3-2.1 { 300937d0deaSdan execsql { 301937d0deaSdan PRAGMA case_sensitive_like=off; 302937d0deaSdan BEGIN; 303937d0deaSdan CREATE TABLE t1(a, b TEXT COLLATE nocase); 304937d0deaSdan CREATE INDEX i1 ON t1(b); 305937d0deaSdan } 306937d0deaSdan for {set i 0} {$i < 1000} {incr i} { 307937d0deaSdan set t "" 308937d0deaSdan append t [lindex {a b c d e f g h i j} [expr $i/100]] 309937d0deaSdan append t [lindex {a b c d e f g h i j} [expr ($i/10)%10]] 310937d0deaSdan append t [lindex {a b c d e f g h i j} [expr ($i%10)]] 311937d0deaSdan execsql { INSERT INTO t1 VALUES($i, $t) } 312937d0deaSdan } 313937d0deaSdan execsql COMMIT 314937d0deaSdan} {} 3153985479bSdando_eqp_test analyze3-2.2 { 3163985479bSdan SELECT count(a) FROM t1 WHERE b LIKE 'a%' 317*8210233cSdrh} {SEARCH t1 USING INDEX i1 (b>? AND b<?)} 3183985479bSdando_eqp_test analyze3-2.3 { 3193985479bSdan SELECT count(a) FROM t1 WHERE b LIKE '%a' 320*8210233cSdrh} {SCAN t1} 321937d0deaSdan 32241d2e66eSdrh# Return the first argument if like_match_blobs is true (the default) 32341d2e66eSdrh# or the second argument if not 32441d2e66eSdrh# 32541d2e66eSdrhproc ilmb {a b} { 32641d2e66eSdrh ifcapable like_match_blobs {return $a} 32741d2e66eSdrh return $b 32841d2e66eSdrh} 32941d2e66eSdrh 330937d0deaSdando_test analyze3-2.4 { 331937d0deaSdan sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE 'a%' } 33241d2e66eSdrh} [list [ilmb 102 101] 0 100] 333937d0deaSdando_test analyze3-2.5 { 334937d0deaSdan sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE '%a' } 335937d0deaSdan} {999 999 100} 336937d0deaSdan 337a9c18a90Sdrhdo_test analyze3-2.6 { 338937d0deaSdan set like "a%" 339937d0deaSdan sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like } 34041d2e66eSdrh} [list [ilmb 102 101] 0 100] 341a9c18a90Sdrhdo_test analyze3-2.7 { 342937d0deaSdan set like "%a" 343937d0deaSdan sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like } 344937d0deaSdan} {999 999 100} 345a9c18a90Sdrhdo_test analyze3-2.8 { 34693ee23ccSdrh set like "a" 34793ee23ccSdrh sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like } 34841d2e66eSdrh} [list [ilmb 102 101] 0 0] 349a9c18a90Sdrhdo_test analyze3-2.9 { 35093ee23ccSdrh set like "ab" 35193ee23ccSdrh sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like } 35241d2e66eSdrh} [list [ilmb 12 11] 0 0] 353a9c18a90Sdrhdo_test analyze3-2.10 { 35493ee23ccSdrh set like "abc" 35593ee23ccSdrh sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like } 35641d2e66eSdrh} [list [ilmb 3 2] 0 1] 357a9c18a90Sdrhdo_test analyze3-2.11 { 35893ee23ccSdrh set like "a_c" 35993ee23ccSdrh sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like } 36041d2e66eSdrh} [list [ilmb 102 101] 0 10] 361937d0deaSdan 362937d0deaSdan 363937d0deaSdan#------------------------------------------------------------------------- 3641d2ce4f8Sdan# This block of tests checks that statements are correctly marked as 3651d2ce4f8Sdan# expired when the values bound to any parameters that may affect the 3661d2ce4f8Sdan# query plan are modified. 367937d0deaSdan# 368937d0deaSdandrop_all_tables 369937d0deaSdandb auth auth 370937d0deaSdanproc auth {args} { 371937d0deaSdan set ::auth 1 372937d0deaSdan return SQLITE_OK 373937d0deaSdan} 374937d0deaSdan 375937d0deaSdando_test analyze3-3.1 { 376937d0deaSdan execsql { 377937d0deaSdan BEGIN; 378937d0deaSdan CREATE TABLE t1(a, b, c); 379937d0deaSdan CREATE INDEX i1 ON t1(b); 380937d0deaSdan } 381937d0deaSdan for {set i 0} {$i < 100} {incr i} { 382937d0deaSdan execsql { INSERT INTO t1 VALUES($i, $i, $i) } 383937d0deaSdan } 384937d0deaSdan execsql COMMIT 385937d0deaSdan execsql ANALYZE 386937d0deaSdan} {} 387937d0deaSdando_test analyze3-3.2.1 { 388937d0deaSdan set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE b>?" -1 dummy] 3891d2ce4f8Sdan sqlite3_expired $S 390937d0deaSdan} {0} 391937d0deaSdando_test analyze3-3.2.2 { 392d893ed8eSdan sqlite3_bind_text $S 1 "abc" 3 3931d2ce4f8Sdan sqlite3_expired $S 394937d0deaSdan} {1} 395937d0deaSdando_test analyze3-3.2.4 { 396937d0deaSdan sqlite3_finalize $S 397937d0deaSdan} {SQLITE_OK} 398937d0deaSdan 3991d2ce4f8Sdando_test analyze3-3.2.5 { 400937d0deaSdan set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE b=?" -1 dummy] 4011d2ce4f8Sdan sqlite3_expired $S 402937d0deaSdan} {0} 4031d2ce4f8Sdando_test analyze3-3.2.6 { 404d893ed8eSdan sqlite3_bind_text $S 1 "abc" 3 4051d2ce4f8Sdan sqlite3_expired $S 4065822d6feSdrh} {1} 4071d2ce4f8Sdando_test analyze3-3.2.7 { 408937d0deaSdan sqlite3_finalize $S 409937d0deaSdan} {SQLITE_OK} 410937d0deaSdan 411937d0deaSdando_test analyze3-3.4.1 { 412937d0deaSdan set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE a=? AND b>?" -1 dummy] 4131d2ce4f8Sdan sqlite3_expired $S 414937d0deaSdan} {0} 415937d0deaSdando_test analyze3-3.4.2 { 416d893ed8eSdan sqlite3_bind_text $S 1 "abc" 3 4171d2ce4f8Sdan sqlite3_expired $S 418937d0deaSdan} {0} 419937d0deaSdando_test analyze3-3.4.3 { 420d893ed8eSdan sqlite3_bind_text $S 2 "def" 3 4211d2ce4f8Sdan sqlite3_expired $S 422937d0deaSdan} {1} 423937d0deaSdando_test analyze3-3.4.4 { 424d893ed8eSdan sqlite3_bind_text $S 2 "ghi" 3 4251d2ce4f8Sdan sqlite3_expired $S 426937d0deaSdan} {1} 427937d0deaSdando_test analyze3-3.4.5 { 4281d2ce4f8Sdan sqlite3_expired $S 4291d2ce4f8Sdan} {1} 430937d0deaSdando_test analyze3-3.4.6 { 431937d0deaSdan sqlite3_finalize $S 432937d0deaSdan} {SQLITE_OK} 433937d0deaSdan 434937d0deaSdando_test analyze3-3.5.1 { 435937d0deaSdan set S [sqlite3_prepare_v2 db { 436937d0deaSdan SELECT * FROM t1 WHERE a IN ( 437937d0deaSdan ?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, 438937d0deaSdan ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20, 439937d0deaSdan ?21, ?22, ?23, ?24, ?25, ?26, ?27, ?28, ?29, ?30, ?31 440937d0deaSdan ) AND b>?32; 441937d0deaSdan } -1 dummy] 4421d2ce4f8Sdan sqlite3_expired $S 443937d0deaSdan} {0} 444937d0deaSdando_test analyze3-3.5.2 { 445d893ed8eSdan sqlite3_bind_text $S 31 "abc" 3 4461d2ce4f8Sdan sqlite3_expired $S 447937d0deaSdan} {0} 448937d0deaSdando_test analyze3-3.5.3 { 449d893ed8eSdan sqlite3_bind_text $S 32 "def" 3 4501d2ce4f8Sdan sqlite3_expired $S 451937d0deaSdan} {1} 452937d0deaSdando_test analyze3-3.5.5 { 453937d0deaSdan sqlite3_finalize $S 454937d0deaSdan} {SQLITE_OK} 455937d0deaSdan 456937d0deaSdando_test analyze3-3.6.1 { 457937d0deaSdan set S [sqlite3_prepare_v2 db { 458937d0deaSdan SELECT * FROM t1 WHERE a IN ( 459937d0deaSdan ?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, 460937d0deaSdan ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20, 461937d0deaSdan ?21, ?22, ?23, ?24, ?25, ?26, ?27, ?28, ?29, ?30, ?31, ?32 462937d0deaSdan ) AND b>?33; 463937d0deaSdan } -1 dummy] 4641d2ce4f8Sdan sqlite3_expired $S 465937d0deaSdan} {0} 466937d0deaSdando_test analyze3-3.6.2 { 467d893ed8eSdan sqlite3_bind_text $S 32 "abc" 3 4681d2ce4f8Sdan sqlite3_expired $S 469937d0deaSdan} {1} 470937d0deaSdando_test analyze3-3.6.3 { 471d893ed8eSdan sqlite3_bind_text $S 33 "def" 3 4721d2ce4f8Sdan sqlite3_expired $S 473937d0deaSdan} {1} 474937d0deaSdando_test analyze3-3.6.5 { 475937d0deaSdan sqlite3_finalize $S 476937d0deaSdan} {SQLITE_OK} 477937d0deaSdan 478937d0deaSdando_test analyze3-3.7.1 { 479937d0deaSdan set S [sqlite3_prepare_v2 db { 480937d0deaSdan SELECT * FROM t1 WHERE a IN ( 481937d0deaSdan ?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?33, 482937d0deaSdan ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20, 483937d0deaSdan ?21, ?22, ?23, ?24, ?25, ?26, ?27, ?28, ?29, ?30, ?31, ?32 484937d0deaSdan ) AND b>?10; 485937d0deaSdan } -1 dummy] 4861d2ce4f8Sdan sqlite3_expired $S 487937d0deaSdan} {0} 488937d0deaSdando_test analyze3-3.7.2 { 489d893ed8eSdan sqlite3_bind_text $S 32 "abc" 3 4901d2ce4f8Sdan sqlite3_expired $S 491937d0deaSdan} {0} 492937d0deaSdando_test analyze3-3.7.3 { 493d893ed8eSdan sqlite3_bind_text $S 33 "def" 3 4941d2ce4f8Sdan sqlite3_expired $S 495937d0deaSdan} {0} 496937d0deaSdando_test analyze3-3.7.4 { 497d893ed8eSdan sqlite3_bind_text $S 10 "def" 3 4981d2ce4f8Sdan sqlite3_expired $S 499937d0deaSdan} {1} 500937d0deaSdando_test analyze3-3.7.6 { 501937d0deaSdan sqlite3_finalize $S 502937d0deaSdan} {SQLITE_OK} 503937d0deaSdan 504937d0deaSdando_test analyze3-3.8.1 { 505937d0deaSdan execsql { 506937d0deaSdan CREATE TABLE t4(x, y TEXT COLLATE NOCASE); 507937d0deaSdan CREATE INDEX i4 ON t4(y); 508937d0deaSdan } 509937d0deaSdan} {} 510937d0deaSdando_test analyze3-3.8.2 { 511937d0deaSdan set S [sqlite3_prepare_v2 db { 512937d0deaSdan SELECT * FROM t4 WHERE x != ? AND y LIKE ? 513937d0deaSdan } -1 dummy] 5141d2ce4f8Sdan sqlite3_expired $S 515937d0deaSdan} {0} 516937d0deaSdando_test analyze3-3.8.3 { 517d893ed8eSdan sqlite3_bind_text $S 1 "abc" 3 5181d2ce4f8Sdan sqlite3_expired $S 519937d0deaSdan} {0} 520937d0deaSdando_test analyze3-3.8.4 { 521d893ed8eSdan sqlite3_bind_text $S 2 "def" 3 522937d0deaSdan sqlite3_expired $S 5231d2ce4f8Sdan} {1} 524937d0deaSdando_test analyze3-3.8.7 { 525d893ed8eSdan sqlite3_bind_text $S 2 "ghi%" 4 526937d0deaSdan sqlite3_expired $S 5271d2ce4f8Sdan} {1} 528937d0deaSdando_test analyze3-3.8.8 { 5291d2ce4f8Sdan sqlite3_expired $S 530937d0deaSdan} {1} 531937d0deaSdando_test analyze3-3.8.9 { 532d893ed8eSdan sqlite3_bind_text $S 2 "ghi%def" 7 533937d0deaSdan sqlite3_expired $S 534937d0deaSdan} {1} 535937d0deaSdando_test analyze3-3.8.10 { 5361d2ce4f8Sdan sqlite3_expired $S 537937d0deaSdan} {1} 538937d0deaSdando_test analyze3-3.8.11 { 539d893ed8eSdan sqlite3_bind_text $S 2 "%ab" 3 540937d0deaSdan sqlite3_expired $S 541937d0deaSdan} {1} 542937d0deaSdando_test analyze3-3.8.12 { 5431d2ce4f8Sdan sqlite3_expired $S 544937d0deaSdan} {1} 545937d0deaSdando_test analyze3-3.8.12 { 546d893ed8eSdan sqlite3_bind_text $S 2 "%de" 3 547937d0deaSdan sqlite3_expired $S 5481d2ce4f8Sdan} {1} 549937d0deaSdando_test analyze3-3.8.13 { 5501d2ce4f8Sdan sqlite3_expired $S 551937d0deaSdan} {1} 552937d0deaSdando_test analyze3-3.8.14 { 553937d0deaSdan sqlite3_finalize $S 554937d0deaSdan} {SQLITE_OK} 555937d0deaSdan 556937d0deaSdan#------------------------------------------------------------------------- 557937d0deaSdan# These tests check that errors encountered while repreparing an SQL 5581d2ce4f8Sdan# statement within sqlite3Reprepare() are handled correctly. 559937d0deaSdan# 560937d0deaSdan 5611d2ce4f8Sdan# Check a schema error. 562937d0deaSdan# 563937d0deaSdando_test analyze3-4.1.1 { 564937d0deaSdan set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE a=? AND b>?" -1 dummy] 5651d2ce4f8Sdan sqlite3_step $S 5661d2ce4f8Sdan} {SQLITE_DONE} 567937d0deaSdando_test analyze3-4.1.2 { 5681d2ce4f8Sdan sqlite3_reset $S 569d893ed8eSdan sqlite3_bind_text $S 2 "abc" 3 570937d0deaSdan execsql { DROP TABLE t1 } 571937d0deaSdan sqlite3_step $S 572cda455b7Sdrh} {SQLITE_ERROR} 5731d2ce4f8Sdando_test analyze3-4.1.3 { 574937d0deaSdan sqlite3_finalize $S 575cda455b7Sdrh} {SQLITE_ERROR} 576937d0deaSdan 577937d0deaSdan# Check an authorization error. 578937d0deaSdan# 579937d0deaSdando_test analyze3-4.2.1 { 580937d0deaSdan execsql { 581937d0deaSdan BEGIN; 582937d0deaSdan CREATE TABLE t1(a, b, c); 583937d0deaSdan CREATE INDEX i1 ON t1(b); 584937d0deaSdan } 585937d0deaSdan for {set i 0} {$i < 100} {incr i} { 586937d0deaSdan execsql { INSERT INTO t1 VALUES($i, $i, $i) } 587937d0deaSdan } 588937d0deaSdan execsql COMMIT 589937d0deaSdan execsql ANALYZE 590937d0deaSdan set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE a=? AND b>?" -1 dummy] 5911d2ce4f8Sdan sqlite3_step $S 5921d2ce4f8Sdan} {SQLITE_DONE} 593937d0deaSdandb auth auth 594937d0deaSdanproc auth {args} { 595937d0deaSdan if {[lindex $args 0] == "SQLITE_READ"} {return SQLITE_DENY} 596937d0deaSdan return SQLITE_OK 597937d0deaSdan} 598937d0deaSdando_test analyze3-4.2.2 { 5991d2ce4f8Sdan sqlite3_reset $S 600d893ed8eSdan sqlite3_bind_text $S 2 "abc" 3 601937d0deaSdan sqlite3_step $S 602cda455b7Sdrh} {SQLITE_AUTH} 603937d0deaSdando_test analyze3-4.2.4 { 604937d0deaSdan sqlite3_finalize $S 605cda455b7Sdrh} {SQLITE_AUTH} 606937d0deaSdan 607937d0deaSdan# Check the effect of an authorization error that occurs in a re-prepare 608937d0deaSdan# performed by sqlite3_step() is the same as one that occurs within 6091d2ce4f8Sdan# sqlite3Reprepare(). 610937d0deaSdan# 611937d0deaSdando_test analyze3-4.3.1 { 612937d0deaSdan db auth {} 613937d0deaSdan set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE a=? AND b>?" -1 dummy] 614937d0deaSdan execsql { CREATE TABLE t2(d, e, f) } 615937d0deaSdan db auth auth 616937d0deaSdan sqlite3_step $S 617cda455b7Sdrh} {SQLITE_AUTH} 618937d0deaSdando_test analyze3-4.3.2 { 619937d0deaSdan sqlite3_finalize $S 620cda455b7Sdrh} {SQLITE_AUTH} 621c94b8595Sdandb auth {} 622c94b8595Sdan 623c94b8595Sdan#------------------------------------------------------------------------- 624c94b8595Sdan# Test that modifying bound variables using the clear_bindings() or 625c94b8595Sdan# transfer_bindings() APIs works. 626c94b8595Sdan# 627c94b8595Sdan# analyze3-5.1.*: sqlite3_clear_bindings() 628c94b8595Sdan# analyze3-5.2.*: sqlite3_transfer_bindings() 629c94b8595Sdan# 630c94b8595Sdando_test analyze3-5.1.1 { 631c94b8595Sdan drop_all_tables 632c94b8595Sdan execsql { 633c94b8595Sdan CREATE TABLE t1(x TEXT COLLATE NOCASE); 634c94b8595Sdan CREATE INDEX i1 ON t1(x); 635c94b8595Sdan INSERT INTO t1 VALUES('aaa'); 636c94b8595Sdan INSERT INTO t1 VALUES('abb'); 637c94b8595Sdan INSERT INTO t1 VALUES('acc'); 638c94b8595Sdan INSERT INTO t1 VALUES('baa'); 639c94b8595Sdan INSERT INTO t1 VALUES('bbb'); 640c94b8595Sdan INSERT INTO t1 VALUES('bcc'); 641c94b8595Sdan } 642c94b8595Sdan 643c94b8595Sdan set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE x LIKE ?" -1 dummy] 644c94b8595Sdan sqlite3_bind_text $S 1 "a%" 2 645c94b8595Sdan set R [list] 646c94b8595Sdan while { "SQLITE_ROW" == [sqlite3_step $S] } { 647c94b8595Sdan lappend R [sqlite3_column_text $S 0] 648c94b8595Sdan } 649c94b8595Sdan concat [sqlite3_reset $S] $R 650c94b8595Sdan} {SQLITE_OK aaa abb acc} 651c94b8595Sdando_test analyze3-5.1.2 { 652c94b8595Sdan sqlite3_clear_bindings $S 653c94b8595Sdan set R [list] 654c94b8595Sdan while { "SQLITE_ROW" == [sqlite3_step $S] } { 655c94b8595Sdan lappend R [sqlite3_column_text $S 0] 656c94b8595Sdan } 657c94b8595Sdan concat [sqlite3_reset $S] $R 658c94b8595Sdan} {SQLITE_OK} 659c94b8595Sdando_test analyze3-5.1.3 { 660c94b8595Sdan sqlite3_finalize $S 661c94b8595Sdan} {SQLITE_OK} 662c94b8595Sdan 663c94b8595Sdando_test analyze3-5.1.1 { 664c94b8595Sdan set S1 [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE x LIKE ?" -1 dummy] 665c94b8595Sdan sqlite3_bind_text $S1 1 "b%" 2 666c94b8595Sdan set R [list] 667c94b8595Sdan while { "SQLITE_ROW" == [sqlite3_step $S1] } { 668c94b8595Sdan lappend R [sqlite3_column_text $S1 0] 669c94b8595Sdan } 670c94b8595Sdan concat [sqlite3_reset $S1] $R 671c94b8595Sdan} {SQLITE_OK baa bbb bcc} 672c94b8595Sdan 673c94b8595Sdando_test analyze3-5.1.2 { 674c94b8595Sdan set S2 [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE x = ?" -1 dummy] 675c94b8595Sdan sqlite3_bind_text $S2 1 "a%" 2 676c94b8595Sdan sqlite3_transfer_bindings $S2 $S1 677c94b8595Sdan set R [list] 678c94b8595Sdan while { "SQLITE_ROW" == [sqlite3_step $S1] } { 679c94b8595Sdan lappend R [sqlite3_column_text $S1 0] 680c94b8595Sdan } 681c94b8595Sdan concat [sqlite3_reset $S1] $R 682c94b8595Sdan} {SQLITE_OK aaa abb acc} 683c94b8595Sdando_test analyze3-5.1.3 { 684c94b8595Sdan sqlite3_finalize $S2 685c94b8595Sdan sqlite3_finalize $S1 686c94b8595Sdan} {SQLITE_OK} 687937d0deaSdan 6882acbc0ddSdan#------------------------------------------------------------------------- 6892acbc0ddSdan 6902acbc0ddSdando_test analyze3-6.1 { 6912acbc0ddSdan execsql { DROP TABLE IF EXISTS t1 } 6922acbc0ddSdan execsql BEGIN 6932acbc0ddSdan execsql { CREATE TABLE t1(a, b, c) } 6942acbc0ddSdan for {set i 0} {$i < 1000} {incr i} { 6952acbc0ddSdan execsql "INSERT INTO t1 VALUES([expr $i/100], 'x', [expr $i/10])" 6962acbc0ddSdan } 6972acbc0ddSdan execsql { 6982acbc0ddSdan CREATE INDEX i1 ON t1(a, b); 6992acbc0ddSdan CREATE INDEX i2 ON t1(c); 7002acbc0ddSdan } 7012acbc0ddSdan execsql COMMIT 7022acbc0ddSdan execsql ANALYZE 7032acbc0ddSdan} {} 7042acbc0ddSdan 7052acbc0ddSdando_eqp_test analyze3-6-3 { 7062acbc0ddSdan SELECT * FROM t1 WHERE a = 5 AND c = 13; 707*8210233cSdrh} {SEARCH t1 USING INDEX i2 (c=?)} 7082acbc0ddSdan 7092acbc0ddSdando_eqp_test analyze3-6-2 { 7102acbc0ddSdan SELECT * FROM t1 WHERE a = 5 AND b > 'w' AND c = 13; 711*8210233cSdrh} {SEARCH t1 USING INDEX i2 (c=?)} 7122acbc0ddSdan 713cef25843Sdrh#----------------------------------------------------------------------------- 714cef25843Sdrh# 2015-04-20. 715cef25843Sdrh# Memory leak in sqlite3Stat4ProbeFree(). (Discovered while fuzzing.) 716cef25843Sdrh# 717cef25843Sdrhdo_execsql_test analyze-7.1 { 718cef25843Sdrh DROP TABLE IF EXISTS t1; 719cef25843Sdrh CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); 720cef25843Sdrh INSERT INTO t1 VALUES(1,1,'0000'); 721cef25843Sdrh CREATE INDEX t0b ON t1(b); 722cef25843Sdrh ANALYZE; 723cef25843Sdrh SELECT c FROM t1 WHERE b=3 AND a BETWEEN 30 AND hex(1); 724cef25843Sdrh} {} 725cef25843Sdrh 7264eed0534Sdan# At one point duplicate stat1 entries were causing a memory leak. 7274eed0534Sdan# 7284eed0534Sdanreset_db 7294eed0534Sdando_execsql_test 7.2 { 7304eed0534Sdan CREATE TABLE t1(a,b,c); 7314eed0534Sdan CREATE INDEX t1a ON t1(a); 7324eed0534Sdan ANALYZE; 7334eed0534Sdan SELECT * FROM sqlite_stat1; 7344eed0534Sdan INSERT INTO sqlite_stat1(tbl,idx,stat) VALUES('t1','t1a','12000'); 7354eed0534Sdan INSERT INTO sqlite_stat1(tbl,idx,stat) VALUES('t1','t1a','12000'); 7364eed0534Sdan ANALYZE sqlite_master; 7374eed0534Sdan} 7384eed0534Sdan 739937d0deaSdanfinish_test 740