Annotation of embedaddon/sqlite3/test/analyze3.test, revision 1.1.1.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>