Annotation of embedaddon/sqlite3/test/tkt3718.test, revision 1.1

1.1     ! misho       1: # 2001 September 15
        !             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: # This file implements regression tests for SQLite library.  The
        !            12: # focus of this file is testing the execution of SQL statements from
        !            13: # within callbacks generated by VMs that themselves open statement 
        !            14: # transactions.
        !            15: #
        !            16: # $Id: tkt3718.test,v 1.2 2009/06/05 17:09:12 drh Exp $
        !            17: 
        !            18: set testdir [file dirname $argv0]
        !            19: source $testdir/tester.tcl
        !            20: 
        !            21: do_test tkt3718-1.1 {
        !            22:   execsql {
        !            23:     CREATE TABLE t1(a PRIMARY KEY, b);
        !            24:     INSERT INTO t1 VALUES(1, 'one');
        !            25:     INSERT INTO t1 VALUES(2, 'two');
        !            26:     INSERT INTO t1 VALUES(3, 'three');
        !            27:     INSERT INTO t1 VALUES(4, 'four');
        !            28:     INSERT INTO t1 VALUES(5, 'five');
        !            29:     CREATE TABLE t2(a PRIMARY KEY, b);
        !            30:   }
        !            31: } {}
        !            32: 
        !            33: # SQL scalar function:
        !            34: #
        !            35: #   f1(<arg>)
        !            36: #
        !            37: # Uses database handle [db] to execute "SELECT f2(<arg>)". Returns either
        !            38: # the results or error message from the "SELECT f2(<arg>)" query to the
        !            39: # caller.
        !            40: #
        !            41: proc f1 {args} {
        !            42:   set a [lindex $args 0]
        !            43:   catch { db eval {SELECT f2($a)} } msg
        !            44:   set msg
        !            45: }
        !            46: 
        !            47: # SQL scalar function:
        !            48: #
        !            49: #   f2(<arg>)
        !            50: #
        !            51: # Return the value of <arg>. Unless <arg> is "three", in which case throw
        !            52: # an exception.
        !            53: #
        !            54: proc f2 {args} {
        !            55:   set a [lindex $args 0]
        !            56:   if {$a == "three"} { error "Three!!" }
        !            57:   return $a
        !            58: }
        !            59: 
        !            60: db func f1 f1
        !            61: db func f2 f2
        !            62: 
        !            63: # The second INSERT statement below uses the f1 user function such that
        !            64: # half-way through the INSERT operation f1() will run an SQL statement
        !            65: # that throws an exception. At one point, before #3718 was fixed, this
        !            66: # caused the statement transaction belonging to the INSERT statement to
        !            67: # be rolled back. The result was that some (but not all) of the rows that 
        !            68: # should have been inserted went missing.
        !            69: #
        !            70: do_test tkt3718-1.2 {
        !            71:   execsql {
        !            72:     BEGIN;
        !            73:     INSERT INTO t2 SELECT a, b FROM t1;
        !            74:     INSERT INTO t2 SELECT a+5, f1(b) FROM t1;
        !            75:     COMMIT;
        !            76:   }
        !            77:   execsql {
        !            78:     SELECT a FROM t2;
        !            79:   }
        !            80: } {1 2 3 4 5 6 7 8 9 10}
        !            81: 
        !            82: # This test turns on the count_changes pragma (causing DML statements to
        !            83: # return SQLITE_ROW once, with a single integer result value reporting the
        !            84: # number of rows affected by the statement). It then executes an INSERT
        !            85: # statement that requires a statement journal. After stepping the statement
        !            86: # once, so that it returns SQLITE_ROW, a second SQL statement that throws an
        !            87: # exception is run. At one point, before #3718 was fixed, this caused the
        !            88: # statement transaction belonging to the INSERT statement to be rolled back.
        !            89: # The result was that none of the rows were actually inserted.
        !            90: # 
        !            91: #
        !            92: do_test tkt3718-1.3 {
        !            93:   execsql { 
        !            94:     DELETE FROM t2 WHERE a > 5;
        !            95:     PRAGMA count_changes = 1;
        !            96:     BEGIN;
        !            97:   }
        !            98:   db eval {INSERT INTO t2 SELECT a+5, b||'+5' FROM t1} {
        !            99:     catch { db eval {SELECT f2('three')} } msg
        !           100:   }
        !           101:   execsql {
        !           102:     COMMIT;
        !           103:     SELECT a FROM t2;
        !           104:   }
        !           105: } {1 2 3 4 5 6 7 8 9 10}
        !           106: 
        !           107: do_test tkt3718-1.4 {
        !           108:   execsql {pragma count_changes=0}
        !           109: } {}
        !           110: 
        !           111: # This SQL function executes the SQL specified as an argument against
        !           112: # database [db].
        !           113: #
        !           114: proc sql {doit zSql} {
        !           115:   if {$doit} { catchsql $zSql }
        !           116: }
        !           117: db func sql [list sql]
        !           118: 
        !           119: # The following tests, tkt3718-2.*, test that a nested statement 
        !           120: # transaction can be successfully committed or reverted without 
        !           121: # affecting the parent statement transaction.
        !           122: #
        !           123: do_test tkt3718-2.1 {
        !           124:   execsql { SELECT sql(1, 'DELETE FROM t2 WHERE a = '||a ) FROM t2 WHERE a>5 }
        !           125:   execsql { SELECT a from t2 }
        !           126: } {1 2 3 4 5}
        !           127: do_test tkt3718-2.2 {
        !           128:   execsql {
        !           129:     DELETE FROM t2 WHERE a > 5;
        !           130:     BEGIN;
        !           131:     INSERT INTO t2 SELECT a+5, sql(a==3,
        !           132:         'INSERT INTO t2 SELECT a+10, f2(b) FROM t1'
        !           133:     ) FROM t1;
        !           134:   }
        !           135:   execsql {
        !           136:     COMMIT;
        !           137:     SELECT a FROM t2;
        !           138:   }
        !           139: } {1 2 3 4 5 6 7 8 9 10}
        !           140: do_test tkt3718-2.3 {
        !           141:   execsql {
        !           142:     DELETE FROM t2 WHERE a > 5;
        !           143:     BEGIN;
        !           144:     INSERT INTO t2 SELECT a+5, sql(a==3,
        !           145:         'INSERT INTO t2 SELECT a+10, b FROM t1'
        !           146:     ) FROM t1;
        !           147:     COMMIT;
        !           148:   }
        !           149:   execsql { SELECT a FROM t2 ORDER BY a+0}
        !           150: } {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15}
        !           151: integrity_check tkt3718.2-4
        !           152: 
        !           153: # The next set of tests, tkt3718-3.*, test that a statement transaction
        !           154: # that has a committed statement transaction nested inside of it can
        !           155: # be committed or reverted.
        !           156: #
        !           157: foreach {tn io ii results} {
        !           158:   1 0 10 {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20}
        !           159:   2 1 10 {6 7 8 9 10 16 17 18 19 20}
        !           160:   3 0 11 {1 2 3 4 5 6 7 8 9 10 16 17 18 19 20}
        !           161:   4 1 11 {6 7 8 9 10 16 17 18 19 20}
        !           162: } {
        !           163:   do_test tkt3718-3.$tn {
        !           164:     execsql { 
        !           165:       DELETE FROM t2;
        !           166:       INSERT INTO t2 SELECT a+5, b FROM t1;
        !           167:       INSERT INTO t2 SELECT a+15, b FROM t1;
        !           168:     }
        !           169: 
        !           170:     catchsql "
        !           171:       BEGIN;
        !           172:       INSERT INTO t2 SELECT a+$io, sql(a==3,
        !           173:           'INSERT INTO t2 SELECT a+$ii, b FROM t1'
        !           174:       ) FROM t1;
        !           175:     "
        !           176: 
        !           177:     execsql { COMMIT }
        !           178: 
        !           179:     execsql { SELECT a FROM t2 ORDER BY a+0}
        !           180:   } $results
        !           181: 
        !           182:   integrity_check tkt3718-3.$tn.integrity
        !           183: }
        !           184: 
        !           185: # This is the same test as tkt3718-3.*, but with 3 levels of nesting.
        !           186: #
        !           187: foreach {tn i1 i2 i3 results} {
        !           188:   1   0 10 20   {5 10 15 20 25 30}
        !           189:   2   0 10 21   {5 10 15 20 30}
        !           190:   3   0 11 20   {5 10 20 30}
        !           191:   4   0 11 21   {5 10 20 30}
        !           192:   5   1 10 20   {10 20 30}
        !           193:   6   1 10 21   {10 20 30}
        !           194:   7   1 11 20   {10 20 30}
        !           195:   8   1 11 21   {10 20 30}
        !           196: } {
        !           197:   do_test tkt3718-4.$tn {
        !           198:     execsql { 
        !           199:       DELETE FROM t2;
        !           200:       INSERT INTO t2 SELECT a+5, b FROM t1;
        !           201:       INSERT INTO t2 SELECT a+15, b FROM t1;
        !           202:       INSERT INTO t2 SELECT a+25, b FROM t1;
        !           203:     }
        !           204: 
        !           205:     catchsql "
        !           206:       BEGIN;
        !           207:       INSERT INTO t2 SELECT a+$i1, sql(a==3,
        !           208:           'INSERT INTO t2 SELECT a+$i2, sql(a==3, 
        !           209:              ''INSERT INTO t2 SELECT a+$i3, b FROM t1''
        !           210:            ) FROM t1'
        !           211:       ) FROM t1;
        !           212:     "
        !           213: 
        !           214:     execsql { COMMIT }
        !           215: 
        !           216:     execsql { SELECT a FROM t2 WHERE (a%5)==0 ORDER BY a+0}
        !           217:   } $results
        !           218: 
        !           219:   do_test tkt3718-4.$tn.extra {
        !           220:     execsql {
        !           221:       SELECT 
        !           222:         (SELECT sum(a) FROM t2)==(SELECT sum(a*5-10) FROM t2 WHERE (a%5)==0)
        !           223:     }
        !           224:   } {1}
        !           225: 
        !           226:   integrity_check tkt3718-4.$tn.integrity
        !           227: }
        !           228: 
        !           229: 
        !           230: finish_test

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