1: # 2011 February 21
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.
12: #
13: # This file implements tests to verify that ticket [b72787b1a7] has been
14: # fixed. From the ticket:
15: #
16: # The sqlite3ExpirePreparedStatements routine marks all statements
17: # as expired. This includes statements that are not expired.
18: #
19: # Steps to reproduce:
20: #
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
29: #
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.
33: #
34:
35: set testdir [file dirname $argv0]
36: source $testdir/tester.tcl
37:
38: unset -nocomplain ::STMT
39: proc runsql {} {
40: db eval {CREATE TABLE IF NOT EXISTS t4(q)}
41: sqlite3_step $::STMT
42: set rc [sqlite3_column_int $::STMT 0]
43: sqlite3_reset $::STMT
44: return $rc
45: }
46:
47: do_test tkt-b72787b1.1 {
48: db eval {
49: CREATE TABLE t1(x);
50: INSERT INTO t1 VALUES(1);
51: INSERT INTO t1 VALUES(2);
52: CREATE TABLE t2(y);
53: INSERT INTO t2 SELECT x+2 FROM t1;
54: INSERT INTO t2 SELECT x+4 FROM t1;
55: }
56: db func runsql ::runsql
57: set DB [sqlite3_connection_pointer db]
58: set sql {SELECT max(x) FROM t1}
59: set ::STMT [sqlite3_prepare_v2 $DB $sql -1 TAIL]
60:
61: # The runsql() call on the second row of the first query will
62: # cause all $::STMT to hit an expired cookie. Prior to the fix
63: # for [b72787b1a7, the bad cookie would expire all statements, including
64: # the following compound SELECT, which would cause a fault when the
65: # second SELECT was reached. After the fix, the current statement
66: # continues to completion.
67: db eval {
68: SELECT CASE WHEN y=3 THEN y+100 WHEN y==4 THEN runsql()+200
69: ELSE 300+y END FROM t2
70: UNION ALL
71: SELECT * FROM t1;
72: }
73: } {103 202 305 306 1 2}
74:
75: sqlite3_finalize $::STMT
76:
77: finish_test
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>