xref: /sqlite-3.40.0/test/progress.test (revision eeb31ff5)
1348bb5d6Sdanielk1977# 2001 September 15
2348bb5d6Sdanielk1977#
3348bb5d6Sdanielk1977# The author disclaims copyright to this source code.  In place of
4348bb5d6Sdanielk1977# a legal notice, here is a blessing:
5348bb5d6Sdanielk1977#
6348bb5d6Sdanielk1977#    May you do good and not evil.
7348bb5d6Sdanielk1977#    May you find forgiveness for yourself and forgive others.
8348bb5d6Sdanielk1977#    May you share freely, never taking more than you give.
9348bb5d6Sdanielk1977#
10348bb5d6Sdanielk1977#***********************************************************************
11348bb5d6Sdanielk1977# This file implements regression tests for SQLite library.  The
12348bb5d6Sdanielk1977# focus of this file is testing the 'progress callback'.
13348bb5d6Sdanielk1977#
14de523accSdanielk1977# $Id: progress.test,v 1.8 2007/06/15 14:53:53 danielk1977 Exp $
15348bb5d6Sdanielk1977
16348bb5d6Sdanielk1977set testdir [file dirname $argv0]
17348bb5d6Sdanielk1977source $testdir/tester.tcl
18348bb5d6Sdanielk1977
194489f9bdSdanielk1977# If the progress callback is not available in this build, skip this
204489f9bdSdanielk1977# whole file.
214489f9bdSdanielk1977ifcapable !progress {
224489f9bdSdanielk1977  finish_test
234489f9bdSdanielk1977  return
244489f9bdSdanielk1977}
254489f9bdSdanielk1977
26348bb5d6Sdanielk1977# Build some test data
27348bb5d6Sdanielk1977#
28348bb5d6Sdanielk1977execsql {
29348bb5d6Sdanielk1977  BEGIN;
30348bb5d6Sdanielk1977  CREATE TABLE t1(a);
31348bb5d6Sdanielk1977  INSERT INTO t1 VALUES(1);
32348bb5d6Sdanielk1977  INSERT INTO t1 VALUES(2);
33348bb5d6Sdanielk1977  INSERT INTO t1 VALUES(3);
34348bb5d6Sdanielk1977  INSERT INTO t1 VALUES(4);
35348bb5d6Sdanielk1977  INSERT INTO t1 VALUES(5);
36348bb5d6Sdanielk1977  INSERT INTO t1 VALUES(6);
37348bb5d6Sdanielk1977  INSERT INTO t1 VALUES(7);
38348bb5d6Sdanielk1977  INSERT INTO t1 VALUES(8);
39348bb5d6Sdanielk1977  INSERT INTO t1 VALUES(9);
40348bb5d6Sdanielk1977  INSERT INTO t1 VALUES(10);
41348bb5d6Sdanielk1977  COMMIT;
42348bb5d6Sdanielk1977}
43348bb5d6Sdanielk1977
44348bb5d6Sdanielk1977
45348bb5d6Sdanielk1977# Test that the progress callback is invoked.
46348bb5d6Sdanielk1977do_test progress-1.0 {
47348bb5d6Sdanielk1977  set counter 0
48348bb5d6Sdanielk1977  db progress 1 "[namespace code {incr counter}] ; expr 0"
49348bb5d6Sdanielk1977  execsql {
50348bb5d6Sdanielk1977    SELECT * FROM t1
51348bb5d6Sdanielk1977  }
52348bb5d6Sdanielk1977  expr $counter > 1
53348bb5d6Sdanielk1977} 1
540f14e2ebSdrhdo_test progress-1.0.1 {
550f14e2ebSdrh  db progress
560f14e2ebSdrh} {::namespace inscope :: {incr counter} ; expr 0}
570f14e2ebSdrhdo_test progress-1.0.2 {
580f14e2ebSdrh  set v [catch {db progress xyz bogus} msg]
590f14e2ebSdrh  lappend v $msg
600f14e2ebSdrh} {1 {expected integer but got "xyz"}}
61348bb5d6Sdanielk1977
62348bb5d6Sdanielk1977# Test that the query is abandoned when the progress callback returns non-zero
63b45bb9f1Sdrhdo_test progress-1.1 {
64348bb5d6Sdanielk1977  set counter 0
65348bb5d6Sdanielk1977  db progress 1 "[namespace code {incr counter}] ; expr 1"
661d850a72Sdanielk1977  set rc [catch {execsql {
67348bb5d6Sdanielk1977    SELECT * FROM t1
681d850a72Sdanielk1977  }}]
691d850a72Sdanielk1977  list $counter $rc
701d850a72Sdanielk1977} {1 1}
71348bb5d6Sdanielk1977
72348bb5d6Sdanielk1977# Test that the query is rolled back when the progress callback returns
73348bb5d6Sdanielk1977# non-zero.
74b45bb9f1Sdrhdo_test progress-1.2 {
75348bb5d6Sdanielk1977
76348bb5d6Sdanielk1977  # This figures out how many opcodes it takes to copy 5 extra rows into t1.
77348bb5d6Sdanielk1977  db progress 1 "[namespace code {incr five_rows}] ; expr 0"
78348bb5d6Sdanielk1977  set five_rows 0
79348bb5d6Sdanielk1977  execsql {
80348bb5d6Sdanielk1977    INSERT INTO t1 SELECT a+10 FROM t1 WHERE a < 6
81348bb5d6Sdanielk1977  }
82348bb5d6Sdanielk1977  db progress 0 ""
83348bb5d6Sdanielk1977  execsql {
84348bb5d6Sdanielk1977    DELETE FROM t1 WHERE a > 10
85348bb5d6Sdanielk1977  }
86348bb5d6Sdanielk1977
87348bb5d6Sdanielk1977  # Now set up the progress callback to abandon the query after the number of
88348bb5d6Sdanielk1977  # opcodes to copy 5 rows. That way, when we try to copy 6 rows, we know
89348bb5d6Sdanielk1977  # some data will have been inserted into the table by the time the progress
90348bb5d6Sdanielk1977  # callback abandons the query.
91348bb5d6Sdanielk1977  db progress $five_rows "expr 1"
921d850a72Sdanielk1977  catchsql {
931d850a72Sdanielk1977    INSERT INTO t1 SELECT a+10 FROM t1 WHERE a < 9
94348bb5d6Sdanielk1977  }
95348bb5d6Sdanielk1977  execsql {
96348bb5d6Sdanielk1977    SELECT count(*) FROM t1
97348bb5d6Sdanielk1977  }
98348bb5d6Sdanielk1977} 10
99348bb5d6Sdanielk1977
1003fe11f30Sdanielk1977# Test that an active transaction remains active and not rolled back
1013fe11f30Sdanielk1977# after the progress query abandons a query.
1023fe11f30Sdanielk1977#
1033fe11f30Sdanielk1977# UPDATE: It is now recognised that this is a sure route to database
1043fe11f30Sdanielk1977# corruption. So the transaction is rolled back.
105b45bb9f1Sdrhdo_test progress-1.3 {
106348bb5d6Sdanielk1977
107348bb5d6Sdanielk1977  db progress 0 ""
108348bb5d6Sdanielk1977  execsql BEGIN
109348bb5d6Sdanielk1977  execsql {
110348bb5d6Sdanielk1977    INSERT INTO t1 VALUES(11)
111348bb5d6Sdanielk1977  }
112348bb5d6Sdanielk1977  db progress 1 "expr 1"
1131d850a72Sdanielk1977  catchsql {
114348bb5d6Sdanielk1977    INSERT INTO t1 VALUES(12)
115348bb5d6Sdanielk1977  }
116348bb5d6Sdanielk1977  db progress 0 ""
1173fe11f30Sdanielk1977  catchsql COMMIT
1183fe11f30Sdanielk1977} {1 {cannot commit - no transaction is active}}
1193fe11f30Sdanielk1977do_test progress-1.3.1 {
120348bb5d6Sdanielk1977  execsql {
121348bb5d6Sdanielk1977    SELECT count(*) FROM t1
122348bb5d6Sdanielk1977  }
1233fe11f30Sdanielk1977} 10
124348bb5d6Sdanielk1977
125348bb5d6Sdanielk1977# Check that a value of 0 for N means no progress callback
126b45bb9f1Sdrhdo_test progress-1.4 {
127348bb5d6Sdanielk1977  set counter 0
128348bb5d6Sdanielk1977  db progress 0 "[namespace code {incr counter}] ; expr 0"
129348bb5d6Sdanielk1977  execsql {
130348bb5d6Sdanielk1977    SELECT * FROM t1;
131348bb5d6Sdanielk1977  }
132348bb5d6Sdanielk1977  set counter
133348bb5d6Sdanielk1977} 0
134348bb5d6Sdanielk1977
135348bb5d6Sdanielk1977db progress 0 ""
136348bb5d6Sdanielk1977
137f8888bb2Sdrh# Make sure other queries can be run from within the progress
138f8888bb2Sdrh# handler.  Ticket #1827
139f8888bb2Sdrh#
140f8888bb2Sdrhdo_test progress-1.5 {
141f8888bb2Sdrh  set rx 0
142f8888bb2Sdrh  proc set_rx {args} {
143f8888bb2Sdrh    db progress 0 {}
144f8888bb2Sdrh    set ::rx [db eval {SELECT count(*) FROM t1}]
145f8888bb2Sdrh    return [expr 0]
146f8888bb2Sdrh  }
147f8888bb2Sdrh  db progress 10 set_rx
148f8888bb2Sdrh  db eval {
149f8888bb2Sdrh    SELECT sum(a) FROM t1
150f8888bb2Sdrh  }
1513fe11f30Sdanielk1977} {55}
152f8888bb2Sdrhdo_test progress-1.6 {
153f8888bb2Sdrh  set ::rx
1543fe11f30Sdanielk1977} {10}
155f8888bb2Sdrh
156de523accSdanielk1977# Check that abandoning a query using the progress handler does
157de523accSdanielk1977# not cause other queries to abort. Ticket #2415.
158de523accSdanielk1977do_test progress-1.7 {
159de523accSdanielk1977  execsql {
160de523accSdanielk1977    CREATE TABLE abc(a, b, c);
161de523accSdanielk1977    INSERT INTO abc VALUES(1, 2, 3);
162de523accSdanielk1977    INSERT INTO abc VALUES(4, 5, 6);
163de523accSdanielk1977    INSERT INTO abc VALUES(7, 8, 9);
164de523accSdanielk1977  }
165de523accSdanielk1977
166de523accSdanielk1977  set ::res [list]
167de523accSdanielk1977  db eval {SELECT a, b, c FROM abc} {
168de523accSdanielk1977    lappend ::res $a $b $c
16949afe3aaSdrh    db progress 5 "expr 1"
170de523accSdanielk1977    catch {db eval {SELECT a, b, c FROM abc} { }} msg
171*22c745a9Sdan    db progress 5 "expr 0"
172de523accSdanielk1977    lappend ::res $msg
173de523accSdanielk1977  }
174de523accSdanielk1977
175de523accSdanielk1977  set ::res
176de523accSdanielk1977} {1 2 3 interrupted 4 5 6 interrupted 7 8 9 interrupted}
177de523accSdanielk1977
178348bb5d6Sdanielk1977finish_test
179