Snapshot of upstream SQLite 3.45.3
[sqlcipher.git] / test / tkt-b72787b1.test
blobdea3f49a6409d2678111bfe9282aac3b36430044
1 # 2011 February 21
3 # The author disclaims copyright to this source code.  In place of
4 # a legal notice, here is a blessing:
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.
10 #***********************************************************************
11 # This file implements regression tests for SQLite library.
13 # This file implements tests to verify that ticket [b72787b1a7] has been
14 # fixed.  From the ticket:
16 #     The sqlite3ExpirePreparedStatements routine marks all statements
17 #     as expired. This includes statements that are not expired.
19 #     Steps to reproduce:
21 #        * Prepare a statement (A)
22 #        * Alter the schema to invalidate cookie in A
23 #        * Prepare a statement (B)
24 #        * Run B and have A run as part of B
25 #        * A will find a bad cookie and cause *all* statements
26 #          to be expired including the currently running B by calling
27 #          sqlite3ExpirePreparedStatements
28 #        * When control returns to B it will then abort 
30 #     The bug is that sqlite3ExpirePreparedStatements expires all statements.
31 #     Note that B was prepared after the schema change and hence is perfectly
32 #     valid and then is marked as expired while running.
35 set testdir [file dirname $argv0]
36 source $testdir/tester.tcl
38 ifcapable !compound {
39   finish_test
40   return
43 unset -nocomplain ::STMT
44 proc runsql {} {
45   db eval {CREATE TABLE IF NOT EXISTS t4(q)}
46   sqlite3_step $::STMT
47   set rc [sqlite3_column_int $::STMT 0]
48   sqlite3_reset $::STMT
49   return $rc
52 do_test tkt-b72787b1.1 {
53   db eval {
54     CREATE TABLE t1(x);
55     INSERT INTO t1 VALUES(1);
56     INSERT INTO t1 VALUES(2);
57     CREATE TABLE t2(y);
58     INSERT INTO t2 SELECT x+2 FROM t1;
59     INSERT INTO t2 SELECT x+4 FROM t1;
60   }
61   db func runsql ::runsql
62   set DB [sqlite3_connection_pointer db]
63   set sql {SELECT max(x) FROM t1}
64   set ::STMT [sqlite3_prepare_v2 $DB $sql -1 TAIL]
66   # The runsql() call on the second row of the first query will
67   # cause all $::STMT to hit an expired cookie.  Prior to the fix
68   # for [b72787b1a7, the bad cookie would expire all statements, including
69   # the following compound SELECT, which would cause a fault when the
70   # second SELECT was reached.  After the fix, the current statement
71   # continues to completion.
72   db eval {
73     SELECT CASE WHEN y=3 THEN y+100 WHEN y==4 THEN runsql()+200
74                 ELSE 300+y END FROM t2
75     UNION ALL
76     SELECT * FROM t1;
77   }
78 } {103 202 305 306 1 2}
80 sqlite3_finalize $::STMT
82 finish_test