mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
More changes for 2.0.7. (CVS 293)
FossilOrigin-Name: f8328a5f11801c5124f9a8dace22df3c1cfb2191
This commit is contained in:
56
manifest
56
manifest
@ -1,5 +1,5 @@
|
|||||||
C 2.0.7\s(CVS\s292)
|
C More\schanges\sfor\s2.0.7.\s(CVS\s293)
|
||||||
D 2001-10-20T12:30:11
|
D 2001-10-22T02:58:09
|
||||||
F Makefile.in 6801df952cb1df64aa32e4de85fed24511d28efd
|
F Makefile.in 6801df952cb1df64aa32e4de85fed24511d28efd
|
||||||
F Makefile.template 1fdb891f14083ee0b63cf7282f91529634438e7a
|
F Makefile.template 1fdb891f14083ee0b63cf7282f91529634438e7a
|
||||||
F README 93d2977cc5c6595c448de16bdefc312b9d401533
|
F README 93d2977cc5c6595c448de16bdefc312b9d401533
|
||||||
@ -19,43 +19,43 @@ F libtool c56e618713c9510a103bda6b95f3ea3900dcacd6
|
|||||||
F ltmain.sh e9ed72eb1d690f447c13945eaf69e28af531eda1
|
F ltmain.sh e9ed72eb1d690f447c13945eaf69e28af531eda1
|
||||||
F publish.sh badcd69b8e3a8bc69b162c4c9d7c209b2a0b119e
|
F publish.sh badcd69b8e3a8bc69b162c4c9d7c209b2a0b119e
|
||||||
F src/TODO af7f3cab0228e34149cf98e073aa83d45878e7e6
|
F src/TODO af7f3cab0228e34149cf98e073aa83d45878e7e6
|
||||||
F src/btree.c 97653e88bc4b7396226b93c878b153c77f1d3d03
|
F src/btree.c 89380aea55bd0d5c756d92ec9bee756203f63a6b
|
||||||
F src/btree.h 57d653ef5137b91f2a068aaf71a2905468dd2cb7
|
F src/btree.h 57d653ef5137b91f2a068aaf71a2905468dd2cb7
|
||||||
F src/build.c d18081e69b23390cb6baaaf6f6c804b93775a0be
|
F src/build.c 8857c16751a5e9c5ee845e1b3cf2da78935c8cb3
|
||||||
F src/delete.c 6fe2191c49c4a31336e2fac11b3ad665ddcd4246
|
F src/delete.c 6fe2191c49c4a31336e2fac11b3ad665ddcd4246
|
||||||
F src/expr.c c1381b8229a5573b0928ede962e45c1c49d067af
|
F src/expr.c 2dd0252ced345c1e64db015b94dc6b5d7a57eef3
|
||||||
F src/hash.c b7ced0735287c142a3b2db46c3cae3e6826afb75
|
F src/hash.c d0110e6da70a5962e21575fccf8206f7d9d75e00
|
||||||
F src/hash.h a5f5b3ce2d086a172c5879b0b06a27a82eac9fac
|
F src/hash.h a5f5b3ce2d086a172c5879b0b06a27a82eac9fac
|
||||||
F src/insert.c b65c1d4b848e45d41e9dcccd2b226ca335de67b6
|
F src/insert.c b65c1d4b848e45d41e9dcccd2b226ca335de67b6
|
||||||
F src/main.c 9a18e97290d41844e8c12e021fb7c42948a19dc9
|
F src/main.c 47922699c75e24ffec071cdf300405436e5bb16e
|
||||||
F src/md5.c 52f677bfc590e09f71d07d7e327bd59da738d07c
|
F src/md5.c 52f677bfc590e09f71d07d7e327bd59da738d07c
|
||||||
F src/os.c 2a501026a66416292a30ab5b0988ec75783340ae
|
F src/os.c 66b677479eae37e30bdfbe32deb0fe6a2efca983
|
||||||
F src/os.h bed702c9e3b768bc3cb1b12c90b83d099c1546be
|
F src/os.h bed702c9e3b768bc3cb1b12c90b83d099c1546be
|
||||||
F src/pager.c 5e2877673e93ad2fa83e6d49fcd8d9590f8f38a5
|
F src/pager.c 0bd0b4b693edb43c72774e3e749d8667e2ae7094
|
||||||
F src/pager.h a0d4c5ae271914aa07b62aee0707997d6932b6ca
|
F src/pager.h a0d4c5ae271914aa07b62aee0707997d6932b6ca
|
||||||
F src/parse.y 148e4cd134d3cbd816dcb0df50e49e498faa6ba4
|
F src/parse.y 148e4cd134d3cbd816dcb0df50e49e498faa6ba4
|
||||||
F src/printf.c b1e22a47be8cdf707815647239991e08e8cb69f9
|
F src/printf.c 167fbfb192b4dce48154398f22dbc614e9f5d088
|
||||||
F src/random.c 2a9cc2c9716d14815fd4c2accf89d87a1143e46b
|
F src/random.c 2a9cc2c9716d14815fd4c2accf89d87a1143e46b
|
||||||
F src/select.c 898b27a324afc067e253a9c04e63701f10b0af1c
|
F src/select.c d14511afacf788bf4a0c517011c2c53038539388
|
||||||
F src/shell.c 71597951753b56a97fea1c7a30908f31e635c00c
|
F src/shell.c 71597951753b56a97fea1c7a30908f31e635c00c
|
||||||
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
|
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
|
||||||
F src/sqlite.h.in b95c161abf1d58bceb05290fa3f657d8f388fc11
|
F src/sqlite.h.in f2c40c869ff40ad3e60d8a3b1f72777fa28b32fc
|
||||||
F src/sqliteInt.h 52577abf2805ba148972f69788ed49c64064fa31
|
F src/sqliteInt.h 9a18aebf42a805ba02f55eba2239beabe35f02b3
|
||||||
F src/table.c 7102da21a8e4b2f8a4df79378d6dc0b01aa76a33
|
F src/table.c be9c7bf883c731c6719f0fcc188ea2bac8ae7122
|
||||||
F src/tclsqlite.c 7d205aeda449047f86b39a6c55731a1ded7a7ab5
|
F src/tclsqlite.c 4896e078495bf868742f5394dcf01c5efe5bea02
|
||||||
F src/test1.c e4b31f62ea71963cbae44338acf477a04fc8fc49
|
F src/test1.c e4b31f62ea71963cbae44338acf477a04fc8fc49
|
||||||
F src/test2.c e9f99aa5ee73872819259d6612c11e55e1644321
|
F src/test2.c e9f99aa5ee73872819259d6612c11e55e1644321
|
||||||
F src/test3.c 4a0d7b882fdae731dbb759f512ad867122452f96
|
F src/test3.c 4a0d7b882fdae731dbb759f512ad867122452f96
|
||||||
F src/tokenize.c 59ddae1501de472e9a6274a1cbf451170c52488c
|
F src/tokenize.c 8f4c2b5e7fb471ba194979fb4dd5f947402fd792
|
||||||
F src/update.c c916182c6bfbc8a6f20c24920c4560fece6c9569
|
F src/update.c c916182c6bfbc8a6f20c24920c4560fece6c9569
|
||||||
F src/util.c 4da3be37d0fd3c640d2d3033503768afdc8e5387
|
F src/util.c aa4d2de60cb2445239b71c79c3a8c0b7c0d3336a
|
||||||
F src/vdbe.c 0aea4e858880867ffd59d9598da9b3f9ab5d97b9
|
F src/vdbe.c aa28392b908ef8ee338e77af49ce2903b85f7b22
|
||||||
F src/vdbe.h f8407fd6b644bc001b1e7c65460c9962f6a15f6b
|
F src/vdbe.h f8407fd6b644bc001b1e7c65460c9962f6a15f6b
|
||||||
F src/where.c 22fe910c7c8e2736eb37e9861343e90c0b513c86
|
F src/where.c 22fe910c7c8e2736eb37e9861343e90c0b513c86
|
||||||
F test/all.test a2320eb40b462f25bd3e33115b1cabf3791450dd
|
F test/all.test 2a51e5395ac7c2c539689b123b9782a05e3837fe
|
||||||
F test/bigrow.test a35f2de9948b24e427fb292c35947795efe182d0
|
F test/bigrow.test a35f2de9948b24e427fb292c35947795efe182d0
|
||||||
F test/btree.test 47952c7a0c22660566264c68c0664592b7da85ce
|
F test/btree.test 47952c7a0c22660566264c68c0664592b7da85ce
|
||||||
F test/btree2.test 20ce47ab804f15b6563736528bdd38aabe5193dc
|
F test/btree2.test 08e9485619265cbaf5d11bd71f357cdc26bb87e0
|
||||||
F test/copy.test 768e6f1701a07d08090e1ca7f7dcce0a7a72b43e
|
F test/copy.test 768e6f1701a07d08090e1ca7f7dcce0a7a72b43e
|
||||||
F test/delete.test c904a62129fe102b314a96111a8417f10249e4d8
|
F test/delete.test c904a62129fe102b314a96111a8417f10249e4d8
|
||||||
F test/expr.test b4171c84b767f7b7e94dbce4824ba8e981a1c72f
|
F test/expr.test b4171c84b767f7b7e94dbce4824ba8e981a1c72f
|
||||||
@ -67,11 +67,11 @@ F test/insert2.test d6901ca931e308fea7fca8c95ebe7dc957cc9fc2
|
|||||||
F test/ioerr.test 57d9bffaca18b34f9e976f786eadc2591d6efc6a
|
F test/ioerr.test 57d9bffaca18b34f9e976f786eadc2591d6efc6a
|
||||||
F test/lock.test 19593689260c419efe7ced55b1418653a4b7bcd1
|
F test/lock.test 19593689260c419efe7ced55b1418653a4b7bcd1
|
||||||
F test/main.test 1626345b5f630c5398eede500d9354813b76b0fd
|
F test/main.test 1626345b5f630c5398eede500d9354813b76b0fd
|
||||||
F test/malloc.test f1400a8d002eb96f1ca0a34abe56d2ab3e324740
|
F test/malloc.test 70fdd0812e2a57eb746aaf015350f58bb8eee0b1
|
||||||
F test/misc1.test 50a5ca3481fc1f3cd6b978bcd6ed04c06f26a1e6
|
F test/misc1.test 50a5ca3481fc1f3cd6b978bcd6ed04c06f26a1e6
|
||||||
F test/pager.test 59bbc4e3d489529ed33db6e15595789e51056077
|
F test/pager.test 59bbc4e3d489529ed33db6e15595789e51056077
|
||||||
F test/printf.test 3cb415073754cb8ff076f26173143c3cd293a9da
|
F test/printf.test 3cb415073754cb8ff076f26173143c3cd293a9da
|
||||||
F test/quick.test b6ec50f808efc06595fd324bf4f3fabadb9c7e9c
|
F test/quick.test 6f023c7a73fc413e6d65b7a1879c79764038dc05
|
||||||
F test/quote.test 286db944717afa9a9bf829dd85e59185c65d5435
|
F test/quote.test 286db944717afa9a9bf829dd85e59185c65d5435
|
||||||
F test/rowid.test 427bfbbe9684fe7a2f851aa05badaae6d4972ce8
|
F test/rowid.test 427bfbbe9684fe7a2f851aa05badaae6d4972ce8
|
||||||
F test/select1.test 75af194669ff9f4fe42c6fd070d9ec3b268354bb
|
F test/select1.test 75af194669ff9f4fe42c6fd070d9ec3b268354bb
|
||||||
@ -83,7 +83,7 @@ F test/sort.test 462c1161eee1abaa7cc93990e0b34d5fdb70ce19
|
|||||||
F test/subselect.test 335d3dad8d585726c447dfee8d9c4f7383c76b78
|
F test/subselect.test 335d3dad8d585726c447dfee8d9c4f7383c76b78
|
||||||
F test/table.test 3ef4254d62ece31a3872ab11cdaec846f6fa8fd1
|
F test/table.test 3ef4254d62ece31a3872ab11cdaec846f6fa8fd1
|
||||||
F test/tableapi.test 51d0c209aa6b1158cb952ec917c656d4ce66e9e4
|
F test/tableapi.test 51d0c209aa6b1158cb952ec917c656d4ce66e9e4
|
||||||
F test/tclsqlite.test a57bb478d7e9f0b2c927f92e161f391e2896631a
|
F test/tclsqlite.test feca0f2b23ba51d202d67d71e10ba7a8a1621f82
|
||||||
F test/temptable.test 37acd9e39781c2ff7cff2ba741b6b27ce020a44a
|
F test/temptable.test 37acd9e39781c2ff7cff2ba741b6b27ce020a44a
|
||||||
F test/tester.tcl c7ddeebc14cc841abb37134cd5d40c1e3ad367c1
|
F test/tester.tcl c7ddeebc14cc841abb37134cd5d40c1e3ad367c1
|
||||||
F test/trans.test 855337b8a178c73c433fcf8ee88e4b2f5efff0d9
|
F test/trans.test 855337b8a178c73c433fcf8ee88e4b2f5efff0d9
|
||||||
@ -93,7 +93,7 @@ F test/vacuum.test 8acf8669f3b627e54149b25165b034aa06c2432e
|
|||||||
F test/where.test 43d5ac94da3f3722375307f948884dc79b326a91
|
F test/where.test 43d5ac94da3f3722375307f948884dc79b326a91
|
||||||
F tool/lemon.c 5533b63e5cdbb1efc939abac3c2f4f37ac839488
|
F tool/lemon.c 5533b63e5cdbb1efc939abac3c2f4f37ac839488
|
||||||
F tool/lempar.c 9b604e6a8b3d55c0b9cbcb130a7302fb8bafe2b9
|
F tool/lempar.c 9b604e6a8b3d55c0b9cbcb130a7302fb8bafe2b9
|
||||||
F tool/memleak.awk a0a11dd84bf4582acc81c3c61271021ae49b3f15
|
F tool/memleak.awk 296dfbce7a9ca499b95ce04e30334e64a50052e0
|
||||||
F tool/opNames.awk 5ba1f48aa854ee3b7c3d2b54233665bc3e649ea2
|
F tool/opNames.awk 5ba1f48aa854ee3b7c3d2b54233665bc3e649ea2
|
||||||
F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
|
F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
|
||||||
F tool/renumberOps.awk 6d067177ad5f8d711b79577b462da9b3634bd0a9
|
F tool/renumberOps.awk 6d067177ad5f8d711b79577b462da9b3634bd0a9
|
||||||
@ -102,7 +102,7 @@ F www/arch.fig d5f9752a4dbf242e9cfffffd3f5762b6c63b3bcf
|
|||||||
F www/arch.png 82ef36db1143828a7abc88b1e308a5f55d4336f4
|
F www/arch.png 82ef36db1143828a7abc88b1e308a5f55d4336f4
|
||||||
F www/arch.tcl 03b521d252575f93b9c52f7c8b0007011512fcfb
|
F www/arch.tcl 03b521d252575f93b9c52f7c8b0007011512fcfb
|
||||||
F www/c_interface.tcl 6c5989670e014de44dce6580cbde0eea965dadbb
|
F www/c_interface.tcl 6c5989670e014de44dce6580cbde0eea965dadbb
|
||||||
F www/changes.tcl 72923f6a051a2f6bdad639933e9e8e153b392123
|
F www/changes.tcl fdd4f8b474bce2463b876c1bedb68c20bc3f5b34
|
||||||
F www/crosscompile.tcl c99efacb3aefaa550c6e80d91b240f55eb9fd33e
|
F www/crosscompile.tcl c99efacb3aefaa550c6e80d91b240f55eb9fd33e
|
||||||
F www/download.tcl 3e51c9ff1326b0a182846134987301310dff7d60
|
F www/download.tcl 3e51c9ff1326b0a182846134987301310dff7d60
|
||||||
F www/dynload.tcl 02eb8273aa78cfa9070dd4501dca937fb22b466c
|
F www/dynload.tcl 02eb8273aa78cfa9070dd4501dca937fb22b466c
|
||||||
@ -114,7 +114,7 @@ F www/speed.tcl ab7d6d3bc898472bd94320a5d3c63de928d4804b
|
|||||||
F www/sqlite.tcl 6a21242a272e9c0939a04419a51c3d50cae33e3e
|
F www/sqlite.tcl 6a21242a272e9c0939a04419a51c3d50cae33e3e
|
||||||
F www/tclsqlite.tcl 13d50723f583888fc80ae1a38247c0ab415066fa
|
F www/tclsqlite.tcl 13d50723f583888fc80ae1a38247c0ab415066fa
|
||||||
F www/vdbe.tcl bb7d620995f0a987293e9d4fb6185a3b077e9b44
|
F www/vdbe.tcl bb7d620995f0a987293e9d4fb6185a3b077e9b44
|
||||||
P c8535a0de90fb7a22df15018984db590a85decfb
|
P a835658e507fc7d0c684959c0f0afb9018b6a8d4
|
||||||
R 04b0305eff69829eee3382ca64677b9c
|
R 123ebf892398ed7efe52cb42cd131987
|
||||||
U drh
|
U drh
|
||||||
Z 0c6d455d9482eaf63fb01fb72aa45066
|
Z 5aa86d25974fbc02d84e2fe588bbca94
|
||||||
|
@ -1 +1 @@
|
|||||||
a835658e507fc7d0c684959c0f0afb9018b6a8d4
|
f8328a5f11801c5124f9a8dace22df3c1cfb2191
|
@ -9,7 +9,7 @@
|
|||||||
** May you share freely, never taking more than you give.
|
** May you share freely, never taking more than you give.
|
||||||
**
|
**
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
** $Id: btree.c,v 1.34 2001/10/15 00:44:35 drh Exp $
|
** $Id: btree.c,v 1.35 2001/10/22 02:58:09 drh Exp $
|
||||||
**
|
**
|
||||||
** This file implements a external (disk-based) database using BTrees.
|
** This file implements a external (disk-based) database using BTrees.
|
||||||
** For a detailed discussion of BTrees, refer to
|
** For a detailed discussion of BTrees, refer to
|
||||||
@ -890,7 +890,7 @@ int sqliteBtreeCloseCursor(BtCursor *pCur){
|
|||||||
}
|
}
|
||||||
unlockBtreeIfUnused(pBt);
|
unlockBtreeIfUnused(pBt);
|
||||||
nLock = (int)sqliteHashFind(&pBt->locks, 0, pCur->pgnoRoot);
|
nLock = (int)sqliteHashFind(&pBt->locks, 0, pCur->pgnoRoot);
|
||||||
assert( nLock!=0 );
|
assert( nLock!=0 || sqlite_malloc_failed );
|
||||||
nLock = nLock<0 ? 0 : nLock-1;
|
nLock = nLock<0 ? 0 : nLock-1;
|
||||||
sqliteHashInsert(&pBt->locks, 0, pCur->pgnoRoot, (void*)nLock);
|
sqliteHashInsert(&pBt->locks, 0, pCur->pgnoRoot, (void*)nLock);
|
||||||
sqliteFree(pCur);
|
sqliteFree(pCur);
|
||||||
|
68
src/build.c
68
src/build.c
@ -25,7 +25,7 @@
|
|||||||
** ROLLBACK
|
** ROLLBACK
|
||||||
** PRAGMA
|
** PRAGMA
|
||||||
**
|
**
|
||||||
** $Id: build.c,v 1.51 2001/10/19 16:44:57 drh Exp $
|
** $Id: build.c,v 1.52 2001/10/22 02:58:10 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -72,7 +72,11 @@ void sqliteExec(Parse *pParse){
|
|||||||
Expr *sqliteExpr(int op, Expr *pLeft, Expr *pRight, Token *pToken){
|
Expr *sqliteExpr(int op, Expr *pLeft, Expr *pRight, Token *pToken){
|
||||||
Expr *pNew;
|
Expr *pNew;
|
||||||
pNew = sqliteMalloc( sizeof(Expr) );
|
pNew = sqliteMalloc( sizeof(Expr) );
|
||||||
if( pNew==0 ) return 0;
|
if( pNew==0 ){
|
||||||
|
sqliteExprDelete(pLeft);
|
||||||
|
sqliteExprDelete(pRight);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
pNew->op = op;
|
pNew->op = op;
|
||||||
pNew->pLeft = pLeft;
|
pNew->pLeft = pLeft;
|
||||||
pNew->pRight = pRight;
|
pNew->pRight = pRight;
|
||||||
@ -108,7 +112,10 @@ void sqliteExprSpan(Expr *pExpr, Token *pLeft, Token *pRight){
|
|||||||
Expr *sqliteExprFunction(ExprList *pList, Token *pToken){
|
Expr *sqliteExprFunction(ExprList *pList, Token *pToken){
|
||||||
Expr *pNew;
|
Expr *pNew;
|
||||||
pNew = sqliteMalloc( sizeof(Expr) );
|
pNew = sqliteMalloc( sizeof(Expr) );
|
||||||
if( pNew==0 ) return 0;
|
if( pNew==0 ){
|
||||||
|
sqliteExprListDelete(pList);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
pNew->op = TK_FUNCTION;
|
pNew->op = TK_FUNCTION;
|
||||||
pNew->pList = pList;
|
pNew->pList = pList;
|
||||||
if( pToken ){
|
if( pToken ){
|
||||||
@ -172,7 +179,7 @@ static void sqliteDeleteIndex(sqlite *db, Index *pIndex){
|
|||||||
** the index from the index hash table and free its memory
|
** the index from the index hash table and free its memory
|
||||||
** structures.
|
** structures.
|
||||||
*/
|
*/
|
||||||
static void sqliteUnlinkAndDeleteIndex(sqlite *db, Index *pIndex){
|
void sqliteUnlinkAndDeleteIndex(sqlite *db, Index *pIndex){
|
||||||
if( pIndex->pTable->pIndex==pIndex ){
|
if( pIndex->pTable->pIndex==pIndex ){
|
||||||
pIndex->pTable->pIndex = pIndex->pNext;
|
pIndex->pTable->pIndex = pIndex->pNext;
|
||||||
}else{
|
}else{
|
||||||
@ -411,7 +418,10 @@ void sqliteStartTable(Parse *pParse, Token *pStart, Token *pName, int isTemp){
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pTable = sqliteMalloc( sizeof(Table) );
|
pTable = sqliteMalloc( sizeof(Table) );
|
||||||
if( pTable==0 ) return;
|
if( pTable==0 ){
|
||||||
|
sqliteFree(zName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
pTable->zName = zName;
|
pTable->zName = zName;
|
||||||
pTable->nCol = 0;
|
pTable->nCol = 0;
|
||||||
pTable->aCol = 0;
|
pTable->aCol = 0;
|
||||||
@ -445,11 +455,10 @@ void sqliteAddColumn(Parse *pParse, Token *pName){
|
|||||||
char **pz;
|
char **pz;
|
||||||
if( (p = pParse->pNewTable)==0 ) return;
|
if( (p = pParse->pNewTable)==0 ) return;
|
||||||
if( (p->nCol & 0x7)==0 ){
|
if( (p->nCol & 0x7)==0 ){
|
||||||
p->aCol = sqliteRealloc( p->aCol, (p->nCol+8)*sizeof(p->aCol[0]));
|
Column *aNew;
|
||||||
if( p->aCol==0 ){
|
aNew = sqliteRealloc( p->aCol, (p->nCol+8)*sizeof(p->aCol[0]));
|
||||||
p->nCol = 0;
|
if( aNew==0 ) return;
|
||||||
return;
|
p->aCol = aNew;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
memset(&p->aCol[p->nCol], 0, sizeof(p->aCol[0]));
|
memset(&p->aCol[p->nCol], 0, sizeof(p->aCol[0]));
|
||||||
pz = &p->aCol[p->nCol++].zName;
|
pz = &p->aCol[p->nCol++].zName;
|
||||||
@ -576,7 +585,12 @@ void sqliteEndTable(Parse *pParse, Token *pEnd){
|
|||||||
*/
|
*/
|
||||||
assert( pParse->nameClash==0 || pParse->initFlag==1 );
|
assert( pParse->nameClash==0 || pParse->initFlag==1 );
|
||||||
if( pParse->explain==0 && pParse->nameClash==0 ){
|
if( pParse->explain==0 && pParse->nameClash==0 ){
|
||||||
sqliteHashInsert(&db->tblHash, p->zName, strlen(p->zName)+1, p);
|
Table *pOld;
|
||||||
|
pOld = sqliteHashInsert(&db->tblHash, p->zName, strlen(p->zName)+1, p);
|
||||||
|
if( pOld ){
|
||||||
|
assert( p==pOld ); /* Malloc must have failed */
|
||||||
|
return;
|
||||||
|
}
|
||||||
pParse->pNewTable = 0;
|
pParse->pNewTable = 0;
|
||||||
db->nTable++;
|
db->nTable++;
|
||||||
db->flags |= SQLITE_InternChanges;
|
db->flags |= SQLITE_InternChanges;
|
||||||
@ -878,12 +892,18 @@ void sqliteCreateIndex(
|
|||||||
/* Link the new Index structure to its table and to the other
|
/* Link the new Index structure to its table and to the other
|
||||||
** in-memory database structures.
|
** in-memory database structures.
|
||||||
*/
|
*/
|
||||||
pIndex->pNext = pTab->pIndex;
|
|
||||||
pTab->pIndex = pIndex;
|
|
||||||
if( !pParse->explain && !hideName ){
|
if( !pParse->explain && !hideName ){
|
||||||
sqliteHashInsert(&db->idxHash, pIndex->zName, strlen(zName)+1, pIndex);
|
Index *p;
|
||||||
|
p = sqliteHashInsert(&db->idxHash, pIndex->zName, strlen(zName)+1, pIndex);
|
||||||
|
if( p ){
|
||||||
|
assert( p==pIndex ); /* Malloc must have failed */
|
||||||
|
sqliteFree(pIndex);
|
||||||
|
goto exit_create_index;
|
||||||
|
}
|
||||||
db->flags |= SQLITE_InternChanges;
|
db->flags |= SQLITE_InternChanges;
|
||||||
}
|
}
|
||||||
|
pIndex->pNext = pTab->pIndex;
|
||||||
|
pTab->pIndex = pIndex;
|
||||||
|
|
||||||
/* If the initFlag is 1 it means we are reading the SQL off the
|
/* If the initFlag is 1 it means we are reading the SQL off the
|
||||||
** "sqlite_master" table on the disk. So do not write to the disk
|
** "sqlite_master" table on the disk. So do not write to the disk
|
||||||
@ -1071,15 +1091,20 @@ ExprList *sqliteExprListAppend(ExprList *pList, Expr *pExpr, Token *pName){
|
|||||||
int i;
|
int i;
|
||||||
if( pList==0 ){
|
if( pList==0 ){
|
||||||
pList = sqliteMalloc( sizeof(ExprList) );
|
pList = sqliteMalloc( sizeof(ExprList) );
|
||||||
if( pList==0 ) return 0;
|
if( pList==0 ){
|
||||||
|
sqliteExprDelete(pExpr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if( (pList->nExpr & 7)==0 ){
|
if( (pList->nExpr & 7)==0 ){
|
||||||
int n = pList->nExpr + 8;
|
int n = pList->nExpr + 8;
|
||||||
pList->a = sqliteRealloc(pList->a, n*sizeof(pList->a[0]));
|
struct ExprList_item *a;
|
||||||
if( pList->a==0 ){
|
a = sqliteRealloc(pList->a, n*sizeof(pList->a[0]));
|
||||||
pList->nExpr = 0;
|
if( a==0 ){
|
||||||
|
sqliteExprDelete(pExpr);
|
||||||
return pList;
|
return pList;
|
||||||
}
|
}
|
||||||
|
pList->a = a;
|
||||||
}
|
}
|
||||||
if( pExpr ){
|
if( pExpr ){
|
||||||
i = pList->nExpr++;
|
i = pList->nExpr++;
|
||||||
@ -1119,12 +1144,13 @@ IdList *sqliteIdListAppend(IdList *pList, Token *pToken){
|
|||||||
if( pList==0 ) return 0;
|
if( pList==0 ) return 0;
|
||||||
}
|
}
|
||||||
if( (pList->nId & 7)==0 ){
|
if( (pList->nId & 7)==0 ){
|
||||||
pList->a = sqliteRealloc(pList->a, (pList->nId+8)*sizeof(pList->a[0]) );
|
struct IdList_item *a;
|
||||||
if( pList->a==0 ){
|
a = sqliteRealloc(pList->a, (pList->nId+8)*sizeof(pList->a[0]) );
|
||||||
pList->nId = 0;
|
if( a==0 ){
|
||||||
sqliteIdListDelete(pList);
|
sqliteIdListDelete(pList);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
pList->a = a;
|
||||||
}
|
}
|
||||||
memset(&pList->a[pList->nId], 0, sizeof(pList->a[0]));
|
memset(&pList->a[pList->nId], 0, sizeof(pList->a[0]));
|
||||||
if( pToken ){
|
if( pToken ){
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
** This file contains routines used for analyzing expressions and
|
** This file contains routines used for analyzing expressions and
|
||||||
** for generating VDBE code that evaluates expressions in SQLite.
|
** for generating VDBE code that evaluates expressions in SQLite.
|
||||||
**
|
**
|
||||||
** $Id: expr.c,v 1.31 2001/10/13 02:59:09 drh Exp $
|
** $Id: expr.c,v 1.32 2001/10/22 02:58:10 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@ -935,11 +935,11 @@ int sqliteExprCompare(Expr *pA, Expr *pB){
|
|||||||
static int appendAggInfo(Parse *pParse){
|
static int appendAggInfo(Parse *pParse){
|
||||||
if( (pParse->nAgg & 0x7)==0 ){
|
if( (pParse->nAgg & 0x7)==0 ){
|
||||||
int amt = pParse->nAgg + 8;
|
int amt = pParse->nAgg + 8;
|
||||||
pParse->aAgg = sqliteRealloc(pParse->aAgg, amt*sizeof(pParse->aAgg[0]));
|
AggExpr *aAgg = sqliteRealloc(pParse->aAgg, amt*sizeof(pParse->aAgg[0]));
|
||||||
if( pParse->aAgg==0 ){
|
if( aAgg==0 ){
|
||||||
pParse->nAgg = 0;
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
pParse->aAgg = aAgg;
|
||||||
}
|
}
|
||||||
memset(&pParse->aAgg[pParse->nAgg], 0, sizeof(pParse->aAgg[0]));
|
memset(&pParse->aAgg[pParse->nAgg], 0, sizeof(pParse->aAgg[0]));
|
||||||
return pParse->nAgg++;
|
return pParse->nAgg++;
|
||||||
|
11
src/hash.c
11
src/hash.c
@ -12,7 +12,7 @@
|
|||||||
** This is the implementation of generic hash-tables
|
** This is the implementation of generic hash-tables
|
||||||
** used in SQLite.
|
** used in SQLite.
|
||||||
**
|
**
|
||||||
** $Id: hash.c,v 1.2 2001/10/12 17:30:05 drh Exp $
|
** $Id: hash.c,v 1.3 2001/10/22 02:58:10 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@ -254,7 +254,8 @@ void *sqliteHashFind(const Hash *pH, const void *pKey, int nKey){
|
|||||||
**
|
**
|
||||||
** If another element already exists with the same key, then the
|
** If another element already exists with the same key, then the
|
||||||
** new data replaces the old data and the old data is returned.
|
** new data replaces the old data and the old data is returned.
|
||||||
** The key is not copied in this instance.
|
** The key is not copied in this instance. If a malloc fails, then
|
||||||
|
** new data is returned.
|
||||||
**
|
**
|
||||||
** If the "data" parameter to this function is NULL, then the
|
** If the "data" parameter to this function is NULL, then the
|
||||||
** element corresponding to "key" is removed from the hash table.
|
** element corresponding to "key" is removed from the hash table.
|
||||||
@ -284,12 +285,12 @@ void *sqliteHashInsert(Hash *pH, void *pKey, int nKey, void *data){
|
|||||||
}
|
}
|
||||||
if( data==0 ) return 0;
|
if( data==0 ) return 0;
|
||||||
new_elem = (HashElem*)sqliteMalloc( sizeof(HashElem) );
|
new_elem = (HashElem*)sqliteMalloc( sizeof(HashElem) );
|
||||||
if( new_elem==0 ) return 0;
|
if( new_elem==0 ) return data;
|
||||||
if( pH->copyKey && pKey!=0 ){
|
if( pH->copyKey && pKey!=0 ){
|
||||||
new_elem->pKey = sqliteMalloc( nKey );
|
new_elem->pKey = sqliteMalloc( nKey );
|
||||||
if( new_elem->pKey==0 ){
|
if( new_elem->pKey==0 ){
|
||||||
sqliteFree(new_elem);
|
sqliteFree(new_elem);
|
||||||
return 0;
|
return data;
|
||||||
}
|
}
|
||||||
memcpy((void*)new_elem->pKey, pKey, nKey);
|
memcpy((void*)new_elem->pKey, pKey, nKey);
|
||||||
}else{
|
}else{
|
||||||
@ -301,7 +302,7 @@ void *sqliteHashInsert(Hash *pH, void *pKey, int nKey, void *data){
|
|||||||
if( pH->htsize==0 ){
|
if( pH->htsize==0 ){
|
||||||
pH->count = 0;
|
pH->count = 0;
|
||||||
sqliteFree(new_elem);
|
sqliteFree(new_elem);
|
||||||
return 0;
|
return data;
|
||||||
}
|
}
|
||||||
if( pH->count > pH->htsize ){
|
if( pH->count > pH->htsize ){
|
||||||
rehash(pH,pH->htsize*2);
|
rehash(pH,pH->htsize*2);
|
||||||
|
24
src/main.c
24
src/main.c
@ -14,7 +14,7 @@
|
|||||||
** other files are for internal use by SQLite and should not be
|
** other files are for internal use by SQLite and should not be
|
||||||
** accessed by users of the library.
|
** accessed by users of the library.
|
||||||
**
|
**
|
||||||
** $Id: main.c,v 1.46 2001/10/12 17:30:05 drh Exp $
|
** $Id: main.c,v 1.47 2001/10/22 02:58:10 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
@ -204,7 +204,7 @@ static int sqliteInit(sqlite *db, char **pzErrMsg){
|
|||||||
*/
|
*/
|
||||||
vdbe = sqliteVdbeCreate(db);
|
vdbe = sqliteVdbeCreate(db);
|
||||||
if( vdbe==0 ){
|
if( vdbe==0 ){
|
||||||
sqliteSetString(pzErrMsg, "out of memory");
|
sqliteSetString(pzErrMsg, "out of memory", 0);
|
||||||
return SQLITE_NOMEM;
|
return SQLITE_NOMEM;
|
||||||
}
|
}
|
||||||
sqliteVdbeAddOpList(vdbe, sizeof(initProg)/sizeof(initProg[0]), initProg);
|
sqliteVdbeAddOpList(vdbe, sizeof(initProg)/sizeof(initProg[0]), initProg);
|
||||||
@ -291,6 +291,7 @@ sqlite *sqlite_open(const char *zFilename, int mode, char **pzErrMsg){
|
|||||||
/* Attempt to read the schema */
|
/* Attempt to read the schema */
|
||||||
rc = sqliteInit(db, pzErrMsg);
|
rc = sqliteInit(db, pzErrMsg);
|
||||||
if( sqlite_malloc_failed ){
|
if( sqlite_malloc_failed ){
|
||||||
|
sqlite_close(db);
|
||||||
goto no_mem_on_open;
|
goto no_mem_on_open;
|
||||||
}else if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){
|
}else if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){
|
||||||
sqlite_close(db);
|
sqlite_close(db);
|
||||||
@ -329,10 +330,21 @@ static void clearHashTable(sqlite *db, int preserveTemps){
|
|||||||
Table *pTab = sqliteHashData(pElem);
|
Table *pTab = sqliteHashData(pElem);
|
||||||
if( preserveTemps && pTab->isTemp ){
|
if( preserveTemps && pTab->isTemp ){
|
||||||
Index *pIdx;
|
Index *pIdx;
|
||||||
sqliteHashInsert(&db->tblHash, pTab->zName, strlen(pTab->zName)+1, pTab);
|
int nName = strlen(pTab->zName);
|
||||||
|
Table *pOld = sqliteHashInsert(&db->tblHash, pTab->zName, nName+1, pTab);
|
||||||
|
if( pOld!=0 ){
|
||||||
|
assert( pOld==pTab ); /* Malloc failed on the HashInsert */
|
||||||
|
sqliteDeleteTable(db, pOld);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
|
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
|
||||||
int n = strlen(pIdx->zName)+1;
|
int n = strlen(pIdx->zName)+1;
|
||||||
sqliteHashInsert(&db->idxHash, pIdx->zName, n, pIdx);
|
Index *pOldIdx;
|
||||||
|
pOldIdx = sqliteHashInsert(&db->idxHash, pIdx->zName, n, pIdx);
|
||||||
|
if( pOld ){
|
||||||
|
assert( pOldIdx==pIdx );
|
||||||
|
sqliteUnlinkAndDeleteIndex(db, pOldIdx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
sqliteDeleteTable(db, pTab);
|
sqliteDeleteTable(db, pTab);
|
||||||
@ -440,6 +452,10 @@ int sqlite_exec(
|
|||||||
if( sqlite_malloc_failed ){
|
if( sqlite_malloc_failed ){
|
||||||
sqliteSetString(pzErrMsg, "out of memory", 0);
|
sqliteSetString(pzErrMsg, "out of memory", 0);
|
||||||
sParse.rc = SQLITE_NOMEM;
|
sParse.rc = SQLITE_NOMEM;
|
||||||
|
sqliteBtreeRollback(db->pBe);
|
||||||
|
if( db->pBeTemp ) sqliteBtreeRollback(db->pBeTemp);
|
||||||
|
db->flags &= ~SQLITE_InTrans;
|
||||||
|
clearHashTable(db, 0);
|
||||||
}
|
}
|
||||||
sqliteStrRealloc(pzErrMsg);
|
sqliteStrRealloc(pzErrMsg);
|
||||||
if( sParse.rc==SQLITE_SCHEMA ){
|
if( sParse.rc==SQLITE_SCHEMA ){
|
||||||
|
9
src/os.c
9
src/os.c
@ -134,12 +134,18 @@ static struct lockInfo *findLockInfo(int fd){
|
|||||||
key.ino = statbuf.st_ino;
|
key.ino = statbuf.st_ino;
|
||||||
pInfo = (struct lockInfo*)sqliteHashFind(&lockHash, &key, sizeof(key));
|
pInfo = (struct lockInfo*)sqliteHashFind(&lockHash, &key, sizeof(key));
|
||||||
if( pInfo==0 ){
|
if( pInfo==0 ){
|
||||||
|
struct lockInfo *pOld;
|
||||||
pInfo = sqliteMalloc( sizeof(*pInfo) );
|
pInfo = sqliteMalloc( sizeof(*pInfo) );
|
||||||
if( pInfo==0 ) return 0;
|
if( pInfo==0 ) return 0;
|
||||||
pInfo->key = key;
|
pInfo->key = key;
|
||||||
pInfo->nRef = 1;
|
pInfo->nRef = 1;
|
||||||
pInfo->cnt = 0;
|
pInfo->cnt = 0;
|
||||||
sqliteHashInsert(&lockHash, &pInfo->key, sizeof(key), pInfo);
|
pOld = sqliteHashInsert(&lockHash, &pInfo->key, sizeof(key), pInfo);
|
||||||
|
if( pOld!=0 ){
|
||||||
|
assert( pOld==pInfo );
|
||||||
|
sqliteFree(pInfo);
|
||||||
|
pInfo = 0;
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
pInfo->nRef++;
|
pInfo->nRef++;
|
||||||
}
|
}
|
||||||
@ -315,6 +321,7 @@ int sqliteOsOpenExclusive(const char *zFilename, OsFile *pResult){
|
|||||||
sqliteOsLeaveMutex();
|
sqliteOsLeaveMutex();
|
||||||
if( s.pLock==0 ){
|
if( s.pLock==0 ){
|
||||||
close(s.fd);
|
close(s.fd);
|
||||||
|
unlink(zFilename);
|
||||||
return SQLITE_NOMEM;
|
return SQLITE_NOMEM;
|
||||||
}
|
}
|
||||||
*pResult = s;
|
*pResult = s;
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
** file simultaneously, or one process from reading the database while
|
** file simultaneously, or one process from reading the database while
|
||||||
** another is writing.
|
** another is writing.
|
||||||
**
|
**
|
||||||
** @(#) $Id: pager.c,v 1.28 2001/10/18 12:34:47 drh Exp $
|
** @(#) $Id: pager.c,v 1.29 2001/10/22 02:58:10 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "pager.h"
|
#include "pager.h"
|
||||||
@ -933,22 +933,28 @@ int sqlitepager_write(void *pData){
|
|||||||
assert( pPager->aInJournal==0 );
|
assert( pPager->aInJournal==0 );
|
||||||
pPager->aInJournal = sqliteMalloc( pPager->dbSize/8 + 1 );
|
pPager->aInJournal = sqliteMalloc( pPager->dbSize/8 + 1 );
|
||||||
if( pPager->aInJournal==0 ){
|
if( pPager->aInJournal==0 ){
|
||||||
|
sqliteFree(pPager->aInJournal);
|
||||||
return SQLITE_NOMEM;
|
return SQLITE_NOMEM;
|
||||||
}
|
}
|
||||||
rc = sqliteOsOpenExclusive(pPager->zJournal, &pPager->jfd);
|
rc = sqliteOsOpenExclusive(pPager->zJournal, &pPager->jfd);
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
|
sqliteFree(pPager->aInJournal);
|
||||||
return SQLITE_CANTOPEN;
|
return SQLITE_CANTOPEN;
|
||||||
}
|
}
|
||||||
pPager->journalOpen = 1;
|
pPager->journalOpen = 1;
|
||||||
pPager->needSync = 0;
|
pPager->needSync = 0;
|
||||||
if( sqliteOsLock(pPager->jfd, 1)!=SQLITE_OK ){
|
if( sqliteOsLock(pPager->jfd, 1)!=SQLITE_OK ){
|
||||||
|
sqliteFree(pPager->aInJournal);
|
||||||
sqliteOsClose(pPager->jfd);
|
sqliteOsClose(pPager->jfd);
|
||||||
|
sqliteOsDelete(pPager->zJournal);
|
||||||
pPager->journalOpen = 0;
|
pPager->journalOpen = 0;
|
||||||
return SQLITE_BUSY;
|
return SQLITE_BUSY;
|
||||||
}
|
}
|
||||||
sqliteOsUnlock(pPager->fd);
|
sqliteOsUnlock(pPager->fd);
|
||||||
if( sqliteOsLock(pPager->fd, 1)!=SQLITE_OK ){
|
if( sqliteOsLock(pPager->fd, 1)!=SQLITE_OK ){
|
||||||
|
sqliteFree(pPager->aInJournal);
|
||||||
sqliteOsClose(pPager->jfd);
|
sqliteOsClose(pPager->jfd);
|
||||||
|
sqliteOsDelete(pPager->zJournal);
|
||||||
pPager->journalOpen = 0;
|
pPager->journalOpen = 0;
|
||||||
pPager->state = SQLITE_UNLOCK;
|
pPager->state = SQLITE_UNLOCK;
|
||||||
pPager->errMask |= PAGER_ERR_LOCK;
|
pPager->errMask |= PAGER_ERR_LOCK;
|
||||||
|
17
src/printf.c
17
src/printf.c
@ -656,7 +656,13 @@ static void mout(void *arg, char *zNewText, int nNewChar){
|
|||||||
pM->zText = sqliteMalloc(pM->nAlloc);
|
pM->zText = sqliteMalloc(pM->nAlloc);
|
||||||
if( pM->zText && pM->nChar ) memcpy(pM->zText,pM->zBase,pM->nChar);
|
if( pM->zText && pM->nChar ) memcpy(pM->zText,pM->zBase,pM->nChar);
|
||||||
}else{
|
}else{
|
||||||
pM->zText = sqliteRealloc(pM->zText, pM->nAlloc);
|
char *z = sqliteRealloc(pM->zText, pM->nAlloc);
|
||||||
|
if( z==0 ){
|
||||||
|
sqliteFree(pM->zText);
|
||||||
|
pM->nChar = 0;
|
||||||
|
pM->nAlloc = 0;
|
||||||
|
}
|
||||||
|
pM->zText = z;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( pM->zText ){
|
if( pM->zText ){
|
||||||
@ -690,6 +696,9 @@ char *sqlite_mprintf(const char *zFormat, ...){
|
|||||||
if( zNew ) strcpy(zNew,zBuf);
|
if( zNew ) strcpy(zNew,zBuf);
|
||||||
}else{
|
}else{
|
||||||
zNew = sqliteRealloc(sMprintf.zText,sMprintf.nChar+1);
|
zNew = sqliteRealloc(sMprintf.zText,sMprintf.nChar+1);
|
||||||
|
if( zNew==0 ){
|
||||||
|
sqliteFree(sMprintf.zText);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return zNew;
|
return zNew;
|
||||||
}
|
}
|
||||||
@ -709,7 +718,11 @@ char *sqlite_vmprintf(const char *zFormat, va_list ap){
|
|||||||
sMprintf.zText = sqliteMalloc( strlen(zBuf)+1 );
|
sMprintf.zText = sqliteMalloc( strlen(zBuf)+1 );
|
||||||
if( sMprintf.zText ) strcpy(sMprintf.zText,zBuf);
|
if( sMprintf.zText ) strcpy(sMprintf.zText,zBuf);
|
||||||
}else{
|
}else{
|
||||||
sMprintf.zText = sqliteRealloc(sMprintf.zText,sMprintf.nChar+1);
|
char *z = sqliteRealloc(sMprintf.zText,sMprintf.nChar+1);
|
||||||
|
if( z==0 ){
|
||||||
|
sqliteFree(sMprintf.zText);
|
||||||
|
}
|
||||||
|
sMprintf.zText = z;
|
||||||
}
|
}
|
||||||
return sMprintf.zText;
|
return sMprintf.zText;
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
** This file contains C code routines that are called by the parser
|
** This file contains C code routines that are called by the parser
|
||||||
** to handle SELECT statements in SQLite.
|
** to handle SELECT statements in SQLite.
|
||||||
**
|
**
|
||||||
** $Id: select.c,v 1.43 2001/10/20 12:30:11 drh Exp $
|
** $Id: select.c,v 1.44 2001/10/22 02:58:10 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@ -359,11 +359,11 @@ static int fillInColumnList(Parse *pParse, Select *p){
|
|||||||
Expr *pExpr = sqliteExpr(TK_DOT, 0, 0, 0);
|
Expr *pExpr = sqliteExpr(TK_DOT, 0, 0, 0);
|
||||||
if( pExpr==0 ) break;
|
if( pExpr==0 ) break;
|
||||||
pExpr->pLeft = sqliteExpr(TK_ID, 0, 0, 0);
|
pExpr->pLeft = sqliteExpr(TK_ID, 0, 0, 0);
|
||||||
if( pExpr->pLeft==0 ) break;
|
if( pExpr->pLeft==0 ){ sqliteExprDelete(pExpr); break; }
|
||||||
pExpr->pLeft->token.z = pTab->zName;
|
pExpr->pLeft->token.z = pTab->zName;
|
||||||
pExpr->pLeft->token.n = strlen(pTab->zName);
|
pExpr->pLeft->token.n = strlen(pTab->zName);
|
||||||
pExpr->pRight = sqliteExpr(TK_ID, 0, 0, 0);
|
pExpr->pRight = sqliteExpr(TK_ID, 0, 0, 0);
|
||||||
if( pExpr->pRight==0 ) break;
|
if( pExpr->pRight==0 ){ sqliteExprDelete(pExpr); break; }
|
||||||
pExpr->pRight->token.z = pTab->aCol[j].zName;
|
pExpr->pRight->token.z = pTab->aCol[j].zName;
|
||||||
pExpr->pRight->token.n = strlen(pTab->aCol[j].zName);
|
pExpr->pRight->token.n = strlen(pTab->aCol[j].zName);
|
||||||
pExpr->span.z = "";
|
pExpr->span.z = "";
|
||||||
|
@ -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.21 2001/10/06 16:33:03 drh Exp $
|
** @(#) $Id: sqlite.h.in,v 1.22 2001/10/22 02:58:10 drh Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef _SQLITE_H_
|
#ifndef _SQLITE_H_
|
||||||
#define _SQLITE_H_
|
#define _SQLITE_H_
|
||||||
@ -165,7 +165,8 @@ int sqlite_exec(
|
|||||||
** defined above, then this routine returns a constant text string which
|
** defined above, then this routine returns a constant text string which
|
||||||
** descripts (in English) the meaning of the return value.
|
** descripts (in English) the meaning of the return value.
|
||||||
*/
|
*/
|
||||||
const char *sqliteErrStr(int);
|
const char *sqlite_error_string(int);
|
||||||
|
#define sqliteErrStr sqlite_error_string /* Legacy. Do not use in new code. */
|
||||||
|
|
||||||
/* This function causes any pending database operation to abort and
|
/* This function causes any pending database operation to abort and
|
||||||
** return at its earliest opportunity. This routine is typically
|
** return at its earliest opportunity. This routine is typically
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** Internal interface definitions for SQLite.
|
** Internal interface definitions for SQLite.
|
||||||
**
|
**
|
||||||
** @(#) $Id: sqliteInt.h,v 1.64 2001/10/19 16:44:57 drh Exp $
|
** @(#) $Id: sqliteInt.h,v 1.65 2001/10/22 02:58:10 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqlite.h"
|
#include "sqlite.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
@ -269,7 +269,7 @@ struct Expr {
|
|||||||
*/
|
*/
|
||||||
struct ExprList {
|
struct ExprList {
|
||||||
int nExpr; /* Number of expressions on the list */
|
int nExpr; /* Number of expressions on the list */
|
||||||
struct {
|
struct ExprList_item {
|
||||||
Expr *pExpr; /* The list of expressions */
|
Expr *pExpr; /* The list of expressions */
|
||||||
char *zName; /* Token associated with this expression */
|
char *zName; /* Token associated with this expression */
|
||||||
char sortOrder; /* 1 for DESC or 0 for ASC */
|
char sortOrder; /* 1 for DESC or 0 for ASC */
|
||||||
@ -283,7 +283,7 @@ struct ExprList {
|
|||||||
*/
|
*/
|
||||||
struct IdList {
|
struct IdList {
|
||||||
int nId; /* Number of identifiers on the list */
|
int nId; /* Number of identifiers on the list */
|
||||||
struct {
|
struct IdList_item {
|
||||||
char *zName; /* Text of the identifier. */
|
char *zName; /* Text of the identifier. */
|
||||||
char *zAlias; /* The "B" part of a "A AS B" phrase. zName is the "A" */
|
char *zAlias; /* The "B" part of a "A AS B" phrase. zName is the "A" */
|
||||||
int idx; /* Index in some Table.aCol[] of a column named zName */
|
int idx; /* Index in some Table.aCol[] of a column named zName */
|
||||||
@ -454,6 +454,7 @@ void sqliteExprIfTrue(Parse*, Expr*, int);
|
|||||||
void sqliteExprIfFalse(Parse*, Expr*, int);
|
void sqliteExprIfFalse(Parse*, Expr*, int);
|
||||||
Table *sqliteFindTable(sqlite*,char*);
|
Table *sqliteFindTable(sqlite*,char*);
|
||||||
Index *sqliteFindIndex(sqlite*,char*);
|
Index *sqliteFindIndex(sqlite*,char*);
|
||||||
|
void sqliteUnlinkAndDeleteIndex(sqlite*,Index*);
|
||||||
void sqliteCopy(Parse*, Token*, Token*, Token*);
|
void sqliteCopy(Parse*, Token*, Token*, Token*);
|
||||||
void sqliteVacuum(Parse*, Token*);
|
void sqliteVacuum(Parse*, Token*);
|
||||||
int sqliteGlobCompare(const unsigned char*,const unsigned char*);
|
int sqliteGlobCompare(const unsigned char*,const unsigned char*);
|
||||||
|
15
src/table.c
15
src/table.c
@ -53,12 +53,14 @@ static int sqlite_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
|
|||||||
need = nCol;
|
need = nCol;
|
||||||
}
|
}
|
||||||
if( p->nData + need >= p->nAlloc ){
|
if( p->nData + need >= p->nAlloc ){
|
||||||
|
char **azNew;
|
||||||
p->nAlloc = p->nAlloc*2 + need + 1;
|
p->nAlloc = p->nAlloc*2 + need + 1;
|
||||||
p->azResult = realloc( p->azResult, sizeof(char*)*p->nAlloc );
|
azNew = realloc( p->azResult, sizeof(char*)*p->nAlloc );
|
||||||
if( p->azResult==0 ){
|
if( azNew==0 ){
|
||||||
p->rc = SQLITE_NOMEM;
|
p->rc = SQLITE_NOMEM;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
p->azResult = azNew;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If this is the first row, then generate an extra row containing
|
/* If this is the first row, then generate an extra row containing
|
||||||
@ -150,8 +152,13 @@ int sqlite_get_table(
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
if( res.nAlloc>res.nData ){
|
if( res.nAlloc>res.nData ){
|
||||||
res.azResult = realloc( res.azResult, sizeof(char*)*(res.nData+1) );
|
char **azNew;
|
||||||
if( res.azResult==0 ) return SQLITE_NOMEM;
|
azNew = realloc( res.azResult, sizeof(char*)*(res.nData+1) );
|
||||||
|
if( res.azResult==0 ){
|
||||||
|
sqlite_free_table(&res.azResult[1]);
|
||||||
|
return SQLITE_NOMEM;
|
||||||
|
}
|
||||||
|
res.azResult = azNew;
|
||||||
}
|
}
|
||||||
*pazResult = &res.azResult[1];
|
*pazResult = &res.azResult[1];
|
||||||
if( pnColumn ) *pnColumn = res.nColumn;
|
if( pnColumn ) *pnColumn = res.nColumn;
|
||||||
|
115
src/tclsqlite.c
115
src/tclsqlite.c
@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** A TCL Interface to SQLite
|
** A TCL Interface to SQLite
|
||||||
**
|
**
|
||||||
** $Id: tclsqlite.c,v 1.26 2001/10/19 16:44:57 drh Exp $
|
** $Id: tclsqlite.c,v 1.27 2001/10/22 02:58:10 drh Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef NO_TCL /* Omit this whole file if TCL is unavailable */
|
#ifndef NO_TCL /* Omit this whole file if TCL is unavailable */
|
||||||
|
|
||||||
@ -52,14 +52,17 @@ struct CallbackData {
|
|||||||
Tcl_Obj *pCode; /* The code to execute for each row */
|
Tcl_Obj *pCode; /* The code to execute for each row */
|
||||||
int once; /* Set only for the first invocation of callback */
|
int once; /* Set only for the first invocation of callback */
|
||||||
int tcl_rc; /* Return code from TCL script */
|
int tcl_rc; /* Return code from TCL script */
|
||||||
#ifdef UTF_TRANSLATION_NEEDED
|
|
||||||
int nColName; /* Number of entries in the azColName[] array */
|
int nColName; /* Number of entries in the azColName[] array */
|
||||||
char **azColName; /* Column names translated to UTF-8 */
|
char **azColName; /* Column names translated to UTF-8 */
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef UTF_TRANSLATION_NEEDED
|
||||||
/*
|
/*
|
||||||
** Called for each row of the result.
|
** Called for each row of the result.
|
||||||
|
**
|
||||||
|
** This version is used when TCL expects UTF-8 data but the database
|
||||||
|
** uses the ISO8859 format. A translation must occur from ISO8859 into
|
||||||
|
** UTF-8.
|
||||||
*/
|
*/
|
||||||
static int DbEvalCallback(
|
static int DbEvalCallback(
|
||||||
void *clientData, /* An instance of CallbackData */
|
void *clientData, /* An instance of CallbackData */
|
||||||
@ -69,9 +72,79 @@ static int DbEvalCallback(
|
|||||||
){
|
){
|
||||||
CallbackData *cbData = (CallbackData*)clientData;
|
CallbackData *cbData = (CallbackData*)clientData;
|
||||||
int i, rc;
|
int i, rc;
|
||||||
#ifdef UTF_TRANSLATION_NEEDED
|
|
||||||
Tcl_DString dCol;
|
Tcl_DString dCol;
|
||||||
#endif
|
Tcl_DStringInit(&dCol);
|
||||||
|
if( azCol==0 || (cbData->once && cbData->zArray[0]) ){
|
||||||
|
Tcl_SetVar2(cbData->interp, cbData->zArray, "*", "", 0);
|
||||||
|
if( azCol ){
|
||||||
|
cbData->azColName = malloc( nCol*sizeof(char*) );
|
||||||
|
if( cbData->azColName==0 ){ return 1; }
|
||||||
|
}
|
||||||
|
cbData->nColName = nCol;
|
||||||
|
for(i=0; i<nCol; i++){
|
||||||
|
Tcl_ExternalToUtfDString(NULL, azN[i], -1, &dCol);
|
||||||
|
if( azCol ){
|
||||||
|
cbData->azColName[i] = malloc( Tcl_DStringLength(&dCol) + 1);
|
||||||
|
if( cbData->azColName[i] ){
|
||||||
|
strcpy(cbData->azColName[i], Tcl_DStringValue(&dCol));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Tcl_SetVar2(cbData->interp, cbData->zArray, "*", Tcl_DStringValue(&dCol),
|
||||||
|
TCL_LIST_ELEMENT|TCL_APPEND_VALUE);
|
||||||
|
Tcl_DStringFree(&dCol);
|
||||||
|
}
|
||||||
|
cbData->once = 0;
|
||||||
|
}
|
||||||
|
if( azCol!=0 ){
|
||||||
|
if( cbData->zArray[0] ){
|
||||||
|
for(i=0; i<nCol; i++){
|
||||||
|
char *z = azCol[i];
|
||||||
|
if( z==0 ) z = "";
|
||||||
|
Tcl_DStringInit(&dCol);
|
||||||
|
Tcl_ExternalToUtfDString(NULL, z, -1, &dCol);
|
||||||
|
Tcl_SetVar2(cbData->interp, cbData->zArray, cbData->azColName[i],
|
||||||
|
Tcl_DStringValue(&dCol), 0);
|
||||||
|
Tcl_DStringFree(&dCol);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
for(i=0; i<nCol; i++){
|
||||||
|
char *z = azCol[i];
|
||||||
|
if( z==0 ) z = "";
|
||||||
|
Tcl_DStringInit(&dCol);
|
||||||
|
Tcl_ExternalToUtfDString(NULL, z, -1, &dCol);
|
||||||
|
Tcl_SetVar(cbData->interp, cbData->azColName[i],
|
||||||
|
Tcl_DStringValue(&dCol), 0);
|
||||||
|
Tcl_DStringFree(&dCol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rc = Tcl_EvalObj(cbData->interp, cbData->pCode);
|
||||||
|
if( rc==TCL_CONTINUE ) rc = TCL_OK;
|
||||||
|
cbData->tcl_rc = rc;
|
||||||
|
return rc!=TCL_OK;
|
||||||
|
}
|
||||||
|
#endif /* UTF_TRANSLATION_NEEDED */
|
||||||
|
|
||||||
|
#ifndef UTF_TRANSLATION_NEEDED
|
||||||
|
/*
|
||||||
|
** Called for each row of the result.
|
||||||
|
**
|
||||||
|
** This version is used when either of the following is true:
|
||||||
|
**
|
||||||
|
** (1) This version of TCL uses UTF-8 and the data in the
|
||||||
|
** SQLite database is already in the UTF-8 format.
|
||||||
|
**
|
||||||
|
** (2) This version of TCL uses ISO8859 and the data in the
|
||||||
|
** SQLite database is already in the ISO8859 format.
|
||||||
|
*/
|
||||||
|
static int DbEvalCallback(
|
||||||
|
void *clientData, /* An instance of CallbackData */
|
||||||
|
int nCol, /* Number of columns in the result */
|
||||||
|
char ** azCol, /* Data for each column */
|
||||||
|
char ** azN /* Name for each column */
|
||||||
|
){
|
||||||
|
CallbackData *cbData = (CallbackData*)clientData;
|
||||||
|
int i, rc;
|
||||||
if( azCol==0 || (cbData->once && cbData->zArray[0]) ){
|
if( azCol==0 || (cbData->once && cbData->zArray[0]) ){
|
||||||
Tcl_SetVar2(cbData->interp, cbData->zArray, "*", "", 0);
|
Tcl_SetVar2(cbData->interp, cbData->zArray, "*", "", 0);
|
||||||
for(i=0; i<nCol; i++){
|
for(i=0; i<nCol; i++){
|
||||||
@ -85,28 +158,13 @@ static int DbEvalCallback(
|
|||||||
for(i=0; i<nCol; i++){
|
for(i=0; i<nCol; i++){
|
||||||
char *z = azCol[i];
|
char *z = azCol[i];
|
||||||
if( z==0 ) z = "";
|
if( z==0 ) z = "";
|
||||||
#ifdef UTF_TRANSLATION_NEEDED
|
|
||||||
Tcl_DStringInit(&dCol);
|
|
||||||
Tcl_ExternalToUtfDString(NULL, z, -1, &dCol);
|
|
||||||
Tcl_SetVar2(cbData->interp, cbData->zArray, azN[i],
|
|
||||||
Tcl_DStringValue(&dCol), 0);
|
|
||||||
Tcl_DStringFree(&dCol);
|
|
||||||
#else
|
|
||||||
Tcl_SetVar2(cbData->interp, cbData->zArray, azN[i], z, 0);
|
Tcl_SetVar2(cbData->interp, cbData->zArray, azN[i], z, 0);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
for(i=0; i<nCol; i++){
|
for(i=0; i<nCol; i++){
|
||||||
char *z = azCol[i];
|
char *z = azCol[i];
|
||||||
if( z==0 ) z = "";
|
if( z==0 ) z = "";
|
||||||
#ifdef UTF_TRANSLATION_NEEDED
|
|
||||||
Tcl_DStringInit(&dCol);
|
|
||||||
Tcl_ExternalToUtfDString(NULL, z, -1, &dCol);
|
|
||||||
Tcl_SetVar(cbData->interp, azN[i], Tcl_DStringValue(&dCol), 0);
|
|
||||||
Tcl_DStringFree(&dCol);
|
|
||||||
#else
|
|
||||||
Tcl_SetVar(cbData->interp, azN[i], z, 0);
|
Tcl_SetVar(cbData->interp, azN[i], z, 0);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -115,6 +173,7 @@ static int DbEvalCallback(
|
|||||||
cbData->tcl_rc = rc;
|
cbData->tcl_rc = rc;
|
||||||
return rc!=TCL_OK;
|
return rc!=TCL_OK;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** This is an alternative callback for database queries. Instead
|
** This is an alternative callback for database queries. Instead
|
||||||
@ -301,6 +360,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
|||||||
int rc;
|
int rc;
|
||||||
#ifdef UTF_TRANSLATION_NEEDED
|
#ifdef UTF_TRANSLATION_NEEDED
|
||||||
Tcl_DString dSql;
|
Tcl_DString dSql;
|
||||||
|
int i;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if( objc!=5 && objc!=3 ){
|
if( objc!=5 && objc!=3 ){
|
||||||
@ -321,6 +381,8 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
|||||||
cbData.zArray = Tcl_GetStringFromObj(objv[3], 0);
|
cbData.zArray = Tcl_GetStringFromObj(objv[3], 0);
|
||||||
cbData.pCode = objv[4];
|
cbData.pCode = objv[4];
|
||||||
cbData.tcl_rc = TCL_OK;
|
cbData.tcl_rc = TCL_OK;
|
||||||
|
cbData.nColName = 0;
|
||||||
|
cbData.azColName = 0;
|
||||||
zErrMsg = 0;
|
zErrMsg = 0;
|
||||||
Tcl_IncrRefCount(objv[3]);
|
Tcl_IncrRefCount(objv[3]);
|
||||||
Tcl_IncrRefCount(objv[4]);
|
Tcl_IncrRefCount(objv[4]);
|
||||||
@ -338,12 +400,21 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
|||||||
Tcl_SetResult(interp, zErrMsg, TCL_VOLATILE);
|
Tcl_SetResult(interp, zErrMsg, TCL_VOLATILE);
|
||||||
free(zErrMsg);
|
free(zErrMsg);
|
||||||
rc = TCL_ERROR;
|
rc = TCL_ERROR;
|
||||||
|
}else if( rc!=SQLITE_OK && rc!=SQLITE_ABORT ){
|
||||||
|
Tcl_AppendResult(interp, sqlite_error_string(rc), 0);
|
||||||
|
rc = TCL_ERROR;
|
||||||
}else{
|
}else{
|
||||||
rc = cbData.tcl_rc;
|
rc = cbData.tcl_rc;
|
||||||
}
|
}
|
||||||
Tcl_DecrRefCount(objv[2]);
|
Tcl_DecrRefCount(objv[2]);
|
||||||
#ifdef UTF_TRANSLATION_NEEDED
|
#ifdef UTF_TRANSLATION_NEEDED
|
||||||
Tcl_DStringFree(&dSql);
|
Tcl_DStringFree(&dSql);
|
||||||
|
if( objc==5 && cbData.azColName ){
|
||||||
|
for(i=0; i<cbData.nColName; i++){
|
||||||
|
if( cbData.azColName[i] ) free(cbData.azColName[i]);
|
||||||
|
}
|
||||||
|
free(cbData.azColName);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -461,13 +532,13 @@ static int DbMain(void *cd, Tcl_Interp *interp, int argc, char **argv){
|
|||||||
int Sqlite_Init(Tcl_Interp *interp){
|
int Sqlite_Init(Tcl_Interp *interp){
|
||||||
Tcl_InitStubs(interp, "8.0", 0);
|
Tcl_InitStubs(interp, "8.0", 0);
|
||||||
Tcl_CreateCommand(interp, "sqlite", DbMain, 0, 0);
|
Tcl_CreateCommand(interp, "sqlite", DbMain, 0, 0);
|
||||||
Tcl_PkgProvide(interp, "sqlite", "1.0");
|
Tcl_PkgProvide(interp, "sqlite", "2.0");
|
||||||
return TCL_OK;
|
return TCL_OK;
|
||||||
}
|
}
|
||||||
int Tclsqlite_Init(Tcl_Interp *interp){
|
int Tclsqlite_Init(Tcl_Interp *interp){
|
||||||
Tcl_InitStubs(interp, "8.0", 0);
|
Tcl_InitStubs(interp, "8.0", 0);
|
||||||
Tcl_CreateCommand(interp, "sqlite", DbMain, 0, 0);
|
Tcl_CreateCommand(interp, "sqlite", DbMain, 0, 0);
|
||||||
Tcl_PkgProvide(interp, "sqlite", "1.0");
|
Tcl_PkgProvide(interp, "sqlite", "2.0");
|
||||||
return TCL_OK;
|
return TCL_OK;
|
||||||
}
|
}
|
||||||
int Sqlite_SafeInit(Tcl_Interp *interp){
|
int Sqlite_SafeInit(Tcl_Interp *interp){
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
** individual tokens and sends those tokens one-by-one over to the
|
** individual tokens and sends those tokens one-by-one over to the
|
||||||
** parser for analysis.
|
** parser for analysis.
|
||||||
**
|
**
|
||||||
** $Id: tokenize.c,v 1.29 2001/10/19 16:44:57 drh Exp $
|
** $Id: tokenize.c,v 1.30 2001/10/22 02:58:10 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
@ -351,11 +351,12 @@ int sqliteRunParser(Parse *pParse, char *zSql, char **pzErrMsg){
|
|||||||
int i;
|
int i;
|
||||||
void *pEngine;
|
void *pEngine;
|
||||||
int once = 1;
|
int once = 1;
|
||||||
|
sqlite *db = pParse->db;
|
||||||
extern void *sqliteParserAlloc(void*(*)(int));
|
extern void *sqliteParserAlloc(void*(*)(int));
|
||||||
extern void sqliteParserFree(void*, void(*)(void*));
|
extern void sqliteParserFree(void*, void(*)(void*));
|
||||||
extern int sqliteParser(void*, int, Token, Parse*);
|
extern int sqliteParser(void*, int, Token, Parse*);
|
||||||
|
|
||||||
pParse->db->flags &= ~SQLITE_Interrupt;
|
db->flags &= ~SQLITE_Interrupt;
|
||||||
pParse->rc = SQLITE_OK;
|
pParse->rc = SQLITE_OK;
|
||||||
i = 0;
|
i = 0;
|
||||||
sqliteParseInfoReset(pParse);
|
sqliteParseInfoReset(pParse);
|
||||||
@ -367,7 +368,7 @@ int sqliteRunParser(Parse *pParse, char *zSql, char **pzErrMsg){
|
|||||||
while( sqlite_malloc_failed==0 && nErr==0 && i>=0 && zSql[i]!=0 ){
|
while( sqlite_malloc_failed==0 && nErr==0 && i>=0 && zSql[i]!=0 ){
|
||||||
int tokenType;
|
int tokenType;
|
||||||
|
|
||||||
if( (pParse->db->flags & SQLITE_Interrupt)!=0 ){
|
if( (db->flags & SQLITE_Interrupt)!=0 ){
|
||||||
pParse->rc = SQLITE_INTERRUPT;
|
pParse->rc = SQLITE_INTERRUPT;
|
||||||
sqliteSetString(pzErrMsg, "interrupt", 0);
|
sqliteSetString(pzErrMsg, "interrupt", 0);
|
||||||
break;
|
break;
|
||||||
@ -401,13 +402,13 @@ int sqliteRunParser(Parse *pParse, char *zSql, char **pzErrMsg){
|
|||||||
sqliteFree(pParse->zErrMsg);
|
sqliteFree(pParse->zErrMsg);
|
||||||
pParse->zErrMsg = 0;
|
pParse->zErrMsg = 0;
|
||||||
}else if( pParse->rc!=SQLITE_OK ){
|
}else if( pParse->rc!=SQLITE_OK ){
|
||||||
sqliteSetString(pzErrMsg, sqliteErrStr(pParse->rc), 0);
|
sqliteSetString(pzErrMsg, sqlite_error_string(pParse->rc), 0);
|
||||||
nErr++;
|
nErr++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( nErr==0 && (pParse->db->flags & SQLITE_Interrupt)==0 ){
|
if( nErr==0 && (db->flags & SQLITE_Interrupt)==0 ){
|
||||||
sqliteParser(pEngine, 0, pParse->sLastToken, pParse);
|
sqliteParser(pEngine, 0, pParse->sLastToken, pParse);
|
||||||
if( pParse->zErrMsg && pParse->sErrToken.z ){
|
if( pParse->zErrMsg && pParse->sErrToken.z ){
|
||||||
sqliteSetNString(pzErrMsg, "near \"", -1,
|
sqliteSetNString(pzErrMsg, "near \"", -1,
|
||||||
|
22
src/util.c
22
src/util.c
@ -14,7 +14,7 @@
|
|||||||
** This file contains functions for allocating memory, comparing
|
** This file contains functions for allocating memory, comparing
|
||||||
** strings, and stuff like that.
|
** strings, and stuff like that.
|
||||||
**
|
**
|
||||||
** $Id: util.c,v 1.29 2001/09/27 03:22:34 drh Exp $
|
** $Id: util.c,v 1.30 2001/10/22 02:58:10 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
@ -49,11 +49,15 @@ void *sqliteMalloc_(int n, char *zFile, int line){
|
|||||||
void *p;
|
void *p;
|
||||||
int *pi;
|
int *pi;
|
||||||
int k;
|
int k;
|
||||||
sqlite_nMalloc++;
|
|
||||||
if( sqlite_iMallocFail>=0 ){
|
if( sqlite_iMallocFail>=0 ){
|
||||||
sqlite_iMallocFail--;
|
sqlite_iMallocFail--;
|
||||||
if( sqlite_iMallocFail==0 ){
|
if( sqlite_iMallocFail==0 ){
|
||||||
sqlite_malloc_failed++;
|
sqlite_malloc_failed++;
|
||||||
|
#if MEMORY_DEBUG>1
|
||||||
|
fprintf(stderr,"**** failed to allocate %d bytes at %s:%d\n",
|
||||||
|
n, zFile,line);
|
||||||
|
#endif
|
||||||
|
sqlite_iMallocFail--;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -64,6 +68,7 @@ void *sqliteMalloc_(int n, char *zFile, int line){
|
|||||||
sqlite_malloc_failed++;
|
sqlite_malloc_failed++;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
sqlite_nMalloc++;
|
||||||
pi[0] = 0xdead1122;
|
pi[0] = 0xdead1122;
|
||||||
pi[1] = n;
|
pi[1] = n;
|
||||||
pi[k+2] = 0xdead3344;
|
pi[k+2] = 0xdead3344;
|
||||||
@ -227,6 +232,7 @@ void sqliteFree(void *p){
|
|||||||
** works just like sqliteFree().
|
** works just like sqliteFree().
|
||||||
*/
|
*/
|
||||||
void *sqliteRealloc(void *p, int n){
|
void *sqliteRealloc(void *p, int n){
|
||||||
|
void *p2;
|
||||||
if( p==0 ){
|
if( p==0 ){
|
||||||
return sqliteMalloc(n);
|
return sqliteMalloc(n);
|
||||||
}
|
}
|
||||||
@ -234,11 +240,11 @@ void *sqliteRealloc(void *p, int n){
|
|||||||
sqliteFree(p);
|
sqliteFree(p);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
p = realloc(p, n);
|
p2 = realloc(p, n);
|
||||||
if( p==0 ){
|
if( p2==0 ){
|
||||||
sqlite_malloc_failed++;
|
sqlite_malloc_failed++;
|
||||||
}
|
}
|
||||||
return p;
|
return p2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -280,7 +286,9 @@ void sqliteSetString(char **pz, const char *zFirst, ...){
|
|||||||
va_end(ap);
|
va_end(ap);
|
||||||
sqliteFree(*pz);
|
sqliteFree(*pz);
|
||||||
*pz = zResult = sqliteMalloc( nByte );
|
*pz = zResult = sqliteMalloc( nByte );
|
||||||
if( zResult==0 ) return;
|
if( zResult==0 ){
|
||||||
|
return;
|
||||||
|
}
|
||||||
strcpy(zResult, zFirst);
|
strcpy(zResult, zFirst);
|
||||||
zResult += strlen(zResult);
|
zResult += strlen(zResult);
|
||||||
va_start(ap, zFirst);
|
va_start(ap, zFirst);
|
||||||
@ -965,7 +973,7 @@ sqliteLikeCompare(const unsigned char *zPattern, const unsigned char *zString){
|
|||||||
** Return a static string that describes the kind of error specified in the
|
** Return a static string that describes the kind of error specified in the
|
||||||
** argument.
|
** argument.
|
||||||
*/
|
*/
|
||||||
const char *sqliteErrStr(int rc){
|
const char *sqlite_error_string(int rc){
|
||||||
const char *z;
|
const char *z;
|
||||||
switch( rc ){
|
switch( rc ){
|
||||||
case SQLITE_OK: z = "not an error"; break;
|
case SQLITE_OK: z = "not an error"; break;
|
||||||
|
138
src/vdbe.c
138
src/vdbe.c
@ -30,7 +30,7 @@
|
|||||||
** But other routines are also provided to help in building up
|
** But other routines are also provided to help in building up
|
||||||
** a program instruction by instruction.
|
** a program instruction by instruction.
|
||||||
**
|
**
|
||||||
** $Id: vdbe.c,v 1.88 2001/10/20 12:30:11 drh Exp $
|
** $Id: vdbe.c,v 1.89 2001/10/22 02:58:10 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -247,13 +247,14 @@ int sqliteVdbeAddOp(Vdbe *p, int op, int p1, int p2){
|
|||||||
p->nOp++;
|
p->nOp++;
|
||||||
if( i>=p->nOpAlloc ){
|
if( i>=p->nOpAlloc ){
|
||||||
int oldSize = p->nOpAlloc;
|
int oldSize = p->nOpAlloc;
|
||||||
|
Op *aNew;
|
||||||
p->nOpAlloc = p->nOpAlloc*2 + 100;
|
p->nOpAlloc = p->nOpAlloc*2 + 100;
|
||||||
p->aOp = sqliteRealloc(p->aOp, p->nOpAlloc*sizeof(Op));
|
aNew = sqliteRealloc(p->aOp, p->nOpAlloc*sizeof(Op));
|
||||||
if( p->aOp==0 ){
|
if( aNew==0 ){
|
||||||
p->nOp = 0;
|
p->nOpAlloc = oldSize;
|
||||||
p->nOpAlloc = 0;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
p->aOp = aNew;
|
||||||
memset(&p->aOp[oldSize], 0, (p->nOpAlloc-oldSize)*sizeof(Op));
|
memset(&p->aOp[oldSize], 0, (p->nOpAlloc-oldSize)*sizeof(Op));
|
||||||
}
|
}
|
||||||
p->aOp[i].opcode = op;
|
p->aOp[i].opcode = op;
|
||||||
@ -273,7 +274,7 @@ int sqliteVdbeAddOp(Vdbe *p, int op, int p1, int p2){
|
|||||||
*/
|
*/
|
||||||
void sqliteVdbeResolveLabel(Vdbe *p, int x){
|
void sqliteVdbeResolveLabel(Vdbe *p, int x){
|
||||||
int j;
|
int j;
|
||||||
if( x<0 && (-x)<=p->nLabel ){
|
if( x<0 && (-x)<=p->nLabel && p->aOp ){
|
||||||
p->aLabel[-1-x] = p->nOp;
|
p->aLabel[-1-x] = p->nOp;
|
||||||
for(j=0; j<p->nOp; j++){
|
for(j=0; j<p->nOp; j++){
|
||||||
if( p->aOp[j].p2==x ) p->aOp[j].p2 = p->nOp;
|
if( p->aOp[j].p2==x ) p->aOp[j].p2 = p->nOp;
|
||||||
@ -296,13 +297,14 @@ int sqliteVdbeAddOpList(Vdbe *p, int nOp, VdbeOp const *aOp){
|
|||||||
int addr;
|
int addr;
|
||||||
if( p->nOp + nOp >= p->nOpAlloc ){
|
if( p->nOp + nOp >= p->nOpAlloc ){
|
||||||
int oldSize = p->nOpAlloc;
|
int oldSize = p->nOpAlloc;
|
||||||
|
Op *aNew;
|
||||||
p->nOpAlloc = p->nOpAlloc*2 + nOp + 10;
|
p->nOpAlloc = p->nOpAlloc*2 + nOp + 10;
|
||||||
p->aOp = sqliteRealloc(p->aOp, p->nOpAlloc*sizeof(Op));
|
aNew = sqliteRealloc(p->aOp, p->nOpAlloc*sizeof(Op));
|
||||||
if( p->aOp==0 ){
|
if( aNew==0 ){
|
||||||
p->nOp = 0;
|
p->nOpAlloc = oldSize;
|
||||||
p->nOpAlloc = 0;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
p->aOp = aNew;
|
||||||
memset(&p->aOp[oldSize], 0, (p->nOpAlloc-oldSize)*sizeof(Op));
|
memset(&p->aOp[oldSize], 0, (p->nOpAlloc-oldSize)*sizeof(Op));
|
||||||
}
|
}
|
||||||
addr = p->nOp;
|
addr = p->nOp;
|
||||||
@ -326,7 +328,7 @@ int sqliteVdbeAddOpList(Vdbe *p, int nOp, VdbeOp const *aOp){
|
|||||||
** few minor changes to the program.
|
** few minor changes to the program.
|
||||||
*/
|
*/
|
||||||
void sqliteVdbeChangeP1(Vdbe *p, int addr, int val){
|
void sqliteVdbeChangeP1(Vdbe *p, int addr, int val){
|
||||||
if( p && addr>=0 && p->nOp>addr ){
|
if( p && addr>=0 && p->nOp>addr && p->aOp ){
|
||||||
p->aOp[addr].p1 = val;
|
p->aOp[addr].p1 = val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -350,7 +352,7 @@ void sqliteVdbeChangeP1(Vdbe *p, int addr, int val){
|
|||||||
*/
|
*/
|
||||||
void sqliteVdbeChangeP3(Vdbe *p, int addr, char *zP3, int n){
|
void sqliteVdbeChangeP3(Vdbe *p, int addr, char *zP3, int n){
|
||||||
Op *pOp;
|
Op *pOp;
|
||||||
if( p==0 ) return;
|
if( p==0 || p->aOp==0 ) return;
|
||||||
if( addr<0 || addr>=p->nOp ){
|
if( addr<0 || addr>=p->nOp ){
|
||||||
addr = p->nOp - 1;
|
addr = p->nOp - 1;
|
||||||
if( addr<0 ) return;
|
if( addr<0 ) return;
|
||||||
@ -383,7 +385,7 @@ void sqliteVdbeChangeP3(Vdbe *p, int addr, char *zP3, int n){
|
|||||||
*/
|
*/
|
||||||
void sqliteVdbeDequoteP3(Vdbe *p, int addr){
|
void sqliteVdbeDequoteP3(Vdbe *p, int addr){
|
||||||
Op *pOp;
|
Op *pOp;
|
||||||
if( addr<0 || addr>=p->nOp ) return;
|
if( p->aOp==0 || addr<0 || addr>=p->nOp ) return;
|
||||||
pOp = &p->aOp[addr];
|
pOp = &p->aOp[addr];
|
||||||
if( pOp->p3==0 || pOp->p3[0]==0 ) return;
|
if( pOp->p3==0 || pOp->p3[0]==0 ) return;
|
||||||
if( pOp->p3type==P3_POINTER ) return;
|
if( pOp->p3type==P3_POINTER ) return;
|
||||||
@ -403,7 +405,7 @@ void sqliteVdbeCompressSpace(Vdbe *p, int addr){
|
|||||||
char *z;
|
char *z;
|
||||||
int i, j;
|
int i, j;
|
||||||
Op *pOp;
|
Op *pOp;
|
||||||
if( addr<0 || addr>=p->nOp ) return;
|
if( p->aOp==0 || addr<0 || addr>=p->nOp ) return;
|
||||||
pOp = &p->aOp[addr];
|
pOp = &p->aOp[addr];
|
||||||
if( pOp->p3type!=P3_DYNAMIC ){
|
if( pOp->p3type!=P3_DYNAMIC ){
|
||||||
pOp->p3 = sqliteStrDup(pOp->p3);
|
pOp->p3 = sqliteStrDup(pOp->p3);
|
||||||
@ -445,8 +447,13 @@ int sqliteVdbeMakeLabel(Vdbe *p){
|
|||||||
int i;
|
int i;
|
||||||
i = p->nLabel++;
|
i = p->nLabel++;
|
||||||
if( i>=p->nLabelAlloc ){
|
if( i>=p->nLabelAlloc ){
|
||||||
|
int *aNew;
|
||||||
p->nLabelAlloc = p->nLabelAlloc*2 + 10;
|
p->nLabelAlloc = p->nLabelAlloc*2 + 10;
|
||||||
p->aLabel = sqliteRealloc( p->aLabel, p->nLabelAlloc*sizeof(p->aLabel[0]));
|
aNew = sqliteRealloc( p->aLabel, p->nLabelAlloc*sizeof(p->aLabel[0]));
|
||||||
|
if( aNew==0 ){
|
||||||
|
sqliteFree(p->aLabel);
|
||||||
|
}
|
||||||
|
p->aLabel = aNew;
|
||||||
}
|
}
|
||||||
if( p->aLabel==0 ){
|
if( p->aLabel==0 ){
|
||||||
p->nLabel = 0;
|
p->nLabel = 0;
|
||||||
@ -484,7 +491,7 @@ static void AggReset(Agg *pAgg){
|
|||||||
** Return 0 on success and 1 if memory is exhausted.
|
** Return 0 on success and 1 if memory is exhausted.
|
||||||
*/
|
*/
|
||||||
static int AggInsert(Agg *p, char *zKey, int nKey){
|
static int AggInsert(Agg *p, char *zKey, int nKey){
|
||||||
AggElem *pElem;
|
AggElem *pElem, *pOld;
|
||||||
int i;
|
int i;
|
||||||
pElem = sqliteMalloc( sizeof(AggElem) + nKey +
|
pElem = sqliteMalloc( sizeof(AggElem) + nKey +
|
||||||
(p->nMem-1)*sizeof(pElem->aMem[0]) );
|
(p->nMem-1)*sizeof(pElem->aMem[0]) );
|
||||||
@ -492,7 +499,12 @@ static int AggInsert(Agg *p, char *zKey, int nKey){
|
|||||||
pElem->zKey = (char*)&pElem->aMem[p->nMem];
|
pElem->zKey = (char*)&pElem->aMem[p->nMem];
|
||||||
memcpy(pElem->zKey, zKey, nKey);
|
memcpy(pElem->zKey, zKey, nKey);
|
||||||
pElem->nKey = nKey;
|
pElem->nKey = nKey;
|
||||||
sqliteHashInsert(&p->hash, pElem->zKey, pElem->nKey, pElem);
|
pOld = sqliteHashInsert(&p->hash, pElem->zKey, pElem->nKey, pElem);
|
||||||
|
if( pOld!=0 ){
|
||||||
|
assert( pOld==pElem ); /* Malloc failed on insert */
|
||||||
|
sqliteFree(pOld);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
for(i=0; i<p->nMem; i++){
|
for(i=0; i<p->nMem; i++){
|
||||||
pElem->aMem[i].s.flags = STK_Null;
|
pElem->aMem[i].s.flags = STK_Null;
|
||||||
}
|
}
|
||||||
@ -638,18 +650,25 @@ static int hardNeedStack(Vdbe *p, int N){
|
|||||||
int oldAlloc;
|
int oldAlloc;
|
||||||
int i;
|
int i;
|
||||||
if( N>=p->nStackAlloc ){
|
if( N>=p->nStackAlloc ){
|
||||||
|
Stack *aNew;
|
||||||
|
char **zNew;
|
||||||
oldAlloc = p->nStackAlloc;
|
oldAlloc = p->nStackAlloc;
|
||||||
p->nStackAlloc = N + 20;
|
p->nStackAlloc = N + 20;
|
||||||
p->aStack = sqliteRealloc(p->aStack, p->nStackAlloc*sizeof(p->aStack[0]));
|
aNew = sqliteRealloc(p->aStack, p->nStackAlloc*sizeof(p->aStack[0]));
|
||||||
p->zStack = sqliteRealloc(p->zStack, p->nStackAlloc*sizeof(char*));
|
zNew = aNew ? sqliteRealloc(p->zStack, p->nStackAlloc*sizeof(char*)) : 0;
|
||||||
if( p->aStack==0 || p->zStack==0 ){
|
if( zNew==0 ){
|
||||||
|
sqliteFree(aNew);
|
||||||
sqliteFree(p->aStack);
|
sqliteFree(p->aStack);
|
||||||
sqliteFree(p->zStack);
|
sqliteFree(p->zStack);
|
||||||
p->aStack = 0;
|
p->aStack = 0;
|
||||||
p->zStack = 0;
|
p->zStack = 0;
|
||||||
p->nStackAlloc = 0;
|
p->nStackAlloc = 0;
|
||||||
|
p->aStack = 0;
|
||||||
|
p->zStack = 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
p->aStack = aNew;
|
||||||
|
p->zStack = zNew;
|
||||||
for(i=oldAlloc; i<p->nStackAlloc; i++){
|
for(i=oldAlloc; i<p->nStackAlloc; i++){
|
||||||
p->zStack[i] = 0;
|
p->zStack[i] = 0;
|
||||||
p->aStack[i].flags = 0;
|
p->aStack[i].flags = 0;
|
||||||
@ -1013,8 +1032,9 @@ int sqliteVdbeExec(
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* if( pzErrMsg ){ *pzErrMsg = 0; } */
|
/* if( pzErrMsg ){ *pzErrMsg = 0; } */
|
||||||
if( sqlite_malloc_failed ) rc = SQLITE_NOMEM;
|
if( sqlite_malloc_failed ) goto no_mem;
|
||||||
for(pc=0; rc==SQLITE_OK && pc<p->nOp VERIFY(&& pc>=0); pc++){
|
for(pc=0; !sqlite_malloc_failed && rc==SQLITE_OK && pc<p->nOp
|
||||||
|
VERIFY(&& pc>=0); pc++){
|
||||||
pOp = &p->aOp[pc];
|
pOp = &p->aOp[pc];
|
||||||
|
|
||||||
/* Interrupt processing if requested.
|
/* Interrupt processing if requested.
|
||||||
@ -1192,8 +1212,9 @@ case OP_Pull: {
|
|||||||
** is done. If this value is wrong, a coredump can result.
|
** is done. If this value is wrong, a coredump can result.
|
||||||
*/
|
*/
|
||||||
case OP_ColumnCount: {
|
case OP_ColumnCount: {
|
||||||
p->azColName = sqliteRealloc(p->azColName, (pOp->p1+1)*sizeof(char*));
|
char **az = sqliteRealloc(p->azColName, (pOp->p1+1)*sizeof(char*));
|
||||||
if( p->azColName==0 ) goto no_mem;
|
if( az==0 ){ goto no_mem; }
|
||||||
|
p->azColName = az;
|
||||||
p->azColName[pOp->p1] = 0;
|
p->azColName[pOp->p1] = 0;
|
||||||
p->nCallback = 0;
|
p->nCallback = 0;
|
||||||
break;
|
break;
|
||||||
@ -1237,6 +1258,7 @@ case OP_Callback: {
|
|||||||
p->nCallback++;
|
p->nCallback++;
|
||||||
}
|
}
|
||||||
PopStack(p, pOp->p1);
|
PopStack(p, pOp->p1);
|
||||||
|
if( sqlite_malloc_failed ) goto no_mem;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1263,6 +1285,7 @@ case OP_NullCallback: {
|
|||||||
}
|
}
|
||||||
p->nCallback++;
|
p->nCallback++;
|
||||||
}
|
}
|
||||||
|
if( sqlite_malloc_failed ) goto no_mem;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2098,7 +2121,7 @@ case OP_Transaction: {
|
|||||||
switch( rc ){
|
switch( rc ){
|
||||||
case SQLITE_BUSY: {
|
case SQLITE_BUSY: {
|
||||||
if( xBusy==0 || (*xBusy)(pBusyArg, "", ++busy)==0 ){
|
if( xBusy==0 || (*xBusy)(pBusyArg, "", ++busy)==0 ){
|
||||||
sqliteSetString(pzErrMsg, sqliteErrStr(rc), 0);
|
sqliteSetString(pzErrMsg, sqlite_error_string(rc), 0);
|
||||||
busy = 0;
|
busy = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2303,8 +2326,9 @@ case OP_Open: {
|
|||||||
VERIFY( if( i<0 ) goto bad_instruction; )
|
VERIFY( if( i<0 ) goto bad_instruction; )
|
||||||
if( i>=p->nCursor ){
|
if( i>=p->nCursor ){
|
||||||
int j;
|
int j;
|
||||||
p->aCsr = sqliteRealloc( p->aCsr, (i+1)*sizeof(Cursor) );
|
Cursor *aCsr = sqliteRealloc( p->aCsr, (i+1)*sizeof(Cursor) );
|
||||||
if( p->aCsr==0 ){ p->nCursor = 0; goto no_mem; }
|
if( aCsr==0 ) goto no_mem;
|
||||||
|
p->aCsr = aCsr;
|
||||||
for(j=p->nCursor; j<=i; j++){
|
for(j=p->nCursor; j<=i; j++){
|
||||||
memset(&p->aCsr[j], 0, sizeof(Cursor));
|
memset(&p->aCsr[j], 0, sizeof(Cursor));
|
||||||
}
|
}
|
||||||
@ -2317,7 +2341,7 @@ case OP_Open: {
|
|||||||
switch( rc ){
|
switch( rc ){
|
||||||
case SQLITE_BUSY: {
|
case SQLITE_BUSY: {
|
||||||
if( xBusy==0 || (*xBusy)(pBusyArg, pOp->p3, ++busy)==0 ){
|
if( xBusy==0 || (*xBusy)(pBusyArg, pOp->p3, ++busy)==0 ){
|
||||||
sqliteSetString(pzErrMsg, sqliteErrStr(rc), 0);
|
sqliteSetString(pzErrMsg, sqlite_error_string(rc), 0);
|
||||||
busy = 0;
|
busy = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2354,8 +2378,9 @@ case OP_OpenTemp: {
|
|||||||
VERIFY( if( i<0 ) goto bad_instruction; )
|
VERIFY( if( i<0 ) goto bad_instruction; )
|
||||||
if( i>=p->nCursor ){
|
if( i>=p->nCursor ){
|
||||||
int j;
|
int j;
|
||||||
p->aCsr = sqliteRealloc( p->aCsr, (i+1)*sizeof(Cursor) );
|
Cursor *aCsr = sqliteRealloc( p->aCsr, (i+1)*sizeof(Cursor) );
|
||||||
if( p->aCsr==0 ){ p->nCursor = 0; goto no_mem; }
|
if( aCsr==0 ){ goto no_mem; }
|
||||||
|
p->aCsr = aCsr;
|
||||||
for(j=p->nCursor; j<=i; j++){
|
for(j=p->nCursor; j<=i; j++){
|
||||||
memset(&p->aCsr[j], 0, sizeof(Cursor));
|
memset(&p->aCsr[j], 0, sizeof(Cursor));
|
||||||
}
|
}
|
||||||
@ -2670,8 +2695,6 @@ case OP_Column: {
|
|||||||
(*xSize)(pCrsr, &payloadSize);
|
(*xSize)(pCrsr, &payloadSize);
|
||||||
if( payloadSize < sizeof(aHdr[0])*(p2+1) ){
|
if( payloadSize < sizeof(aHdr[0])*(p2+1) ){
|
||||||
rc = SQLITE_CORRUPT;
|
rc = SQLITE_CORRUPT;
|
||||||
printf("keyasdata=%d ", p->aCsr[i].keyAsData);
|
|
||||||
printf("payloadSize=%d aHdr[0]=%d p2=%d\n", payloadSize, aHdr[0], p2);
|
|
||||||
goto abort_due_to_error;
|
goto abort_due_to_error;
|
||||||
}
|
}
|
||||||
if( p2+1<mxHdr ){
|
if( p2+1<mxHdr ){
|
||||||
@ -3075,8 +3098,9 @@ case OP_ListOpen: {
|
|||||||
VERIFY( if( i<0 ) goto bad_instruction; )
|
VERIFY( if( i<0 ) goto bad_instruction; )
|
||||||
if( i>=p->nList ){
|
if( i>=p->nList ){
|
||||||
int j;
|
int j;
|
||||||
p->apList = sqliteRealloc( p->apList, (i+1)*sizeof(Keylist*) );
|
Keylist **apList = sqliteRealloc( p->apList, (i+1)*sizeof(Keylist*) );
|
||||||
if( p->apList==0 ){ p->nList = 0; goto no_mem; }
|
if( apList==0 ){ goto no_mem; }
|
||||||
|
p->apList = apList;
|
||||||
for(j=p->nList; j<=i; j++) p->apList[j] = 0;
|
for(j=p->nList; j<=i; j++) p->apList[j] = 0;
|
||||||
p->nList = i+1;
|
p->nList = i+1;
|
||||||
}else if( p->apList[i] ){
|
}else if( p->apList[i] ){
|
||||||
@ -3177,8 +3201,9 @@ case OP_SortOpen: {
|
|||||||
VERIFY( if( i<0 ) goto bad_instruction; )
|
VERIFY( if( i<0 ) goto bad_instruction; )
|
||||||
if( i>=p->nSort ){
|
if( i>=p->nSort ){
|
||||||
int j;
|
int j;
|
||||||
p->apSort = sqliteRealloc( p->apSort, (i+1)*sizeof(Sorter*) );
|
Sorter **apSort = sqliteRealloc( p->apSort, (i+1)*sizeof(Sorter*) );
|
||||||
if( p->apSort==0 ){ p->nSort = 0; goto no_mem; }
|
if( apSort==0 ){ goto no_mem; }
|
||||||
|
p->apSort = apSort;
|
||||||
for(j=p->nSort; j<=i; j++) p->apSort[j] = 0;
|
for(j=p->nSort; j<=i; j++) p->apSort[j] = 0;
|
||||||
p->nSort = i+1;
|
p->nSort = i+1;
|
||||||
}
|
}
|
||||||
@ -3295,7 +3320,7 @@ case OP_SortMakeKey: {
|
|||||||
zNewKey[j++] = 0;
|
zNewKey[j++] = 0;
|
||||||
}
|
}
|
||||||
zNewKey[j] = 0;
|
zNewKey[j] = 0;
|
||||||
VERIFY( j<nByte );
|
assert( j<nByte );
|
||||||
PopStack(p, nField);
|
PopStack(p, nField);
|
||||||
VERIFY( NeedStack(p, p->tos+1); )
|
VERIFY( NeedStack(p, p->tos+1); )
|
||||||
p->tos++;
|
p->tos++;
|
||||||
@ -3409,6 +3434,7 @@ case OP_SortCallback: {
|
|||||||
p->nCallback++;
|
p->nCallback++;
|
||||||
}
|
}
|
||||||
POPSTACK;
|
POPSTACK;
|
||||||
|
if( sqlite_malloc_failed ) goto no_mem;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3497,23 +3523,25 @@ case OP_FileRead: {
|
|||||||
nField = pOp->p1;
|
nField = pOp->p1;
|
||||||
if( nField<=0 ) goto fileread_jump;
|
if( nField<=0 ) goto fileread_jump;
|
||||||
if( nField!=p->nField || p->azField==0 ){
|
if( nField!=p->nField || p->azField==0 ){
|
||||||
p->azField = sqliteRealloc(p->azField, sizeof(char*)*nField+1);
|
char **azField = sqliteRealloc(p->azField, sizeof(char*)*nField+1);
|
||||||
if( p->azField==0 ){
|
if( azField==0 ){ goto no_mem; }
|
||||||
p->nField = 0;
|
p->azField = azField;
|
||||||
goto fileread_jump;
|
|
||||||
}
|
|
||||||
p->nField = nField;
|
p->nField = nField;
|
||||||
}
|
}
|
||||||
n = 0;
|
n = 0;
|
||||||
eol = 0;
|
eol = 0;
|
||||||
while( eol==0 ){
|
while( eol==0 ){
|
||||||
if( p->zLine==0 || n+200>p->nLineAlloc ){
|
if( p->zLine==0 || n+200>p->nLineAlloc ){
|
||||||
|
char *zLine;
|
||||||
p->nLineAlloc = p->nLineAlloc*2 + 300;
|
p->nLineAlloc = p->nLineAlloc*2 + 300;
|
||||||
p->zLine = sqliteRealloc(p->zLine, p->nLineAlloc);
|
zLine = sqliteRealloc(p->zLine, p->nLineAlloc);
|
||||||
if( p->zLine==0 ){
|
if( zLine==0 ){
|
||||||
p->nLineAlloc = 0;
|
p->nLineAlloc = 0;
|
||||||
goto fileread_jump;
|
sqliteFree(p->zLine);
|
||||||
|
p->zLine = 0;
|
||||||
|
goto no_mem;
|
||||||
}
|
}
|
||||||
|
p->zLine = zLine;
|
||||||
}
|
}
|
||||||
if( fgets(&p->zLine[n], p->nLineAlloc-n, p->pFile)==0 ){
|
if( fgets(&p->zLine[n], p->nLineAlloc-n, p->pFile)==0 ){
|
||||||
eol = 1;
|
eol = 1;
|
||||||
@ -3606,9 +3634,11 @@ case OP_MemStore: {
|
|||||||
VERIFY( if( tos<0 ) goto not_enough_stack; )
|
VERIFY( if( tos<0 ) goto not_enough_stack; )
|
||||||
if( i>=p->nMem ){
|
if( i>=p->nMem ){
|
||||||
int nOld = p->nMem;
|
int nOld = p->nMem;
|
||||||
|
Mem *aMem;
|
||||||
p->nMem = i + 5;
|
p->nMem = i + 5;
|
||||||
p->aMem = sqliteRealloc(p->aMem, p->nMem*sizeof(p->aMem[0]));
|
aMem = sqliteRealloc(p->aMem, p->nMem*sizeof(p->aMem[0]));
|
||||||
if( p->aMem==0 ) goto no_mem;
|
if( aMem==0 ) goto no_mem;
|
||||||
|
p->aMem = aMem;
|
||||||
if( nOld<p->nMem ){
|
if( nOld<p->nMem ){
|
||||||
memset(&p->aMem[nOld], 0, sizeof(p->aMem[0])*(p->nMem-nOld));
|
memset(&p->aMem[nOld], 0, sizeof(p->aMem[0])*(p->nMem-nOld));
|
||||||
}
|
}
|
||||||
@ -3752,8 +3782,9 @@ case OP_AggSet: {
|
|||||||
pMem->s = aStack[tos];
|
pMem->s = aStack[tos];
|
||||||
if( pMem->s.flags & STK_Str ){
|
if( pMem->s.flags & STK_Str ){
|
||||||
pMem->z = sqliteMalloc( aStack[tos].n );
|
pMem->z = sqliteMalloc( aStack[tos].n );
|
||||||
if( pMem->z==0 ) goto no_mem;
|
if( pMem->z ){
|
||||||
memcpy(pMem->z, zStack[tos], pMem->s.n);
|
memcpy(pMem->z, zStack[tos], pMem->s.n);
|
||||||
|
}
|
||||||
pMem->s.flags |= STK_Str|STK_Dyn;
|
pMem->s.flags |= STK_Str|STK_Dyn;
|
||||||
}
|
}
|
||||||
if( zOld ) sqliteFree(zOld);
|
if( zOld ) sqliteFree(zOld);
|
||||||
@ -3833,8 +3864,9 @@ case OP_SetInsert: {
|
|||||||
int i = pOp->p1;
|
int i = pOp->p1;
|
||||||
if( p->nSet<=i ){
|
if( p->nSet<=i ){
|
||||||
int k;
|
int k;
|
||||||
p->aSet = sqliteRealloc(p->aSet, (i+1)*sizeof(p->aSet[0]) );
|
Set *aSet = sqliteRealloc(p->aSet, (i+1)*sizeof(p->aSet[0]) );
|
||||||
if( p->aSet==0 ) goto no_mem;
|
if( aSet==0 ) goto no_mem;
|
||||||
|
p->aSet = aSet;
|
||||||
for(k=p->nSet; k<=i; k++){
|
for(k=p->nSet; k<=i; k++){
|
||||||
sqliteHashInit(&p->aSet[k].hash, SQLITE_HASH_BINARY, 1);
|
sqliteHashInit(&p->aSet[k].hash, SQLITE_HASH_BINARY, 1);
|
||||||
}
|
}
|
||||||
@ -4098,7 +4130,7 @@ cleanup:
|
|||||||
** to fail on a modern VM computer, so this code is untested.
|
** to fail on a modern VM computer, so this code is untested.
|
||||||
*/
|
*/
|
||||||
no_mem:
|
no_mem:
|
||||||
sqliteSetString(pzErrMsg, "out or memory", 0);
|
sqliteSetString(pzErrMsg, "out of memory", 0);
|
||||||
rc = SQLITE_NOMEM;
|
rc = SQLITE_NOMEM;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
@ -4106,7 +4138,7 @@ no_mem:
|
|||||||
** should hold the error number.
|
** should hold the error number.
|
||||||
*/
|
*/
|
||||||
abort_due_to_error:
|
abort_due_to_error:
|
||||||
sqliteSetString(pzErrMsg, sqliteErrStr(rc), 0);
|
sqliteSetString(pzErrMsg, sqlite_error_string(rc), 0);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
/* Jump to here if a operator is encountered that requires more stack
|
/* Jump to here if a operator is encountered that requires more stack
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
# This file runs all tests.
|
# This file runs all tests.
|
||||||
#
|
#
|
||||||
# $Id: all.test,v 1.10 2001/09/16 00:13:28 drh Exp $
|
# $Id: all.test,v 1.11 2001/10/22 02:58:11 drh Exp $
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@ -65,8 +65,9 @@ if {$LeakList!=""} {
|
|||||||
puts " Ok"
|
puts " Ok"
|
||||||
}
|
}
|
||||||
|
|
||||||
if {[file readable $testdir/malloc.test]} {
|
# Run the malloc tests after memory leak detection. We do leak
|
||||||
source $testdir/malloc.test
|
# some if malloc fails.
|
||||||
}
|
#
|
||||||
|
catch {source $testdir/malloc.test}
|
||||||
|
|
||||||
really_finish_test
|
really_finish_test
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
# This file implements regression tests for SQLite library. The
|
# This file implements regression tests for SQLite library. The
|
||||||
# focus of this script is btree database backend
|
# focus of this script is btree database backend
|
||||||
#
|
#
|
||||||
# $Id: btree2.test,v 1.8 2001/09/23 02:35:53 drh Exp $
|
# $Id: btree2.test,v 1.9 2001/10/22 02:58:11 drh Exp $
|
||||||
|
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
@ -326,15 +326,8 @@ foreach {N L} {
|
|||||||
} {0}
|
} {0}
|
||||||
do_test btree2-$testno.7 {
|
do_test btree2-$testno.7 {
|
||||||
btree_close $::b
|
btree_close $::b
|
||||||
set ::b [btree_open test2.bt]
|
|
||||||
set ::c2 [btree_cursor $::b 2 1]
|
|
||||||
set ::c3 [btree_cursor $::b 3 1]
|
|
||||||
set ::c4 [btree_cursor $::b 4 1]
|
|
||||||
set ::c5 [btree_cursor $::b 5 1]
|
|
||||||
set ::c6 [btree_cursor $::b 6 1]
|
|
||||||
check_invariants
|
|
||||||
} {}
|
} {}
|
||||||
|
after 100
|
||||||
# For each database size, run various changes tests.
|
# For each database size, run various changes tests.
|
||||||
#
|
#
|
||||||
set num2 1
|
set num2 1
|
||||||
@ -348,6 +341,16 @@ foreach {N L} {
|
|||||||
2.0 1.0 0.0 0.0
|
2.0 1.0 0.0 0.0
|
||||||
} {
|
} {
|
||||||
set testid btree2-$testno.8.$num2
|
set testid btree2-$testno.8.$num2
|
||||||
|
set hash [md5file test2.bt]
|
||||||
|
do_test $testid.0 {
|
||||||
|
set ::b [btree_open test2.bt]
|
||||||
|
set ::c2 [btree_cursor $::b 2 1]
|
||||||
|
set ::c3 [btree_cursor $::b 3 1]
|
||||||
|
set ::c4 [btree_cursor $::b 4 1]
|
||||||
|
set ::c5 [btree_cursor $::b 5 1]
|
||||||
|
set ::c6 [btree_cursor $::b 6 1]
|
||||||
|
check_invariants
|
||||||
|
} {}
|
||||||
set cnt 6
|
set cnt 6
|
||||||
for {set i 2} {$i<=6} {incr i} {
|
for {set i 2} {$i<=6} {incr i} {
|
||||||
if {[lindex [btree_cursor_dump [set ::c$i]] 0]!=$i} {incr cnt}
|
if {[lindex [btree_cursor_dump [set ::c$i]] 0]!=$i} {incr cnt}
|
||||||
@ -356,7 +359,6 @@ foreach {N L} {
|
|||||||
btree_begin_transaction $::b
|
btree_begin_transaction $::b
|
||||||
lindex [btree_pager_stats $::b] 1
|
lindex [btree_pager_stats $::b] 1
|
||||||
} $cnt
|
} $cnt
|
||||||
set hash [md5file test2.bt]
|
|
||||||
# exec cp test2.bt test2.bt.bu1
|
# exec cp test2.bt test2.bt.bu1
|
||||||
do_test $testid.2 [subst {
|
do_test $testid.2 [subst {
|
||||||
random_changes $n $I $K $D
|
random_changes $n $I $K $D
|
||||||
@ -409,14 +411,21 @@ foreach {N L} {
|
|||||||
set ::c6 [btree_cursor $::b 6 1]
|
set ::c6 [btree_cursor $::b 6 1]
|
||||||
check_invariants
|
check_invariants
|
||||||
} {}
|
} {}
|
||||||
|
do_test $testid.10 {
|
||||||
|
btree_close_cursor $::c2
|
||||||
|
btree_close_cursor $::c3
|
||||||
|
btree_close_cursor $::c4
|
||||||
|
btree_close_cursor $::c5
|
||||||
|
btree_close_cursor $::c6
|
||||||
|
lindex [btree_pager_stats $::b] 1
|
||||||
|
} {0}
|
||||||
|
do_test $testid.11 {
|
||||||
|
btree_close $::b
|
||||||
|
} {}
|
||||||
incr num2
|
incr num2
|
||||||
}
|
}
|
||||||
btree_close_cursor $::c2
|
|
||||||
btree_close_cursor $::c3
|
|
||||||
btree_close_cursor $::c4
|
|
||||||
btree_close_cursor $::c5
|
|
||||||
btree_close_cursor $::c6
|
|
||||||
incr testno
|
incr testno
|
||||||
|
set ::b [btree_open test2.bt]
|
||||||
}
|
}
|
||||||
|
|
||||||
# Testing is complete. Shut everything down.
|
# Testing is complete. Shut everything down.
|
||||||
|
173
test/malloc.test
173
test/malloc.test
@ -10,11 +10,11 @@
|
|||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
# This file attempts to check the library in an out-of-memory situation.
|
# This file attempts to check the library in an out-of-memory situation.
|
||||||
# When compiled with -DMEMORY_DEBUG=1, the SQLite library accepts a special
|
# When compiled with -DMEMORY_DEBUG=1, the SQLite library accepts a special
|
||||||
# command (--malloc-fail=N) which causes the N-th malloc to fail. This
|
# command (sqlite_malloc_fail N) which causes the N-th malloc to fail. This
|
||||||
# special feature is used to see what happens in the library if a malloc
|
# special feature is used to see what happens in the library if a malloc
|
||||||
# were to really fail due to an out-of-memory situation.
|
# were to really fail due to an out-of-memory situation.
|
||||||
#
|
#
|
||||||
# $Id: malloc.test,v 1.3 2001/09/16 00:13:28 drh Exp $
|
# $Id: malloc.test,v 1.4 2001/10/22 02:58:11 drh Exp $
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@ -30,55 +30,164 @@ if {[info command sqlite_malloc_fail]==""} {
|
|||||||
for {set go 1; set i 1} {$go} {incr i} {
|
for {set go 1; set i 1} {$go} {incr i} {
|
||||||
do_test malloc-1.$i {
|
do_test malloc-1.$i {
|
||||||
sqlite_malloc_fail 0
|
sqlite_malloc_fail 0
|
||||||
catch {execsql {DROP TABLE t1}}
|
catch {db close}
|
||||||
|
catch {file delete -force test.db}
|
||||||
|
catch {file delete -force test.db-journal}
|
||||||
sqlite_malloc_fail $i
|
sqlite_malloc_fail $i
|
||||||
set v [catch {execsql {
|
set v [catch {sqlite db test.db} msg]
|
||||||
CREATE TABLE t1(
|
if {$v} {
|
||||||
a int, b float, c double, d text, e varchar(20),
|
set msg ""
|
||||||
primary key(a,b,c)
|
} else {
|
||||||
);
|
set v [catch {execsql {
|
||||||
CREATE INDEX i1 ON t1(a,b);
|
CREATE TABLE t1(
|
||||||
INSERT INTO t1 VALUES(1,2.3,4.5,'hi','there');
|
a int, b float, c double, d text, e varchar(20),
|
||||||
INSERT INTO t1 VALUES(6,7.0,0.8,'hello','out yonder');
|
primary key(a,b,c)
|
||||||
SELECT * FROM t1;
|
);
|
||||||
SELECT avg(b) FROM t1 GROUP BY a HAVING b>20.0;
|
CREATE INDEX i1 ON t1(a,b);
|
||||||
DELETE FROM t1 WHERE a==6;
|
INSERT INTO t1 VALUES(1,2.3,4.5,'hi','there');
|
||||||
SELECT count(*) FROM t1;
|
INSERT INTO t1 VALUES(6,7.0,0.8,'hello','out yonder');
|
||||||
}} msg]
|
SELECT * FROM t1;
|
||||||
if {[lindex [sqlite_malloc_stat] 2]>0} {
|
SELECT avg(b) FROM t1 GROUP BY a HAVING b>20.0;
|
||||||
|
DELETE FROM t1 WHERE a IN (SELECT min(a) FROM t1);
|
||||||
|
SELECT count(*) FROM t1;
|
||||||
|
}} msg]
|
||||||
|
}
|
||||||
|
set leftover [lindex [sqlite_malloc_stat] 2]
|
||||||
|
if {$leftover>0} {
|
||||||
|
if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v Message=$msg"}
|
||||||
set ::go 0
|
set ::go 0
|
||||||
set v {1 1}
|
set v {1 1}
|
||||||
} else {
|
} else {
|
||||||
lappend v [expr {$msg=="" || $msg=="out of memory"}]
|
set v2 [expr {$msg=="" || $msg=="out of memory"}]
|
||||||
|
if {!$v2} {puts "\nError message returned: $msg"}
|
||||||
|
lappend v $v2
|
||||||
}
|
}
|
||||||
} {1 1}
|
} {1 1}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
finish_test
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
set fd [open ./data.tmp w]
|
set fd [open ./data.tmp w]
|
||||||
for {set i 1} {$i<=40} {incr i} {
|
for {set i 1} {$i<=20} {incr i} {
|
||||||
puts $fd "$i\t[expr {$i*$i}]\t[expr {100-$i}]"
|
puts $fd "$i\t[expr {$i*$i}]\t[expr {100-$i}] abcdefghijklmnopqrstuvwxyz"
|
||||||
}
|
}
|
||||||
close $fd
|
close $fd
|
||||||
|
|
||||||
for {set go 1; set i 1} {$go} {incr i} {
|
for {set go 1; set i 1} {$go} {incr i} {
|
||||||
do_test malloc-2.$i {
|
do_test malloc-2.$i {
|
||||||
sqlite_malloc_fail 0
|
sqlite_malloc_fail 0
|
||||||
catch {execsql {DROP TABLE t1}}
|
catch {db close}
|
||||||
|
catch {file delete -force test.db}
|
||||||
|
catch {file delete -force test.db-journal}
|
||||||
sqlite_malloc_fail $i
|
sqlite_malloc_fail $i
|
||||||
set v [catch {execsql {
|
set v [catch {sqlite db test.db} msg]
|
||||||
CREATE TABLE t1(a int, b int, c int);
|
if {$v} {
|
||||||
CREATE INDEX i1 ON t1(a,b);
|
set msg ""
|
||||||
COPY t1 FROM 'data.tmp';
|
} else {
|
||||||
SELECT 'stuff', count(*) as 'other stuff' FROM t1;
|
set v [catch {execsql {
|
||||||
UPDATE t1 SET b=a WHERE a in (10,12,22);
|
CREATE TABLE t1(a int, b int, c int);
|
||||||
DROP INDEX i1;
|
CREATE INDEX i1 ON t1(a,b);
|
||||||
VACUUM t1;
|
COPY t1 FROM 'data.tmp';
|
||||||
}} msg]
|
SELECT 'stuff', count(*) as 'other stuff', max(a+10) FROM t1;
|
||||||
if {[lindex [sqlite_malloc_stat] 2]>0} {
|
UPDATE t1 SET b=b||b||b||b;
|
||||||
|
UPDATE t1 SET b=a WHERE a in (10,12,22);
|
||||||
|
INSERT INTO t1(c,b,a) VALUES(20,10,5);
|
||||||
|
INSERT INTO t1 SELECT * FROM t1
|
||||||
|
WHERE a IN (SELECT a FROM t1 WHERE a<10);
|
||||||
|
DELETE FROM t1 WHERE a>=10;
|
||||||
|
DROP INDEX i1;
|
||||||
|
DELETE FROM t1;
|
||||||
|
}} msg]
|
||||||
|
}
|
||||||
|
set leftover [lindex [sqlite_malloc_stat] 2]
|
||||||
|
if {$leftover>0} {
|
||||||
|
if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v Message=$msg"}
|
||||||
set ::go 0
|
set ::go 0
|
||||||
set v {1 1}
|
set v {1 1}
|
||||||
} else {
|
} else {
|
||||||
lappend v [expr {$msg=="" || $msg=="out of memory"}]
|
set v2 [expr {$msg=="" || $msg=="out of memory"}]
|
||||||
|
if {!$v2} {puts "\nError message returned: $msg"}
|
||||||
|
lappend v $v2
|
||||||
|
}
|
||||||
|
} {1 1}
|
||||||
|
}
|
||||||
|
|
||||||
|
set fd [open ./data.tmp w]
|
||||||
|
for {set i 1} {$i<=10} {incr i} {
|
||||||
|
puts $fd "$i\t[expr {$i*$i}]\t[expr {100-$i}]"
|
||||||
|
}
|
||||||
|
close $fd
|
||||||
|
|
||||||
|
for {set go 1; set i 1} {$go} {incr i} {
|
||||||
|
do_test malloc-3.$i {
|
||||||
|
sqlite_malloc_fail 0
|
||||||
|
catch {db close}
|
||||||
|
catch {file delete -force test.db}
|
||||||
|
catch {file delete -force test.db-journal}
|
||||||
|
sqlite_malloc_fail $i
|
||||||
|
set v [catch {sqlite db test.db} msg]
|
||||||
|
if {$v} {
|
||||||
|
set msg ""
|
||||||
|
} else {
|
||||||
|
set v [catch {execsql {
|
||||||
|
BEGIN TRANSACTION;
|
||||||
|
CREATE TABLE t1(a int, b int, c int);
|
||||||
|
CREATE INDEX i1 ON t1(a,b);
|
||||||
|
COPY t1 FROM 'data.tmp';
|
||||||
|
INSERT INTO t1(c,b,a) VALUES(20,10,5);
|
||||||
|
DELETE FROM t1 WHERE a>=10;
|
||||||
|
DROP INDEX i1;
|
||||||
|
DELETE FROM t1;
|
||||||
|
ROLLBACK;
|
||||||
|
}} msg]
|
||||||
|
}
|
||||||
|
set leftover [lindex [sqlite_malloc_stat] 2]
|
||||||
|
if {$leftover>0} {
|
||||||
|
if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v Message=$msg"}
|
||||||
|
set ::go 0
|
||||||
|
set v {1 1}
|
||||||
|
} else {
|
||||||
|
set v2 [expr {$msg=="" || $msg=="out of memory"}]
|
||||||
|
if {!$v2} {puts "\nError message returned: $msg"}
|
||||||
|
lappend v $v2
|
||||||
|
}
|
||||||
|
} {1 1}
|
||||||
|
}
|
||||||
|
for {set go 1; set i 1} {$go} {incr i} {
|
||||||
|
do_test malloc-4.$i {
|
||||||
|
sqlite_malloc_fail 0
|
||||||
|
catch {db close}
|
||||||
|
catch {file delete -force test.db}
|
||||||
|
catch {file delete -force test.db-journal}
|
||||||
|
sqlite_malloc_fail $i
|
||||||
|
set v [catch {sqlite db test.db} msg]
|
||||||
|
if {$v} {
|
||||||
|
set msg ""
|
||||||
|
} else {
|
||||||
|
set v [catch {execsql {
|
||||||
|
BEGIN TRANSACTION;
|
||||||
|
CREATE TABLE t1(a int, b int, c int);
|
||||||
|
CREATE INDEX i1 ON t1(a,b);
|
||||||
|
COPY t1 FROM 'data.tmp';
|
||||||
|
UPDATE t1 SET b=a WHERE a in (10,12,22);
|
||||||
|
INSERT INTO t1 SELECT * FROM t1
|
||||||
|
WHERE a IN (SELECT a FROM t1 WHERE a<10);
|
||||||
|
DROP INDEX i1;
|
||||||
|
DELETE FROM t1;
|
||||||
|
COMMIT;
|
||||||
|
}} msg]
|
||||||
|
}
|
||||||
|
set leftover [lindex [sqlite_malloc_stat] 2]
|
||||||
|
if {$leftover>0} {
|
||||||
|
if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v Message=$msg"}
|
||||||
|
set ::go 0
|
||||||
|
set v {1 1}
|
||||||
|
} else {
|
||||||
|
set v2 [expr {$msg=="" || $msg=="out of memory"}]
|
||||||
|
if {!$v2} {puts "\nError message returned: $msg"}
|
||||||
|
lappend v $v2
|
||||||
}
|
}
|
||||||
} {1 1}
|
} {1 1}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
# This file runs all tests.
|
# This file runs all tests.
|
||||||
#
|
#
|
||||||
# $Id: quick.test,v 1.1 2001/09/16 00:13:28 drh Exp $
|
# $Id: quick.test,v 1.2 2001/10/22 02:58:11 drh Exp $
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@ -21,6 +21,7 @@ set EXCLUDE {
|
|||||||
all.test
|
all.test
|
||||||
quick.test
|
quick.test
|
||||||
btree2.test
|
btree2.test
|
||||||
|
malloc.test
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach testfile [lsort -dictionary [glob $testdir/*.test]] {
|
foreach testfile [lsort -dictionary [glob $testdir/*.test]] {
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
# interface is pretty well tested. This file contains some addition
|
# interface is pretty well tested. This file contains some addition
|
||||||
# tests for fringe issues that the main test suite does not cover.
|
# tests for fringe issues that the main test suite does not cover.
|
||||||
#
|
#
|
||||||
# $Id: tclsqlite.test,v 1.2 2001/09/16 00:13:28 drh Exp $
|
# $Id: tclsqlite.test,v 1.3 2001/10/22 02:58:11 drh Exp $
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@ -65,4 +65,29 @@ do_test tcl-1.6 {
|
|||||||
lappend v $msg
|
lappend v $msg
|
||||||
} {1 {syntax error in expression "x*"}}
|
} {1 {syntax error in expression "x*"}}
|
||||||
|
|
||||||
|
if {[sqlite -encoding]=="UTF-8" && [sqlite -tcl-uses-utf]} {
|
||||||
|
do_test tcl-2.1 {
|
||||||
|
execsql "CREATE TABLE t\u0123x(a int, b\u1235 float)"
|
||||||
|
execsql "PRAGMA table_info(t\u0123x)"
|
||||||
|
} "0 a int 0 {} 1 b\u1235 float 0 {}"
|
||||||
|
do_test tcl-2.2 {
|
||||||
|
execsql "INSERT INTO t\u0123x VALUES(1,2.3)"
|
||||||
|
db eval "SELECT * FROM t\u0123x" result break
|
||||||
|
set result(*)
|
||||||
|
} "a b\u1235"
|
||||||
|
}
|
||||||
|
|
||||||
|
if {[sqlite -encoding]=="iso8859" && [sqlite -tcl-uses-utf]} {
|
||||||
|
do_test tcl-2.1 {
|
||||||
|
execsql "CREATE TABLE t\251x(a int, b\306 float)"
|
||||||
|
execsql "PRAGMA table_info(t\251x)"
|
||||||
|
} "0 a int 0 {} 1 b\306 float 0 {}"
|
||||||
|
do_test tcl-2.2 {
|
||||||
|
execsql "INSERT INTO t\251x VALUES(1,2.3)"
|
||||||
|
db eval "SELECT * FROM t\251x" result break
|
||||||
|
set result(*)
|
||||||
|
} "a b\306"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
}
|
}
|
||||||
/^free / {
|
/^free / {
|
||||||
mem[$5] = "";
|
mem[$5] = "";
|
||||||
|
str[$5] = ""
|
||||||
}
|
}
|
||||||
/^string at / {
|
/^string at / {
|
||||||
addr = $3
|
addr = $3
|
||||||
|
@ -17,8 +17,16 @@ proc chng {date desc} {
|
|||||||
puts "<DD><P><UL>$desc</UL></P></DD>"
|
puts "<DD><P><UL>$desc</UL></P></DD>"
|
||||||
}
|
}
|
||||||
|
|
||||||
chng {2001 Oct 20 (2.0.7)} {
|
chng {2001 Oct 21 (2.0.7)} {
|
||||||
<li>Patches from Christian Werner</li>
|
<li>Any UTF-8 character or ISO8859 character can be used as part of
|
||||||
|
an identifier.</li>
|
||||||
|
<li>Patches from Christian Werner to improve ODBC compatibility and to
|
||||||
|
fix a bug in the round() function.</li>
|
||||||
|
<li>Plug some memory leaks that use to occur if malloc() failed.
|
||||||
|
We have been and continue to be memory leak free as long as
|
||||||
|
malloc() works.</li>
|
||||||
|
<li>Changes to some test scripts so that they work on Windows in
|
||||||
|
addition to Unix.</li>
|
||||||
}
|
}
|
||||||
|
|
||||||
chng {2001 Oct 19 (2.0.6)} {
|
chng {2001 Oct 19 (2.0.6)} {
|
||||||
|
Reference in New Issue
Block a user