]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Tests to improve coverage of vdbeaux.c. (CVS 2201)
authordanielk1977 <danielk1977@noemail.net>
Wed, 12 Jan 2005 09:10:39 +0000 (09:10 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Wed, 12 Jan 2005 09:10:39 +0000 (09:10 +0000)
FossilOrigin-Name: 2b3e21ce2e8126ec2851751546094c3a2c831942

manifest
manifest.uuid
src/vdbe.c
src/vdbeInt.h
src/vdbeaux.c
test/ioerr.test
test/malloc.test

index f0a6775b90eae06c7d4e8449a3504d7b5c850a99..4f21e270751b665a620a81b7cfdaaaec0bfd6c79 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Tests\sto\simprove\scoverage\sof\svdbemem.c.\s(CVS\s2200)
-D 2005-01-12T07:15:05
+C Tests\sto\simprove\scoverage\sof\svdbeaux.c.\s(CVS\s2201)
+D 2005-01-12T09:10:40
 F Makefile.in ecf441ac5ca1ccfc8748a8a9537706e69893dfa4
 F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
 F README a01693e454a00cc117967e3f9fdab2d4d52e9bc1
@@ -76,11 +76,11 @@ F src/update.c 0979397c41ac29c54fe0cc687a356d8629a633af
 F src/utf.c 9bece2c7b94d9002ab1bb900a7658c6f826b0f74
 F src/util.c 4511559caf83e70a036deb5c56f10ddf35a688fb
 F src/vacuum.c 1a9db113a027461daaf44724c71dd1ebbd064203
-F src/vdbe.c b8e619fbaa59be3e537804469d8cedd4a98d3c2e
+F src/vdbe.c a89bb4eefa60226ddfdf8e708ea9352c0a124da3
 F src/vdbe.h 067ca8d6750ba4f69a50284765e5883dee860181
-F src/vdbeInt.h 0f74561e629af86172de7cdf0ecaea014c51696c
+F src/vdbeInt.h f2b5f54d9881bbc89fff02d95f3f825ade68bce2
 F src/vdbeapi.c 0cf3bdc1072616bedc8eec7fc22e3f5a169d33fd
-F src/vdbeaux.c 60c24559b458d4da368694c0d322326b22edffd1
+F src/vdbeaux.c 0675db9f7f801b36e2e71504f5380feeadba56bc
 F src/vdbemem.c 5d9fd8de5d4f5d1f3446c9a90a7b3f8c38557821
 F src/where.c 3a0d08505e298242f6f151f019a05129a4f8704c
 F tclinstaller.tcl 36478c3bbfc5b93ceac42d94e3c736937b808432
@@ -138,7 +138,7 @@ F test/insert.test 56f9c20c9adc8d707490c4ffa5d4daa94826ea03
 F test/insert2.test 0bb50ff999e35a21549d8ee5dc44db8ac24d31a7
 F test/interrupt.test 5b4d8389e6cf2d01b94f87cfd02d9df1073bfb2d
 F test/intpkey.test b57cf5236fde1bd8cbc1388fa0c91908f6fd9194
-F test/ioerr.test 01ac547c4a6fc53fcd9fe7ecc9698ab5d827093a
+F test/ioerr.test 0563e3eace01d94661899a90e5888b7817fb57e0
 F test/join.test ea8c77b9fbc377fe553cdb5ce5f1bd72021dca5d
 F test/join2.test c97e4c5aa65dea462145529e58212a709b4722b8
 F test/join3.test 67dc0d7c8dab3fff25796d0f3c3fd9c999aeded3
@@ -150,7 +150,7 @@ F test/lock.test 32fe28e5030f25f23bcf6beef440675b0d848413
 F test/lock2.test 59c3dd7d9b24d1bf7ec91b2d1541c37e97939d5f
 F test/lock3.test 615111293cf32aa2ed16d01c6611737651c96fb9
 F test/main.test a60a1d234b5f5784097973bd395514ca56003ef1
-F test/malloc.test 79c5e0676a8346884b3197c811f2eac60b0521cc
+F test/malloc.test c3985c0a5a2f28dbfdb68a4e07886f9090feeda1
 F test/memdb.test 532aac7128a3da494cddc4461d76c6e3988f771b
 F test/memleak.test f1fa233f8295dd1d955a00d5e5ee857850f27f29
 F test/minmax.test e7048476940df0af11d0f2cf687572f557cd0b29
@@ -268,7 +268,7 @@ F www/tclsqlite.tcl e73f8f8e5f20e8277619433f7970060ab01088fc
 F www/vdbe.tcl 095f106d93875c94b47367384ebc870517431618
 F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
 F www/whentouse.tcl c3b50d3ac31c54be2a1af9b488a89d22f1e6e746
-P 50f1e229652610b386745bb39fed45549cc74aa7
-R bf4878fa2c84d42762e103055cb55fd1
+P 319bb4a9064deb062a888fdc31067619c9b749bb
+R eca04ac646dc0adf8b62dade6edd7859
 U danielk1977
-Z 3c12901d279d54cf5f64fafd62ec59a5
+Z bac0bd5515f392b48e8053527f28ff2a
index c6e2d79a0da1d3e76992f7827a0a444e4534666d..e9bbbfea7e0899db23601401de7401d8fb910b8f 100644 (file)
@@ -1 +1 @@
-319bb4a9064deb062a888fdc31067619c9b749bb
\ No newline at end of file
+2b3e21ce2e8126ec2851751546094c3a2c831942
\ No newline at end of file
index e5992d271e3ea06c8d3c0da8f4f860c374cfc0cd..5389557ad316b7f41b27acf0173800583af2e2b4 100644 (file)
@@ -43,7 +43,7 @@
 ** 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.441 2005/01/12 07:15:06 danielk1977 Exp $
+** $Id: vdbe.c,v 1.442 2005/01/12 09:10:40 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -477,9 +477,9 @@ int sqlite3VdbeExec(
 #endif
     pOp = &p->aOp[pc];
 
-    /* Only allow tracing if NDEBUG is not defined.
+    /* Only allow tracing if SQLITE_DEBUG is defined.
     */
-#ifndef NDEBUG
+#ifdef SQLITE_DEBUG
     if( p->trace ){
       if( pc==0 ){
         printf("VDBE Execution Trace:\n");
@@ -487,8 +487,6 @@ int sqlite3VdbeExec(
       }
       sqlite3VdbePrintOp(p->trace, pc, pOp);
     }
-#endif
-#ifdef SQLITE_TEST
     if( p->trace==0 && pc==0 && sqlite3OsFileExists("vdbe_sqltrace") ){
       sqlite3VdbePrintSql(p);
     }
index 86e601f04a30dbc681741aee7e9d037df7b47ef4..e15a421079d54bba5f3648034d097d2e5754354d 100644 (file)
@@ -362,10 +362,12 @@ int sqlite3VdbeAggReset(sqlite3*, Agg *, KeyInfo *);
 void sqlite3VdbeKeylistFree(Keylist*);
 void sqliteVdbePopStack(Vdbe*,int);
 int sqlite3VdbeCursorMoveto(Cursor*);
-#if !defined(NDEBUG) || defined(VDBE_PROFILE)
+#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
 void sqlite3VdbePrintOp(FILE*, int, Op*);
 #endif
+#ifdef SQLITE_DEBUG
 void sqlite3VdbePrintSql(Vdbe*);
+#endif
 int sqlite3VdbeSerialTypeLen(u32);
 u32 sqlite3VdbeSerialType(Mem*);
 int sqlite3VdbeSerialPut(unsigned char*, Mem*);
index fcf503ae11fa35310d03191f528c3c244f06c9a3..f06e357ef49f31e866c27d88c07cc8732cc6e1bb 100644 (file)
@@ -103,7 +103,7 @@ int sqlite3VdbeAddOp(Vdbe *p, int op, int p1, int p2){
   pOp->p2 = p2;
   pOp->p3 = 0;
   pOp->p3type = P3_NOTUSED;
-#ifndef NDEBUG
+#ifdef SQLITE_DEBUG
   if( sqlite3_vdbe_addop_trace ) sqlite3VdbePrintOp(0, i, &p->aOp[i]);
 #endif
   return i;
@@ -212,7 +212,7 @@ int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp){
       pOut->p2 = p2<0 ? addr + ADDR(p2) : p2;
       pOut->p3 = pIn->p3;
       pOut->p3type = pIn->p3 ? P3_STATIC : P3_NOTUSED;
-#ifndef NDEBUG
+#ifdef SQLITE_DEBUG
       if( sqlite3_vdbe_addop_trace ){
         sqlite3VdbePrintOp(0, i+addr, &p->aOp[i+addr]);
       }
@@ -449,7 +449,7 @@ static char *displayP3(Op *pOp, char *zTemp, int nTemp){
 #endif
 
 
-#if !defined(NDEBUG) || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
+#if defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
 /*
 ** Print a single opcode.  This routine is used for debugging only.
 */
@@ -689,7 +689,7 @@ void sqlite3VdbeSorterReset(Vdbe *p){
 ** Free all resources allociated with AggElem pElem, an element of
 ** aggregate pAgg.
 */
-void freeAggElem(AggElem *pElem, Agg *pAgg){
+static void freeAggElem(AggElem *pElem, Agg *pAgg){
   int i;
   for(i=0; i<pAgg->nMem; i++){
     Mem *pMem = &pElem->aMem[i];
@@ -752,7 +752,7 @@ int sqlite3VdbeAggReset(sqlite3 *db, Agg *pAgg, KeyInfo *pKeyInfo){
     while( res==0 && rc==SQLITE_OK ){
       AggElem *pElem;
       rc = sqlite3BtreeData(pCsr, 0, sizeof(AggElem*), (char *)&pElem);
-      if( res!=SQLITE_OK ){
+      if( rc!=SQLITE_OK ){
         return rc;
       }
       assert( pAgg->apFunc!=0 );
@@ -1058,18 +1058,12 @@ static int vdbeCommit(sqlite3 *db){
     */
     zMainFile = sqlite3BtreeGetDirname(db->aDb[0].pBt);
     rc = sqlite3OsOpenDirectory(zMainFile, &master);
-    if( rc!=SQLITE_OK ){
+    if( rc!=SQLITE_OK || (rc = sqlite3OsSync(&master))!=SQLITE_OK ){
       sqlite3OsClose(&master);
       sqlite3OsDelete(zMaster);
       sqliteFree(zMaster);
       return rc;
     }
-    rc = sqlite3OsSync(&master);
-    if( rc!=SQLITE_OK ){
-      sqlite3OsClose(&master);
-      sqliteFree(zMaster);
-      return rc;
-    }
 
     /* Sync all the db files involved in the transaction. The same call
     ** sets the master journal pointer in each individual journal. If
@@ -1111,8 +1105,6 @@ static int vdbeCommit(sqlite3 *db){
       ** master journal exists now or if it will exist after the operating
       ** system crash that may follow the fsync() failure.
       */
-      assert(0);
-      sqliteFree(zMaster);
       return rc;
     }
 
index 75f6806eb0b5fdb20518af2abdd7ac83c6b5137f..fe56811d9b5d8ac0190320d0a69e0e6244efad0d 100644 (file)
 # The tests in this file use special facilities that are only
 # available in the SQLite test fixture.
 #
-# $Id: ioerr.test,v 1.10 2005/01/11 13:02:34 danielk1977 Exp $
+# $Id: ioerr.test,v 1.11 2005/01/12 09:10:41 danielk1977 Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
 
 set ::AV [execsql {pragma auto_vacuum}]
 
-set ::go 1
-for {set n 1} {$go} {incr n} {
+# Usage: do_ioerr_test <test number> <options...>
+#
+# The first argument, <test number>, is an integer used to name the
+# tests executed by this proc. Options are as follows:
+#
+#     -tclprep          TCL script to run to prepare test.
+#     -sqlprep          SQL script to run to prepare test.
+#     -tclbody          TCL script to run with IO error simulation.
+#     -sqlbody          TCL script to run with IO error simulation.
+#     -exclude          List of 'N' values not to test.
+#
+proc do_ioerr_test {tn args} {
+  array set ::ioerropts $args
 
-  # If SQLITE_DEFAULT_AUTOVACUUM is set to true, then a simulated IO error
-  # on the 8th IO operation in the SQL script below doesn't report an error.
-  #
-  # This is because the 8th IO call attempts to read page 2 of the database
-  # file when the file on disk is only 1 page. The pager layer detects that
-  # this has happened and suppresses the error returned by the OS layer.
-  #
-  if {$::AV} {
-    if {$n==8} continue
-  } 
+  set ::go 1
+  for {set n 1} {$::go} {incr n} {
+    if {[info exists ::ioerropts(-exclude)]} {
+      if {[lsearch $::ioerropts(-exclude) $n]!=-1} continue
+    }
 
-  do_test ioerr-1.$n.1 {
-    set ::sqlite_io_error_pending 0
-    db close
-    catch {file delete -force test.db}
-    catch {file delete -force test.db-journal}
-    sqlite3 db test.db
-    execsql {SELECT * FROM sqlite_master}
-  } {}
-  do_test ioerr-1.$n.2 [subst {
-    set ::sqlite_io_error_pending $n
-  }] $n
-  do_test ioerr-1.$n.3 {
-    set r [catch {db eval {
-      CREATE TABLE t1(a,b,c);
-      SELECT * FROM sqlite_master;
-      BEGIN TRANSACTION;
-      INSERT INTO t1 VALUES(1,2,3);
-      INSERT INTO t1 VALUES(4,5,6);
-      ROLLBACK;
-      SELECT * FROM t1;
-      BEGIN TRANSACTION;
-      INSERT INTO t1 VALUES(1,2,3);
-      INSERT INTO t1 VALUES(4,5,6);
-      COMMIT;
-      SELECT * FROM t1;
-      DELETE FROM t1 WHERE a<100;
-    }} msg]
-    # if {$r} {puts $msg}
-    set ::go [expr {$::sqlite_io_error_pending<=0}]
-    expr {$::sqlite_io_error_pending>0 || $r!=0}
-  } {1}
+    do_test ioerr-$tn.$n.1 {
+      set ::sqlite_io_error_pending 0
+      db close
+      catch {file delete -force test.db}
+      catch {file delete -force test.db-journal}
+      catch {file delete -force test2.db}
+      catch {file delete -force test2.db-journal}
+  
+      set ::DB [sqlite3 db test.db]
+  
+      if {[info exists ::ioerropts(-tclprep)]} {
+        eval $::ioerropts(-tclprep)
+      }
+      if {[info exists ::ioerropts(-sqlprep)]} {
+        execsql $::ioerropts(-sqlprep)
+      }
+      expr 0
+    } {0}
+  
+    do_test ioerr-$tn.$n.2 [subst {
+      set ::sqlite_io_error_pending $n
+    }] $n
+  
+    set ::ioerrorbody {}
+    if {[info exists ::ioerropts(-tclbody)]} {
+      append ::ioerrorbody "$::ioerropts(-tclbody)\n"
+    }
+    if {[info exists ::ioerropts(-sqlbody)]} {
+      append ::ioerrorbody "db eval {$::ioerropts(-sqlbody)}"
+    }
+    do_test ioerr-$tn.$n.3 {
+      set r [catch $::ioerrorbody msg]
+      set ::go [expr {$::sqlite_io_error_pending<=0}]
+      expr {$::sqlite_io_error_pending>0 || $r!=0}
+    } {1}
+  }
+  set ::sqlite_io_error_pending 0
 }
-set ::sqlite_io_error_pending 0
+
+# If SQLITE_DEFAULT_AUTOVACUUM is set to true, then a simulated IO error
+# on the 8th IO operation in the SQL script below doesn't report an error.
+#
+# This is because the 8th IO call attempts to read page 2 of the database
+# file when the file on disk is only 1 page. The pager layer detects that
+# this has happened and suppresses the error returned by the OS layer.
+#
+do_ioerr_test 1 -sqlprep {
+  SELECT * FROM sqlite_master;
+} -sqlbody {
+  CREATE TABLE t1(a,b,c);
+  SELECT * FROM sqlite_master;
+  BEGIN TRANSACTION;
+  INSERT INTO t1 VALUES(1,2,3);
+  INSERT INTO t1 VALUES(4,5,6);
+  ROLLBACK;
+  SELECT * FROM t1;
+  BEGIN TRANSACTION;
+  INSERT INTO t1 VALUES(1,2,3);
+  INSERT INTO t1 VALUES(4,5,6);
+  COMMIT;
+  SELECT * FROM t1;
+  DELETE FROM t1 WHERE a<100;
+} -exclude [expr [execsql {pragma auto_vacuum}] ? 8 : 0]
+
 
 proc cksum {{db db}} {
   set txt [$db eval {
@@ -95,6 +133,8 @@ for {set n 1} {$go} {incr n} {
     db close
     catch {file delete -force test.db}
     catch {file delete -force test.db-journal}
+    catch {file delete -force test2.db}
+    catch {file delete -force test2.db-journal}
     sqlite3 db test.db
     execsql {
       BEGIN;
@@ -135,72 +175,51 @@ for {set n 1} {$go} {incr n} {
 }
 set ::sqlite_io_error_pending 0
 
-set ::go 1
-for {set n 1} {$go} {incr n} {
-  do_test ioerr-3.$n.1 {
-    set ::sqlite_io_error_pending 0
-    db close
-    catch {file delete -force test.db}
-    catch {file delete -force test.db-journal}
-    sqlite3 db test.db
+
+do_ioerr_test 3 -tclprep {
+  execsql {
+    PRAGMA cache_size = 10;
+    BEGIN;
+    CREATE TABLE abc(a);
+    INSERT INTO abc VALUES(randstr(1500,1500)); -- Page 4 is overflow
+  }
+  for {set i 0} {$i<150} {incr i} {
     execsql {
-      PRAGMA cache_size = 10;
-      BEGIN;
-      CREATE TABLE abc(a);
-      INSERT INTO abc VALUES(randstr(1500,1500)); -- Page 4 is overflow
+      INSERT INTO abc VALUES(randstr(100,100)); 
     }
-    for {set i 0} {$i<150} {incr i} {
-      execsql {
-        INSERT INTO abc VALUES(randstr(100,100)); 
-      }
-    }
-    execsql COMMIT
-  } {}
-  do_test ioerr-3.$n.2 [subst {
-    set ::sqlite_io_error_pending $n
-  }] $n
-  do_test ioerr-3.$n.3 {
-    set r [catch {db eval {
-      CREATE TABLE abc2(a);
-      BEGIN;
-      DELETE FROM abc WHERE length(a)>100;
-      UPDATE abc SET a = randstr(90,90);
-      COMMIT;
-      CREATE TABLE abc3(a);
-    }} msg]
-    set ::go [expr {$::sqlite_io_error_pending<=0}]
-    expr {$::sqlite_io_error_pending>0 || $r!=0}
-  } {1}
+  }
+  execsql COMMIT
+} -sqlbody {
+  CREATE TABLE abc2(a);
+  BEGIN;
+  DELETE FROM abc WHERE length(a)>100;
+  UPDATE abc SET a = randstr(90,90);
+  COMMIT;
+  CREATE TABLE abc3(a);
 }
-set ::sqlite_io_error_pending 0
 
-set ::go 1
-for {set n 1} {$go} {incr n} {
-  do_test ioerr-4.$n.1 {
-    set ::sqlite_io_error_pending 0
-    db close
-    catch {file delete -force test.db}
-    catch {file delete -force test.db-journal}
-    sqlite3 db test.db
-    set sql "CREATE TABLE abc(a1"
-    for {set i 2} {$i<1300} {incr i} {
-      append sql ", a$i"
-    }
-    append sql ");"
-    execsql $sql
-    execsql {INSERT INTO abc (a1) VALUES(NULL)}
-  } {}
-  do_test ioerr-4.$n.2 [subst {
-    set ::sqlite_io_error_pending $n
-  }] $n
-  do_test ioerr-4.$n.3 {
-    set r [catch {db eval {
-      SELECT * FROM abc;
-    }} msg]
-    set ::go [expr {$::sqlite_io_error_pending<=0}]
-    expr {$::sqlite_io_error_pending>0 || $r!=0}
-  } {1}
+# Test IO errors that can occur retrieving a record header that flows over
+# onto an overflow page.
+do_ioerr_test 4 -tclprep {
+  set sql "CREATE TABLE abc(a1"
+  for {set i 2} {$i<1300} {incr i} {
+    append sql ", a$i"
+  }
+  append sql ");"
+  execsql $sql
+  execsql {INSERT INTO abc (a1) VALUES(NULL)}
+} -sqlbody {
+ SELECT * FROM abc;
+}
+
+# Test IO errors that may occur during a multi-file commit.
+do_ioerr_test 5 -sqlprep {
+  ATTACH 'test2.db' AS test2;
+} -sqlbody {
+  BEGIN;
+  CREATE TABLE t1(a,b,c);
+  CREATE TABLE test2.t2(a,b,c);
+  COMMIT;
 }
-set ::sqlite_io_error_pending 0
 
 finish_test
index 3d8876024dd2d66c1b73b72f40143bd0cd40a07a..9b117b68e9fac7776a0c6dd6d2f66fb264eba83f 100644 (file)
@@ -14,7 +14,7 @@
 # special feature is used to see what happens in the library if a malloc
 # were to really fail due to an out-of-memory situation.
 #
-# $Id: malloc.test,v 1.14 2005/01/12 07:15:07 danielk1977 Exp $
+# $Id: malloc.test,v 1.15 2005/01/12 09:10:41 danielk1977 Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -342,8 +342,12 @@ for {set go 1; set i 1} {$go} {incr i} {
 # when converting UTF-16 text to integers and real numbers is handled
 # correctly. 
 #
-# This doesn't actually return an error to the user. That could be 
-# viewed as a bug.
+# This is done by retrieving a string from the database engine and
+# manipulating it using the sqlite3_column_*** APIs. This doesn't 
+# actually return an error to the user when a malloc() fails.. That 
+# could be viewed as a bug.
+#
+# These tests only run if UTF-16 support is compiled in.
 #
 for {set go 1; set i 1} {$go && $::sqlite_options(utf16)} {incr i} {
   do_test malloc-8.$i {
@@ -382,6 +386,46 @@ for {set go 1; set i 1} {$go && $::sqlite_options(utf16)} {incr i} {
   } {0}
 }
 
+# This block tests that malloc() failures that occur whilst commiting
+# a multi-file transaction are handled correctly.
+#
+for {set go 1; set i 1} {$go} {incr i} {
+  do_test malloc-9.$i {
+     sqlite_malloc_fail 0
+     catch {db close}
+     catch {file delete -force test.db}
+     catch {file delete -force test.db-journal}
+     catch {file delete -force test2.db}
+     catch {file delete -force test2.db-journal}
+
+     sqlite3 db test.db
+     execsql {
+       ATTACH 'test2.db' as test2;
+       CREATE TABLE abc1(a, b, c);
+       CREATE TABLE test2.abc2(a, b, c);
+     }
+
+     sqlite_malloc_fail $i
+     set v [catch {execsql {
+       BEGIN;
+       INSERT INTO abc1 VALUES(1, 2, 3);
+       INSERT INTO abc2 VALUES(1, 2, 3);
+       COMMIT;
+     }} msg]
+     set leftover [lindex [sqlite_malloc_stat] 2]
+     if {$leftover>0} {
+       if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v  Message=$msg"}
+       set ::go 0
+       set v {1 1}
+     } else {
+       set v2 [expr {$msg=="" || $msg=="out of memory"}]
+       if {!$v2} {puts "\nError message returned: $msg"}
+       lappend v $v2
+     }
+  } {1 1}
+}
+
+
 # Ensure that no file descriptors were leaked.
 do_test malloc-99.X {
   catch {db close}