]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Test some more incremental IO error cases. (CVS 3910)
authordanielk1977 <danielk1977@noemail.net>
Thu, 3 May 2007 18:14:10 +0000 (18:14 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Thu, 3 May 2007 18:14:10 +0000 (18:14 +0000)
FossilOrigin-Name: 64705410bdf43b6283f7a7e59ce8c20d09cd46e4

manifest
manifest.uuid
src/vdbeblob.c
test/incrblob.test

index dcb854d0b8125ca69ce440906685c62804ed8140..ff539b71f8077cd6236925fe371930202b99917a 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Improvements\sto\sI/O\stracing\soutput.\s\sRequire\s-DSQLITE_ENABLE_IOTRACE\swhen\ncompiling\sshell.c\sin\sorder\sto\slink\sin\sthe\sI/O\stracing\scapability.\s(CVS\s3909)
-D 2007-05-03T17:18:37
+C Test\ssome\smore\sincremental\sIO\serror\scases.\s(CVS\s3910)
+D 2007-05-03T18:14:10
 F Makefile.in 8cab54f7c9f5af8f22fd97ddf1ecfd1e1860de62
 F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -130,7 +130,7 @@ F src/vdbe.h 0025259af1939fb264a545816c69e4b5b8d52691
 F src/vdbeInt.h cb02cbbceddf3b40d49012e9f41576f17bcbec97
 F src/vdbeapi.c 37d793559390bec8a00c556f651f21b5f9e589af
 F src/vdbeaux.c 8c7f22e22d1ea578971f5a3fcd3a56a6882ced64
-F src/vdbeblob.c 74fe0c7fc149a80715be7e3a33ed0e545d5e33e1
+F src/vdbeblob.c ed2f9b46cc2de8de97d2a4a4ec466c5914d68333
 F src/vdbefifo.c 3ca8049c561d5d67cbcb94dc909ae9bb68c0bf8f
 F src/vdbemem.c ba98f8572ec4609846b368fa7580db178022f1bb
 F src/vtab.c 89a0d5f39c1beba65a77fdb4d507b831fc5e6baf
@@ -242,7 +242,7 @@ F test/fts2n.test a70357e72742681eaebfdbe9007b87ff3b771638
 F test/func.test 6727c7729472ae52b5acd86e802f89aa350ba50f
 F test/hook.test 7e7645fd9a033f79cce8fdff151e32715e7ec50a
 F test/in.test 369cb2aa1eab02296b4ec470732fe8c131260b1d
-F test/incrblob.test 9f6f5c23716d6c9386d1011cff732399900750df
+F test/incrblob.test 5cf5a7693c6cde33eef361d94c00c7bdbc30f563
 F test/incrvacuum.test 2173bc075c7b3b96ccf228d737dd4f5c29500dc4
 F test/incrvacuum_ioerr.test 0ebc382bcc2036ec58cf49cc5ffada45f75d907b
 F test/index.test e65df12bed94b2903ee89987115e1578687e9266
@@ -473,7 +473,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
 F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
-P 92b53601657be3f1be70873b2960cd97b97f72a1
-R 2fb024d0ffb855b54c72bde6978aacd6
-U drh
-Z f0fb6fb797fd898d24e13ec3e7829264
+P 8a43e1676fdd29903e0b3f9d3b05d217d42962b8
+R f2daf03cbf23d5e395cd82f06da9d675
+U danielk1977
+Z 8d660e54025b30b52414bf1578df31ed
index 32922fd5652bbd6a528829ce7739e71d0eeef2d4..090107392a711ea79f9a9961b62f886a2a5de33e 100644 (file)
@@ -1 +1 @@
-8a43e1676fdd29903e0b3f9d3b05d217d42962b8
\ No newline at end of file
+64705410bdf43b6283f7a7e59ce8c20d09cd46e4
\ No newline at end of file
index b095a5e8144c2086ac0ad5065cdac32fc107c0e5..c81ac214103f4f8e58ade0689fb33e55034798c6 100644 (file)
@@ -10,7 +10,7 @@
 **
 *************************************************************************
 **
-** $Id: vdbeblob.c,v 1.4 2007/05/03 16:31:26 danielk1977 Exp $
+** $Id: vdbeblob.c,v 1.5 2007/05/03 18:14:10 danielk1977 Exp $
 */
 
 #include "sqliteInt.h"
@@ -101,7 +101,6 @@ int sqlite3_blob_open(
     if( !pTab ){
       if( sParse.zErrMsg ){
         sqlite3_snprintf(sizeof(zErr), zErr, "%s", sParse.zErrMsg);
-        zErr[sizeof(zErr)-1] = '\0';
       }
       sqliteFree(sParse.zErrMsg);
       rc = SQLITE_ERROR;
@@ -116,12 +115,31 @@ int sqlite3_blob_open(
       }
     }
     if( iCol==pTab->nCol ){
-      sprintf(zErr, "no such column: \"%s\"", zColumn);
+      sqlite3_snprintf(sizeof(zErr), zErr, "no such column: \"%s\"", zColumn);
       rc = SQLITE_ERROR;
       sqlite3SafetyOff(db);
       goto blob_open_out;
     }
 
+    /* If the value is being opened for writing, check that the
+    ** column is not indexed. It is against the rules to open an
+    ** indexed column for writing.
+    */
+    if( flags ){
+      Index *pIdx;
+      for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+        int j;
+        for(j=0; j<pIdx->nColumn; j++){
+          if( pIdx->aiColumn[j]==iCol ){
+            strcpy(zErr, "cannot open indexed column for writing");
+            rc = SQLITE_ERROR;
+            sqlite3SafetyOff(db);
+            goto blob_open_out;
+          }
+        }
+      }
+    }
+
     v = sqlite3VdbeCreate(db);
     if( v ){
       int iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
@@ -138,8 +156,8 @@ int sqlite3_blob_open(
       /* Configure the db number pushed onto the stack */
       sqlite3VdbeChangeP1(v, 2, iDb);
 
-      /* Remove either the OP_OpenWrite or OpenRead. Set the P2 parameter
-      ** of the other to pTab->tnum. 
+      /* Remove either the OP_OpenWrite or OpenRead. Set the P2 
+      ** parameter of the other to pTab->tnum. 
       */
       sqlite3VdbeChangeToNoop(v, (flags ? 3 : 4), 1);
       sqlite3VdbeChangeP2(v, (flags ? 4 : 3), pTab->tnum);
@@ -165,7 +183,7 @@ int sqlite3_blob_open(
     if( rc!=SQLITE_ROW ){
       nAttempt++;
       rc = sqlite3_finalize((sqlite3_stmt *)v);
-      sprintf(zErr, "no such rowid: %lld", iRow);
+      sqlite3_snprintf(sizeof(zErr), zErr, sqlite3_errmsg(db));
       v = 0;
     }
   } while( nAttempt<5 && rc==SQLITE_SCHEMA );
@@ -179,6 +197,9 @@ int sqlite3_blob_open(
     u32 type = v->apCsr[0]->aType[iCol];
 
     if( type<12 ){
+      sqlite3_snprintf(sizeof(zErr), zErr, "cannot open value of type %s",
+          type==0?"null": type==7?"real": "integer"
+      );
       rc = SQLITE_ERROR;
       goto blob_open_out;
     }
@@ -196,6 +217,7 @@ int sqlite3_blob_open(
     *ppBlob = (sqlite3_blob *)pBlob;
     rc = SQLITE_OK;
   }else if( rc==SQLITE_OK ){
+    sqlite3_snprintf(sizeof(zErr), zErr, "no such rowid: %lld", iRow);
     rc = SQLITE_ERROR;
   }
 
@@ -203,6 +225,7 @@ blob_open_out:
   if( rc!=SQLITE_OK || sqlite3MallocFailed() ){
     sqlite3_finalize((sqlite3_stmt *)v);
   }
+  zErr[sizeof(zErr)-1] = '\0';
   sqlite3Error(db, rc, zErr);
   return sqlite3ApiExit(db, rc);
 }
index 96038c6c6e08bcfd825aa510a0e24f0af643aff3..ff88ba706dcd5b2dca5b2742ebf63355bca2bb26 100644 (file)
@@ -9,7 +9,7 @@
 #
 #***********************************************************************
 #
-# $Id: incrblob.test,v 1.5 2007/05/03 16:31:26 danielk1977 Exp $
+# $Id: incrblob.test,v 1.6 2007/05/03 18:14:10 danielk1977 Exp $
 #
 
 set testdir [file dirname $argv0]
@@ -208,6 +208,7 @@ do_test incrblob-3.2 {
   set rc [catch {
     puts -nonewline $::blob "helloworld"
   } msg]
+  close $::blob
   list $rc $msg
 } "1 {channel \"$::blob\" wasn't opened for writing}"
 
@@ -221,27 +222,31 @@ do_test incrblob-3.2 {
 #     4.3 - Attempt to open a table that does not exist.
 #     4.4 - Attempt to open a database that does not exist.
 #
+#     4.5 - Attempt to open an integer
+#     4.6 - Attempt to open a real value
+#     4.7 - Attempt to open an SQL null
+#
+#     4.8 - Attempt to open an indexed column for writing
+#     4.9 - Attempt to open an indexed column for reading (this works)
+#
 do_test incrblob-4.1 {
   set rc [catch {
     set ::blob [db incrblob blobs v 2]
   } msg ] 
   list $rc $msg
 } {1 {no such rowid: 2}}
-
 do_test incrblob-4.2 {
   set rc [catch {
     set ::blob [db incrblob blobs blue 1]
   } msg ] 
   list $rc $msg
 } {1 {no such column: "blue"}}
-
 do_test incrblob-4.3 {
   set rc [catch {
     set ::blob [db incrblob nosuchtable blue 1]
-  } msg ] 
+  } msg ]
   list $rc $msg
 } {1 {no such table: main.nosuchtable}}
-
 do_test incrblob-4.4 {
   set rc [catch {
     set ::blob [db incrblob nosuchdb blobs v 1]
@@ -249,5 +254,167 @@ do_test incrblob-4.4 {
   list $rc $msg
 } {1 {no such table: nosuchdb.blobs}}
 
-finish_test
+do_test incrblob-4.5 {
+  set rc [catch {
+    set ::blob [db incrblob blobs i 1]
+  } msg ] 
+  list $rc $msg
+} {1 {cannot open value of type integer}}
+do_test incrblob-4.6 {
+  execsql {
+    INSERT INTO blobs(k, v, i) VALUES(123, 567.765, NULL);
+  }
+  set rc [catch {
+    set ::blob [db incrblob blobs v 2]
+  } msg ] 
+  list $rc $msg
+} {1 {cannot open value of type real}}
+do_test incrblob-4.7 {
+  set rc [catch {
+    set ::blob [db incrblob blobs i 2]
+  } msg ] 
+  list $rc $msg
+} {1 {cannot open value of type null}}
 
+do_test incrblob-4.8 {
+  execsql {
+    INSERT INTO blobs(k, v, i) VALUES(X'010203040506070809', 'hello', 'world');
+  }
+  set rc [catch {
+    set ::blob [db incrblob blobs k 3]
+  } msg ] 
+  list $rc $msg
+} {1 {cannot open indexed column for writing}}
+
+do_test incrblob-4.9.1 {
+  set rc [catch {
+    set ::blob [db incrblob -readonly blobs k 3]
+  } msg]
+} {0}
+do_test incrblob-4.9.2 {
+  binary scan [read $::blob] c* c
+  close $::blob
+  set c
+} {1 2 3 4 5 6 7 8 9}
+
+#------------------------------------------------------------------------
+# incrblob-5.*: 
+#
+#     Test that opening a blob in an attached database works.
+#
+do_test incrblob-5.1 {
+  file delete -force test2.db test2.db-journal
+  set ::size [expr [file size [info script]]]
+  execsql {
+    ATTACH 'test2.db' AS aux;
+    CREATE TABLE aux.files(name, text);
+    INSERT INTO aux.files VALUES('this one', zeroblob($::size));
+  }
+  set fd  [db incrblob aux files text 1]
+  set fd2 [open [info script]]
+  puts -nonewline $fd [read $fd2]
+  close $fd
+  close $fd2
+  set ::text [db one {select text from aux.files}]
+  string length $::text
+} [file size [info script]]
+do_test incrblob-5.2 {
+  set fd2 [open [info script]]
+  set ::data [read $fd2]
+  close $fd2
+  set ::data
+} $::text
+
+# free memory
+unset ::data
+unset ::text
+
+#------------------------------------------------------------------------
+# incrblob-6.*: 
+#
+#     Test that opening a blob for write-access is impossible if
+#     another connection has the database RESERVED lock.
+#
+#     Then test that blob writes that take place inside of a
+#     transaction are not visible to external connections until
+#     after the transaction is commited and the blob channel 
+#     closed.
+#
+do_test incrblob-6.1 {
+  sqlite3 db2 test.db
+  execsql {
+    BEGIN;
+    INSERT INTO blobs(k, v, i) VALUES('a', 'different', 'connection');
+  } db2
+} {}
+do_test incrblob-6.2 {
+  execsql {
+    SELECT rowid FROM blobs
+  }
+} {1 2 3}
+do_test incrblob-6.3 {
+  set rc [catch {
+    db incrblob blobs v 1
+  } msg]
+  list $rc $msg
+} {1 {database is locked}}
+do_test incrblob-6.4 {
+  set rc [catch {
+    db incrblob blobs v 3
+  } msg]
+  list $rc $msg
+} {1 {database is locked}}
+do_test incrblob-6.5 {
+  set ::blob [db incrblob -readonly blobs v 3]
+  read $::blob
+} {hello}
+do_test incrblob-6.6 {
+  close $::blob
+} {}
+
+do_test incrblob-6.7 {
+  set ::blob [db2 incrblob blobs i 4]
+  gets $::blob
+} {connection}
+do_test incrblob-6.8 {
+  tell $::blob
+} {10}
+breakpoint
+do_test incrblob-6.9 {
+  seek $::blob 0
+  puts -nonewline $::blob "invocation"
+  flush $::blob
+} {}
+
+# At this point rollback or commit should be illegal (because 
+# there is an open blob channel).
+do_test incrblob-6.10 {
+  catchsql {
+    ROLLBACK;
+  } db2
+} {1 {cannot rollback transaction - SQL statements in progress}}
+do_test incrblob-6.11 {
+  catchsql {
+    COMMIT;
+  } db2
+} {1 {cannot commit transaction - SQL statements in progress}}
+
+do_test incrblob-6.12 {
+  execsql {
+    SELECT * FROM blobs WHERE rowid = 4;
+  }
+} {}
+do_test incrblob-6.13 {
+  close $::blob
+  execsql {
+    COMMIT;
+  } db2
+} {}
+do_test incrblob-6.14 {
+  execsql {
+    SELECT * FROM blobs WHERE rowid = 4;
+  }
+} {a different invocation}
+db2 close
+
+finish_test