-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
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
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
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
-8a43e1676fdd29903e0b3f9d3b05d217d42962b8
\ No newline at end of file
+64705410bdf43b6283f7a7e59ce8c20d09cd46e4
\ No newline at end of file
**
*************************************************************************
**
-** $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"
if( !pTab ){
if( sParse.zErrMsg ){
sqlite3_snprintf(sizeof(zErr), zErr, "%s", sParse.zErrMsg);
- zErr[sizeof(zErr)-1] = '\0';
}
sqliteFree(sParse.zErrMsg);
rc = SQLITE_ERROR;
}
}
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);
/* 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);
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 );
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;
}
*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;
}
if( rc!=SQLITE_OK || sqlite3MallocFailed() ){
sqlite3_finalize((sqlite3_stmt *)v);
}
+ zErr[sizeof(zErr)-1] = '\0';
sqlite3Error(db, rc, zErr);
return sqlite3ApiExit(db, rc);
}
#
#***********************************************************************
#
-# $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]
set rc [catch {
puts -nonewline $::blob "helloworld"
} msg]
+ close $::blob
list $rc $msg
} "1 {channel \"$::blob\" wasn't opened for writing}"
# 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]
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