1# 2009 August 06 2# 3# The author disclaims copyright to this source code. In place of 4# a legal notice, here is a blessing: 5# 6# May you do good and not evil. 7# May you find forgiveness for yourself and forgive others. 8# May you share freely, never taking more than you give. 9# 10#*********************************************************************** 11# 12# This file implements regression tests for SQLite library. This file 13# implements tests for range and LIKE constraints that use bound variables 14# instead of literal constant arguments. 15# 16 17set testdir [file dirname $argv0] 18source $testdir/tester.tcl 19set testprefix analyze3 20 21ifcapable !stat4 { 22 finish_test 23 return 24} 25 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. 31if {[permutation]=="prepare"} { 32 finish_test 33 return 34} 35 36#---------------------------------------------------------------------- 37# Test Organization: 38# 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. 42# 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. 46# 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. 50# 51# analyze3-4.*: Test that SQL or authorization callback errors occuring 52# within sqlite3Reprepare() are handled correctly. 53# 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. 59# 60# analyze3-7.*: Test that some memory leaks discovered by fuzz testing 61# have been fixed. 62# 63 64proc getvar {varname} { uplevel #0 set $varname } 65db function var getvar 66 67proc eqp {sql {db db}} { 68 uplevel execsql [list "EXPLAIN QUERY PLAN $sql"] $db 69} 70 71proc sf_execsql {sql {db db}} { 72 set ::sqlite_search_count 0 73 set r [uplevel [list execsql $sql $db]] 74 75 concat $::sqlite_search_count [$db status step] $r 76} 77 78#------------------------------------------------------------------------- 79# 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. 84# 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. 90# 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. 94# 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". 98# 99do_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 } 112 113 execsql { SELECT count(*)>0 FROM sqlite_stat4; } 114} {1} 115 116do_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} 120 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. 124# 125do_eqp_test analyze3-1.1.2 { 126 SELECT sum(y) FROM t1 WHERE x>200 AND x<300 127} {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?)} 128do_eqp_test analyze3-1.1.3 { 129 SELECT sum(y) FROM t1 WHERE x>0 AND x<1100 130} {SCAN TABLE t1} 131 132# 2017-06-26: Verify that the SQLITE_DBCONFIG_ENABLE_QPSG setting disables 133# the use of bound parameters by STAT4 134# 135db cache flush 136unset -nocomplain l 137unset -nocomplain u 138do_eqp_test analyze3-1.1.3.100 { 139 SELECT sum(y) FROM t1 WHERE x>$l AND x<$u 140} {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?)} 141set l 200 142set u 300 143do_eqp_test analyze3-1.1.3.101 { 144 SELECT sum(y) FROM t1 WHERE x>$l AND x<$u 145} {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?)} 146set l 0 147set u 1100 148do_eqp_test analyze3-1.1.3.102 { 149 SELECT sum(y) FROM t1 WHERE x>$l AND x<$u 150} {SCAN TABLE t1} 151db cache flush 152sqlite3_db_config db ENABLE_QPSG 1 153do_eqp_test analyze3-1.1.3.103 { 154 SELECT sum(y) FROM t1 WHERE x>$l AND x<$u 155} {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?)} 156db cache flush 157sqlite3_db_config db ENABLE_QPSG 0 158do_eqp_test analyze3-1.1.3.104 { 159 SELECT sum(y) FROM t1 WHERE x>$l AND x<$u 160} {SCAN TABLE t1} 161 162do_test analyze3-1.1.4 { 163 sf_execsql { SELECT sum(y) FROM t1 WHERE x>200 AND x<300 } 164} {199 0 14850} 165do_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} 170do_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} 175do_test analyze3-1.1.7 { 176 sf_execsql { SELECT sum(y) FROM t1 WHERE x>0 AND x<1100 } 177} {999 999 499500} 178do_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} 183do_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} 188 189 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. 193# 194do_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} {} 204do_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} 208do_eqp_test analyze3-1.2.2 { 209 SELECT sum(y) FROM t2 WHERE x>1 AND x<2 210} {SEARCH TABLE t2 USING INDEX i2 (x>? AND x<?)} 211do_eqp_test analyze3-1.2.3 { 212 SELECT sum(y) FROM t2 WHERE x>0 AND x<99 213} {SCAN TABLE t2} 214 215do_test analyze3-1.2.4 { 216 sf_execsql { SELECT sum(y) FROM t2 WHERE x>12 AND x<20 } 217} {161 0 4760} 218do_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} 223do_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} 228do_test analyze3-1.2.7 { 229 sf_execsql { SELECT sum(y) FROM t2 WHERE x>0 AND x<99 } 230} {999 999 490555} 231do_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} 236do_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} 241 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. 245# 246do_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} {} 256do_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} 260do_eqp_test analyze3-1.3.2 { 261 SELECT sum(y) FROM t3 WHERE x>200 AND x<300 262} {SEARCH TABLE t3 USING INDEX i3 (x>? AND x<?)} 263do_eqp_test analyze3-1.3.3 { 264 SELECT sum(y) FROM t3 WHERE x>0 AND x<1100 265} {SCAN TABLE t3} 266 267do_test analyze3-1.3.4 { 268 sf_execsql { SELECT sum(y) FROM t3 WHERE x>200 AND x<300 } 269} {199 0 14850} 270do_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} 275do_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} 280do_test analyze3-1.3.7 { 281 sf_execsql { SELECT sum(y) FROM t3 WHERE x>0 AND x<1100 } 282} {999 999 499500} 283do_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} 288do_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} 293 294#------------------------------------------------------------------------- 295# Test that the values of bound SQL variables may be used for the LIKE 296# optimization. 297# 298drop_all_tables 299do_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} {} 315do_eqp_test analyze3-2.2 { 316 SELECT count(a) FROM t1 WHERE b LIKE 'a%' 317} {SEARCH TABLE t1 USING INDEX i1 (b>? AND b<?)} 318do_eqp_test analyze3-2.3 { 319 SELECT count(a) FROM t1 WHERE b LIKE '%a' 320} {SCAN TABLE t1} 321 322# Return the first argument if like_match_blobs is true (the default) 323# or the second argument if not 324# 325proc ilmb {a b} { 326 ifcapable like_match_blobs {return $a} 327 return $b 328} 329 330do_test analyze3-2.4 { 331 sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE 'a%' } 332} [list [ilmb 102 101] 0 100] 333do_test analyze3-2.5 { 334 sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE '%a' } 335} {999 999 100} 336 337do_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] 341do_test analyze3-2.7 { 342 set like "%a" 343 sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like } 344} {999 999 100} 345do_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] 349do_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] 353do_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] 357do_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] 361 362 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. 367# 368drop_all_tables 369db auth auth 370proc auth {args} { 371 set ::auth 1 372 return SQLITE_OK 373} 374 375do_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} {} 387do_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} 391do_test analyze3-3.2.2 { 392 sqlite3_bind_text $S 1 "abc" 3 393 sqlite3_expired $S 394} {1} 395do_test analyze3-3.2.4 { 396 sqlite3_finalize $S 397} {SQLITE_OK} 398 399do_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} 403do_test analyze3-3.2.6 { 404 sqlite3_bind_text $S 1 "abc" 3 405 sqlite3_expired $S 406} {1} 407do_test analyze3-3.2.7 { 408 sqlite3_finalize $S 409} {SQLITE_OK} 410 411do_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} 415do_test analyze3-3.4.2 { 416 sqlite3_bind_text $S 1 "abc" 3 417 sqlite3_expired $S 418} {0} 419do_test analyze3-3.4.3 { 420 sqlite3_bind_text $S 2 "def" 3 421 sqlite3_expired $S 422} {1} 423do_test analyze3-3.4.4 { 424 sqlite3_bind_text $S 2 "ghi" 3 425 sqlite3_expired $S 426} {1} 427do_test analyze3-3.4.5 { 428 sqlite3_expired $S 429} {1} 430do_test analyze3-3.4.6 { 431 sqlite3_finalize $S 432} {SQLITE_OK} 433 434do_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} 444do_test analyze3-3.5.2 { 445 sqlite3_bind_text $S 31 "abc" 3 446 sqlite3_expired $S 447} {0} 448do_test analyze3-3.5.3 { 449 sqlite3_bind_text $S 32 "def" 3 450 sqlite3_expired $S 451} {1} 452do_test analyze3-3.5.5 { 453 sqlite3_finalize $S 454} {SQLITE_OK} 455 456do_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} 466do_test analyze3-3.6.2 { 467 sqlite3_bind_text $S 32 "abc" 3 468 sqlite3_expired $S 469} {1} 470do_test analyze3-3.6.3 { 471 sqlite3_bind_text $S 33 "def" 3 472 sqlite3_expired $S 473} {1} 474do_test analyze3-3.6.5 { 475 sqlite3_finalize $S 476} {SQLITE_OK} 477 478do_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} 488do_test analyze3-3.7.2 { 489 sqlite3_bind_text $S 32 "abc" 3 490 sqlite3_expired $S 491} {0} 492do_test analyze3-3.7.3 { 493 sqlite3_bind_text $S 33 "def" 3 494 sqlite3_expired $S 495} {0} 496do_test analyze3-3.7.4 { 497 sqlite3_bind_text $S 10 "def" 3 498 sqlite3_expired $S 499} {1} 500do_test analyze3-3.7.6 { 501 sqlite3_finalize $S 502} {SQLITE_OK} 503 504do_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} {} 510do_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} 516do_test analyze3-3.8.3 { 517 sqlite3_bind_text $S 1 "abc" 3 518 sqlite3_expired $S 519} {0} 520do_test analyze3-3.8.4 { 521 sqlite3_bind_text $S 2 "def" 3 522 sqlite3_expired $S 523} {1} 524do_test analyze3-3.8.7 { 525 sqlite3_bind_text $S 2 "ghi%" 4 526 sqlite3_expired $S 527} {1} 528do_test analyze3-3.8.8 { 529 sqlite3_expired $S 530} {1} 531do_test analyze3-3.8.9 { 532 sqlite3_bind_text $S 2 "ghi%def" 7 533 sqlite3_expired $S 534} {1} 535do_test analyze3-3.8.10 { 536 sqlite3_expired $S 537} {1} 538do_test analyze3-3.8.11 { 539 sqlite3_bind_text $S 2 "%ab" 3 540 sqlite3_expired $S 541} {1} 542do_test analyze3-3.8.12 { 543 sqlite3_expired $S 544} {1} 545do_test analyze3-3.8.12 { 546 sqlite3_bind_text $S 2 "%de" 3 547 sqlite3_expired $S 548} {1} 549do_test analyze3-3.8.13 { 550 sqlite3_expired $S 551} {1} 552do_test analyze3-3.8.14 { 553 sqlite3_finalize $S 554} {SQLITE_OK} 555 556#------------------------------------------------------------------------- 557# These tests check that errors encountered while repreparing an SQL 558# statement within sqlite3Reprepare() are handled correctly. 559# 560 561# Check a schema error. 562# 563do_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} 567do_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} 573do_test analyze3-4.1.3 { 574 sqlite3_finalize $S 575} {SQLITE_ERROR} 576 577# Check an authorization error. 578# 579do_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} 593db auth auth 594proc auth {args} { 595 if {[lindex $args 0] == "SQLITE_READ"} {return SQLITE_DENY} 596 return SQLITE_OK 597} 598do_test analyze3-4.2.2 { 599 sqlite3_reset $S 600 sqlite3_bind_text $S 2 "abc" 3 601 sqlite3_step $S 602} {SQLITE_AUTH} 603do_test analyze3-4.2.4 { 604 sqlite3_finalize $S 605} {SQLITE_AUTH} 606 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(). 610# 611do_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} 618do_test analyze3-4.3.2 { 619 sqlite3_finalize $S 620} {SQLITE_AUTH} 621db auth {} 622 623#------------------------------------------------------------------------- 624# Test that modifying bound variables using the clear_bindings() or 625# transfer_bindings() APIs works. 626# 627# analyze3-5.1.*: sqlite3_clear_bindings() 628# analyze3-5.2.*: sqlite3_transfer_bindings() 629# 630do_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 } 642 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} 651do_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} 659do_test analyze3-5.1.3 { 660 sqlite3_finalize $S 661} {SQLITE_OK} 662 663do_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} 672 673do_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} 683do_test analyze3-5.1.3 { 684 sqlite3_finalize $S2 685 sqlite3_finalize $S1 686} {SQLITE_OK} 687 688#------------------------------------------------------------------------- 689 690do_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} {} 704 705do_eqp_test analyze3-6-3 { 706 SELECT * FROM t1 WHERE a = 5 AND c = 13; 707} {SEARCH TABLE t1 USING INDEX i2 (c=?)} 708 709do_eqp_test analyze3-6-2 { 710 SELECT * FROM t1 WHERE a = 5 AND b > 'w' AND c = 13; 711} {SEARCH TABLE t1 USING INDEX i2 (c=?)} 712 713#----------------------------------------------------------------------------- 714# 2015-04-20. 715# Memory leak in sqlite3Stat4ProbeFree(). (Discovered while fuzzing.) 716# 717do_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} {} 725 726# At one point duplicate stat1 entries were causing a memory leak. 727# 728reset_db 729do_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; 737} 738 739finish_test 740