Fix an assertion failure when the disk fills up. Add tests for a full

disk situation. (CVS 285)

FossilOrigin-Name: 0a7848b6190981cb7eb673bbe68cb217694daf2e
This commit is contained in:
drh 2001-10-12 17:30:04 +00:00
parent 4299020922
commit 81a20f21d5
16 changed files with 232 additions and 49 deletions

View File

@ -99,6 +99,7 @@ SRC = \
#
TESTSRC = \
$(TOP)/src/btree.c \
$(TOP)/src/os.c \
$(TOP)/src/pager.c \
$(TOP)/src/test1.c \
$(TOP)/src/test2.c \

View File

@ -146,6 +146,7 @@ SRC = \
#
TESTSRC = \
$(TOP)/src/btree.c \
$(TOP)/src/os.c \
$(TOP)/src/pager.c \
$(TOP)/src/test1.c \
$(TOP)/src/test2.c \

View File

@ -1,7 +1,7 @@
C Version\s2.0.2\s(CVS\s468)
D 2001-10-09T14:00:00
F Makefile.in 98d4627cb364537e4c3a29ee806171f3abf5211a
F Makefile.template 1e54087c0390c4ce0bb5be43e14ba028283751e6
C Fix\san\sassertion\sfailure\swhen\sthe\sdisk\sfills\sup.\s\sAdd\stests\sfor\sa\sfull\ndisk\ssituation.\s(CVS\s285)
D 2001-10-12T17:30:04
F Makefile.in 6801df952cb1df64aa32e4de85fed24511d28efd
F Makefile.template 582916b263aa40a70521dfb3d99d574028abd47b
F README 93d2977cc5c6595c448de16bdefc312b9d401533
F VERSION 73e5f5e088b67ed1629b08ca531b81c778ab8695
F aclocal.m4 11faa843caa38fd451bc6aeb43e248d1723a269d
@ -21,36 +21,36 @@ F publish.sh badcd69b8e3a8bc69b162c4c9d7c209b2a0b119e
F src/TODO af7f3cab0228e34149cf98e073aa83d45878e7e6
F src/btree.c 7e9c33a714ed1630562f89ad19847f5f28bd6d4d
F src/btree.h 57d653ef5137b91f2a068aaf71a2905468dd2cb7
F src/build.c 707f6ef58dcdd50ead9ead914d673b08e7121bc5
F src/build.c cb3607c86f20dd3c18dccbe21f1b9bcd33ef9a36
F src/delete.c 93c9d5e160395020a25d59371625db74c97c7c4d
F src/expr.c 2f68829d983ec3f92eeb8b89ce4b9e5704169a80
F src/hash.c bf36fb4cba114015123b0050f137d2c4553778a1
F src/hash.c b7ced0735287c142a3b2db46c3cae3e6826afb75
F src/hash.h a5f5b3ce2d086a172c5879b0b06a27a82eac9fac
F src/insert.c a48ba850461b203fb8dbc7add83fc6b6a9cf47f3
F src/main.c ece73e5a44fab98144c4a93084d68b4fc413ba66
F src/main.c 9a18e97290d41844e8c12e021fb7c42948a19dc9
F src/md5.c 52f677bfc590e09f71d07d7e327bd59da738d07c
F src/os.c a83f4cb85e4d3b98c1659a799f9e318fcaf1c76c
F src/os.c cece4ac6cabc9d377ef0a4ab4c16f6f0f6c84377
F src/os.h bed702c9e3b768bc3cb1b12c90b83d099c1546be
F src/pager.c 3445bd7c18cbfdffd8d6d1077f0b2bdf788da4fe
F src/pager.c e2e189a15e230c60e811f5e2ab25e68ae41c90be
F src/pager.h a0d4c5ae271914aa07b62aee0707997d6932b6ca
F src/parse.y e88f1efe096a1a01c9076099fe1d81deedfa11de
F src/parse.y 2275a832b544e8b57c422880a0d9badd4976d042
F src/printf.c b1e22a47be8cdf707815647239991e08e8cb69f9
F src/random.c 2a9cc2c9716d14815fd4c2accf89d87a1143e46b
F src/select.c 0ef8ca1b7de2467fe082bcb35a5ab3b5be56153c
F src/shell.c cb8c41f1b2173efd212dab3f35f1fc6bf32ead76
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
F src/sqlite.h.in b95c161abf1d58bceb05290fa3f657d8f388fc11
F src/sqliteInt.h 603566f58dff0e0295e57792e9313fe5d253f1a2
F src/sqliteInt.h 141b57b9eee7e8c937ac603f6cb7ecca77c1dd77
F src/table.c abd0adbe0fee39d995287b3bcccd908d174dfcac
F src/tclsqlite.c 765599686c19ed777ac379928d732c8bfc63ebac
F src/test1.c e4b31f62ea71963cbae44338acf477a04fc8fc49
F src/test2.c 0168b39225b768cfdadd534406f9dec58c27879e
F src/test2.c e9f99aa5ee73872819259d6612c11e55e1644321
F src/test3.c 4a0d7b882fdae731dbb759f512ad867122452f96
F src/tokenize.c 15d349b68d9dc5722956bd7549752ace62034787
F src/update.c 49a1edb1a3e44dfff3f799e00f2a3319f2393cd8
F src/util.c 4da3be37d0fd3c640d2d3033503768afdc8e5387
F src/vdbe.c 594050d9a8dc51b97320c52d4665de313b842c27
F src/vdbe.h 7eb7e9e6c58fe9430efab35e168f96cb4bd6cb45
F src/vdbe.h adecb0f37d2c1aa34f2cbd359b63b8c922e72c1f
F src/where.c b676765ad0360769173b09f46265ddec8d48367a
F test/all.test a2320eb40b462f25bd3e33115b1cabf3791450dd
F test/bigrow.test a35f2de9948b24e427fb292c35947795efe182d0
@ -64,6 +64,7 @@ F test/in.test 9323681388be301dc73f370b4cd62c5a33f79d1e
F test/index.test 6076f29d09a4f26a2efa38b03b8cc338b8662f0e
F test/insert.test a5c122aa726f1cef6f07d6767e8fd6f220994c11
F test/insert2.test 252d7130d8cc20f649b31a4f503cd87e660abda8
F test/ioerr.test 57d9bffaca18b34f9e976f786eadc2591d6efc6a
F test/lock.test 19593689260c419efe7ced55b1418653a4b7bcd1
F test/main.test 085ece17913a487caacbc0a392638c958c83a75d
F test/malloc.test f1400a8d002eb96f1ca0a34abe56d2ab3e324740
@ -100,8 +101,8 @@ F tool/report1.txt 9eae07f26a8fc53889b45fc833a66a33daa22816
F www/arch.fig d5f9752a4dbf242e9cfffffd3f5762b6c63b3bcf
F www/arch.png 82ef36db1143828a7abc88b1e308a5f55d4336f4
F www/arch.tcl 03b521d252575f93b9c52f7c8b0007011512fcfb
F www/c_interface.tcl 8e8d9e66e8467c5751116c3427296bde77f474a6
F www/changes.tcl 2b416b49a136312678317f509821cf9359e421b5
F www/c_interface.tcl a59ee0835d1b33fcddab7d4fd65cf9e50f7d2dc7
F www/changes.tcl 4c722e1271b9c25477f2483dad1a96681ce73380
F www/crosscompile.tcl c99efacb3aefaa550c6e80d91b240f55eb9fd33e
F www/download.tcl 3e51c9ff1326b0a182846134987301310dff7d60
F www/dynload.tcl 02eb8273aa78cfa9070dd4501dca937fb22b466c
@ -113,7 +114,7 @@ F www/speed.tcl ab7d6d3bc898472bd94320a5d3c63de928d4804b
F www/sqlite.tcl 6a21242a272e9c0939a04419a51c3d50cae33e3e
F www/tclsqlite.tcl 13d50723f583888fc80ae1a38247c0ab415066fa
F www/vdbe.tcl bb7d620995f0a987293e9d4fb6185a3b077e9b44
P abe5a25b9dcf1e47f3cb37fd419f620db03bd4da
R 811a44282886ed3bd9485148120cee71
P 44d00a6f58c71ca11423df12530177baaa054a01
R 8b125f0466bafcf592b4cb611703e2d3
U drh
Z bb72d0236472bbdc7b77722d8537d4bf
Z c3df09919ca8934d0890578a526b0048

View File

@ -1 +1 @@
44d00a6f58c71ca11423df12530177baaa054a01
0a7848b6190981cb7eb673bbe68cb217694daf2e

View File

@ -25,7 +25,7 @@
** ROLLBACK
** PRAGMA
**
** $Id: build.c,v 1.46 2001/10/09 04:19:47 drh Exp $
** $Id: build.c,v 1.47 2001/10/12 17:30:05 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@ -1477,6 +1477,36 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
}
}else
if( sqliteStrICmp(zLeft, "index_list")==0 ){
Index *pIdx;
Table *pTab;
Vdbe *v;
pTab = sqliteFindTable(db, zRight);
if( pTab ){
v = sqliteGetVdbe(pParse);
pIdx = pTab->pIndex;
}
if( pTab && pIdx && v ){
int i = 0;
static VdbeOp indexListPreface[] = {
{ OP_ColumnCount, 3, 0, 0},
{ OP_ColumnName, 0, 0, "seq"},
{ OP_ColumnName, 1, 0, "name"},
{ OP_ColumnName, 2, 0, "unique"},
};
sqliteVdbeAddOpList(v, ArraySize(indexListPreface), indexListPreface);
while(pIdx){
sqliteVdbeAddOp(v, OP_Integer, i, 0, 0, 0);
sqliteVdbeAddOp(v, OP_String, 0, 0, pIdx->zName, 0);
sqliteVdbeAddOp(v, OP_Integer, pIdx->isUnique, 0, 0, 0);
sqliteVdbeAddOp(v, OP_Callback, 3, 0, 0, 0);
++i;
pIdx = pIdx->pNext;
}
}
}else
#ifndef NDEBUG
if( sqliteStrICmp(zLeft, "parser_trace")==0 ){
extern void sqliteParserTrace(FILE*, char *);

View File

@ -12,7 +12,7 @@
** This is the implementation of generic hash-tables
** used in SQLite.
**
** $Id: hash.c,v 1.1 2001/09/22 18:12:10 drh Exp $
** $Id: hash.c,v 1.2 2001/10/12 17:30:05 drh Exp $
*/
#include "sqliteInt.h"
#include <assert.h>
@ -197,7 +197,7 @@ static HashElem *findElementGivenHash(
return 0;
}
/* Remove a single entry from the pH given a pointer to that
/* Remove a single entry from the hash table given a pointer to that
** element and a hash on the element's key.
*/
static void removeElementGivenHash(
@ -228,7 +228,7 @@ static void removeElementGivenHash(
}
/* Attempt to locate an element of the associative pH with a key
** that matches "key". Return the data for this element if it is
** that matches pKey,nKey. Return the data for this element if it is
** found, or NULL if no match is found.
*/
void *sqliteHashFind(const Hash *pH, const void *pKey, int nKey){
@ -245,19 +245,19 @@ void *sqliteHashFind(const Hash *pH, const void *pKey, int nKey){
return elem ? elem->data : 0;
}
/* Insert an element into the pH. The key will be "key" and
** the data will be "data".
/* Insert an element into the hash table pH. The key is pKey,nKey
** and the data is "data".
**
** If no pH element exists with a matching key, then a new
** pH element is created. The key is copied (using the copy
** function of the key class) into the new element. NULL is returned.
** If no element exists with a matching key, then a new
** element is created. A copy of the key is made if the copyKey
** flag is set. NULL is returned.
**
** If another element already exists with the same key, then the
** new data replaces the old data and the old data is returned.
** The key is not copied in this instance.
**
** If the "data" parameter to this function is NULL, then the
** element corresponding to "key" is removed from the pH.
** element corresponding to "key" is removed from the hash table.
*/
void *sqliteHashInsert(Hash *pH, void *pKey, int nKey, void *data){
int hraw; /* Raw hash value of the key */

View File

@ -14,7 +14,7 @@
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.45 2001/10/09 13:46:01 drh Exp $
** $Id: main.c,v 1.46 2001/10/12 17:30:05 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"

View File

@ -11,7 +11,7 @@
******************************************************************************
**
** This file contains code that is specific to particular operating
** systems. The purpose of this file is to provide a uniform abstract
** systems. The purpose of this file is to provide a uniform abstraction
** on which the rest of SQLite can operate.
*/
#include "sqliteInt.h"
@ -158,6 +158,23 @@ static void releaseLockInfo(struct lockInfo *pInfo){
}
#endif /** POSIX advisory lock work-around **/
/*
** If we compile with the SQLITE_TEST macro set, then the following block
** of code will give us the ability to simulate a disk I/O error. This
** is used for testing the I/O recovery logic.
*/
#ifdef SQLITE_TEST
int sqlite_io_error_pending = 0;
#define SimulateIOError(A) \
if( sqlite_io_error_pending ) \
if( sqlite_io_error_pending-- == 1 ){ local_ioerr(); return A; }
static void local_ioerr(){
sqlite_io_error_pending = 0; /* Really just a place to set a breakpoint */
}
#else
#define SimulateIOError(A)
#endif
/*
** Delete the named file
@ -248,7 +265,7 @@ int sqliteOsOpenReadWrite(
NULL
);
if( h==INVALID_HANDLE_VALUE ){
HANDLE h = CreateFile(zFilename,
h = CreateFile(zFilename,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
@ -443,12 +460,14 @@ int sqliteOsClose(OsFile id){
int sqliteOsRead(OsFile id, void *pBuf, int amt){
#if OS_UNIX
int got;
SimulateIOError(SQLITE_IOERR);
got = read(id.fd, pBuf, amt);
if( got<0 ) got = 0;
return got==amt ? SQLITE_OK : SQLITE_IOERR;
#endif
#if OS_WIN
DWORD got;
SimulateIOError(SQLITE_IOERR);
if( !ReadFile(id, pBuf, amt, &got, 0) ){
got = 0;
}
@ -463,12 +482,14 @@ int sqliteOsRead(OsFile id, void *pBuf, int amt){
int sqliteOsWrite(OsFile id, const void *pBuf, int amt){
#if OS_UNIX
int wrote;
SimulateIOError(SQLITE_IOERR);
wrote = write(id.fd, pBuf, amt);
if( wrote<amt ) return SQLITE_FULL;
return SQLITE_OK;
#endif
#if OS_WIN
DWORD wrote;
SimulateIOError(SQLITE_IOERR);
if( !WriteFile(id, pBuf, amt, &wrote, 0) || wrote<amt ){
return SQLITE_FULL;
}
@ -494,6 +515,7 @@ int sqliteOsSeek(OsFile id, int offset){
** Make sure all writes to a particular file are committed to disk.
*/
int sqliteOsSync(OsFile id){
SimulateIOError(SQLITE_IOERR);
#if OS_UNIX
return fsync(id.fd)==0 ? SQLITE_OK : SQLITE_IOERR;
#endif
@ -506,6 +528,7 @@ int sqliteOsSync(OsFile id){
** Truncate an open file to a specified size
*/
int sqliteOsTruncate(OsFile id, int nByte){
SimulateIOError(SQLITE_IOERR);
#if OS_UNIX
return ftruncate(id.fd, nByte)==0 ? SQLITE_OK : SQLITE_IOERR;
#endif
@ -522,6 +545,7 @@ int sqliteOsTruncate(OsFile id, int nByte){
int sqliteOsFileSize(OsFile id, int *pSize){
#if OS_UNIX
struct stat buf;
SimulateIOError(SQLITE_IOERR);
if( fstat(id.fd, &buf)!=0 ){
return SQLITE_IOERR;
}
@ -529,6 +553,7 @@ int sqliteOsFileSize(OsFile id, int *pSize){
return SQLITE_OK;
#endif
#if OS_WIN
SimulateIOError(SQLITE_IOERR);
*pSize = GetFileSize(id, 0);
return SQLITE_OK;
#endif

View File

@ -18,7 +18,7 @@
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.26 2001/10/08 13:22:33 drh Exp $
** @(#) $Id: pager.c,v 1.27 2001/10/12 17:30:05 drh Exp $
*/
#include "sqliteInt.h"
#include "pager.h"
@ -128,6 +128,7 @@ struct Pager {
#define PAGER_ERR_MEM 0x02 /* malloc() failed */
#define PAGER_ERR_LOCK 0x04 /* error in the locking protocol */
#define PAGER_ERR_CORRUPT 0x08 /* database or journal corruption */
#define PAGER_ERR_DISK 0x10 /* general disk I/O error - bad hard drive? */
/*
** The journal file contains page records in the following
@ -178,6 +179,7 @@ static const unsigned char aJournalMagic[] = {
static int pager_errcode(Pager *pPager){
int rc = SQLITE_OK;
if( pPager->errMask & PAGER_ERR_LOCK ) rc = SQLITE_PROTOCOL;
if( pPager->errMask & PAGER_ERR_DISK ) rc = SQLITE_IOERR;
if( pPager->errMask & PAGER_ERR_FULL ) rc = SQLITE_FULL;
if( pPager->errMask & PAGER_ERR_MEM ) rc = SQLITE_NOMEM;
if( pPager->errMask & PAGER_ERR_CORRUPT ) rc = SQLITE_CORRUPT;
@ -305,20 +307,25 @@ static int pager_playback(Pager *pPager){
sqliteOsSeek(pPager->jfd, 0);
rc = sqliteOsRead(pPager->jfd, aMagic, sizeof(aMagic));
if( rc!=SQLITE_OK || memcmp(aMagic,aJournalMagic,sizeof(aMagic))!=0 ){
return SQLITE_PROTOCOL;
rc = SQLITE_PROTOCOL;
goto end_playback;
}
rc = sqliteOsRead(pPager->jfd, &mxPg, sizeof(mxPg));
if( rc!=SQLITE_OK ){
return SQLITE_PROTOCOL;
goto end_playback;
}
rc = sqliteOsTruncate(pPager->fd, mxPg*SQLITE_PAGE_SIZE);
if( rc!=SQLITE_OK ){
goto end_playback;
}
sqliteOsTruncate(pPager->fd, mxPg*SQLITE_PAGE_SIZE);
pPager->dbSize = mxPg;
/* Begin reading the journal beginning at the end and moving
** toward the beginning.
*/
if( sqliteOsFileSize(pPager->jfd, &nRec)!=SQLITE_OK ){
return SQLITE_OK;
rc = sqliteOsFileSize(pPager->jfd, &nRec);
if( rc!=SQLITE_OK ){
goto end_playback;
}
nRec = (nRec - (sizeof(aMagic)+sizeof(Pgno))) / sizeof(PageRecord);
@ -353,6 +360,8 @@ static int pager_playback(Pager *pPager){
rc = sqliteOsWrite(pPager->fd, pgRec.aData, SQLITE_PAGE_SIZE);
if( rc!=SQLITE_OK ) break;
}
end_playback:
if( rc!=SQLITE_OK ){
pager_unwritelock(pPager);
pPager->errMask |= PAGER_ERR_CORRUPT;
@ -470,6 +479,7 @@ int sqlitepager_pagecount(Pager *pPager){
return pPager->dbSize;
}
if( sqliteOsFileSize(pPager->fd, &n)!=SQLITE_OK ){
pPager->errMask |= PAGER_ERR_DISK;
return 0;
}
n /= SQLITE_PAGE_SIZE;
@ -589,7 +599,7 @@ static int syncAllPages(Pager *pPager){
pPg->dirty = 0;
}
}
return SQLITE_OK;
return rc;
}
/*
@ -790,8 +800,12 @@ int sqlitepager_get(Pager *pPager, Pgno pgno, void **ppPage){
if( pPager->dbSize<pgno ){
memset(PGHDR_TO_DATA(pPg), 0, SQLITE_PAGE_SIZE);
}else{
int rc;
sqliteOsSeek(pPager->fd, (pgno-1)*SQLITE_PAGE_SIZE);
sqliteOsRead(pPager->fd, PGHDR_TO_DATA(pPg), SQLITE_PAGE_SIZE);
rc = sqliteOsRead(pPager->fd, PGHDR_TO_DATA(pPg), SQLITE_PAGE_SIZE);
if( rc!=SQLITE_OK ){
return rc;
}
}
if( pPager->nExtra>0 ){
memset(PGHDR_TO_EXTRA(pPg), 0, pPager->nExtra);

View File

@ -14,7 +14,7 @@
** the parser. Lemon will also generate a header file containing
** numeric codes for all of the tokens.
**
** @(#) $Id: parse.y,v 1.35 2001/10/08 13:22:33 drh Exp $
** @(#) $Id: parse.y,v 1.36 2001/10/12 17:30:05 drh Exp $
*/
%token_prefix TK_
%token_type {Token}
@ -329,10 +329,11 @@ inscollist(A) ::= ids(Y). {A = sqliteIdListAppend(0,&Y);}
%right NOT.
%left EQ NE ISNULL NOTNULL IS LIKE GLOB BETWEEN IN.
%left GT GE LT LE.
%left BITAND BITOR LSHIFT RSHIFT.
%left PLUS MINUS.
%left STAR SLASH.
%left STAR SLASH MOD.
%left CONCAT.
%right UMINUS.
%right UMINUS BITNOT.
%type expr {Expr*}
%destructor expr {sqliteExprDelete($$);}
@ -364,6 +365,10 @@ expr(A) ::= expr(X) LE expr(Y). {A = sqliteExpr(TK_LE, X, Y, 0);}
expr(A) ::= expr(X) GE expr(Y). {A = sqliteExpr(TK_GE, X, Y, 0);}
expr(A) ::= expr(X) NE expr(Y). {A = sqliteExpr(TK_NE, X, Y, 0);}
expr(A) ::= expr(X) EQ expr(Y). {A = sqliteExpr(TK_EQ, X, Y, 0);}
expr(A) ::= expr(X) BITAND expr(Y). {A = sqliteExpr(TK_BITAND, X, Y, 0);}
expr(A) ::= expr(X) BITOR expr(Y). {A = sqliteExpr(TK_BITOR, X, Y, 0);}
expr(A) ::= expr(X) LSHIFT expr(Y). {A = sqliteExpr(TK_LSHIFT, X, Y, 0);}
expr(A) ::= expr(X) RSHIFT expr(Y). {A = sqliteExpr(TK_RSHIFT, X, Y, 0);}
expr(A) ::= expr(X) LIKE expr(Y). {A = sqliteExpr(TK_LIKE, X, Y, 0);}
expr(A) ::= expr(X) NOT LIKE expr(Y). {
A = sqliteExpr(TK_LIKE, X, Y, 0);
@ -380,6 +385,7 @@ expr(A) ::= expr(X) PLUS expr(Y). {A = sqliteExpr(TK_PLUS, X, Y, 0);}
expr(A) ::= expr(X) MINUS expr(Y). {A = sqliteExpr(TK_MINUS, X, Y, 0);}
expr(A) ::= expr(X) STAR expr(Y). {A = sqliteExpr(TK_STAR, X, Y, 0);}
expr(A) ::= expr(X) SLASH expr(Y). {A = sqliteExpr(TK_SLASH, X, Y, 0);}
expr(A) ::= expr(X) MOD expr(Y). {A = sqliteExpr(TK_MOD, X, Y, 0);}
expr(A) ::= expr(X) CONCAT expr(Y). {A = sqliteExpr(TK_CONCAT, X, Y, 0);}
expr(A) ::= expr(X) ISNULL(E). {
A = sqliteExpr(TK_ISNULL, X, 0, 0);
@ -397,10 +403,18 @@ expr(A) ::= expr(X) NOT NULL(E). {
A = sqliteExpr(TK_NOTNULL, X, 0, 0);
sqliteExprSpan(A,&X->span,&E);
}
expr(A) ::= expr(X) IS NOT NULL(E). {
A = sqliteExpr(TK_NOTNULL, X, 0, 0);
sqliteExprSpan(A,&X->span,&E);
}
expr(A) ::= NOT(B) expr(X). {
A = sqliteExpr(TK_NOT, X, 0, 0);
sqliteExprSpan(A,&B,&X->span);
}
expr(A) ::= BITNOT(B) expr(X). {
A = sqliteExpr(TK_BITNOT, X, 0, 0);
sqliteExprSpan(A,&B,&X->span);
}
expr(A) ::= MINUS(B) expr(X). [UMINUS] {
A = sqliteExpr(TK_UMINUS, X, 0, 0);
sqliteExprSpan(A,&B,&X->span);

View File

@ -11,7 +11,7 @@
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.59 2001/10/09 04:19:47 drh Exp $
** @(#) $Id: sqliteInt.h,v 1.60 2001/10/12 17:30:05 drh Exp $
*/
#include "sqlite.h"
#include "hash.h"
@ -117,6 +117,21 @@ extern int sqlite_iMallocFail; /* Fail sqliteMalloc() after this many calls */
#define FN_Fcnt 6
#define FN_Length 7
#define FN_Substr 8
#if 0
#define FN_Abs 9
#define FN_Ceil 10
#define FN_Floor 11
#define FN_Frac 12
#define FN_Sin 13
#define FN_Cos 14
#define FN_Tan 15
#define FN_Asin 16
#define FN_Acos 17
#define FN_Atan 18
#define FN_Exp 19
#define FN_Ln 20
#define FN_Pow 21
#endif
/*
** Forward references to structures

View File

@ -13,7 +13,7 @@
** is not included in the SQLite library. It is used for automated
** testing of the SQLite library.
**
** $Id: test2.c,v 1.5 2001/09/16 00:13:27 drh Exp $
** $Id: test2.c,v 1.6 2001/10/12 17:30:05 drh Exp $
*/
#include "sqliteInt.h"
#include "pager.h"
@ -388,6 +388,7 @@ static int page_write(
** Register commands with the TCL interpreter.
*/
int Sqlitetest2_Init(Tcl_Interp *interp){
extern int sqlite_io_error_pending;
Tcl_CreateCommand(interp, "pager_open", pager_open, 0, 0);
Tcl_CreateCommand(interp, "pager_close", pager_close, 0, 0);
Tcl_CreateCommand(interp, "pager_commit", pager_commit, 0, 0);
@ -400,5 +401,7 @@ int Sqlitetest2_Init(Tcl_Interp *interp){
Tcl_CreateCommand(interp, "page_read", page_read, 0, 0);
Tcl_CreateCommand(interp, "page_write", page_write, 0, 0);
Tcl_CreateCommand(interp, "page_number", page_number, 0, 0);
Tcl_LinkVar(interp, "sqlite_io_error_pending",
(char*)&sqlite_io_error_pending, TCL_LINK_INT);
return TCL_OK;
}

View File

@ -15,7 +15,7 @@
** or VDBE. The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database.
**
** $Id: vdbe.h,v 1.26 2001/10/08 13:22:33 drh Exp $
** $Id: vdbe.h,v 1.27 2001/10/12 17:30:05 drh Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
@ -160,6 +160,15 @@ typedef struct VdbeOp VdbeOp;
#define OP_Subtract 83
#define OP_Multiply 84
#define OP_Divide 85
#define OP_Remainder
#define OP_BitAnd
#define OP_BitOr
#define OP_BitNot
#define OP_ShiftLeft
#define OP_ShiftRight
#define OP_Power
#define OP_Exp
#define OP_Log
#define OP_Min 86
#define OP_Max 87
#define OP_Like 88

59
test/ioerr.test Normal file
View File

@ -0,0 +1,59 @@
# 2001 October 12
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# 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 file is testing for correct handling of I/O errors
# such as writes failing because the disk is full.
#
# The tests in this file use special facilities that are only
# available in the SQLite test fixture.
#
# $Id: ioerr.test,v 1.1 2001/10/12 17:30:05 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::go 1
for {set n 1} {$go} {incr n} {
do_test ioerr-1.$n.1 {
set ::sqlite_io_error_pending 0
db close
catch {file delete -force test.db}
sqlite 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}
}
set ::sqlite_io_error_pending 0
finish_test

View File

@ -1,7 +1,7 @@
#
# Run this Tcl script to generate the sqlite.html file.
#
set rcsid {$Id: c_interface.tcl,v 1.16 2001/09/28 23:11:24 drh Exp $}
set rcsid {$Id: c_interface.tcl,v 1.17 2001/10/12 17:30:05 drh Exp $}
puts {<html>
<head>
@ -292,7 +292,10 @@ that there is no more space left on the disk.
<dd><p>This value is returned if SQLite detects that the database it is
working on has become corrupted. Corruption might occur due to a rogue
process writing to the database file or it might happen due to an
perviously undetected logic error in of SQLite.
perviously undetected logic error in of SQLite. This value is also
returned if a disk I/O error occurs in such a way that SQLite is forced
to leave the database file in a corrupted state. The latter should only
happen due to a hardware or operating system malfunction.
</p></dd>
<dt>SQLITE_FULL</dt>
<dd><p>This value is returned if an insertion failed because there is

View File

@ -17,6 +17,14 @@ proc chng {date desc} {
puts "<DD><P><UL>$desc</UL></P></DD>"
}
chng {2001 Oct ? (2.0.3)} {
<li>Bug fix: the <b>sqlite_busy_timeout()</b> function was delaying 1000
times too long before failing.</li>
<li>Bug fix: an assertion was failing if the disk holding the database
file became full or stopped accepting writes for some other reason.
New tests were added to detect similar problems in the future.</li>
}
chng {2001 Oct 9 (2.0.2)} {
<li>Fix two bugs in the locking protocol. (One was masking the other.)</li>
<li>Removed some unused "#include <unistd.h>" that were causing problems