blob: dea3f49a6409d2678111bfe9282aac3b36430044 [file] [log] [blame]
drh5b6c5452011-02-22 03:34:56 +00001# 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
35set testdir [file dirname $argv0]
36source $testdir/tester.tcl
37
dan2f56da32012-02-13 10:00:35 +000038ifcapable !compound {
39 finish_test
40 return
41}
42
drh5b6c5452011-02-22 03:34:56 +000043unset -nocomplain ::STMT
44proc 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
50}
51
52do_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]
65
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}
79
80sqlite3_finalize $::STMT
81
82finish_test