aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2006-09-15 07:28:50 +0000
committerdrh <drh@noemail.net>2006-09-15 07:28:50 +0000
commit4ac285a1c241a792cd5e650bd3edc093432d3de4 (patch)
tree84c0074e297df167a2802af7b34de0a5e589e8b9 /src
parent8abc58e33b57915a155c9d0569371363f96d8b33 (diff)
downloadsqlite-4ac285a1c241a792cd5e650bd3edc093432d3de4.tar.gz
sqlite-4ac285a1c241a792cd5e650bd3edc093432d3de4.zip
Add support for extended result codes - additional result information
carried in the higher bits of the integer return codes. This must be enabled using the sqlite3_extended_result_code() API. Only a few extra result codes are currently defined. (CVS 3422) FossilOrigin-Name: ba579ddc4361fc6e8ea66f9385770d70dfe94751
Diffstat (limited to 'src')
-rw-r--r--src/legacy.c3
-rw-r--r--src/loadext.c3
-rw-r--r--src/main.c16
-rw-r--r--src/os_unix.c32
-rw-r--r--src/pager.c13
-rw-r--r--src/prepare.c3
-rw-r--r--src/sqlite.h.in40
-rw-r--r--src/sqliteInt.h3
-rw-r--r--src/table.c8
-rw-r--r--src/test1.c38
-rw-r--r--src/util.c4
-rw-r--r--src/vdbeapi.c2
-rw-r--r--src/vdbeaux.c18
-rw-r--r--src/vtab.c3
14 files changed, 136 insertions, 50 deletions
diff --git a/src/legacy.c b/src/legacy.c
index 39e1361fa..a74ad4f15 100644
--- a/src/legacy.c
+++ b/src/legacy.c
@@ -14,7 +14,7 @@
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
-** $Id: legacy.c,v 1.15 2006/06/26 21:35:45 drh Exp $
+** $Id: legacy.c,v 1.16 2006/09/15 07:28:50 drh Exp $
*/
#include "sqliteInt.h"
@@ -131,5 +131,6 @@ exec_out:
*pzErrMsg = 0;
}
+ assert( (rc&db->errMask)==rc );
return rc;
}
diff --git a/src/loadext.c b/src/loadext.c
index 81f6856d5..80cfc4ccc 100644
--- a/src/loadext.c
+++ b/src/loadext.c
@@ -385,7 +385,8 @@ int sqlite3_auto_extension(void *xInit){
aAutoExtension[nAutoExtension-1] = xInit;
}
}
- sqlite3OsLeaveMutex();
+ sqlite3OsLeaveMutex();
+ assert( (rc&0xff)==rc );
return rc;
}
diff --git a/src/main.c b/src/main.c
index b7e2cf16d..476577f11 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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.356 2006/09/02 13:58:07 drh Exp $
+** $Id: main.c,v 1.357 2006/09/15 07:28:50 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -223,7 +223,7 @@ void sqlite3RollbackAll(sqlite3 *db){
*/
const char *sqlite3ErrStr(int rc){
const char *z;
- switch( rc ){
+ switch( rc & 0xff ){
case SQLITE_ROW:
case SQLITE_DONE:
case SQLITE_OK: z = "not an error"; break;
@@ -763,7 +763,7 @@ int sqlite3_errcode(sqlite3 *db){
if( sqlite3SafetyCheck(db) ){
return SQLITE_MISUSE;
}
- return db->errCode;
+ return db->errCode & db->errMask;
}
/*
@@ -841,6 +841,7 @@ static int openDatabase(
/* Allocate the sqlite data structure */
db = sqliteMalloc( sizeof(sqlite3) );
if( db==0 ) goto opendb_out;
+ db->errMask = 0xff;
db->priorNewRowid = 0;
db->magic = SQLITE_MAGIC_BUSY;
db->nDb = 2;
@@ -1011,6 +1012,7 @@ int sqlite3_reset(sqlite3_stmt *pStmt){
}else{
rc = sqlite3VdbeReset((Vdbe*)pStmt);
sqlite3VdbeMakeReady((Vdbe*)pStmt, -1, 0, 0, 0);
+ assert( (rc & (sqlite3_db_handle(pStmt)->errMask))==rc );
}
return rc;
}
@@ -1297,3 +1299,11 @@ int sqlite3_clear_bindings(sqlite3_stmt *pStmt){
int sqlite3_sleep(int ms){
return sqlite3OsSleep(ms);
}
+
+/*
+** Enable or disable the extended result codes.
+*/
+int sqlite3_extended_result_codes(sqlite3 *db, int onoff){
+ db->errMask = onoff ? 0xffffffff : 0xff;
+ return SQLITE_OK;
+}
diff --git a/src/os_unix.c b/src/os_unix.c
index ed810d6df..ada697463 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -937,8 +937,10 @@ static int unixRead(OsFile *id, void *pBuf, int amt){
SimulateIOError( got=0 );
if( got==amt ){
return SQLITE_OK;
+ }else if( got<0 ){
+ return SQLITE_IOERR_READ;
}else{
- return SQLITE_IOERR;
+ return SQLITE_IOERR_SHORT_READ;
}
}
@@ -982,7 +984,7 @@ static int unixWrite(OsFile *id, const void *pBuf, int amt){
SimulateDiskfullError(( wrote=0, amt=1 ));
if( amt>0 ){
if( wrote<0 ){
- return SQLITE_IOERR;
+ return SQLITE_IOERR_WRITE;
}else{
return SQLITE_FULL;
}
@@ -1065,19 +1067,13 @@ static int full_fsync(int fd, int fullSync, int dataOnly){
#if HAVE_FULLFSYNC
if( fullSync ){
rc = fcntl(fd, F_FULLFSYNC, 0);
- }else{
- rc = 1;
- }
- /* If the FULLSYNC failed, try to do a normal fsync() */
- if( rc ) rc = fsync(fd);
-
-#else /* if !defined(F_FULLSYNC) */
+ }else
+#endif /* HAVE_FULLFSYNC */
if( dataOnly ){
rc = fdatasync(fd);
}else{
rc = fsync(fd);
}
-#endif /* defined(F_FULLFSYNC) */
#endif /* defined(SQLITE_NO_SYNC) */
return rc;
@@ -1106,7 +1102,7 @@ static int unixSync(OsFile *id, int dataOnly){
rc = full_fsync(pFile->h, pFile->fullSync, dataOnly);
SimulateIOError( rc=1 );
if( rc ){
- return SQLITE_IOERR;
+ return SQLITE_IOERR_FSYNC;
}
if( pFile->dirfd>=0 ){
TRACE4("DIRSYNC %-3d (have_fullfsync=%d fullsync=%d)\n", pFile->dirfd,
@@ -1155,7 +1151,7 @@ int sqlite3UnixSyncDirectory(const char *zDirname){
close(fd);
SimulateIOError( r=1 );
if( r ){
- return SQLITE_IOERR;
+ return SQLITE_IOERR_DIR_FSYNC;
}else{
return SQLITE_OK;
}
@@ -1171,7 +1167,7 @@ static int unixTruncate(OsFile *id, i64 nByte){
rc = ftruncate(((unixFile*)id)->h, nByte);
SimulateIOError( rc=1 );
if( rc ){
- return SQLITE_IOERR;
+ return SQLITE_IOERR_TRUNCATE;
}else{
return SQLITE_OK;
}
@@ -1187,7 +1183,7 @@ static int unixFileSize(OsFile *id, i64 *pSize){
rc = fstat(((unixFile*)id)->h, &buf);
SimulateIOError( rc=1 );
if( rc!=0 ){
- return SQLITE_IOERR;
+ return SQLITE_IOERR_FSTAT;
}
*pSize = buf.st_size;
return SQLITE_OK;
@@ -1397,7 +1393,7 @@ static int unixLock(OsFile *id, int locktype){
lock.l_len = 1L;
lock.l_type = F_UNLCK;
if( fcntl(pFile->h, F_SETLK, &lock)!=0 ){
- rc = SQLITE_IOERR; /* This should never happen */
+ rc = SQLITE_IOERR_UNLOCK; /* This should never happen */
goto end_lock;
}
if( s ){
@@ -1486,7 +1482,7 @@ static int unixUnlock(OsFile *id, int locktype){
lock.l_len = SHARED_SIZE;
if( fcntl(pFile->h, F_SETLK, &lock)!=0 ){
/* This should never happen */
- rc = SQLITE_IOERR;
+ rc = SQLITE_IOERR_RDLOCK;
}
}
lock.l_type = F_UNLCK;
@@ -1496,7 +1492,7 @@ static int unixUnlock(OsFile *id, int locktype){
if( fcntl(pFile->h, F_SETLK, &lock)==0 ){
pLock->locktype = SHARED_LOCK;
}else{
- rc = SQLITE_IOERR; /* This should never happen */
+ rc = SQLITE_IOERR_UNLOCK; /* This should never happen */
}
}
if( locktype==NO_LOCK ){
@@ -1514,7 +1510,7 @@ static int unixUnlock(OsFile *id, int locktype){
if( fcntl(pFile->h, F_SETLK, &lock)==0 ){
pLock->locktype = NO_LOCK;
}else{
- rc = SQLITE_IOERR; /* This should never happen */
+ rc = SQLITE_IOERR_UNLOCK; /* This should never happen */
}
}
diff --git a/src/pager.c b/src/pager.c
index 1013c1c2c..e8923e06f 100644
--- a/src/pager.c
+++ b/src/pager.c
@@ -18,7 +18,7 @@
** file simultaneously, or one process from reading the database while
** another is writing.
**
-** @(#) $Id: pager.c,v 1.271 2006/08/08 13:51:43 drh Exp $
+** @(#) $Id: pager.c,v 1.272 2006/09/15 07:28:50 drh Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
@@ -476,12 +476,13 @@ static u32 retrieve32bits(PgHdr *p, int offset){
** will immediately return the same error code.
*/
static int pager_error(Pager *pPager, int rc){
+ int rc2 = rc & 0xff;
assert( pPager->errCode==SQLITE_FULL || pPager->errCode==SQLITE_OK );
if(
- rc==SQLITE_FULL ||
- rc==SQLITE_IOERR ||
- rc==SQLITE_CORRUPT ||
- rc==SQLITE_PROTOCOL
+ rc2==SQLITE_FULL ||
+ rc2==SQLITE_IOERR ||
+ rc2==SQLITE_CORRUPT ||
+ rc2==SQLITE_PROTOCOL
){
pPager->errCode = rc;
}
@@ -2578,7 +2579,7 @@ int sqlite3pager_release_memory(int nReq){
** The error will be returned to the user (or users, in the case
** of a shared pager cache) of the pager for which the error occured.
*/
- assert( rc==SQLITE_IOERR || rc==SQLITE_FULL );
+ assert( (rc&0xff)==SQLITE_IOERR || rc==SQLITE_FULL );
assert( p->state>=PAGER_RESERVED );
pager_error(p, rc);
}
diff --git a/src/prepare.c b/src/prepare.c
index b89059b85..7e52c8787 100644
--- a/src/prepare.c
+++ b/src/prepare.c
@@ -13,7 +13,7 @@
** interface, and routines that contribute to loading the database schema
** from disk.
**
-** $Id: prepare.c,v 1.38 2006/08/12 13:28:23 drh Exp $
+** $Id: prepare.c,v 1.39 2006/09/15 07:28:50 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -546,6 +546,7 @@ int sqlite3_prepare(
rc = sqlite3ApiExit(db, rc);
sqlite3ReleaseThreadData();
+ assert( (rc&db->errMask)==rc );
return rc;
}
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index 2cd534b6d..302814884 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -12,7 +12,7 @@
** This header file defines the interface that the SQLite library
** presents to client programs.
**
-** @(#) $Id: sqlite.h.in,v 1.192 2006/09/11 00:34:22 drh Exp $
+** @(#) $Id: sqlite.h.in,v 1.193 2006/09/15 07:28:50 drh Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
@@ -199,6 +199,44 @@ int sqlite3_exec(
/* end-of-error-codes */
/*
+** Using the sqlite3_extended_result_codes() API, you can cause
+** SQLite to return result codes with additional information in
+** their upper bits. The lower 8 bits will be the same as the
+** primary result codes above. But the upper bits might contain
+** more specific error information.
+**
+** To extract the primary result code from an extended result code,
+** simply mask off the lower 8 bits.
+**
+** primary = extended & 0xff;
+**
+** New result error codes may be added from time to time. Software
+** that uses the extended result codes should plan accordingly and be
+** sure to always handle new unknown codes gracefully.
+**
+** The SQLITE_OK result code will never be extended. It will always
+** be exactly zero.
+**
+** The extended result codes always have the primary result code
+** as a prefix. Primary result codes only contain a single "_"
+** character. Extended result codes contain two or more "_" characters.
+*/
+#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8))
+#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8))
+#define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8))
+#define SQLITE_IOERR_FSYNC (SQLITE_IOERR | (4<<8))
+#define SQLITE_IOERR_DIR_FSYNC (SQLITE_IOERR | (5<<8))
+#define SQLITE_IOERR_TRUNCATE (SQLITE_IOERR | (6<<8))
+#define SQLITE_IOERR_FSTAT (SQLITE_IOERR | (7<<8))
+#define SQLITE_IOERR_UNLOCK (SQLITE_IOERR | (8<<8))
+#define SQLITE_IOERR_RDLOCK (SQLITE_IOERR | (9<<8))
+
+/*
+** Enable or disable the extended result codes.
+*/
+int sqlite3_extended_result_codes(sqlite3*, int onoff);
+
+/*
** Each entry in an SQLite table has a unique integer key. (The key is
** the value of the INTEGER PRIMARY KEY column if there is such a column,
** otherwise the key is generated at random. The unique key is always
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index fae55f2ec..3aa94ff34 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -11,7 +11,7 @@
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.526 2006/09/11 23:45:50 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.527 2006/09/15 07:28:50 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
@@ -447,6 +447,7 @@ struct sqlite3 {
Db *aDb; /* All backends */
int flags; /* Miscellanous flags. See below */
int errCode; /* Most recent error code (SQLITE_*) */
+ int errMask; /* & result codes with this before returning */
u8 autoCommit; /* The auto-commit flag. */
u8 temp_store; /* 1: file 2: memory 0: default */
int nTable; /* Number of tables in the database */
diff --git a/src/table.c b/src/table.c
index c4e228361..30c148489 100644
--- a/src/table.c
+++ b/src/table.c
@@ -146,7 +146,7 @@ int sqlite3_get_table(
assert( sizeof(res.azResult[0])>= sizeof(res.nData) );
res.azResult[0] = (char*)res.nData;
}
- if( rc==SQLITE_ABORT ){
+ if( (rc&0xff)==SQLITE_ABORT ){
sqlite3_free_table(&res.azResult[1]);
if( res.zErrMsg ){
if( pzErrMsg ){
@@ -156,12 +156,12 @@ int sqlite3_get_table(
sqliteFree(res.zErrMsg);
}
db->errCode = res.rc;
- return res.rc;
+ return res.rc & db->errMask;
}
sqliteFree(res.zErrMsg);
if( rc!=SQLITE_OK ){
sqlite3_free_table(&res.azResult[1]);
- return rc;
+ return rc & db->errMask;
}
if( res.nAlloc>res.nData ){
char **azNew;
@@ -176,7 +176,7 @@ int sqlite3_get_table(
*pazResult = &res.azResult[1];
if( pnColumn ) *pnColumn = res.nColumn;
if( pnRow ) *pnRow = res.nRow;
- return rc;
+ return rc & db->errMask;
}
/*
diff --git a/src/test1.c b/src/test1.c
index e4e1359d1..b9dce6b99 100644
--- a/src/test1.c
+++ b/src/test1.c
@@ -13,7 +13,7 @@
** is not included in the SQLite library. It is used for automated
** testing of the SQLite library.
**
-** $Id: test1.c,v 1.221 2006/09/13 19:21:28 drh Exp $
+** $Id: test1.c,v 1.222 2006/09/15 07:28:51 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
@@ -65,7 +65,7 @@ static int get_sqlite_pointer(
const char *sqlite3TestErrorName(int rc){
const char *zName = 0;
- switch( rc ){
+ switch( rc & 0xff ){
case SQLITE_OK: zName = "SQLITE_OK"; break;
case SQLITE_ERROR: zName = "SQLITE_ERROR"; break;
case SQLITE_PERM: zName = "SQLITE_PERM"; break;
@@ -1062,6 +1062,29 @@ static int test_enable_shared(
#endif
/*
+** Usage: sqlite3_extended_result_codes DB BOOLEAN
+**
+*/
+static int test_extended_result_codes(
+ ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
+ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
+ int objc, /* Number of arguments */
+ Tcl_Obj *CONST objv[] /* Command arguments */
+){
+ int enable;
+ sqlite3 *db;
+
+ if( objc!=3 ){
+ Tcl_WrongNumArgs(interp, 1, objv, "DB BOOLEAN");
+ return TCL_ERROR;
+ }
+ if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
+ if( Tcl_GetBooleanFromObj(interp, objv[2], &enable) ) return TCL_ERROR;
+ sqlite3_extended_result_codes(db, enable);
+ return TCL_OK;
+}
+
+/*
** Usage: sqlite3_libversion_number
**
*/
@@ -2331,6 +2354,8 @@ static int test_errcode(
Tcl_Obj *CONST objv[]
){
sqlite3 *db;
+ int rc;
+ char zBuf[30];
if( objc!=2 ){
Tcl_AppendResult(interp, "wrong # args: should be \"",
@@ -2338,7 +2363,13 @@ static int test_errcode(
return TCL_ERROR;
}
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
- Tcl_SetResult(interp, (char *)errorName(sqlite3_errcode(db)), 0);
+ rc = sqlite3_errcode(db);
+ if( (rc&0xff)==rc ){
+ zBuf[0] = 0;
+ }else{
+ sprintf(zBuf,"+%d", rc>>8);
+ }
+ Tcl_AppendResult(interp, (char *)errorName(rc), zBuf, 0);
return TCL_OK;
}
@@ -3861,6 +3892,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "sqlite3_load_extension", test_load_extension, 0},
{ "sqlite3_enable_load_extension", test_enable_load, 0},
+ { "sqlite3_extended_result_codes", test_extended_result_codes, 0},
/* sqlite3_column_*() API */
{ "sqlite3_column_count", test_column_count ,0 },
diff --git a/src/util.c b/src/util.c
index 905477d1f..457227da0 100644
--- a/src/util.c
+++ b/src/util.c
@@ -14,7 +14,7 @@
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
-** $Id: util.c,v 1.192 2006/07/26 01:39:30 drh Exp $
+** $Id: util.c,v 1.193 2006/09/15 07:28:51 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -1446,7 +1446,7 @@ int sqlite3ApiExit(sqlite3* db, int rc){
sqlite3Error(db, SQLITE_NOMEM, 0);
rc = SQLITE_NOMEM;
}
- return rc;
+ return rc & (db ? db->errMask : 0xff);
}
/*
diff --git a/src/vdbeapi.c b/src/vdbeapi.c
index a0ced3d79..983f164cb 100644
--- a/src/vdbeapi.c
+++ b/src/vdbeapi.c
@@ -254,6 +254,7 @@ int sqlite3_step(sqlite3_stmt *pStmt){
sqlite3Error(p->db, rc, 0);
p->rc = sqlite3ApiExit(p->db, p->rc);
+ assert( (rc&0xff)==rc );
return rc;
}
@@ -815,6 +816,7 @@ int sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){
rc = sqlite3VdbeMemMove(&pTo->aVar[i], &pFrom->aVar[i]);
sqlite3MallocAllow();
}
+ assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
return rc;
}
diff --git a/src/vdbeaux.c b/src/vdbeaux.c
index a6ca9c3c7..5c534d122 100644
--- a/src/vdbeaux.c
+++ b/src/vdbeaux.c
@@ -1435,18 +1435,20 @@ int sqlite3VdbeHalt(Vdbe *p){
** VDBE_MAGIC_INIT.
*/
int sqlite3VdbeReset(Vdbe *p){
+ sqlite3 *db;
if( p->magic!=VDBE_MAGIC_RUN && p->magic!=VDBE_MAGIC_HALT ){
sqlite3Error(p->db, SQLITE_MISUSE, 0);
return SQLITE_MISUSE;
}
+ db = p->db;
/* If the VM did not run to completion or if it encountered an
** error, then it might not have been halted properly. So halt
** it now.
*/
- sqlite3SafetyOn(p->db);
+ sqlite3SafetyOn(db);
sqlite3VdbeHalt(p);
- sqlite3SafetyOff(p->db);
+ sqlite3SafetyOff(db);
/* If the VDBE has be run even partially, then transfer the error code
** and error message from the VDBE into the main database structure. But
@@ -1455,21 +1457,20 @@ int sqlite3VdbeReset(Vdbe *p){
*/
if( p->pc>=0 ){
if( p->zErrMsg ){
- sqlite3* db = p->db;
sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, sqlite3FreeX);
db->errCode = p->rc;
p->zErrMsg = 0;
}else if( p->rc ){
- sqlite3Error(p->db, p->rc, 0);
+ sqlite3Error(db, p->rc, 0);
}else{
- sqlite3Error(p->db, SQLITE_OK, 0);
+ sqlite3Error(db, SQLITE_OK, 0);
}
}else if( p->rc && p->expired ){
/* The expired flag was set on the VDBE before the first call
** to sqlite3_step(). For consistency (since sqlite3_step() was
** called), set the database error in this case as well.
*/
- sqlite3Error(p->db, p->rc, 0);
+ sqlite3Error(db, p->rc, 0);
}
/* Reclaim all memory used by the VDBE
@@ -1504,9 +1505,9 @@ int sqlite3VdbeReset(Vdbe *p){
p->magic = VDBE_MAGIC_INIT;
p->aborted = 0;
if( p->rc==SQLITE_SCHEMA ){
- sqlite3ResetInternalSchema(p->db, 0);
+ sqlite3ResetInternalSchema(db, 0);
}
- return p->rc;
+ return p->rc & db->errMask;
}
/*
@@ -1517,6 +1518,7 @@ int sqlite3VdbeFinalize(Vdbe *p){
int rc = SQLITE_OK;
if( p->magic==VDBE_MAGIC_RUN || p->magic==VDBE_MAGIC_HALT ){
rc = sqlite3VdbeReset(p);
+ assert( (rc & p->db->errMask)==rc );
}else if( p->magic!=VDBE_MAGIC_INIT ){
return SQLITE_MISUSE;
}
diff --git a/src/vtab.c b/src/vtab.c
index 2fa389b43..c3e2481a6 100644
--- a/src/vtab.c
+++ b/src/vtab.c
@@ -11,7 +11,7 @@
*************************************************************************
** This file contains code used to help implement virtual tables.
**
-** $Id: vtab.c,v 1.35 2006/09/13 19:21:28 drh Exp $
+** $Id: vtab.c,v 1.36 2006/09/15 07:28:51 drh Exp $
*/
#ifndef SQLITE_OMIT_VIRTUALTABLE
#include "sqliteInt.h"
@@ -471,6 +471,7 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
sParse.pNewTable = 0;
db->pVTab = 0;
+ assert( (rc&0xff)==rc );
return rc;
}