CoolFace
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 9mo agoView on Hugging Face
0likes
analyze3.test767 linesDownload Raw Back to test
1# 2009 August 062#3# The author disclaims copyright to this source code.  In place of4# 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 variables14# instead of literal constant arguments.15#16 17set testdir [file dirname $argv0]18source $testdir/tester.tcl19set testprefix analyze320 21ifcapable !stat4 {22  finish_test23  return24}25 26# This test cannot be run with the sqlite3_prepare() permutation, as it27# tests that stat4 data can be used to influence the plans of queries28# based on bound variable values. And this is not possible when using29# sqlite3_prepare() - as queries cannot be internally re-prepared after30# binding values are available.31if {[permutation]=="prepare"} {32  finish_test33  return34}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 that41#               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 that45#               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 the49#               query may produce a superior outcome.50#51# analyze3-4.*: Test that SQL or authorization callback errors occurring52#               within sqlite3Reprepare() are handled correctly.53#54# analyze3-5.*: Check that the query plans of applicable statements are55#               invalidated if the values of SQL parameter are modified56#               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 getvar66 67proc eqp {sql {db db}} {68  uplevel execsql [list "EXPLAIN QUERY PLAN $sql"] $db69}70 71proc sf_execsql {sql {db db}} {72  set ::sqlite_search_count 073  set r [uplevel [list execsql $sql $db]]74 75  concat $::sqlite_search_count [$db status step] $r76}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.386#   Show that there are two possible plans for querying the table with87#   a range constraint on the indexed column - "full table scan" or "use 88#   the index". When the range is specified using literal values, SQLite89#   is able to pick the best plan based on the samples in sqlite_stat3.90#91# analyze3-1.1.4 - 3.1.992#   Show that using SQL variables produces the same results as using93#   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. So122# 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<300127} {SEARCH 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 t1}131 132# 2017-06-26:  Verify that the SQLITE_DBCONFIG_ENABLE_QPSG setting disables133# the use of bound parameters by STAT4134#135db cache flush136unset -nocomplain l137unset -nocomplain u138do_eqp_test analyze3-1.1.3.100 {139  SELECT sum(y) FROM t1 WHERE x>$l AND x<$u140} {SEARCH t1 USING INDEX i1 (x>? AND x<?)}141set l 200142set u 300143do_eqp_test analyze3-1.1.3.101 {144  SELECT sum(y) FROM t1 WHERE x>$l AND x<$u145} {SEARCH t1 USING INDEX i1 (x>? AND x<?)}146set l 0147set u 1100148do_eqp_test analyze3-1.1.3.102 {149  SELECT sum(y) FROM t1 WHERE x>$l AND x<$u150} {SCAN t1}151db cache flush152sqlite3_db_config db ENABLE_QPSG 1153do_eqp_test analyze3-1.1.3.103 {154  SELECT sum(y) FROM t1 WHERE x>$l AND x<$u155} {SEARCH t1 USING INDEX i1 (x>? AND x<?)}156db cache flush157sqlite3_db_config db ENABLE_QPSG 0158do_eqp_test analyze3-1.1.3.104 {159  SELECT sum(y) FROM t1 WHERE x>$l AND x<$u160} {SCAN 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 is191# that the indexed column has TEXT affinity in this case. In the tests192# 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<2210} {SEARCH 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<99213} {SCAN 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 and243# is not the leftmost column of the table. This triggered a bug causing244# 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<1100259} {99 1000}260do_eqp_test analyze3-1.3.2 {261  SELECT sum(y) FROM t3 WHERE x>200 AND x<300262} {SEARCH 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<1100265} {SCAN 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 LIKE296# optimization.297#298drop_all_tables299do_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 COMMIT314} {}315do_eqp_test analyze3-2.2 {316  SELECT count(a) FROM t1 WHERE b LIKE 'a%'317} {SEARCH 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 t1}321 322# Return the first argument if like_match_blobs is true (the default)323# or the second argument if not324#325proc ilmb {a b} {326  ifcapable like_match_blobs {return $a}327  return $b328}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 as365# expired when the values bound to any parameters that may affect the 366# query plan are modified.367#368drop_all_tables369db auth auth370proc auth {args} {371  set ::auth 1372  return SQLITE_OK373}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 COMMIT385  execsql ANALYZE386} {}387do_test analyze3-3.2.1 {388  set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE b>?" -1 dummy]389  sqlite3_expired $S390} {0}391do_test analyze3-3.2.2 {392  sqlite3_bind_text $S 1 "abc" 3393  sqlite3_expired $S394} {1}395do_test analyze3-3.2.4 {396  sqlite3_finalize $S397} {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 $S402} {0}403do_test analyze3-3.2.6 {404  sqlite3_bind_text $S 1 "abc" 3405  sqlite3_expired $S406} {1}407do_test analyze3-3.2.7 {408  sqlite3_finalize $S409} {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 $S414} {0}415do_test analyze3-3.4.2 {416  sqlite3_bind_text $S 1 "abc" 3417  sqlite3_expired $S418} {0}419do_test analyze3-3.4.3 {420  sqlite3_bind_text $S 2 "def" 3421  sqlite3_expired $S422} {1}423do_test analyze3-3.4.4 {424  sqlite3_bind_text $S 2 "ghi" 3425  sqlite3_expired $S426} {1}427do_test analyze3-3.4.5 {428  sqlite3_expired $S429} {1}430do_test analyze3-3.4.6 {431  sqlite3_finalize $S432} {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, ?31440    ) AND b>?32;441  } -1 dummy]442  sqlite3_expired $S443} {0}444do_test analyze3-3.5.2 {445  sqlite3_bind_text $S 31 "abc" 3446  sqlite3_expired $S447} {0}448do_test analyze3-3.5.3 {449  sqlite3_bind_text $S 32 "def" 3450  sqlite3_expired $S451} {1}452do_test analyze3-3.5.5 {453  sqlite3_finalize $S454} {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, ?32462    ) AND b>?33;463  } -1 dummy]464  sqlite3_expired $S465} {0}466do_test analyze3-3.6.2 {467  sqlite3_bind_text $S 32 "abc" 3468  sqlite3_expired $S469} {1}470do_test analyze3-3.6.3 {471  sqlite3_bind_text $S 33 "def" 3472  sqlite3_expired $S473} {1}474do_test analyze3-3.6.5 {475  sqlite3_finalize $S476} {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, ?32484    ) AND b>?10;485  } -1 dummy]486  sqlite3_expired $S487} {0}488do_test analyze3-3.7.2 {489  sqlite3_bind_text $S 32 "abc" 3490  sqlite3_expired $S491} {0}492do_test analyze3-3.7.3 {493  sqlite3_bind_text $S 33 "def" 3494  sqlite3_expired $S495} {0}496do_test analyze3-3.7.4 {497  sqlite3_bind_text $S 10 "def" 3498  sqlite3_expired $S499} {1}500do_test analyze3-3.7.6 {501  sqlite3_finalize $S502} {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 $S515} {0}516do_test analyze3-3.8.3 {517  sqlite3_bind_text $S 1 "abc" 3518  sqlite3_expired $S519} {0}520do_test analyze3-3.8.4 {521  sqlite3_bind_text $S 2 "def" 3522  sqlite3_expired $S523} {1}524do_test analyze3-3.8.7 {525  sqlite3_bind_text $S 2 "ghi%" 4526  sqlite3_expired $S527} {1}528do_test analyze3-3.8.8 {529  sqlite3_expired $S530} {1}531do_test analyze3-3.8.9 {532  sqlite3_bind_text $S 2 "ghi%def" 7533  sqlite3_expired $S534} {1}535do_test analyze3-3.8.10 {536  sqlite3_expired $S537} {1}538do_test analyze3-3.8.11 {539  sqlite3_bind_text $S 2 "%ab" 3540  sqlite3_expired $S541} {1}542do_test analyze3-3.8.12 {543  sqlite3_expired $S544} {1}545do_test analyze3-3.8.12 {546  sqlite3_bind_text $S 2 "%de" 3547  sqlite3_expired $S548} {1}549do_test analyze3-3.8.13 {550  sqlite3_expired $S551} {1}552do_test analyze3-3.8.14 {553  sqlite3_finalize $S554} {SQLITE_OK}555 556#-------------------------------------------------------------------------557# These tests check that errors encountered while repreparing an SQL558# 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 $S566} {SQLITE_DONE}567do_test analyze3-4.1.2 {568  sqlite3_reset $S569  sqlite3_bind_text $S 2 "abc" 3570  execsql { DROP TABLE t1 }571  sqlite3_step $S572} {SQLITE_ERROR}573do_test analyze3-4.1.3 {574  sqlite3_finalize $S575} {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 COMMIT589  execsql ANALYZE590  set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE a=? AND b>?" -1 dummy]591  sqlite3_step $S592} {SQLITE_DONE}593db auth auth594proc auth {args} {595  if {[lindex $args 0] == "SQLITE_READ"} {return SQLITE_DENY}596  return SQLITE_OK597}598do_test analyze3-4.2.2 {599  sqlite3_reset $S600  sqlite3_bind_text $S 2 "abc" 3601  sqlite3_step $S602} {SQLITE_AUTH}603do_test analyze3-4.2.4 {604  sqlite3_finalize $S605} {SQLITE_AUTH}606 607# Check the effect of an authorization error that occurs in a re-prepare608# performed by sqlite3_step() is the same as one that occurs within609# 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 auth616  sqlite3_step $S617} {SQLITE_AUTH}618do_test analyze3-4.3.2 {619  sqlite3_finalize $S620} {SQLITE_AUTH}621db auth {}622 623#-------------------------------------------------------------------------624# Test that modifying bound variables using the clear_bindings() or625# 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_tables632  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%" 2645  set R [list]646  while { "SQLITE_ROW" == [sqlite3_step $S] } {647    lappend R [sqlite3_column_text $S 0]648  }649  concat [sqlite3_reset $S] $R650} {SQLITE_OK aaa abb acc}651do_test analyze3-5.1.2 {652  sqlite3_clear_bindings $S653  set R [list]654  while { "SQLITE_ROW" == [sqlite3_step $S] } {655    lappend R [sqlite3_column_text $S 0]656  }657  concat [sqlite3_reset $S] $R658} {SQLITE_OK}659do_test analyze3-5.1.3 {660  sqlite3_finalize $S661} {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%" 2666  set R [list]667  while { "SQLITE_ROW" == [sqlite3_step $S1] } {668    lappend R [sqlite3_column_text $S1 0]669  }670  concat [sqlite3_reset $S1] $R671} {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%" 2676  sqlite3_transfer_bindings $S2 $S1677  set R [list]678  while { "SQLITE_ROW" == [sqlite3_step $S1] } {679    lappend R [sqlite3_column_text $S1 0]680  }681  concat [sqlite3_reset $S1] $R682} {SQLITE_OK aaa abb acc}683do_test analyze3-5.1.3 {684  sqlite3_finalize $S2685  sqlite3_finalize $S1686} {SQLITE_OK}687 688#-------------------------------------------------------------------------689 690do_test analyze3-6.1 {691  execsql { DROP TABLE IF EXISTS t1 }692  execsql BEGIN693  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 COMMIT702  execsql ANALYZE703} {}704 705do_eqp_test analyze3-6-3 {706  SELECT * FROM t1 WHERE a = 5 AND c = 13;707} {SEARCH 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 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_db729do_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# 2023-04-22 https://sqlite.org/forum/info/6c118daad0f1f5ef740# Case differences in the sqlite_stat4.idx field should not matter.741#742reset_db743do_execsql_test 8.0 {744  CREATE TABLE t1(a PRIMARY KEY, v) WITHOUT ROWID;745  ANALYZE sqlite_schema;746  INSERT INTO sqlite_stat1 VALUES('t1','t1','1 1');747  INSERT INTO sqlite_stat4 VALUES('t1','t1','1','0','0',X'021b76657273696f6e');748  INSERT INTO sqlite_stat4 VALUES('T1','T1','1','0','0',X'021b76657273696f6e');749  ANALYZE sqlite_schema;750} {}751 752# 2023-05-03 https://sqlite.org/forum/forumpost/537d8ab118753# Same index appears by two different names in the sqlite_stat4 table.754#755reset_db756do_execsql_test 8.1 {757  CREATE TABLE t1(a INT PRIMARY KEY, b INT) WITHOUT ROWID;758  ANALYZE sqlite_schema;759  INSERT INTO sqlite_stat4 VALUES760     ('t1','t1','1','2','2',X'03000103'),761     ('t1','sqlite_autoindex_t1_1','1','2','2',X'03000103');762  ANALYZE sqlite_schema;763  PRAGMA integrity_check;764} {ok}765 766finish_test767