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