github.com/jdgcs/sqlite3@v1.12.1-0.20210908114423-bc5f96e4dd51/testdata/tcl/analyze3.test (about) 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 17 set testdir [file dirname $argv0] 18 source $testdir/tester.tcl 19 set testprefix analyze3 20 21 ifcapable !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. 31 if {[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 64 proc getvar {varname} { uplevel #0 set $varname } 65 db function var getvar 66 67 proc eqp {sql {db db}} { 68 uplevel execsql [list "EXPLAIN QUERY PLAN $sql"] $db 69 } 70 71 proc 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 # 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 } 112 113 execsql { SELECT count(*)>0 FROM sqlite_stat4; } 114 } {1} 115 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} 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 # 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} 131 132 # 2017-06-26: Verify that the SQLITE_DBCONFIG_ENABLE_QPSG setting disables 133 # the use of bound parameters by STAT4 134 # 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} 161 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} 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 # 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} 214 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} 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 # 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} 266 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} 293 294 #------------------------------------------------------------------------- 295 # Test that the values of bound SQL variables may be used for the LIKE 296 # optimization. 297 # 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} 321 322 # Return the first argument if like_match_blobs is true (the default) 323 # or the second argument if not 324 # 325 proc ilmb {a b} { 326 ifcapable like_match_blobs {return $a} 327 return $b 328 } 329 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} 336 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] 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 # 368 drop_all_tables 369 db auth auth 370 proc auth {args} { 371 set ::auth 1 372 return SQLITE_OK 373 } 374 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} 398 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} 410 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} 433 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} 455 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} 477 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} 503 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} 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 # 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} 576 577 # Check an authorization error. 578 # 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 597 } 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} 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 # 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 {} 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 # 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 } 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} 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} 662 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} 672 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} 687 688 #------------------------------------------------------------------------- 689 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 } {} 704 705 do_eqp_test analyze3-6-3 { 706 SELECT * FROM t1 WHERE a = 5 AND c = 13; 707 } {SEARCH t1 USING INDEX i2 (c=?)} 708 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=?)} 712 713 #----------------------------------------------------------------------------- 714 # 2015-04-20. 715 # Memory leak in sqlite3Stat4ProbeFree(). (Discovered while fuzzing.) 716 # 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 } {} 725 726 # At one point duplicate stat1 entries were causing a memory leak. 727 # 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; 737 } 738 739 finish_test