Annotation of embedaddon/sqlite3/test/analyze3.test, revision 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>