/ Check-in [d596f513]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Improvements to testing of sqlite_interrupt. More checking for interrupt inside of VACUUM. (CVS 1344)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | version_2
Files: files | file ages | folders
SHA1: d596f513c3acfe0d297dc3f5c66f4b0ea2d12a34
User & Date: drh 2004-05-10 20:27:41
Context
2004-06-04
19:07
Calling sqlite_interrupt() while VACUUM is running should not cause an error. (CVS 1529) check-in: 1cf94a7c user: drh tags: version_2
2004-05-10
20:27
Improvements to testing of sqlite_interrupt. More checking for interrupt inside of VACUUM. (CVS 1344) check-in: d596f513 user: drh tags: version_2
2004-05-07
01:46
Fix a memory leak in DETACH when using the codec. (CVS 1317) check-in: c4bd99b7 user: drh tags: version_2
Changes
Hide Diffs Unified Diffs Show Whitespace Changes Patch

Changes to src/vacuum.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
234
235
236
237
238
239
240



241
242
243
244
245
246
247
...
304
305
306
307
308
309
310




311
312
313
314
315
316
317
318
319
320
**
*************************************************************************
** This file contains code used to implement the VACUUM command.
**
** Most of the code in this file may be omitted by defining the
** SQLITE_OMIT_VACUUM macro.
**
** $Id: vacuum.c,v 1.13 2004/03/10 18:57:32 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"

/*
** A structure for holding a dynamic string - a string that can grow
** without bound. 
................................................................................
     /* "default_temp_store", */
  };

  if( db->flags & SQLITE_InTrans ){
    sqliteSetString(pzErrMsg, "cannot VACUUM from within a transaction", 
       (char*)0);
    return SQLITE_ERROR;



  }
  memset(&sVac, 0, sizeof(sVac));

  /* Get the full pathname of the database file and create two
  ** temporary filenames in the same directory as the original file.
  */
  zFilename = sqliteBtreeGetFilename(db->aDb[0].pBt);
................................................................................

end_of_vacuum:
  if( rc && zErrMsg!=0 ){
    sqliteSetString(pzErrMsg, "unable to vacuum database - ", 
       zErrMsg, (char*)0);
  }
  sqlite_exec(db, "ROLLBACK", 0, 0, 0);




  if( dbNew ) sqlite_close(dbNew);
  sqliteOsDelete(zTemp);
  sqliteFree(zTemp);
  sqliteFree(sVac.s1.z);
  sqliteFree(sVac.s2.z);
  if( zErrMsg ) sqlite_freemem(zErrMsg);
  if( rc==SQLITE_ABORT ) sVac.rc = SQLITE_ERROR;
  return sVac.rc;
#endif
}







|







 







>
>
>







 







>
>
>
>






|



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
...
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
**
*************************************************************************
** This file contains code used to implement the VACUUM command.
**
** Most of the code in this file may be omitted by defining the
** SQLITE_OMIT_VACUUM macro.
**
** $Id: vacuum.c,v 1.13.2.1 2004/05/10 20:27:41 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"

/*
** A structure for holding a dynamic string - a string that can grow
** without bound. 
................................................................................
     /* "default_temp_store", */
  };

  if( db->flags & SQLITE_InTrans ){
    sqliteSetString(pzErrMsg, "cannot VACUUM from within a transaction", 
       (char*)0);
    return SQLITE_ERROR;
  }
  if( db->flags & SQLITE_Interrupt ){
    return SQLITE_INTERRUPT;
  }
  memset(&sVac, 0, sizeof(sVac));

  /* Get the full pathname of the database file and create two
  ** temporary filenames in the same directory as the original file.
  */
  zFilename = sqliteBtreeGetFilename(db->aDb[0].pBt);
................................................................................

end_of_vacuum:
  if( rc && zErrMsg!=0 ){
    sqliteSetString(pzErrMsg, "unable to vacuum database - ", 
       zErrMsg, (char*)0);
  }
  sqlite_exec(db, "ROLLBACK", 0, 0, 0);
  if( (dbNew && (dbNew->flags & SQLITE_Interrupt)) 
         || (db->flags & SQLITE_Interrupt) ){
    rc = SQLITE_INTERRUPT;
  }
  if( dbNew ) sqlite_close(dbNew);
  sqliteOsDelete(zTemp);
  sqliteFree(zTemp);
  sqliteFree(sVac.s1.z);
  sqliteFree(sVac.s2.z);
  if( zErrMsg ) sqlite_freemem(zErrMsg);
  if( rc==SQLITE_ABORT && sVac.rc==SQLITE_OK ) sVac.rc = SQLITE_ERROR;
  return sVac.rc;
#endif
}

Changes to src/vdbe.c.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
..
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
....
4861
4862
4863
4864
4865
4866
4867

4868
4869
4870
4871
4872
4873
4874
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.268.2.1 2004/04/29 16:16:30 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................
** help verify the correct operation of the library.
*/
int sqlite_search_count = 0;

/*
** When this global variable is positive, it gets decremented once before
** each instruction in the VDBE.  When reaches zero, the SQLITE_Interrupt
** of the db.flags field is set in order to simulate and interrupt.
**
** This facility is used for testing purposes only.  It does not function
** in an ordinary build.
*/
int sqlite_interrupt_count = 0;

/*
................................................................................
    }
#endif
  }  /* The end of the for(;;) loop the loops through opcodes */

  /* If we reach this point, it means that execution is finished.
  */
vdbe_halt:

  if( rc ){
    p->rc = rc;
    rc = SQLITE_ERROR;
  }else{
    rc = SQLITE_DONE;
  }
  p->magic = VDBE_MAGIC_HALT;







|







 







|







 







>







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
..
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
....
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.268.2.2 2004/05/10 20:27:41 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................
** help verify the correct operation of the library.
*/
int sqlite_search_count = 0;

/*
** When this global variable is positive, it gets decremented once before
** each instruction in the VDBE.  When reaches zero, the SQLITE_Interrupt
** of the db.flags field is set in order to simulate an interrupt.
**
** This facility is used for testing purposes only.  It does not function
** in an ordinary build.
*/
int sqlite_interrupt_count = 0;

/*
................................................................................
    }
#endif
  }  /* The end of the for(;;) loop the loops through opcodes */

  /* If we reach this point, it means that execution is finished.
  */
vdbe_halt:
  CHECK_FOR_INTERRUPT
  if( rc ){
    p->rc = rc;
    rc = SQLITE_ERROR;
  }else{
    rc = SQLITE_DONE;
  }
  p->magic = VDBE_MAGIC_HALT;

Changes to test/interrupt.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
33
34
35
36
37
38
39
40
41
42

43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
...
157
158
159
160
161
162
163
164

165
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is the sqlite_interrupt() API.
#
# $Id: interrupt.test,v 1.4 2004/02/18 16:57:23 drh Exp $


set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Compute a checksum on the entire database.
#
................................................................................
}

# This routine attempts to execute the sql in $sql.  It triggers an
# interrupt a progressively later and later points during the processing
# and checks to make sure SQLITE_INTERRUPT is returned.  Eventually,
# the routine completes successfully.
#
proc interrupt_test {testid sql result {initcnt 0}} {
  set orig_sum [cksum]
  set i $initcnt

  while 1 {
    incr i
    set ::sqlite_interrupt_count $i
    do_test $testid.$i.1 [format {
      set ::r [catchsql %s]
      set ::code [db errorcode]
      expr {$::code==0 || $::code==9}
    } [list $sql]] 1
    if {$::code==9} {
      do_test $testid.$i.2 {
        cksum
      } $orig_sum
    } else {
      do_test $testid.$i.99 {
        set ::r
      } [list 0 $result]
      break
    }
  }
  set ::sqlite_interrupt_count 0
}

do_test interrupt-1.1 {
  execsql {
    CREATE TABLE t1(a,b);
    SELECT name FROM sqlite_master;
  }
} {t1}
interrupt_test interrupt-1.2 {DROP TABLE t1} {}
do_test interrupt-1.3 {
  execsql {
    SELECT name FROM sqlite_master;
  }
} {}
integrity_check interrupt-1.4

................................................................................
set max_count [expr {1000000-$sqlite_interrupt_count}]
for {set i 1} {$i<$max_count-5} {incr i 1} {
  do_test interrupt-4.$i.1 {
    set ::sqlite_interrupt_count $::i
    catchsql $sql
  } {1 interrupted}
}


finish_test







|







 







|


>
|

|









|






|








|







 








>

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
...
158
159
160
161
162
163
164
165
166
167
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is the sqlite_interrupt() API.
#
# $Id: interrupt.test,v 1.4.2.1 2004/05/10 20:27:42 drh Exp $


set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Compute a checksum on the entire database.
#
................................................................................
}

# This routine attempts to execute the sql in $sql.  It triggers an
# interrupt a progressively later and later points during the processing
# and checks to make sure SQLITE_INTERRUPT is returned.  Eventually,
# the routine completes successfully.
#
proc interrupt_test {testid sql result {initcnt 0} {maxcnt 1000000}} {
  set orig_sum [cksum]
  set i $initcnt
  global sqlite_interrupt_count
  while {$i<$maxcnt} {
    incr i
    set sqlite_interrupt_count $i
    do_test $testid.$i.1 [format {
      set ::r [catchsql %s]
      set ::code [db errorcode]
      expr {$::code==0 || $::code==9}
    } [list $sql]] 1
    if {$::code==9} {
      do_test $testid.$i.2 {
        cksum
      } $orig_sum
    } elseif {$sqlite_interrupt_count>0} {
      do_test $testid.$i.99 {
        set ::r
      } [list 0 $result]
      break
    }
  }
  set sqlite_interrupt_count 0
}

do_test interrupt-1.1 {
  execsql {
    CREATE TABLE t1(a,b);
    SELECT name FROM sqlite_master;
  }
} {t1}
interrupt_test interrupt-1.2 {DROP TABLE t1} {} 1 14
do_test interrupt-1.3 {
  execsql {
    SELECT name FROM sqlite_master;
  }
} {}
integrity_check interrupt-1.4

................................................................................
set max_count [expr {1000000-$sqlite_interrupt_count}]
for {set i 1} {$i<$max_count-5} {incr i 1} {
  do_test interrupt-4.$i.1 {
    set ::sqlite_interrupt_count $::i
    catchsql $sql
  } {1 interrupted}
}


finish_test