mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
Add tests and fixes for handling malloc() failures related to the virtual table feature. (CVS 3285)
FossilOrigin-Name: 5d1d907189ff3ca7afada83033280cf258984ac0
This commit is contained in:
32
manifest
32
manifest
@ -1,5 +1,5 @@
|
|||||||
C Test\sthe\shandling\sof\serrors\sin\svirtual\stable\smethods.\s(CVS\s3284)
|
C Add\stests\sand\sfixes\sfor\shandling\smalloc()\sfailures\srelated\sto\sthe\svirtual\stable\sfeature.\s(CVS\s3285)
|
||||||
D 2006-06-22T09:53:49
|
D 2006-06-23T08:05:19
|
||||||
F Makefile.in f839b470345d3cb4b0644068474623fe2464b5d3
|
F Makefile.in f839b470345d3cb4b0644068474623fe2464b5d3
|
||||||
F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
|
F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
|
||||||
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
||||||
@ -72,9 +72,9 @@ F src/random.c d40f8d356cecbd351ccfab6eaedd7ec1b54f5261
|
|||||||
F src/select.c 380fa06c99ae01050c0054c4b1db91e9f1d8322d
|
F src/select.c 380fa06c99ae01050c0054c4b1db91e9f1d8322d
|
||||||
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
|
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
|
||||||
F src/shell.c ad73192b30a338a58fe81183d4a5d5a1d4e51d36
|
F src/shell.c ad73192b30a338a58fe81183d4a5d5a1d4e51d36
|
||||||
F src/sqlite.h.in b8c6139b3af13a2c361a8a5aeabb28aa3eef1ae1
|
F src/sqlite.h.in 698928d10c9960e14c008a9dfcbb1d785fc1d039
|
||||||
F src/sqlite3ext.h e334107f6cad0d00c0414e04189742a45ce916b1
|
F src/sqlite3ext.h e334107f6cad0d00c0414e04189742a45ce916b1
|
||||||
F src/sqliteInt.h d79b031593462dfcbc8c122a5f698a00e6b124fa
|
F src/sqliteInt.h 83920044668752bc05fde6176e5dea30851cdce0
|
||||||
F src/table.c f64ec4fbfe333f8df925bc6ba494f55e05b0e75e
|
F src/table.c f64ec4fbfe333f8df925bc6ba494f55e05b0e75e
|
||||||
F src/tclsqlite.c 32d9e0147077f2e2c127c5f214fb3fe03ef97d18
|
F src/tclsqlite.c 32d9e0147077f2e2c127c5f214fb3fe03ef97d18
|
||||||
F src/test1.c 233d5c83d11f34aa1c02eb72011ba9a30b72e078
|
F src/test1.c 233d5c83d11f34aa1c02eb72011ba9a30b72e078
|
||||||
@ -84,7 +84,7 @@ F src/test4.c 8b784cd82de158a2317cb4ac4bc86f91ad315e25
|
|||||||
F src/test5.c 7162f8526affb771c4ed256826eee7bb9eca265f
|
F src/test5.c 7162f8526affb771c4ed256826eee7bb9eca265f
|
||||||
F src/test6.c 60a02961ceb7b3edc25f5dc5c1ac2556622a76de
|
F src/test6.c 60a02961ceb7b3edc25f5dc5c1ac2556622a76de
|
||||||
F src/test7.c 03fa8d787f6aebc6d1f72504d52f33013ad2c8e3
|
F src/test7.c 03fa8d787f6aebc6d1f72504d52f33013ad2c8e3
|
||||||
F src/test8.c b8014836e18b9f42d0ac5c190efcc8318694c14e
|
F src/test8.c e09bf2654269ff025350d1a40f4b1058a6a07dbb
|
||||||
F src/test_async.c e3deaedd4d86a56391b81808fde9e44fbd92f1d3
|
F src/test_async.c e3deaedd4d86a56391b81808fde9e44fbd92f1d3
|
||||||
F src/test_loadext.c 22065d601a18878e5542191001f0eaa5d77c0ed8
|
F src/test_loadext.c 22065d601a18878e5542191001f0eaa5d77c0ed8
|
||||||
F src/test_md5.c 6c42bc0a3c0b54be34623ff77a0eec32b2fa96e3
|
F src/test_md5.c 6c42bc0a3c0b54be34623ff77a0eec32b2fa96e3
|
||||||
@ -97,15 +97,15 @@ F src/update.c 686b13db8b28a129a2407aaffc8b7588d1104e0b
|
|||||||
F src/utf.c ab81ac59084ff1c07d421eb1a0a84ec809603b44
|
F src/utf.c ab81ac59084ff1c07d421eb1a0a84ec809603b44
|
||||||
F src/util.c ca6ee72772c0f5dc04d2e0ab1973fd3b6a9bf79d
|
F src/util.c ca6ee72772c0f5dc04d2e0ab1973fd3b6a9bf79d
|
||||||
F src/vacuum.c 5b37d0f436f8e1ffacd17934e44720b38d2247f9
|
F src/vacuum.c 5b37d0f436f8e1ffacd17934e44720b38d2247f9
|
||||||
F src/vdbe.c 2c36e0badc0bcc14f099e95ec84470c479fbd399
|
F src/vdbe.c b4232a43e8603ed2aced49865bb1de82aa8371e1
|
||||||
F src/vdbe.h 258b5d1c0aaa72192f09ff0568ce42b383f156fa
|
F src/vdbe.h 258b5d1c0aaa72192f09ff0568ce42b383f156fa
|
||||||
F src/vdbeInt.h 6ccb7eaae76ebd761470f6a035501ff33aa92c20
|
F src/vdbeInt.h de89a3475a0a914c49f92e51c303f7dd6f2b21fe
|
||||||
F src/vdbeapi.c 6af0e7160af260052a7a4500464221a03dada75f
|
F src/vdbeapi.c 6af0e7160af260052a7a4500464221a03dada75f
|
||||||
F src/vdbeaux.c 2e4cb97e6d1612c0e108d68e038a7cd612bceb72
|
F src/vdbeaux.c d8cf95bc96fbcd933db14cf6cd196098146d2afd
|
||||||
F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5
|
F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5
|
||||||
F src/vdbemem.c 5f0afe3b92bb2c037f8d5d697f7c151fa50783a3
|
F src/vdbemem.c 5f0afe3b92bb2c037f8d5d697f7c151fa50783a3
|
||||||
F src/vtab.c 99ca599e9e4af1a63a3caf4389410a16adacf9f6
|
F src/vtab.c 7edad77e201cc83b7826e53393c21d617e472fe1
|
||||||
F src/where.c 0a13357175678d51a218326bca389f20bb41e38b
|
F src/where.c 6175449f1ff97a5bfea4068a35c050456c632e89
|
||||||
F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42
|
F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42
|
||||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||||
F test/all.test 5df90d015ca63fcef2a4b62c24f7316b66c4bfd4
|
F test/all.test 5df90d015ca63fcef2a4b62c24f7316b66c4bfd4
|
||||||
@ -225,7 +225,7 @@ F test/pagesize.test 05c74ea49f790734ec1e9ab765d9bf1cce79b8f2
|
|||||||
F test/pragma.test e2d72d9e9a24744356cd5a4d25ea842c5020d345
|
F test/pragma.test e2d72d9e9a24744356cd5a4d25ea842c5020d345
|
||||||
F test/printf.test cdd8e20dd901382a385afcbaa777b9377815c2ad
|
F test/printf.test cdd8e20dd901382a385afcbaa777b9377815c2ad
|
||||||
F test/progress.test 8b22b4974b0a95272566385f8cb8c341c7130df8 x
|
F test/progress.test 8b22b4974b0a95272566385f8cb8c341c7130df8 x
|
||||||
F test/quick.test fc44005d54bc6b43609e3942ddf22babd8230fcc
|
F test/quick.test 4eabf0fd67dc6e116cbebe3f8d899608239eae50
|
||||||
F test/quote.test 5891f2338980916cf7415484b4ce785294044adb
|
F test/quote.test 5891f2338980916cf7415484b4ce785294044adb
|
||||||
F test/reindex.test 38b138abe36bf9a08c791ed44d9f76cd6b97b78b
|
F test/reindex.test 38b138abe36bf9a08c791ed44d9f76cd6b97b78b
|
||||||
F test/rollback.test 673cd8c44c685ad54987fe7f0eeba84efa09685d
|
F test/rollback.test 673cd8c44c685ad54987fe7f0eeba84efa09685d
|
||||||
@ -252,7 +252,7 @@ F test/table.test 1c1539af8db89c68e467df02ec2607ec61c67bac
|
|||||||
F test/tableapi.test 6a66d58b37d46dc0f2b3c7d4bd2617d209399bd1
|
F test/tableapi.test 6a66d58b37d46dc0f2b3c7d4bd2617d209399bd1
|
||||||
F test/tclsqlite.test 93c399414273d829f3fc5fc4a8349b484fe84d5b
|
F test/tclsqlite.test 93c399414273d829f3fc5fc4a8349b484fe84d5b
|
||||||
F test/temptable.test c36f3e5a94507abb64f7ba23deeb4e1a8a8c3821
|
F test/temptable.test c36f3e5a94507abb64f7ba23deeb4e1a8a8c3821
|
||||||
F test/tester.tcl 66a4bfa61a05e08ea523ef077e7ad0eab090c327
|
F test/tester.tcl 0436eda9b45cd937662b9766262cc2527448413f
|
||||||
F test/thread1.test 776c9e459b75ba905193b351926ac4019b049f35
|
F test/thread1.test 776c9e459b75ba905193b351926ac4019b049f35
|
||||||
F test/thread2.test 6d7b30102d600f51b4055ee3a5a19228799049fb
|
F test/thread2.test 6d7b30102d600f51b4055ee3a5a19228799049fb
|
||||||
F test/threadtest1.c 6029d9c5567db28e6dc908a0c63099c3ba6c383b
|
F test/threadtest1.c 6029d9c5567db28e6dc908a0c63099c3ba6c383b
|
||||||
@ -297,7 +297,7 @@ F test/vtab3.test f38d6d7d19f08bffdadce4d5b8cba078f8118587
|
|||||||
F test/vtab4.test 4b4293341443839ef6dc02f8d9e614702a6c67ff
|
F test/vtab4.test 4b4293341443839ef6dc02f8d9e614702a6c67ff
|
||||||
F test/vtab5.test 9fb8f335651afe8f870011e2f68e5b00c5ad03cd
|
F test/vtab5.test 9fb8f335651afe8f870011e2f68e5b00c5ad03cd
|
||||||
F test/vtab6.test 0b4fe07e421b2b9a334bec8781e75cbd8e230bd3
|
F test/vtab6.test 0b4fe07e421b2b9a334bec8781e75cbd8e230bd3
|
||||||
F test/vtab_err.test 7b435152e5555ca01645cbd15864430a80c44765
|
F test/vtab_err.test 11b90203ad60d63746d0de547b1ca014704d8f0e
|
||||||
F test/where.test ee7c9a6659b07e1ee61177f6e7ff71565ee2c9df
|
F test/where.test ee7c9a6659b07e1ee61177f6e7ff71565ee2c9df
|
||||||
F test/where2.test a16476a5913e75cf65b38f2daa6157a6b7791394
|
F test/where2.test a16476a5913e75cf65b38f2daa6157a6b7791394
|
||||||
F test/where3.test 3b5ad2c58069e12be2bd86bc5e211a82810521aa
|
F test/where3.test 3b5ad2c58069e12be2bd86bc5e211a82810521aa
|
||||||
@ -373,7 +373,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
|
|||||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||||
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
||||||
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
|
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
|
||||||
P d50c37975de7639627422cbed40eb03a431874d5
|
P 51b729d9d9f8a60cdfb552809e4aa10012f4eb68
|
||||||
R deba37635ada8fb35f1bc556c53eccea
|
R c21237f21b6a4ca0ffad3dda7ecba2f2
|
||||||
U danielk1977
|
U danielk1977
|
||||||
Z fb72a1410426354cd3d1ca1870332bcd
|
Z 9f0e1165f66a8128b5c09a2e388b1740
|
||||||
|
@ -1 +1 @@
|
|||||||
51b729d9d9f8a60cdfb552809e4aa10012f4eb68
|
5d1d907189ff3ca7afada83033280cf258984ac0
|
@ -12,7 +12,7 @@
|
|||||||
** This header file defines the interface that the SQLite library
|
** This header file defines the interface that the SQLite library
|
||||||
** presents to client programs.
|
** presents to client programs.
|
||||||
**
|
**
|
||||||
** @(#) $Id: sqlite.h.in,v 1.181 2006/06/22 09:53:50 danielk1977 Exp $
|
** @(#) $Id: sqlite.h.in,v 1.182 2006/06/23 08:05:19 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef _SQLITE3_H_
|
#ifndef _SQLITE3_H_
|
||||||
#define _SQLITE3_H_
|
#define _SQLITE3_H_
|
||||||
@ -1662,6 +1662,7 @@ int sqlite3_create_module(
|
|||||||
*/
|
*/
|
||||||
struct sqlite3_vtab {
|
struct sqlite3_vtab {
|
||||||
const sqlite3_module *pModule; /* The module for this virtual table */
|
const sqlite3_module *pModule; /* The module for this virtual table */
|
||||||
|
int nRef; /* Used internally */
|
||||||
/* Virtual table implementations will typically add additional fields */
|
/* Virtual table implementations will typically add additional fields */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** Internal interface definitions for SQLite.
|
** Internal interface definitions for SQLite.
|
||||||
**
|
**
|
||||||
** @(#) $Id: sqliteInt.h,v 1.510 2006/06/17 10:44:42 drh Exp $
|
** @(#) $Id: sqliteInt.h,v 1.511 2006/06/23 08:05:19 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef _SQLITEINT_H_
|
#ifndef _SQLITEINT_H_
|
||||||
#define _SQLITEINT_H_
|
#define _SQLITEINT_H_
|
||||||
@ -1820,13 +1820,11 @@ void sqlite3CloseExtensions(sqlite3*);
|
|||||||
|
|
||||||
#ifdef SQLITE_OMIT_VIRTUALTABLE
|
#ifdef SQLITE_OMIT_VIRTUALTABLE
|
||||||
# define sqlite3VtabClear(X)
|
# define sqlite3VtabClear(X)
|
||||||
# define sqlite3VtabCodeLock(X,Y)
|
|
||||||
# define sqlite3VtabSync(X,Y) (Y)
|
# define sqlite3VtabSync(X,Y) (Y)
|
||||||
# define sqlite3VtabRollback(X)
|
# define sqlite3VtabRollback(X)
|
||||||
# define sqlite3VtabCommit(X)
|
# define sqlite3VtabCommit(X)
|
||||||
#else
|
#else
|
||||||
void sqlite3VtabClear(Table*);
|
void sqlite3VtabClear(Table*);
|
||||||
void sqlite3VtabCodeLock(Parse *pParse, Table *pTab);
|
|
||||||
int sqlite3VtabSync(sqlite3 *db, int rc);
|
int sqlite3VtabSync(sqlite3 *db, int rc);
|
||||||
int sqlite3VtabRollback(sqlite3 *db);
|
int sqlite3VtabRollback(sqlite3 *db);
|
||||||
int sqlite3VtabCommit(sqlite3 *db);
|
int sqlite3VtabCommit(sqlite3 *db);
|
||||||
|
57
src/test8.c
57
src/test8.c
@ -13,7 +13,7 @@
|
|||||||
** is not included in the SQLite library. It is used for automated
|
** is not included in the SQLite library. It is used for automated
|
||||||
** testing of the SQLite library.
|
** testing of the SQLite library.
|
||||||
**
|
**
|
||||||
** $Id: test8.c,v 1.31 2006/06/22 09:53:50 danielk1977 Exp $
|
** $Id: test8.c,v 1.32 2006/06/23 08:05:26 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "tcl.h"
|
#include "tcl.h"
|
||||||
@ -72,7 +72,7 @@ static int getColumnNames(
|
|||||||
char zBuf[1024];
|
char zBuf[1024];
|
||||||
sqlite3_stmt *pStmt = 0;
|
sqlite3_stmt *pStmt = 0;
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
int nCol;
|
int nCol = 0;
|
||||||
|
|
||||||
sprintf(zBuf, "SELECT * FROM %s", zTab);
|
sprintf(zBuf, "SELECT * FROM %s", zTab);
|
||||||
rc = sqlite3_prepare(db, zBuf, -1, &pStmt, 0);
|
rc = sqlite3_prepare(db, zBuf, -1, &pStmt, 0);
|
||||||
@ -143,14 +143,18 @@ static int getIndexArray(sqlite3 *db, const char *zTab, int **paIndex){
|
|||||||
assert( cid>=0 && cid<nCol );
|
assert( cid>=0 && cid<nCol );
|
||||||
aIndex[cid] = 1;
|
aIndex[cid] = 1;
|
||||||
}
|
}
|
||||||
rc = sqlite3_finalize(pStmt2);
|
if( pStmt2 ){
|
||||||
|
rc = sqlite3_finalize(pStmt2);
|
||||||
|
}
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
sqlite3_finalize(pStmt);
|
sqlite3_finalize(pStmt);
|
||||||
goto get_index_array_out;
|
goto get_index_array_out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = sqlite3_finalize(pStmt);
|
if( pStmt ){
|
||||||
|
rc = sqlite3_finalize(pStmt);
|
||||||
|
}
|
||||||
|
|
||||||
get_index_array_out:
|
get_index_array_out:
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
@ -206,10 +210,14 @@ static int echoDeclareVtab(
|
|||||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||||
sqlite3_declare_vtab(db, zCreateTable);
|
sqlite3_declare_vtab(db, zCreateTable);
|
||||||
#endif
|
#endif
|
||||||
|
rc = sqlite3_finalize(pStmt);
|
||||||
} else {
|
} else {
|
||||||
rc = SQLITE_ERROR;
|
rc = sqlite3_finalize(pStmt);
|
||||||
|
if( rc==SQLITE_OK ){
|
||||||
|
rc = SQLITE_ERROR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sqlite3_finalize(pStmt);
|
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
rc = getIndexArray(db, argv[3], &pVtab->aIndex);
|
rc = getIndexArray(db, argv[3], &pVtab->aIndex);
|
||||||
}
|
}
|
||||||
@ -244,9 +252,16 @@ static int echoConstructor(
|
|||||||
echo_vtab *pVtab;
|
echo_vtab *pVtab;
|
||||||
|
|
||||||
pVtab = sqliteMalloc( sizeof(*pVtab) );
|
pVtab = sqliteMalloc( sizeof(*pVtab) );
|
||||||
|
if( !pVtab ){
|
||||||
|
return SQLITE_NOMEM;
|
||||||
|
}
|
||||||
pVtab->interp = (Tcl_Interp *)pAux;
|
pVtab->interp = (Tcl_Interp *)pAux;
|
||||||
pVtab->db = db;
|
pVtab->db = db;
|
||||||
pVtab->zTableName = sqlite3MPrintf("%s", argv[3]);
|
pVtab->zTableName = sqlite3MPrintf("%s", argv[3]);
|
||||||
|
if( !pVtab->zTableName ){
|
||||||
|
return SQLITE_NOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
for(i=0; i<argc; i++){
|
for(i=0; i<argc; i++){
|
||||||
appendToEchoModule(pVtab->interp, argv[i]);
|
appendToEchoModule(pVtab->interp, argv[i]);
|
||||||
}
|
}
|
||||||
@ -318,14 +333,17 @@ static int echoOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
|
|||||||
echo_cursor *pCur;
|
echo_cursor *pCur;
|
||||||
pCur = sqliteMalloc(sizeof(echo_cursor));
|
pCur = sqliteMalloc(sizeof(echo_cursor));
|
||||||
*ppCursor = (sqlite3_vtab_cursor *)pCur;
|
*ppCursor = (sqlite3_vtab_cursor *)pCur;
|
||||||
return SQLITE_OK;
|
return (pCur ? SQLITE_OK : SQLITE_NOMEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int echoClose(sqlite3_vtab_cursor *cur){
|
static int echoClose(sqlite3_vtab_cursor *cur){
|
||||||
|
int rc;
|
||||||
echo_cursor *pCur = (echo_cursor *)cur;
|
echo_cursor *pCur = (echo_cursor *)cur;
|
||||||
sqlite3_finalize(pCur->pStmt);
|
sqlite3_stmt *pStmt = pCur->pStmt;
|
||||||
|
pCur->pStmt = 0;
|
||||||
sqliteFree(pCur);
|
sqliteFree(pCur);
|
||||||
return SQLITE_OK;
|
rc = sqlite3_finalize(pStmt);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -339,7 +357,7 @@ static int echoEof(sqlite3_vtab_cursor *cur){
|
|||||||
static int echoNext(sqlite3_vtab_cursor *cur){
|
static int echoNext(sqlite3_vtab_cursor *cur){
|
||||||
int rc;
|
int rc;
|
||||||
echo_cursor *pCur = (echo_cursor *)cur;
|
echo_cursor *pCur = (echo_cursor *)cur;
|
||||||
|
sqlite3_stmt *pStmt = pCur->pStmt;
|
||||||
rc = sqlite3_step(pCur->pStmt);
|
rc = sqlite3_step(pCur->pStmt);
|
||||||
|
|
||||||
if( rc==SQLITE_ROW ){
|
if( rc==SQLITE_ROW ){
|
||||||
@ -398,13 +416,18 @@ static int echoFilter(
|
|||||||
int argc, sqlite3_value **argv
|
int argc, sqlite3_value **argv
|
||||||
){
|
){
|
||||||
int rc;
|
int rc;
|
||||||
int ret;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
echo_cursor *pCur = (echo_cursor *)pVtabCursor;
|
echo_cursor *pCur = (echo_cursor *)pVtabCursor;
|
||||||
echo_vtab *pVtab = (echo_vtab *)pVtabCursor->pVtab;
|
echo_vtab *pVtab = (echo_vtab *)pVtabCursor->pVtab;
|
||||||
sqlite3 *db = pVtab->db;
|
sqlite3 *db = pVtab->db;
|
||||||
|
|
||||||
|
appendToEchoModule(pVtab->interp, "xFilter");
|
||||||
|
appendToEchoModule(pVtab->interp, idxStr);
|
||||||
|
for(i=0; i<argc; i++){
|
||||||
|
appendToEchoModule(pVtab->interp, sqlite3_value_text(argv[i]));
|
||||||
|
}
|
||||||
|
|
||||||
assert( idxNum==hashString(idxStr) );
|
assert( idxNum==hashString(idxStr) );
|
||||||
sqlite3_finalize(pCur->pStmt);
|
sqlite3_finalize(pCur->pStmt);
|
||||||
pCur->pStmt = 0;
|
pCur->pStmt = 0;
|
||||||
@ -437,20 +460,12 @@ static int echoFilter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
ret = echoNext(pVtabCursor);
|
rc = echoNext(pVtabCursor);
|
||||||
}else{
|
}else{
|
||||||
assert( !pCur->pStmt );
|
assert( !pCur->pStmt );
|
||||||
ret = 0;
|
|
||||||
pCur->errcode = rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
appendToEchoModule(pVtab->interp, "xFilter");
|
return rc;
|
||||||
appendToEchoModule(pVtab->interp, idxStr);
|
|
||||||
for(i=0; i<argc; i++){
|
|
||||||
appendToEchoModule(pVtab->interp, sqlite3_value_text(argv[i]));
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
15
src/vdbe.c
15
src/vdbe.c
@ -43,7 +43,7 @@
|
|||||||
** in this file for details. If in doubt, do not deviate from existing
|
** in this file for details. If in doubt, do not deviate from existing
|
||||||
** commenting and indentation practices when changing or adding code.
|
** commenting and indentation practices when changing or adding code.
|
||||||
**
|
**
|
||||||
** $Id: vdbe.c,v 1.565 2006/06/22 09:53:50 danielk1977 Exp $
|
** $Id: vdbe.c,v 1.566 2006/06/23 08:05:26 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
@ -180,7 +180,7 @@ static Cursor *allocateCursor(Vdbe *p, int iCur, int iDb){
|
|||||||
Cursor *pCx;
|
Cursor *pCx;
|
||||||
assert( iCur<p->nCursor );
|
assert( iCur<p->nCursor );
|
||||||
if( p->apCsr[iCur] ){
|
if( p->apCsr[iCur] ){
|
||||||
sqlite3VdbeFreeCursor(p->apCsr[iCur]);
|
sqlite3VdbeFreeCursor(p, p->apCsr[iCur]);
|
||||||
}
|
}
|
||||||
p->apCsr[iCur] = pCx = sqliteMalloc( sizeof(Cursor) );
|
p->apCsr[iCur] = pCx = sqliteMalloc( sizeof(Cursor) );
|
||||||
if( pCx ){
|
if( pCx ){
|
||||||
@ -2733,7 +2733,7 @@ case OP_OpenPseudo: { /* no-push */
|
|||||||
case OP_Close: { /* no-push */
|
case OP_Close: { /* no-push */
|
||||||
int i = pOp->p1;
|
int i = pOp->p1;
|
||||||
if( i>=0 && i<p->nCursor ){
|
if( i>=0 && i<p->nCursor ){
|
||||||
sqlite3VdbeFreeCursor(p->apCsr[i]);
|
sqlite3VdbeFreeCursor(p, p->apCsr[i]);
|
||||||
p->apCsr[i] = 0;
|
p->apCsr[i] = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -4597,7 +4597,10 @@ case OP_VOpen: { /* no-push */
|
|||||||
|
|
||||||
/* Initialise vdbe cursor object */
|
/* Initialise vdbe cursor object */
|
||||||
pCur = allocateCursor(p, pOp->p1, -1);
|
pCur = allocateCursor(p, pOp->p1, -1);
|
||||||
pCur->pVtabCursor = pVtabCursor;
|
if( pCur ){
|
||||||
|
pCur->pVtabCursor = pVtabCursor;
|
||||||
|
pCur->pModule = pVtabCursor->pVtab->pModule;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -4651,7 +4654,9 @@ case OP_VFilter: { /* no-push */
|
|||||||
}
|
}
|
||||||
|
|
||||||
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
|
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
|
||||||
|
p->inVtabMethod = 1;
|
||||||
rc = pModule->xFilter(pCur->pVtabCursor, pTos->i, pOp->p3, nArg, apArg);
|
rc = pModule->xFilter(pCur->pVtabCursor, pTos->i, pOp->p3, nArg, apArg);
|
||||||
|
p->inVtabMethod = 0;
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
res = pModule->xEof(pCur->pVtabCursor);
|
res = pModule->xEof(pCur->pVtabCursor);
|
||||||
}
|
}
|
||||||
@ -4762,7 +4767,9 @@ case OP_VNext: { /* no-push */
|
|||||||
** some other method is next invoked on the save virtual table cursor.
|
** some other method is next invoked on the save virtual table cursor.
|
||||||
*/
|
*/
|
||||||
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
|
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
|
||||||
|
p->inVtabMethod = 1;
|
||||||
rc = pModule->xNext(pCur->pVtabCursor);
|
rc = pModule->xNext(pCur->pVtabCursor);
|
||||||
|
p->inVtabMethod = 0;
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
res = pModule->xEof(pCur->pVtabCursor);
|
res = pModule->xEof(pCur->pVtabCursor);
|
||||||
}
|
}
|
||||||
|
@ -85,6 +85,7 @@ struct Cursor {
|
|||||||
i64 seqCount; /* Sequence counter */
|
i64 seqCount; /* Sequence counter */
|
||||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||||
sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */
|
sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */
|
||||||
|
sqlite3_module *pModule; /* Module for cursor pVtabCursor */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Cached information about the header for the data record that the
|
/* Cached information about the header for the data record that the
|
||||||
@ -324,6 +325,9 @@ struct Vdbe {
|
|||||||
int fetchId; /* Statement number used by sqlite3_fetch_statement */
|
int fetchId; /* Statement number used by sqlite3_fetch_statement */
|
||||||
int lru; /* Counter used for LRU cache replacement */
|
int lru; /* Counter used for LRU cache replacement */
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||||
|
int inVtabMethod;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -337,7 +341,7 @@ struct Vdbe {
|
|||||||
/*
|
/*
|
||||||
** Function prototypes
|
** Function prototypes
|
||||||
*/
|
*/
|
||||||
void sqlite3VdbeFreeCursor(Cursor*);
|
void sqlite3VdbeFreeCursor(Vdbe *, Cursor*);
|
||||||
void sqliteVdbePopStack(Vdbe*,int);
|
void sqliteVdbePopStack(Vdbe*,int);
|
||||||
int sqlite3VdbeCursorMoveto(Cursor*);
|
int sqlite3VdbeCursorMoveto(Cursor*);
|
||||||
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
|
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
|
||||||
|
@ -841,7 +841,7 @@ void sqlite3VdbeMakeReady(
|
|||||||
** Close a cursor and release all the resources that cursor happens
|
** Close a cursor and release all the resources that cursor happens
|
||||||
** to hold.
|
** to hold.
|
||||||
*/
|
*/
|
||||||
void sqlite3VdbeFreeCursor(Cursor *pCx){
|
void sqlite3VdbeFreeCursor(Vdbe *p, Cursor *pCx){
|
||||||
if( pCx==0 ){
|
if( pCx==0 ){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -855,8 +855,10 @@ void sqlite3VdbeFreeCursor(Cursor *pCx){
|
|||||||
if( pCx->pVtabCursor ){
|
if( pCx->pVtabCursor ){
|
||||||
sqlite3_vtab_cursor *pVtabCursor = pCx->pVtabCursor;
|
sqlite3_vtab_cursor *pVtabCursor = pCx->pVtabCursor;
|
||||||
sqlite3_vtab *pVtab = pVtabCursor->pVtab;
|
sqlite3_vtab *pVtab = pVtabCursor->pVtab;
|
||||||
const sqlite3_module *pModule = pVtab->pModule;
|
const sqlite3_module *pModule = pCx->pModule;
|
||||||
|
p->inVtabMethod = 1;
|
||||||
pModule->xClose(pVtabCursor);
|
pModule->xClose(pVtabCursor);
|
||||||
|
p->inVtabMethod = 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
sqliteFree(pCx->pData);
|
sqliteFree(pCx->pData);
|
||||||
@ -871,7 +873,9 @@ static void closeAllCursors(Vdbe *p){
|
|||||||
int i;
|
int i;
|
||||||
if( p->apCsr==0 ) return;
|
if( p->apCsr==0 ) return;
|
||||||
for(i=0; i<p->nCursor; i++){
|
for(i=0; i<p->nCursor; i++){
|
||||||
sqlite3VdbeFreeCursor(p->apCsr[i]);
|
if( !p->inVtabMethod || (p->apCsr[i] && !p->apCsr[i]->pVtabCursor) ){
|
||||||
|
sqlite3VdbeFreeCursor(p, p->apCsr[i]);
|
||||||
|
}
|
||||||
p->apCsr[i] = 0;
|
p->apCsr[i] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1149,23 +1153,6 @@ static int vdbeCommit(sqlite3 *db){
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
** Find every active VM other than pVdbe and change its status to
|
|
||||||
** aborted. This happens when one VM causes a rollback due to an
|
|
||||||
** ON CONFLICT ROLLBACK clause (for example). The other VMs must be
|
|
||||||
** aborted so that they do not have data rolled out from underneath
|
|
||||||
** them leading to a segfault.
|
|
||||||
*/
|
|
||||||
void sqlite3AbortOtherActiveVdbes(sqlite3 *db, Vdbe *pExcept){
|
|
||||||
Vdbe *pOther;
|
|
||||||
for(pOther=db->pVdbe; pOther; pOther=pOther->pNext){
|
|
||||||
if( pOther==pExcept ) continue;
|
|
||||||
if( pOther->magic!=VDBE_MAGIC_RUN || pOther->pc<0 ) continue;
|
|
||||||
closeAllCursors(pOther);
|
|
||||||
pOther->aborted = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** This routine checks that the sqlite3.activeVdbeCnt count variable
|
** This routine checks that the sqlite3.activeVdbeCnt count variable
|
||||||
** matches the number of vdbe's in the list sqlite3.pVdbe that are
|
** matches the number of vdbe's in the list sqlite3.pVdbe that are
|
||||||
@ -1192,6 +1179,25 @@ static void checkActiveVdbeCnt(sqlite3 *db){
|
|||||||
#define checkActiveVdbeCnt(x)
|
#define checkActiveVdbeCnt(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Find every active VM other than pVdbe and change its status to
|
||||||
|
** aborted. This happens when one VM causes a rollback due to an
|
||||||
|
** ON CONFLICT ROLLBACK clause (for example). The other VMs must be
|
||||||
|
** aborted so that they do not have data rolled out from underneath
|
||||||
|
** them leading to a segfault.
|
||||||
|
*/
|
||||||
|
void sqlite3AbortOtherActiveVdbes(sqlite3 *db, Vdbe *pExcept){
|
||||||
|
Vdbe *pOther;
|
||||||
|
for(pOther=db->pVdbe; pOther; pOther=pOther->pNext){
|
||||||
|
if( pOther==pExcept ) continue;
|
||||||
|
if( pOther->magic!=VDBE_MAGIC_RUN || pOther->pc<0 ) continue;
|
||||||
|
checkActiveVdbeCnt(db);
|
||||||
|
closeAllCursors(pOther);
|
||||||
|
checkActiveVdbeCnt(db);
|
||||||
|
pOther->aborted = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** This routine is called the when a VDBE tries to halt. If the VDBE
|
** This routine is called the when a VDBE tries to halt. If the VDBE
|
||||||
** has made changes and is in autocommit mode, then commit those
|
** has made changes and is in autocommit mode, then commit those
|
||||||
@ -1375,8 +1381,7 @@ int sqlite3VdbeHalt(Vdbe *p){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We have successfully halted and closed the VM. Record this fact. */
|
if( p->pc>=0 ){
|
||||||
if( p->pc>=0 ){
|
|
||||||
db->activeVdbeCnt--;
|
db->activeVdbeCnt--;
|
||||||
}
|
}
|
||||||
p->magic = VDBE_MAGIC_HALT;
|
p->magic = VDBE_MAGIC_HALT;
|
||||||
|
39
src/vtab.c
39
src/vtab.c
@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** This file contains code used to help implement virtual tables.
|
** This file contains code used to help implement virtual tables.
|
||||||
**
|
**
|
||||||
** $Id: vtab.c,v 1.20 2006/06/21 16:02:43 danielk1977 Exp $
|
** $Id: vtab.c,v 1.21 2006/06/23 08:05:30 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
@ -46,9 +46,14 @@ int sqlite3_create_module(
|
|||||||
** record.
|
** record.
|
||||||
*/
|
*/
|
||||||
void sqlite3VtabClear(Table *p){
|
void sqlite3VtabClear(Table *p){
|
||||||
if( p->pVtab ){
|
sqlite3_vtab *pVtab = p->pVtab;
|
||||||
|
if( pVtab ){
|
||||||
assert( p->pMod && p->pMod->pModule );
|
assert( p->pMod && p->pMod->pModule );
|
||||||
p->pMod->pModule->xDisconnect(p->pVtab);
|
pVtab->nRef--;
|
||||||
|
if( pVtab->nRef==0 ){
|
||||||
|
pVtab->pModule->xDisconnect(pVtab);
|
||||||
|
}
|
||||||
|
p->pVtab = 0;
|
||||||
}
|
}
|
||||||
if( p->azModuleArg ){
|
if( p->azModuleArg ){
|
||||||
int i;
|
int i;
|
||||||
@ -91,7 +96,6 @@ void sqlite3VtabBeginParse(
|
|||||||
){
|
){
|
||||||
int iDb; /* The database the table is being created in */
|
int iDb; /* The database the table is being created in */
|
||||||
Table *pTable; /* The new virtual table */
|
Table *pTable; /* The new virtual table */
|
||||||
Token *pDummy; /* Dummy arg for sqlite3TwoPartName() */
|
|
||||||
|
|
||||||
sqlite3StartTable(pParse, pName1, pName2, 0, 0, 1, 0);
|
sqlite3StartTable(pParse, pName1, pName2, 0, 0, 1, 0);
|
||||||
pTable = pParse->pNewTable;
|
pTable = pParse->pNewTable;
|
||||||
@ -114,10 +118,9 @@ void sqlite3VtabBeginParse(
|
|||||||
** sqlite_master table, has already been made by sqlite3StartTable().
|
** sqlite_master table, has already been made by sqlite3StartTable().
|
||||||
** The second call, to obtain permission to create the table, is made now.
|
** The second call, to obtain permission to create the table, is made now.
|
||||||
*/
|
*/
|
||||||
if( sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName,
|
if( pTable->azModuleArg ){
|
||||||
pTable->azModuleArg[0], pParse->db->aDb[iDb].zName)
|
sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName,
|
||||||
){
|
pTable->azModuleArg[0], pParse->db->aDb[iDb].zName);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -272,6 +275,7 @@ static int vtabCallConstructor(
|
|||||||
int rc2;
|
int rc2;
|
||||||
char **azArg = pTab->azModuleArg;
|
char **azArg = pTab->azModuleArg;
|
||||||
int nArg = pTab->nModuleArg;
|
int nArg = pTab->nModuleArg;
|
||||||
|
char *zErr = sqlite3MPrintf("vtable constructor failed: %s", pTab->zName);
|
||||||
|
|
||||||
assert( !db->pVTab );
|
assert( !db->pVTab );
|
||||||
assert( xConstruct );
|
assert( xConstruct );
|
||||||
@ -281,12 +285,14 @@ static int vtabCallConstructor(
|
|||||||
assert( rc==SQLITE_OK );
|
assert( rc==SQLITE_OK );
|
||||||
rc = xConstruct(db, pMod->pAux, nArg, azArg, &pTab->pVtab);
|
rc = xConstruct(db, pMod->pAux, nArg, azArg, &pTab->pVtab);
|
||||||
rc2 = sqlite3SafetyOn(db);
|
rc2 = sqlite3SafetyOn(db);
|
||||||
if( pTab->pVtab ){
|
if( rc==SQLITE_OK && pTab->pVtab ){
|
||||||
pTab->pVtab->pModule = pMod->pModule;
|
pTab->pVtab->pModule = pMod->pModule;
|
||||||
|
pTab->pVtab->nRef = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( SQLITE_OK!=rc ){
|
if( SQLITE_OK!=rc ){
|
||||||
*pzErr = sqlite3MPrintf("vtable constructor failed: %s", pTab->zName);
|
*pzErr = zErr;
|
||||||
|
zErr = 0;
|
||||||
} else if( db->pVTab ){
|
} else if( db->pVTab ){
|
||||||
const char *zFormat = "vtable constructor did not declare schema: %s";
|
const char *zFormat = "vtable constructor did not declare schema: %s";
|
||||||
*pzErr = sqlite3MPrintf(zFormat, pTab->zName);
|
*pzErr = sqlite3MPrintf(zFormat, pTab->zName);
|
||||||
@ -296,6 +302,7 @@ static int vtabCallConstructor(
|
|||||||
rc = rc2;
|
rc = rc2;
|
||||||
}
|
}
|
||||||
db->pVTab = 0;
|
db->pVTab = 0;
|
||||||
|
sqliteFree(zErr);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -337,7 +344,7 @@ int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){
|
|||||||
/*
|
/*
|
||||||
** Add the virtual table pVtab to the array sqlite3.aVTrans[].
|
** Add the virtual table pVtab to the array sqlite3.aVTrans[].
|
||||||
*/
|
*/
|
||||||
int addToVTrans(sqlite3 *db, sqlite3_vtab *pVtab){
|
static int addToVTrans(sqlite3 *db, sqlite3_vtab *pVtab){
|
||||||
const int ARRAY_INCR = 5;
|
const int ARRAY_INCR = 5;
|
||||||
|
|
||||||
/* Grow the sqlite3.aVTrans array if required */
|
/* Grow the sqlite3.aVTrans array if required */
|
||||||
@ -354,6 +361,7 @@ int addToVTrans(sqlite3 *db, sqlite3_vtab *pVtab){
|
|||||||
|
|
||||||
/* Add pVtab to the end of sqlite3.aVTrans */
|
/* Add pVtab to the end of sqlite3.aVTrans */
|
||||||
db->aVTrans[db->nVTrans++] = pVtab;
|
db->aVTrans[db->nVTrans++] = pVtab;
|
||||||
|
pVtab->nRef++;
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -471,11 +479,6 @@ int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sqlite3VtabCodeLock(Parse *pParse, Table *pTab){
|
|
||||||
Vdbe *v = sqlite3GetVdbe(pParse);
|
|
||||||
sqlite3VdbeOp3(v, OP_VBegin, 0, 0, (const char*)pTab->pVtab, P3_VTAB);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** This function invokes either the xRollback or xCommit method
|
** This function invokes either the xRollback or xCommit method
|
||||||
** of each of the virtual tables in the sqlite3.aVTrans array. The method
|
** of each of the virtual tables in the sqlite3.aVTrans array. The method
|
||||||
@ -491,6 +494,10 @@ static void callFinaliser(sqlite3 *db, int offset){
|
|||||||
int (*x)(sqlite3_vtab *);
|
int (*x)(sqlite3_vtab *);
|
||||||
x = *(int (**)(sqlite3_vtab *))((char *)pVtab->pModule + offset);
|
x = *(int (**)(sqlite3_vtab *))((char *)pVtab->pModule + offset);
|
||||||
if( x ) x(pVtab);
|
if( x ) x(pVtab);
|
||||||
|
pVtab->nRef--;
|
||||||
|
if( pVtab->nRef==0 ){
|
||||||
|
pVtab->pModule->xDisconnect(pVtab);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sqliteFree(db->aVTrans);
|
sqliteFree(db->aVTrans);
|
||||||
db->nVTrans = 0;
|
db->nVTrans = 0;
|
||||||
|
14
src/where.c
14
src/where.c
@ -16,7 +16,7 @@
|
|||||||
** so is applicable. Because this module is responsible for selecting
|
** so is applicable. Because this module is responsible for selecting
|
||||||
** indices, you might also think of this module as the "query optimizer".
|
** indices, you might also think of this module as the "query optimizer".
|
||||||
**
|
**
|
||||||
** $Id: where.c,v 1.221 2006/06/20 13:07:28 danielk1977 Exp $
|
** $Id: where.c,v 1.222 2006/06/23 08:05:31 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@ -1125,10 +1125,16 @@ static double bestVirtualIndex(
|
|||||||
}
|
}
|
||||||
|
|
||||||
sqlite3SafetyOff(pParse->db);
|
sqlite3SafetyOff(pParse->db);
|
||||||
pTab->pVtab->pModule->xBestIndex(pTab->pVtab, pIdxInfo);
|
rc = pTab->pVtab->pModule->xBestIndex(pTab->pVtab, pIdxInfo);
|
||||||
rc = sqlite3SafetyOn(pParse->db);
|
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
sqlite3ErrorMsg(pParse, "%s", sqlite3ErrStr(rc));
|
if( rc==SQLITE_NOMEM ){
|
||||||
|
sqlite3FailedMalloc();
|
||||||
|
}else {
|
||||||
|
sqlite3ErrorMsg(pParse, "%s", sqlite3ErrStr(rc));
|
||||||
|
}
|
||||||
|
sqlite3SafetyOn(pParse->db);
|
||||||
|
}else{
|
||||||
|
rc = sqlite3SafetyOn(pParse->db);
|
||||||
}
|
}
|
||||||
|
|
||||||
*(int*)&pIdxInfo->nOrderBy = nOrderBy;
|
*(int*)&pIdxInfo->nOrderBy = nOrderBy;
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
# This file runs all tests.
|
# This file runs all tests.
|
||||||
#
|
#
|
||||||
# $Id: quick.test,v 1.44 2006/06/14 10:38:03 danielk1977 Exp $
|
# $Id: quick.test,v 1.45 2006/06/23 08:05:38 danielk1977 Exp $
|
||||||
|
|
||||||
proc lshift {lvar} {
|
proc lshift {lvar} {
|
||||||
upvar $lvar l
|
upvar $lvar l
|
||||||
@ -55,6 +55,7 @@ set EXCLUDE {
|
|||||||
btree8.test
|
btree8.test
|
||||||
utf16.test
|
utf16.test
|
||||||
shared_err.test
|
shared_err.test
|
||||||
|
vtab_err.test
|
||||||
}
|
}
|
||||||
|
|
||||||
if {[sqlite3 -has-codec]} {
|
if {[sqlite3 -has-codec]} {
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
# This file implements some common TCL routines used for regression
|
# This file implements some common TCL routines used for regression
|
||||||
# testing the SQLite library
|
# testing the SQLite library
|
||||||
#
|
#
|
||||||
# $Id: tester.tcl,v 1.64 2006/01/24 13:09:33 danielk1977 Exp $
|
# $Id: tester.tcl,v 1.65 2006/06/23 08:05:38 danielk1977 Exp $
|
||||||
|
|
||||||
# Make sure tclsqlite3 was compiled correctly. Abort now with an
|
# Make sure tclsqlite3 was compiled correctly. Abort now with an
|
||||||
# error message if not.
|
# error message if not.
|
||||||
@ -149,6 +149,7 @@ proc finalize_testing {} {
|
|||||||
catch {
|
catch {
|
||||||
pp_check_for_leaks
|
pp_check_for_leaks
|
||||||
}
|
}
|
||||||
|
breakpoint
|
||||||
sqlite3 db {}
|
sqlite3 db {}
|
||||||
# sqlite3_clear_tsd_memdebug
|
# sqlite3_clear_tsd_memdebug
|
||||||
db close
|
db close
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#
|
#
|
||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
#
|
#
|
||||||
# $Id: vtab_err.test,v 1.1 2006/06/22 09:53:50 danielk1977 Exp $
|
# $Id: vtab_err.test,v 1.2 2006/06/23 08:05:39 danielk1977 Exp $
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@ -19,6 +19,107 @@ ifcapable !vtab {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Usage: do_malloc_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 malloc failure simulation.
|
||||||
|
# -sqlbody TCL script to run with malloc failure simulation.
|
||||||
|
# -cleanup TCL script to run after the test.
|
||||||
|
#
|
||||||
|
# This command runs a series of tests to verify SQLite's ability
|
||||||
|
# to handle an out-of-memory condition gracefully. It is assumed
|
||||||
|
# that if this condition occurs a malloc() call will return a
|
||||||
|
# NULL pointer. Linux, for example, doesn't do that by default. See
|
||||||
|
# the "BUGS" section of malloc(3).
|
||||||
|
#
|
||||||
|
# Each iteration of a loop, the TCL commands in any argument passed
|
||||||
|
# to the -tclbody switch, followed by the SQL commands in any argument
|
||||||
|
# passed to the -sqlbody switch are executed. Each iteration the
|
||||||
|
# Nth call to sqliteMalloc() is made to fail, where N is increased
|
||||||
|
# each time the loop runs starting from 1. When all commands execute
|
||||||
|
# successfully, the loop ends.
|
||||||
|
#
|
||||||
|
proc do_malloc_test {tn args} {
|
||||||
|
array unset ::mallocopts
|
||||||
|
array set ::mallocopts $args
|
||||||
|
|
||||||
|
set ::go 1
|
||||||
|
for {set ::n 1} {$::go && $::n < 50000} {incr ::n} {
|
||||||
|
do_test $tn.$::n {
|
||||||
|
|
||||||
|
# Remove all traces of database files test.db and test2.db from the files
|
||||||
|
# system. Then open (empty database) "test.db" with the handle [db].
|
||||||
|
#
|
||||||
|
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}
|
||||||
|
catch {sqlite3 db test.db}
|
||||||
|
set ::DB [sqlite3_connection_pointer db]
|
||||||
|
|
||||||
|
# Execute any -tclprep and -sqlprep scripts.
|
||||||
|
#
|
||||||
|
if {[info exists ::mallocopts(-tclprep)]} {
|
||||||
|
eval $::mallocopts(-tclprep)
|
||||||
|
}
|
||||||
|
if {[info exists ::mallocopts(-sqlprep)]} {
|
||||||
|
execsql $::mallocopts(-sqlprep)
|
||||||
|
}
|
||||||
|
|
||||||
|
# Now set the ${::n}th malloc() to fail and execute the -tclbody and
|
||||||
|
# -sqlbody scripts.
|
||||||
|
#
|
||||||
|
sqlite_malloc_fail $::n
|
||||||
|
set ::mallocbody {}
|
||||||
|
if {[info exists ::mallocopts(-tclbody)]} {
|
||||||
|
append ::mallocbody "$::mallocopts(-tclbody)\n"
|
||||||
|
}
|
||||||
|
if {[info exists ::mallocopts(-sqlbody)]} {
|
||||||
|
append ::mallocbody "db eval {$::mallocopts(-sqlbody)}"
|
||||||
|
}
|
||||||
|
set v [catch $::mallocbody msg]
|
||||||
|
|
||||||
|
# If the test fails (if $v!=0) and the database connection actually
|
||||||
|
# exists, make sure the failure code is SQLITE_NOMEM.
|
||||||
|
if {$v&&[info command db]=="db"&&[info exists ::mallocopts(-sqlbody)]} {
|
||||||
|
if {[db errorcode]!=7 && $msg!="vtable constructor failed: e"} {
|
||||||
|
set v 999
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set leftover [lindex [sqlite_malloc_stat] 2]
|
||||||
|
if {$leftover>0} {
|
||||||
|
if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v Message=$msg"}
|
||||||
|
set ::go 0
|
||||||
|
if {$v} {
|
||||||
|
puts "\nError message returned: $msg"
|
||||||
|
} else {
|
||||||
|
set v {1 1}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
set v2 [expr {
|
||||||
|
$msg == "" || $msg == "out of memory" ||
|
||||||
|
$msg == "vtable constructor failed: e"
|
||||||
|
}]
|
||||||
|
if {!$v2} {puts "\nError message returned: $msg"}
|
||||||
|
lappend v $v2
|
||||||
|
}
|
||||||
|
} {1 1}
|
||||||
|
|
||||||
|
if {[info exists ::mallocopts(-cleanup)]} {
|
||||||
|
catch [list uplevel #0 $::mallocopts(-cleanup)] msg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unset ::mallocopts
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
do_ioerr_test vtab_err-1 -tclprep {
|
do_ioerr_test vtab_err-1 -tclprep {
|
||||||
register_echo_module [sqlite3_connection_pointer db]
|
register_echo_module [sqlite3_connection_pointer db]
|
||||||
} -sqlbody {
|
} -sqlbody {
|
||||||
@ -38,5 +139,24 @@ do_ioerr_test vtab_err-1 -tclprep {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
do_malloc_test vtab_err-2 -tclprep {
|
||||||
|
register_echo_module [sqlite3_connection_pointer db]
|
||||||
|
} -sqlbody {
|
||||||
|
BEGIN;
|
||||||
|
CREATE TABLE r(a PRIMARY KEY, b, c);
|
||||||
|
CREATE VIRTUAL TABLE e USING echo(r);
|
||||||
|
INSERT INTO e VALUES(1, 2, 3);
|
||||||
|
INSERT INTO e VALUES('a', 'b', 'c');
|
||||||
|
UPDATE e SET c = 10;
|
||||||
|
DELETE FROM e WHERE a = 'a';
|
||||||
|
COMMIT;
|
||||||
|
BEGIN;
|
||||||
|
CREATE TABLE r2(a, b, c);
|
||||||
|
INSERT INTO r2 SELECT * FROM e;
|
||||||
|
INSERT INTO e SELECT a||'x', b, c FROM r2;
|
||||||
|
COMMIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite_malloc_fail 0
|
||||||
finish_test
|
finish_test
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user