mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Many problems fixed. Many problems yet to go. (CVS 242)
FossilOrigin-Name: 62c7bd11bcf6438cdcbf66fa67a2bf4ab9d1664d
This commit is contained in:
41
manifest
41
manifest
@@ -1,5 +1,5 @@
|
|||||||
C It\sruns.\sSimple\stables\scan\sbe\screated.\sINSERT\sand\sSELECT\swork.\sMuch\smore\ntesting\sis\sneeded,\showever.\s(CVS\s241)
|
C Many\sproblems\sfixed.\sMany\sproblems\syet\sto\sgo.\s(CVS\s242)
|
||||||
D 2001-09-13T16:18:54
|
D 2001-09-13T21:53:09
|
||||||
F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4
|
F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4
|
||||||
F Makefile.in 7ecb2370b5cb34d390af1fcb3118ea6d84a253ca
|
F Makefile.in 7ecb2370b5cb34d390af1fcb3118ea6d84a253ca
|
||||||
F README 51f6a4e7408b34afa5bc1c0485f61b6a4efb6958
|
F README 51f6a4e7408b34afa5bc1c0485f61b6a4efb6958
|
||||||
@@ -13,10 +13,10 @@ F notes/notes2.txt 7e3fafd5e25906c1fe1e95f13b089aa398ca403e
|
|||||||
F notes/notes2b.txt 1c17a5b7f6b44a75cd3eb98ed2c24db1eefb06c3
|
F notes/notes2b.txt 1c17a5b7f6b44a75cd3eb98ed2c24db1eefb06c3
|
||||||
F notes/notes3.txt 71e47be517e3d2578b3b9343a45b772d43b7ba16
|
F notes/notes3.txt 71e47be517e3d2578b3b9343a45b772d43b7ba16
|
||||||
F src/TODO f0ea267ab55c4d15127c1ac1667edbf781147438
|
F src/TODO f0ea267ab55c4d15127c1ac1667edbf781147438
|
||||||
F src/btree.c 9f22b51681bcc0026ea300134e4e2f1f40fc0800
|
F src/btree.c 823d765a20ef208ba9e8fc841d2c521fa91baefd
|
||||||
F src/btree.h 2427961c702dd0755ec70f529cf3db32707d689b
|
F src/btree.h 2427961c702dd0755ec70f529cf3db32707d689b
|
||||||
F src/build.c 5839600c9fced909e9d336203b758aeaa541b3b1
|
F src/build.c ebc3ecd58f2c2792d23dd20c06fbd58393628ad7
|
||||||
F src/delete.c 769a28cf35ab75df4b2416982d8369520b28f3c5
|
F src/delete.c 62500a09606c0f714b651756475cd42979ef08e8
|
||||||
F src/ex/README b745b00acce2d892f60c40111dacdfc48e0c1c7a
|
F src/ex/README b745b00acce2d892f60c40111dacdfc48e0c1c7a
|
||||||
F src/ex/db.c f1419ae6c93e40b5ac6e39fe7efd95d868e6f9d7
|
F src/ex/db.c f1419ae6c93e40b5ac6e39fe7efd95d868e6f9d7
|
||||||
F src/ex/db.h 3f2933ee20c147fe494835786e4c6f3a562def4e
|
F src/ex/db.h 3f2933ee20c147fe494835786e4c6f3a562def4e
|
||||||
@@ -27,14 +27,14 @@ F src/ex/pg.h 23a4ac807b0546ec2bb6239ec8bd3e06926572cd
|
|||||||
F src/ex/sizes.tcl f54bad4a2ac567624be59131a6ee42d71b41a3d7
|
F src/ex/sizes.tcl f54bad4a2ac567624be59131a6ee42d71b41a3d7
|
||||||
F src/expr.c 83b6a7ed4cf502249f192b698517e9a9b8f05303
|
F src/expr.c 83b6a7ed4cf502249f192b698517e9a9b8f05303
|
||||||
F src/insert.c 1072c0dd7782c17af735df37f447630d4d577ba1
|
F src/insert.c 1072c0dd7782c17af735df37f447630d4d577ba1
|
||||||
F src/main.c 1feb8e6681fd7bf5d8da5cbec2f6d15767c26033
|
F src/main.c b72d2b03a226fdbc241afd3cf66254d504ce74b5
|
||||||
F src/md5.c 52f677bfc590e09f71d07d7e327bd59da738d07c
|
F src/md5.c 52f677bfc590e09f71d07d7e327bd59da738d07c
|
||||||
F src/pager.c 05a2177c99a835c3efec1e4187556e2e29311d4a
|
F src/pager.c 05a2177c99a835c3efec1e4187556e2e29311d4a
|
||||||
F src/pager.h 238aa88bafe33911bf9b0b365f35afd0a261cd46
|
F src/pager.h 238aa88bafe33911bf9b0b365f35afd0a261cd46
|
||||||
F src/parse.y 8fc096948994a7ffbf61ba13129cc589f794a9cb
|
F src/parse.y 8fc096948994a7ffbf61ba13129cc589f794a9cb
|
||||||
F src/printf.c b1e22a47be8cdf707815647239991e08e8cb69f9
|
F src/printf.c b1e22a47be8cdf707815647239991e08e8cb69f9
|
||||||
F src/random.c b36c3f57dc80c8f354e6bfbf39cf1e1de021d54a
|
F src/random.c 55775802549c7152086bd19c3342293d31608532
|
||||||
F src/select.c 0f7e6652b5a1869f8eb39778ffece5055a909b29
|
F src/select.c 1e37bea8f9d8e8fdb31ef750bb038ca6a2337447
|
||||||
F src/shell.c 1fcdf8c4180098bcfdee12501e01b4c8eb21d726
|
F src/shell.c 1fcdf8c4180098bcfdee12501e01b4c8eb21d726
|
||||||
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
|
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
|
||||||
F src/sqlite.h.in 8faa2fed0513d188ced16e5f9094e57694594e70
|
F src/sqlite.h.in 8faa2fed0513d188ced16e5f9094e57694594e70
|
||||||
@@ -43,23 +43,22 @@ F src/table.c adcaf074f6c1075e86359174e68701fa2acfc4d6
|
|||||||
F src/tclsqlite.c d328970848c028e13e61e173bef79adcc379568a
|
F src/tclsqlite.c d328970848c028e13e61e173bef79adcc379568a
|
||||||
F src/test1.c abb3cb427e735ae87e6533f5b3b7164b7da91bc4
|
F src/test1.c abb3cb427e735ae87e6533f5b3b7164b7da91bc4
|
||||||
F src/test2.c b3177e061fabd20d48e4b1b4bca610a0d2b28670
|
F src/test2.c b3177e061fabd20d48e4b1b4bca610a0d2b28670
|
||||||
F src/test3.c 147b42ec368a10e9f267e7466d30c46e76d7f278
|
F src/test3.c 1fc103f198cbd0447d1a12c3ce48795755ec1a53
|
||||||
F src/tokenize.c 0118b57702cb6550769316e8443b06760b067acf
|
F src/tokenize.c 0118b57702cb6550769316e8443b06760b067acf
|
||||||
F src/update.c ea8f2c0712cd4cd19314a26ef4766866013facda
|
F src/update.c ea8f2c0712cd4cd19314a26ef4766866013facda
|
||||||
F src/util.c c77668fef860cfd2e4e682ef4f3ed8f9e68c551b
|
F src/util.c c77668fef860cfd2e4e682ef4f3ed8f9e68c551b
|
||||||
F src/vdbe.c d7d30c19330b6c2452859424d7fd6d452d6dee62
|
F src/vdbe.c 826fcc85277ed256d2db725cabfbefbd186b734a
|
||||||
F src/vdbe.h 6ee941ecd78b7b224607517fd060d6547910dc10
|
F src/vdbe.h 9f32bd12c47bd2b4bdd7e93092bb796f2a3b649f
|
||||||
F src/where.c fef978a9a2234b01e30e36833ab63e14bbc626d3
|
F src/where.c fef978a9a2234b01e30e36833ab63e14bbc626d3
|
||||||
F test/all.test 21d55a97e39e7ec5776751dc9dd8b1b51ef4a048
|
F test/all.test 841d176f11fe2fb4419e5b617faedfa617f815fa
|
||||||
F test/btree.test 5e1eeb03cda22161eec827dc5224ce6c500eaaf9
|
F test/btree.test 5e1eeb03cda22161eec827dc5224ce6c500eaaf9
|
||||||
F test/btree2.test a3c9ff1e4490357dd15c9a41f8aefd02f6e32fdc
|
F test/btree2.test a3c9ff1e4490357dd15c9a41f8aefd02f6e32fdc
|
||||||
F test/copy.test b77a1214bd7756f2849d5c4fa6e715c0ff0c34eb
|
F test/copy.test b77a1214bd7756f2849d5c4fa6e715c0ff0c34eb
|
||||||
F test/dbbe.test a022fe2d983848f786e17ef1fc6809cfd37fb02c
|
|
||||||
F test/delete.test 50b9b1f06c843d591741dba7869433a105360dbf
|
F test/delete.test 50b9b1f06c843d591741dba7869433a105360dbf
|
||||||
F test/expr.test 80bf8f0e9aa6b9c35bf97ce5d603a28381168d8a
|
F test/expr.test 80bf8f0e9aa6b9c35bf97ce5d603a28381168d8a
|
||||||
F test/func.test ac3def2a673d1042750ae1a4ad1768bb7c7ae90b
|
F test/func.test ac3def2a673d1042750ae1a4ad1768bb7c7ae90b
|
||||||
F test/in.test ea48016c4fcc479d315932ae2b8568146686ffaf
|
F test/in.test ea48016c4fcc479d315932ae2b8568146686ffaf
|
||||||
F test/index.test 266474cd101d7ed3703a0fc0428145cedacc92e0
|
F test/index.test 73f34caeab4751e48dc337e504199b934e06b12d
|
||||||
F test/insert.test dbd3bd189edb61fddbe66c236694ef23352429f1
|
F test/insert.test dbd3bd189edb61fddbe66c236694ef23352429f1
|
||||||
F test/insert2.test 732405e30331635af8d159fccabe835eea5cd0c6
|
F test/insert2.test 732405e30331635af8d159fccabe835eea5cd0c6
|
||||||
F test/lock.test bca7d53de73138b1f670a2fbdb1f481ff7eaa45a
|
F test/lock.test bca7d53de73138b1f670a2fbdb1f481ff7eaa45a
|
||||||
@@ -70,19 +69,19 @@ F test/printf.test 4c71871e1a75a2dacb673945fc13ddb30168798f
|
|||||||
F test/quote.test 40a3164af8456933a81312803fa8cdb21b205c12
|
F test/quote.test 40a3164af8456933a81312803fa8cdb21b205c12
|
||||||
F test/rowid.test b01e6dec09780c93f55db6cfe7ad097323954f23
|
F test/rowid.test b01e6dec09780c93f55db6cfe7ad097323954f23
|
||||||
F test/select1.test 223507655cdb4f9901d83fa7f5c5328e022c211f
|
F test/select1.test 223507655cdb4f9901d83fa7f5c5328e022c211f
|
||||||
F test/select2.test 4cee2d9d4d7d4657b086569064a0c454e1795afe
|
F test/select2.test 3817db11ee8d547328cfb6775f6399f50e3a4aa6
|
||||||
F test/select3.test a9234b8424b6c6d71de534f43b91ade9be68e9cc
|
F test/select3.test a9234b8424b6c6d71de534f43b91ade9be68e9cc
|
||||||
F test/select4.test cb5374d7c87680e294ac749307459a5cc547609d
|
F test/select4.test cb5374d7c87680e294ac749307459a5cc547609d
|
||||||
F test/select5.test e2b9d51d88cbd6c307c2c05b0ef55fe7ba811ac2
|
F test/select5.test e2b9d51d88cbd6c307c2c05b0ef55fe7ba811ac2
|
||||||
F test/sort.test 838cd862642ed9a2c47e1a17b5c33da452b4552e
|
F test/sort.test 838cd862642ed9a2c47e1a17b5c33da452b4552e
|
||||||
F test/subselect.test bf8b251a92fb091973c1c469ce499dc9648a41d5
|
F test/subselect.test bf8b251a92fb091973c1c469ce499dc9648a41d5
|
||||||
F test/table.test 3e0d74ec03f3df167544d63f39b9b6cd6d1d1273
|
F test/table.test 4d3a978ea7fb0bd88e6eec27ebd69877a529b7dd
|
||||||
F test/tableapi.test 4778414470ba150983d03b9858334effe720c2e0
|
F test/tableapi.test 4778414470ba150983d03b9858334effe720c2e0
|
||||||
F test/tclsqlite.test d2aa55926874783b2401f0146e839f773c6796e1
|
F test/tclsqlite.test d2aa55926874783b2401f0146e839f773c6796e1
|
||||||
F test/tester.tcl 39a707dac2b6048d9c9e07a98d3256d50069fe47
|
F test/tester.tcl 3147bb13461280dfc0afb7a74d14efcd8c0969a0
|
||||||
F test/trans.test 51e50e8273da6845b31a2095e9d3b221fb60d8d0
|
F test/trans.test 51e50e8273da6845b31a2095e9d3b221fb60d8d0
|
||||||
F test/update.test 72c0c93310483b86dc904a992220c5b84c7ce100
|
F test/update.test 72c0c93310483b86dc904a992220c5b84c7ce100
|
||||||
F test/vacuum.test b95d8119a0a83dc6c4ac63888f8872f06199e065
|
F test/vacuum.test 62b01e7972dd513fb9587fbc383e5f6a5ef1a3fb
|
||||||
F test/where.test 755957829c493b1b7ad1ecb27d6c782131a6b3d5
|
F test/where.test 755957829c493b1b7ad1ecb27d6c782131a6b3d5
|
||||||
F tool/gdbmdump.c 529e67c78d920606ba196326ea55b57b75fcc82b
|
F tool/gdbmdump.c 529e67c78d920606ba196326ea55b57b75fcc82b
|
||||||
F tool/gdbmstat.c 56a9033531e5f5a48413f6ec436d5fb0341632c1
|
F tool/gdbmstat.c 56a9033531e5f5a48413f6ec436d5fb0341632c1
|
||||||
@@ -108,7 +107,7 @@ F www/opcode.tcl cb3a1abf8b7b9be9f3a228d097d6bf8b742c2b6f
|
|||||||
F www/sqlite.tcl cb0d23d8f061a80543928755ec7775da6e4f362f
|
F www/sqlite.tcl cb0d23d8f061a80543928755ec7775da6e4f362f
|
||||||
F www/tclsqlite.tcl 06f81c401f79a04f2c5ebfb97e7c176225c0aef2
|
F www/tclsqlite.tcl 06f81c401f79a04f2c5ebfb97e7c176225c0aef2
|
||||||
F www/vdbe.tcl 0c8aaa529dd216ccbf7daaabd80985e413d5f9ad
|
F www/vdbe.tcl 0c8aaa529dd216ccbf7daaabd80985e413d5f9ad
|
||||||
P 991ce8115052da9395d4bf8ff29f417e3c36dc7f
|
P 9ac8399c99cb996a382f3d49f45b6ca857adc827
|
||||||
R f709a5820bca7397e17a0af30d07e86d
|
R 2372c1f59dbe1995efdd6847c777d732
|
||||||
U drh
|
U drh
|
||||||
Z c3ae2020eeb73a32f1d2074b9db28833
|
Z 2c92ace69c7d17b3485a5d299eba152d
|
||||||
|
@@ -1 +1 @@
|
|||||||
9ac8399c99cb996a382f3d49f45b6ca857adc827
|
62c7bd11bcf6438cdcbf66fa67a2bf4ab9d1664d
|
51
src/btree.c
51
src/btree.c
@@ -21,7 +21,7 @@
|
|||||||
** http://www.hwaci.com/drh/
|
** http://www.hwaci.com/drh/
|
||||||
**
|
**
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
** $Id: btree.c,v 1.23 2001/09/13 14:46:10 drh Exp $
|
** $Id: btree.c,v 1.24 2001/09/13 21:53: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
|
||||||
@@ -1685,6 +1685,7 @@ static int balance(Btree *pBt, MemPage *pPage, BtCursor *pCur){
|
|||||||
int nxDiv; /* Next divider slot in pParent->apCell[] */
|
int nxDiv; /* Next divider slot in pParent->apCell[] */
|
||||||
int rc; /* The return code */
|
int rc; /* The return code */
|
||||||
int iCur; /* apCell[iCur] is the cell of the cursor */
|
int iCur; /* apCell[iCur] is the cell of the cursor */
|
||||||
|
MemPage *pOldCurPage; /* The cursor originally points to this page */
|
||||||
int totalSize; /* Total bytes for all cells */
|
int totalSize; /* Total bytes for all cells */
|
||||||
int subtotal; /* Subtotal of bytes in cells on one page */
|
int subtotal; /* Subtotal of bytes in cells on one page */
|
||||||
int cntNew[4]; /* Index in apCell[] of cell after i-th page */
|
int cntNew[4]; /* Index in apCell[] of cell after i-th page */
|
||||||
@@ -1730,6 +1731,11 @@ static int balance(Btree *pBt, MemPage *pPage, BtCursor *pCur){
|
|||||||
rc = initPage(pPage, sqlitepager_pagenumber(pPage), 0);
|
rc = initPage(pPage, sqlitepager_pagenumber(pPage), 0);
|
||||||
assert( rc==SQLITE_OK );
|
assert( rc==SQLITE_OK );
|
||||||
reparentChildPages(pBt->pPager, pPage);
|
reparentChildPages(pBt->pPager, pPage);
|
||||||
|
if( pCur && pCur->pPage==pChild ){
|
||||||
|
sqlitepager_unref(pChild);
|
||||||
|
pCur->pPage = pPage;
|
||||||
|
sqlitepager_ref(pPage);
|
||||||
|
}
|
||||||
freePage(pBt, pChild, pgnoChild);
|
freePage(pBt, pChild, pgnoChild);
|
||||||
sqlitepager_unref(pChild);
|
sqlitepager_unref(pChild);
|
||||||
}else{
|
}else{
|
||||||
@@ -1760,8 +1766,8 @@ static int balance(Btree *pBt, MemPage *pPage, BtCursor *pCur){
|
|||||||
pChild->pParent = pPage;
|
pChild->pParent = pPage;
|
||||||
sqlitepager_ref(pPage);
|
sqlitepager_ref(pPage);
|
||||||
pChild->isOverfull = 1;
|
pChild->isOverfull = 1;
|
||||||
if( pCur ){
|
if( pCur && pCur->pPage==pPage ){
|
||||||
sqlitepager_unref(pCur->pPage);
|
sqlitepager_unref(pPage);
|
||||||
pCur->pPage = pChild;
|
pCur->pPage = pChild;
|
||||||
}else{
|
}else{
|
||||||
extraUnref = pChild;
|
extraUnref = pChild;
|
||||||
@@ -1796,7 +1802,7 @@ static int balance(Btree *pBt, MemPage *pPage, BtCursor *pCur){
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
** Initialize variables so that it will be safe to jump
|
** Initialize variables so that it will be safe to jump
|
||||||
** directory to balance_cleanup at any moment.
|
** directly to balance_cleanup at any moment.
|
||||||
*/
|
*/
|
||||||
nOld = nNew = 0;
|
nOld = nNew = 0;
|
||||||
sqlitepager_ref(pParent);
|
sqlitepager_ref(pParent);
|
||||||
@@ -1836,15 +1842,25 @@ static int balance(Btree *pBt, MemPage *pPage, BtCursor *pCur){
|
|||||||
/*
|
/*
|
||||||
** Set iCur to be the index in apCell[] of the cell that the cursor
|
** Set iCur to be the index in apCell[] of the cell that the cursor
|
||||||
** is pointing to. We will need this later on in order to keep the
|
** is pointing to. We will need this later on in order to keep the
|
||||||
** cursor pointing at the same cell.
|
** cursor pointing at the same cell. If pCur points to a page that
|
||||||
|
** has no involvement with this rebalancing, then set iCur to a large
|
||||||
|
** number so that the iCur==j tests always fail in the main cell
|
||||||
|
** distribution loop below.
|
||||||
*/
|
*/
|
||||||
if( pCur ){
|
if( pCur ){
|
||||||
iCur = pCur->idx;
|
iCur = 0;
|
||||||
for(i=0; i<nDiv && idxDiv[i]<idx; i++){
|
for(i=0; i<nOld; i++){
|
||||||
iCur += apOld[i]->nCell + 1;
|
if( pCur->pPage==apOld[i] ){
|
||||||
|
iCur += pCur->idx;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
sqlitepager_unref(pCur->pPage);
|
iCur += apOld[i]->nCell;
|
||||||
pCur->pPage = 0;
|
if( i<nOld-1 && pCur->pPage==pParent && pCur->idx==idxDiv[i] ){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
iCur++;
|
||||||
|
}
|
||||||
|
pOldCurPage = pCur->pPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1965,8 +1981,9 @@ static int balance(Btree *pBt, MemPage *pPage, BtCursor *pCur){
|
|||||||
pParent->apCell[nxDiv]->h.leftChild = pgnoNew[nNew-1];
|
pParent->apCell[nxDiv]->h.leftChild = pgnoNew[nNew-1];
|
||||||
}
|
}
|
||||||
if( pCur ){
|
if( pCur ){
|
||||||
assert( pCur->pPage!=0 );
|
assert( pOldCurPage!=0 );
|
||||||
sqlitepager_ref(pCur->pPage);
|
sqlitepager_ref(pCur->pPage);
|
||||||
|
sqlitepager_unref(pOldCurPage);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1980,7 +1997,7 @@ static int balance(Btree *pBt, MemPage *pPage, BtCursor *pCur){
|
|||||||
/*
|
/*
|
||||||
** balance the parent page.
|
** balance the parent page.
|
||||||
*/
|
*/
|
||||||
rc = balance(pBt, pParent, 0);
|
rc = balance(pBt, pParent, pCur);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Cleanup before returning.
|
** Cleanup before returning.
|
||||||
@@ -2022,7 +2039,7 @@ int sqliteBtreeInsert(
|
|||||||
MemPage *pPage;
|
MemPage *pPage;
|
||||||
Btree *pBt = pCur->pBt;
|
Btree *pBt = pCur->pBt;
|
||||||
|
|
||||||
if( !pCur->pBt->inTrans ){
|
if( !pCur->pBt->inTrans || nKey+nData==0 ){
|
||||||
return SQLITE_ERROR; /* Must start a transaction first */
|
return SQLITE_ERROR; /* Must start a transaction first */
|
||||||
}
|
}
|
||||||
rc = sqliteBtreeMoveto(pCur, pKey, nKey, &loc);
|
rc = sqliteBtreeMoveto(pCur, pKey, nKey, &loc);
|
||||||
@@ -2107,8 +2124,10 @@ int sqliteBtreeDelete(BtCursor *pCur){
|
|||||||
releaseTempCursor(&leafCur);
|
releaseTempCursor(&leafCur);
|
||||||
}else{
|
}else{
|
||||||
dropCell(pPage, pCur->idx, cellSize(pCell));
|
dropCell(pPage, pCur->idx, cellSize(pCell));
|
||||||
if( pCur->idx>=pPage->nCell && pCur->idx>0 ){
|
if( pCur->idx>=pPage->nCell ){
|
||||||
pCur->idx--;
|
pCur->idx = pPage->nCell-1;
|
||||||
|
if( pCur->idx<0 ){ pCur->idx = 0; }
|
||||||
|
pCur->bSkipNext = 0;
|
||||||
}else{
|
}else{
|
||||||
pCur->bSkipNext = 1;
|
pCur->bSkipNext = 1;
|
||||||
}
|
}
|
||||||
@@ -2252,7 +2271,7 @@ int sqliteBtreeUpdateMeta(Btree *pBt, int *aMeta){
|
|||||||
** All of the following code is omitted unless the library is compiled with
|
** All of the following code is omitted unless the library is compiled with
|
||||||
** the -DSQLITE_TEST=1 compiler option.
|
** the -DSQLITE_TEST=1 compiler option.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#ifdef SQLITE_TEST
|
#if 1
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Print a disassembly of the given page on standard output. This routine
|
** Print a disassembly of the given page on standard output. This routine
|
||||||
|
90
src/build.c
90
src/build.c
@@ -33,7 +33,7 @@
|
|||||||
** COPY
|
** COPY
|
||||||
** VACUUM
|
** VACUUM
|
||||||
**
|
**
|
||||||
** $Id: build.c,v 1.31 2001/09/13 16:18:54 drh Exp $
|
** $Id: build.c,v 1.32 2001/09/13 21:53:10 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -240,6 +240,26 @@ void sqliteDeleteTable(sqlite *db, Table *pTable){
|
|||||||
sqliteFree(pTable);
|
sqliteFree(pTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Unlink the given table from the hash tables and the delete the
|
||||||
|
** table structure and all its indices.
|
||||||
|
*/
|
||||||
|
static void sqliteUnlinkAndDeleteTable(sqlite *db, Table *pTable){
|
||||||
|
if( pTable->zName && db ){
|
||||||
|
int h = sqliteHashNoCase(pTable->zName, 0) % N_HASH;
|
||||||
|
if( db->apTblHash[h]==pTable ){
|
||||||
|
db->apTblHash[h] = pTable->pHash;
|
||||||
|
}else{
|
||||||
|
Table *p;
|
||||||
|
for(p=db->apTblHash[h]; p && p->pHash!=pTable; p=p->pHash){}
|
||||||
|
if( p && p->pHash==pTable ){
|
||||||
|
p->pHash = pTable->pHash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sqliteDeleteTable(db, pTable);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Check all Tables and Indexes in the internal hash table and commit
|
** Check all Tables and Indexes in the internal hash table and commit
|
||||||
** any additions or deletions to those hash tables.
|
** any additions or deletions to those hash tables.
|
||||||
@@ -262,7 +282,7 @@ void sqliteCommitInternalChanges(sqlite *db){
|
|||||||
for(pTable = db->apTblHash[i]; pTable; pTable=pNext){
|
for(pTable = db->apTblHash[i]; pTable; pTable=pNext){
|
||||||
pNext = pTable->pHash;
|
pNext = pTable->pHash;
|
||||||
if( pTable->isDelete ){
|
if( pTable->isDelete ){
|
||||||
sqliteDeleteTable(db, pTable);
|
sqliteUnlinkAndDeleteTable(db, pTable);
|
||||||
}else if( pTable->isCommit==0 ){
|
}else if( pTable->isCommit==0 ){
|
||||||
pTable->isCommit = 1;
|
pTable->isCommit = 1;
|
||||||
}
|
}
|
||||||
@@ -298,7 +318,7 @@ void sqliteRollbackInternalChanges(sqlite *db){
|
|||||||
for(pTable = db->apTblHash[i]; pTable; pTable=pNext){
|
for(pTable = db->apTblHash[i]; pTable; pTable=pNext){
|
||||||
pNext = pTable->pHash;
|
pNext = pTable->pHash;
|
||||||
if( !pTable->isCommit ){
|
if( !pTable->isCommit ){
|
||||||
sqliteDeleteTable(db, pTable);
|
sqliteUnlinkAndDeleteTable(db, pTable);
|
||||||
}else if( pTable->isDelete ){
|
}else if( pTable->isDelete ){
|
||||||
pTable->isDelete = 0;
|
pTable->isDelete = 0;
|
||||||
}
|
}
|
||||||
@@ -473,7 +493,7 @@ void sqliteEndTable(Parse *pParse, Token *pEnd){
|
|||||||
*/
|
*/
|
||||||
if( !pParse->initFlag ){
|
if( !pParse->initFlag ){
|
||||||
static VdbeOp addTable[] = {
|
static VdbeOp addTable[] = {
|
||||||
{ OP_Open, 0, 2, 0},
|
{ OP_Open, 0, 2, MASTER_NAME},
|
||||||
{ OP_NewRecno, 0, 0, 0},
|
{ OP_NewRecno, 0, 0, 0},
|
||||||
{ OP_String, 0, 0, "table" },
|
{ OP_String, 0, 0, "table" },
|
||||||
{ OP_String, 0, 0, 0}, /* 3 */
|
{ OP_String, 0, 0, 0}, /* 3 */
|
||||||
@@ -495,6 +515,15 @@ void sqliteEndTable(Parse *pParse, Token *pEnd){
|
|||||||
sqliteVdbeChangeP3(v, base+5, p->zName, 0);
|
sqliteVdbeChangeP3(v, base+5, p->zName, 0);
|
||||||
sqliteVdbeChangeP3(v, base+6, pParse->sFirstToken.z, n);
|
sqliteVdbeChangeP3(v, base+6, pParse->sFirstToken.z, n);
|
||||||
sqliteVdbeAddOp(v, OP_Close, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Close, 0, 0, 0, 0);
|
||||||
|
if( p->pIndex ){
|
||||||
|
/* If the table has a primary key, create an index in the database
|
||||||
|
** for that key. */
|
||||||
|
Index *pIndex = p->pIndex;
|
||||||
|
assert( pIndex->pNext==0 );
|
||||||
|
assert( pIndex->tnum==0 );
|
||||||
|
sqliteVdbeAddOp(v, OP_CreateIndex, 0, 0, 0, 0),
|
||||||
|
sqliteVdbeIndexRootAddr(v, &pIndex->tnum);
|
||||||
|
}
|
||||||
if( (db->flags & SQLITE_InTrans)==0 ){
|
if( (db->flags & SQLITE_InTrans)==0 ){
|
||||||
sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
@@ -528,6 +557,7 @@ void sqliteDropTable(Parse *pParse, Token *pName){
|
|||||||
Table *pTable;
|
Table *pTable;
|
||||||
Vdbe *v;
|
Vdbe *v;
|
||||||
int base;
|
int base;
|
||||||
|
sqlite *db = pParse->db;
|
||||||
|
|
||||||
if( pParse->nErr || sqlite_malloc_failed ) return;
|
if( pParse->nErr || sqlite_malloc_failed ) return;
|
||||||
pTable = sqliteTableFromToken(pParse, pName);
|
pTable = sqliteTableFromToken(pParse, pName);
|
||||||
@@ -545,29 +575,29 @@ void sqliteDropTable(Parse *pParse, Token *pName){
|
|||||||
v = sqliteGetVdbe(pParse);
|
v = sqliteGetVdbe(pParse);
|
||||||
if( v ){
|
if( v ){
|
||||||
static VdbeOp dropTable[] = {
|
static VdbeOp dropTable[] = {
|
||||||
{ OP_Open, 0, 2, 0},
|
{ OP_Open, 0, 2, MASTER_NAME},
|
||||||
{ OP_Rewind, 0, 0, 0},
|
{ OP_Rewind, 0, 0, 0},
|
||||||
{ OP_String, 0, 0, 0}, /* 2 */
|
{ OP_String, 0, 0, 0}, /* 2 */
|
||||||
{ OP_Next, 0, ADDR(10), 0}, /* 3 */
|
{ OP_Next, 0, ADDR(9), 0}, /* 3 */
|
||||||
{ OP_Dup, 0, 0, 0},
|
{ OP_Dup, 0, 0, 0},
|
||||||
{ OP_Column, 0, 3, 0},
|
{ OP_Column, 0, 3, 0},
|
||||||
{ OP_Ne, 0, ADDR(3), 0},
|
{ OP_Ne, 0, ADDR(3), 0},
|
||||||
{ OP_Recno, 0, 0, 0},
|
|
||||||
{ OP_Delete, 0, 0, 0},
|
{ OP_Delete, 0, 0, 0},
|
||||||
{ OP_Goto, 0, ADDR(3), 0},
|
{ OP_Goto, 0, ADDR(3), 0},
|
||||||
{ OP_Destroy, 0, 0, 0}, /* 10 */
|
{ OP_Destroy, 0, 0, 0}, /* 9 */
|
||||||
{ OP_Close, 0, 0, 0},
|
{ OP_Close, 0, 0, 0},
|
||||||
};
|
};
|
||||||
Index *pIdx;
|
Index *pIdx;
|
||||||
if( (pParse->db->flags & SQLITE_InTrans)==0 ){
|
if( (db->flags & SQLITE_InTrans)==0 ){
|
||||||
sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
base = sqliteVdbeAddOpList(v, ArraySize(dropTable), dropTable);
|
base = sqliteVdbeAddOpList(v, ArraySize(dropTable), dropTable);
|
||||||
sqliteVdbeChangeP1(v, base+10, pTable->tnum);
|
sqliteVdbeChangeP3(v, base+2, pTable->zName, 0);
|
||||||
|
sqliteVdbeChangeP1(v, base+9, pTable->tnum);
|
||||||
for(pIdx=pTable->pIndex; pIdx; pIdx=pIdx->pNext){
|
for(pIdx=pTable->pIndex; pIdx; pIdx=pIdx->pNext){
|
||||||
sqliteVdbeAddOp(v, OP_Destroy, pIdx->tnum, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Destroy, pIdx->tnum, 0, 0, 0);
|
||||||
}
|
}
|
||||||
if( (pParse->db->flags & SQLITE_InTrans)==0 ){
|
if( (db->flags & SQLITE_InTrans)==0 ){
|
||||||
sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -580,7 +610,7 @@ void sqliteDropTable(Parse *pParse, Token *pName){
|
|||||||
*/
|
*/
|
||||||
if( !pParse->explain ){
|
if( !pParse->explain ){
|
||||||
pTable->isDelete = 1;
|
pTable->isDelete = 1;
|
||||||
pParse->db->flags |= SQLITE_InternChanges;
|
db->flags |= SQLITE_InternChanges;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -720,16 +750,25 @@ void sqliteCreateIndex(
|
|||||||
** CREATE INDEX statements are read out of the master table. In
|
** CREATE INDEX statements are read out of the master table. In
|
||||||
** the latter case the index already exists on disk, which is why
|
** the latter case the index already exists on disk, which is why
|
||||||
** we don't want to recreate it.
|
** we don't want to recreate it.
|
||||||
|
**
|
||||||
|
** If pTable==0 it means this index is generated as a primary key
|
||||||
|
** and those does not have a CREATE INDEX statement to add to the
|
||||||
|
** master table. Also, since primary keys are created at the same
|
||||||
|
** time as tables, the table will be empty so there is no need to
|
||||||
|
** initialize the index. Hence, skip all the code generation if
|
||||||
|
** pTable==0.
|
||||||
*/
|
*/
|
||||||
if( pParse->initFlag==0 ){
|
else if( pParse->initFlag==0 && pTable!=0 ){
|
||||||
static VdbeOp addTable[] = {
|
static VdbeOp addTable[] = {
|
||||||
{ OP_Open, 2, 2, 0},
|
{ OP_Open, 2, 2, MASTER_NAME},
|
||||||
{ OP_NewRecno, 2, 0, 0},
|
{ OP_NewRecno, 2, 0, 0},
|
||||||
{ OP_String, 0, 0, "index"},
|
{ OP_String, 0, 0, "index"},
|
||||||
{ OP_String, 0, 0, 0}, /* 3 */
|
{ OP_String, 0, 0, 0}, /* 3 */
|
||||||
{ OP_CreateIndex, 0, 0, 0},
|
{ OP_CreateIndex, 1, 0, 0},
|
||||||
{ OP_String, 0, 0, 0}, /* 5 */
|
{ OP_Dup, 0, 0, 0},
|
||||||
{ OP_String, 0, 0, 0}, /* 6 */
|
{ OP_Open, 1, 0, 0}, /* 6 */
|
||||||
|
{ OP_String, 0, 0, 0}, /* 7 */
|
||||||
|
{ OP_String, 0, 0, 0}, /* 8 */
|
||||||
{ OP_MakeRecord, 5, 0, 0},
|
{ OP_MakeRecord, 5, 0, 0},
|
||||||
{ OP_Put, 2, 0, 0},
|
{ OP_Put, 2, 0, 0},
|
||||||
{ OP_Close, 2, 0, 0},
|
{ OP_Close, 2, 0, 0},
|
||||||
@@ -744,17 +783,17 @@ void sqliteCreateIndex(
|
|||||||
if( pTable!=0 && (db->flags & SQLITE_InTrans)==0 ){
|
if( pTable!=0 && (db->flags & SQLITE_InTrans)==0 ){
|
||||||
sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
sqliteVdbeAddOp(v, OP_Open, 0, pTab->tnum, pTab->zName, 0);
|
|
||||||
sqliteVdbeAddOp(v, OP_Open, 1, pIndex->tnum, pIndex->zName, 0);
|
|
||||||
if( pStart && pEnd ){
|
if( pStart && pEnd ){
|
||||||
int base;
|
int base;
|
||||||
n = (int)pEnd->z - (int)pStart->z + 1;
|
n = (int)pEnd->z - (int)pStart->z + 1;
|
||||||
base = sqliteVdbeAddOpList(v, ArraySize(addTable), addTable);
|
base = sqliteVdbeAddOpList(v, ArraySize(addTable), addTable);
|
||||||
sqliteVdbeChangeP3(v, base+3, pIndex->zName, 0);
|
sqliteVdbeChangeP3(v, base+3, pIndex->zName, 0);
|
||||||
sqliteVdbeIndexRootAddr(v, &pIndex->tnum);
|
sqliteVdbeIndexRootAddr(v, &pIndex->tnum);
|
||||||
sqliteVdbeChangeP3(v, base+5, pTab->zName, 0);
|
sqliteVdbeChangeP3(v, base+6, pIndex->zName, 0);
|
||||||
sqliteVdbeChangeP3(v, base+6, pStart->z, n);
|
sqliteVdbeChangeP3(v, base+7, pTab->zName, 0);
|
||||||
|
sqliteVdbeChangeP3(v, base+8, pStart->z, n);
|
||||||
}
|
}
|
||||||
|
sqliteVdbeAddOp(v, OP_Open, 0, pTab->tnum, pTab->zName, 0);
|
||||||
lbl1 = sqliteVdbeMakeLabel(v);
|
lbl1 = sqliteVdbeMakeLabel(v);
|
||||||
lbl2 = sqliteVdbeMakeLabel(v);
|
lbl2 = sqliteVdbeMakeLabel(v);
|
||||||
sqliteVdbeAddOp(v, OP_Rewind, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Rewind, 0, 0, 0, 0);
|
||||||
@@ -812,16 +851,15 @@ void sqliteDropIndex(Parse *pParse, Token *pName){
|
|||||||
v = sqliteGetVdbe(pParse);
|
v = sqliteGetVdbe(pParse);
|
||||||
if( v ){
|
if( v ){
|
||||||
static VdbeOp dropIndex[] = {
|
static VdbeOp dropIndex[] = {
|
||||||
{ OP_Open, 0, 2, 0},
|
{ OP_Open, 0, 2, MASTER_NAME},
|
||||||
{ OP_Rewind, 0, 0, 0},
|
{ OP_Rewind, 0, 0, 0},
|
||||||
{ OP_String, 0, 0, 0}, /* 2 */
|
{ OP_String, 0, 0, 0}, /* 2 */
|
||||||
{ OP_Next, 0, ADDR(9), 0}, /* 3 */
|
{ OP_Next, 0, ADDR(8), 0}, /* 3 */
|
||||||
{ OP_Dup, 0, 0, 0},
|
{ OP_Dup, 0, 0, 0},
|
||||||
{ OP_Column, 0, 1, 0},
|
{ OP_Column, 0, 1, 0},
|
||||||
{ OP_Ne, 0, ADDR(3), 0},
|
{ OP_Ne, 0, ADDR(3), 0},
|
||||||
{ OP_Recno, 0, 0, 0},
|
|
||||||
{ OP_Delete, 0, 0, 0},
|
{ OP_Delete, 0, 0, 0},
|
||||||
{ OP_Destroy, 0, 0, 0}, /* 9 */
|
{ OP_Destroy, 0, 0, 0}, /* 8 */
|
||||||
{ OP_Close, 0, 0, 0},
|
{ OP_Close, 0, 0, 0},
|
||||||
};
|
};
|
||||||
int base;
|
int base;
|
||||||
@@ -830,7 +868,7 @@ void sqliteDropIndex(Parse *pParse, Token *pName){
|
|||||||
sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
base = sqliteVdbeAddOpList(v, ArraySize(dropIndex), dropIndex);
|
base = sqliteVdbeAddOpList(v, ArraySize(dropIndex), dropIndex);
|
||||||
sqliteVdbeChangeP1(v, base+9, pIndex->tnum);
|
sqliteVdbeChangeP1(v, base+8, pIndex->tnum);
|
||||||
if( (db->flags & SQLITE_InTrans)==0 ){
|
if( (db->flags & SQLITE_InTrans)==0 ){
|
||||||
sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
13
src/delete.c
13
src/delete.c
@@ -24,7 +24,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 DELETE FROM statements.
|
** to handle DELETE FROM statements.
|
||||||
**
|
**
|
||||||
** $Id: delete.c,v 1.11 2001/09/13 14:46:10 drh Exp $
|
** $Id: delete.c,v 1.12 2001/09/13 21:53:10 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -96,12 +96,12 @@ void sqliteDeleteFrom(
|
|||||||
|
|
||||||
|
|
||||||
/* Special case: A DELETE without a WHERE clause deletes everything.
|
/* Special case: A DELETE without a WHERE clause deletes everything.
|
||||||
** It is easier just to deleted the database files directly.
|
** It is easier just to clear all information the database tables directly.
|
||||||
*/
|
*/
|
||||||
if( pWhere==0 ){
|
if( pWhere==0 ){
|
||||||
sqliteVdbeAddOp(v, OP_Destroy, pTab->tnum, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Clear, pTab->tnum, 0, 0, 0);
|
||||||
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
|
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
|
||||||
sqliteVdbeAddOp(v, OP_Destroy, pIdx->tnum, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Clear, pIdx->tnum, 0, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,12 +135,11 @@ void sqliteDeleteFrom(
|
|||||||
}
|
}
|
||||||
end = sqliteVdbeMakeLabel(v);
|
end = sqliteVdbeMakeLabel(v);
|
||||||
addr = sqliteVdbeAddOp(v, OP_ListRead, 0, end, 0, 0);
|
addr = sqliteVdbeAddOp(v, OP_ListRead, 0, end, 0, 0);
|
||||||
if( pTab->pIndex ){
|
|
||||||
sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
|
|
||||||
sqliteVdbeAddOp(v, OP_MoveTo, base, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_MoveTo, base, 0, 0, 0);
|
||||||
|
if( pTab->pIndex ){
|
||||||
for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
|
for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
|
||||||
int j;
|
int j;
|
||||||
sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Recno, base, 0, 0, 0);
|
||||||
for(j=0; j<pIdx->nColumn; j++){
|
for(j=0; j<pIdx->nColumn; j++){
|
||||||
sqliteVdbeAddOp(v, OP_Column, base, pIdx->aiColumn[j], 0, 0);
|
sqliteVdbeAddOp(v, OP_Column, base, pIdx->aiColumn[j], 0, 0);
|
||||||
}
|
}
|
||||||
|
@@ -26,7 +26,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.33 2001/09/13 16:18:54 drh Exp $
|
** $Id: main.c,v 1.34 2001/09/13 21:53:10 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#if defined(HAVE_USLEEP) && HAVE_USLEEP
|
#if defined(HAVE_USLEEP) && HAVE_USLEEP
|
||||||
@@ -253,6 +253,7 @@ sqlite *sqlite_open(const char *zFilename, int mode, char **pzErrMsg){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqliteFree(db);
|
sqliteFree(db);
|
||||||
|
sqliteStrRealloc(pzErrMsg);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,6 +266,7 @@ sqlite *sqlite_open(const char *zFilename, int mode, char **pzErrMsg){
|
|||||||
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);
|
||||||
|
sqliteStrRealloc(pzErrMsg);
|
||||||
return 0;
|
return 0;
|
||||||
}else /* if( pzErrMsg ) */{
|
}else /* if( pzErrMsg ) */{
|
||||||
sqliteFree(*pzErrMsg);
|
sqliteFree(*pzErrMsg);
|
||||||
|
@@ -27,7 +27,7 @@
|
|||||||
** Random numbers are used by some of the database backends in order
|
** Random numbers are used by some of the database backends in order
|
||||||
** to generate random integer keys for tables or random filenames.
|
** to generate random integer keys for tables or random filenames.
|
||||||
**
|
**
|
||||||
** $Id: random.c,v 1.2 2001/01/31 13:28:09 drh Exp $
|
** $Id: random.c,v 1.3 2001/09/13 21:53:10 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
@@ -87,7 +87,7 @@ int sqliteRandomByte(void){
|
|||||||
prng_state.s[prng_state.i] = prng_state.s[prng_state.j];
|
prng_state.s[prng_state.i] = prng_state.s[prng_state.j];
|
||||||
prng_state.s[prng_state.j] = t;
|
prng_state.s[prng_state.j] = t;
|
||||||
t = prng_state.s[prng_state.i] + prng_state.s[prng_state.j];
|
t = prng_state.s[prng_state.i] + prng_state.s[prng_state.j];
|
||||||
return t & 0xff;
|
return prng_state.s[t & 0xff];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -24,7 +24,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.
|
** to handle SELECT statements.
|
||||||
**
|
**
|
||||||
** $Id: select.c,v 1.34 2001/09/13 16:18:54 drh Exp $
|
** $Id: select.c,v 1.35 2001/09/13 21:53:10 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -182,6 +182,7 @@ static int selectInnerLoop(
|
|||||||
*/
|
*/
|
||||||
if( eDest==SRT_Except ){
|
if( eDest==SRT_Except ){
|
||||||
sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, 0, 0, 0);
|
||||||
|
sqliteVdbeAddOp(v, OP_MoveTo, iParm, 0, 0, 0);
|
||||||
sqliteVdbeAddOp(v, OP_Delete, iParm, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Delete, iParm, 0, 0, 0);
|
||||||
}else
|
}else
|
||||||
|
|
||||||
|
14
src/test3.c
14
src/test3.c
@@ -25,7 +25,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: test3.c,v 1.9 2001/08/20 00:33:58 drh Exp $
|
** $Id: test3.c,v 1.10 2001/09/13 21:53:10 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "pager.h"
|
#include "pager.h"
|
||||||
@@ -715,9 +715,11 @@ static int btree_key(
|
|||||||
sqliteBtreeKeySize(pCur, &n);
|
sqliteBtreeKeySize(pCur, &n);
|
||||||
zBuf = malloc( n+1 );
|
zBuf = malloc( n+1 );
|
||||||
rc = sqliteBtreeKey(pCur, 0, n, zBuf);
|
rc = sqliteBtreeKey(pCur, 0, n, zBuf);
|
||||||
if( rc ){
|
if( rc!=n ){
|
||||||
|
char zMsg[100];
|
||||||
free(zBuf);
|
free(zBuf);
|
||||||
Tcl_AppendResult(interp, errorName(rc), 0);
|
sprintf(zMsg, "truncated key: got %d of %d bytes", rc, n);
|
||||||
|
Tcl_AppendResult(interp, zMsg, 0);
|
||||||
return TCL_ERROR;
|
return TCL_ERROR;
|
||||||
}
|
}
|
||||||
zBuf[n] = 0;
|
zBuf[n] = 0;
|
||||||
@@ -751,9 +753,11 @@ static int btree_data(
|
|||||||
sqliteBtreeDataSize(pCur, &n);
|
sqliteBtreeDataSize(pCur, &n);
|
||||||
zBuf = malloc( n+1 );
|
zBuf = malloc( n+1 );
|
||||||
rc = sqliteBtreeData(pCur, 0, n, zBuf);
|
rc = sqliteBtreeData(pCur, 0, n, zBuf);
|
||||||
if( rc ){
|
if( rc!=n ){
|
||||||
|
char zMsg[100];
|
||||||
free(zBuf);
|
free(zBuf);
|
||||||
Tcl_AppendResult(interp, errorName(rc), 0);
|
sprintf(zMsg, "truncated data: got %d of %d bytes", rc, n);
|
||||||
|
Tcl_AppendResult(interp, zMsg, 0);
|
||||||
return TCL_ERROR;
|
return TCL_ERROR;
|
||||||
}
|
}
|
||||||
zBuf[n] = 0;
|
zBuf[n] = 0;
|
||||||
|
108
src/vdbe.c
108
src/vdbe.c
@@ -41,10 +41,11 @@
|
|||||||
** 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.63 2001/09/13 16:18:54 drh Exp $
|
** $Id: vdbe.c,v 1.64 2001/09/13 21:53:10 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** SQL is translated into a sequence of instructions to be
|
** SQL is translated into a sequence of instructions to be
|
||||||
@@ -875,26 +876,26 @@ static char *zOpName[] = { 0,
|
|||||||
"NewRecno", "Put", "Distinct", "Found",
|
"NewRecno", "Put", "Distinct", "Found",
|
||||||
"NotFound", "Delete", "Column", "KeyAsData",
|
"NotFound", "Delete", "Column", "KeyAsData",
|
||||||
"Recno", "FullKey", "Rewind", "Next",
|
"Recno", "FullKey", "Rewind", "Next",
|
||||||
"Destroy", "CreateIndex", "CreateTable", "Reorganize",
|
"Destroy", "Clear", "CreateIndex", "CreateTable",
|
||||||
"BeginIdx", "NextIdx", "PutIdx", "DeleteIdx",
|
"Reorganize", "BeginIdx", "NextIdx", "PutIdx",
|
||||||
"MemLoad", "MemStore", "ListOpen", "ListWrite",
|
"DeleteIdx", "MemLoad", "MemStore", "ListOpen",
|
||||||
"ListRewind", "ListRead", "ListClose", "SortOpen",
|
"ListWrite", "ListRewind", "ListRead", "ListClose",
|
||||||
"SortPut", "SortMakeRec", "SortMakeKey", "Sort",
|
"SortOpen", "SortPut", "SortMakeRec", "SortMakeKey",
|
||||||
"SortNext", "SortKey", "SortCallback", "SortClose",
|
"Sort", "SortNext", "SortKey", "SortCallback",
|
||||||
"FileOpen", "FileRead", "FileColumn", "FileClose",
|
"SortClose", "FileOpen", "FileRead", "FileColumn",
|
||||||
"AggReset", "AggFocus", "AggIncr", "AggNext",
|
"FileClose", "AggReset", "AggFocus", "AggIncr",
|
||||||
"AggSet", "AggGet", "SetInsert", "SetFound",
|
"AggNext", "AggSet", "AggGet", "SetInsert",
|
||||||
"SetNotFound", "SetClear", "MakeRecord", "MakeKey",
|
"SetFound", "SetNotFound", "SetClear", "MakeRecord",
|
||||||
"MakeIdxKey", "Goto", "If", "Halt",
|
"MakeKey", "MakeIdxKey", "Goto", "If",
|
||||||
"ColumnCount", "ColumnName", "Callback", "Integer",
|
"Halt", "ColumnCount", "ColumnName", "Callback",
|
||||||
"String", "Null", "Pop", "Dup",
|
"Integer", "String", "Null", "Pop",
|
||||||
"Pull", "Add", "AddImm", "Subtract",
|
"Dup", "Pull", "Add", "AddImm",
|
||||||
"Multiply", "Divide", "Min", "Max",
|
"Subtract", "Multiply", "Divide", "Min",
|
||||||
"Like", "Glob", "Eq", "Ne",
|
"Max", "Like", "Glob", "Eq",
|
||||||
"Lt", "Le", "Gt", "Ge",
|
"Ne", "Lt", "Le", "Gt",
|
||||||
"IsNull", "NotNull", "Negative", "And",
|
"Ge", "IsNull", "NotNull", "Negative",
|
||||||
"Or", "Not", "Concat", "Noop",
|
"And", "Or", "Not", "Concat",
|
||||||
"Strlen", "Substr",
|
"Noop", "Strlen", "Substr",
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1979,6 +1980,8 @@ case OP_Rollback: {
|
|||||||
** of P1. The P1 values need not be contiguous but all P1 values
|
** of P1. The P1 values need not be contiguous but all P1 values
|
||||||
** should be small integers. It is an error for P1 to be negative.
|
** should be small integers. It is an error for P1 to be negative.
|
||||||
**
|
**
|
||||||
|
** If P2==0 then take the root page number from the top of the stack.
|
||||||
|
**
|
||||||
** The P3 value is the name of the table or index being opened.
|
** The P3 value is the name of the table or index being opened.
|
||||||
** The P3 value is not actually used by this opcode and may be
|
** The P3 value is not actually used by this opcode and may be
|
||||||
** omitted. But the code generator usually inserts the index or
|
** omitted. But the code generator usually inserts the index or
|
||||||
@@ -1987,6 +1990,19 @@ case OP_Rollback: {
|
|||||||
case OP_Open: {
|
case OP_Open: {
|
||||||
int busy = 0;
|
int busy = 0;
|
||||||
int i = pOp->p1;
|
int i = pOp->p1;
|
||||||
|
int tos = p->tos;
|
||||||
|
int p2 = pOp->p2;
|
||||||
|
if( p2<=0 ){
|
||||||
|
if( tos<0 ) goto not_enough_stack;
|
||||||
|
Integerify(p, tos);
|
||||||
|
p2 = p->aStack[tos].i;
|
||||||
|
POPSTACK;
|
||||||
|
if( p2<2 ){
|
||||||
|
sqliteSetString(pzErrMsg, "root page number less than 2", 0);
|
||||||
|
rc = SQLITE_INTERNAL;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
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;
|
||||||
@@ -1999,7 +2015,7 @@ case OP_Open: {
|
|||||||
}
|
}
|
||||||
memset(&p->aCsr[i], 0, sizeof(Cursor));
|
memset(&p->aCsr[i], 0, sizeof(Cursor));
|
||||||
do{
|
do{
|
||||||
rc = sqliteBtreeCursor(pBt, pOp->p2, &p->aCsr[i].pCursor);
|
rc = sqliteBtreeCursor(pBt, p2, &p->aCsr[i].pCursor);
|
||||||
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 ){
|
||||||
@@ -2240,29 +2256,18 @@ case OP_Put: {
|
|||||||
|
|
||||||
/* Opcode: Delete P1 * *
|
/* Opcode: Delete P1 * *
|
||||||
**
|
**
|
||||||
** The top of the stack is a key. Remove this key and its data
|
** Delete the record at which the P1 cursor is currently pointing.
|
||||||
** from database file P1. Then pop the stack to discard the key.
|
**
|
||||||
|
** The cursor will be left pointing at either the next or the previous
|
||||||
|
** record in the table. If it is left pointing at the next record, then
|
||||||
|
** the next OP_Next will be a no-op. Hence it is OK to delete a record
|
||||||
|
** from within an OP_Next loop.
|
||||||
*/
|
*/
|
||||||
case OP_Delete: {
|
case OP_Delete: {
|
||||||
int tos = p->tos;
|
|
||||||
int i = pOp->p1;
|
int i = pOp->p1;
|
||||||
int res;
|
|
||||||
VERIFY( if( tos<0 ) goto not_enough_stack; )
|
|
||||||
if( VERIFY( i>=0 && i<p->nCursor && ) p->aCsr[i].pCursor!=0 ){
|
if( VERIFY( i>=0 && i<p->nCursor && ) p->aCsr[i].pCursor!=0 ){
|
||||||
char *zKey;
|
|
||||||
int nKey;
|
|
||||||
if( aStack[tos].flags & STK_Int ){
|
|
||||||
nKey = sizeof(int);
|
|
||||||
zKey = (char*)&aStack[tos].i;
|
|
||||||
}else{
|
|
||||||
if( Stringify(p, tos) ) goto no_mem;
|
|
||||||
nKey = aStack[tos].n;
|
|
||||||
zKey = zStack[tos];
|
|
||||||
}
|
|
||||||
rc = sqliteBtreeMoveto(p->aCsr[i].pCursor, zKey, nKey, &res);
|
|
||||||
rc = sqliteBtreeDelete(p->aCsr[i].pCursor);
|
rc = sqliteBtreeDelete(p->aCsr[i].pCursor);
|
||||||
}
|
}
|
||||||
POPSTACK;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2303,11 +2308,11 @@ case OP_Column: {
|
|||||||
static const int mxHdr = sizeof(aHdr)/sizeof(aHdr[0]);
|
static const int mxHdr = sizeof(aHdr)/sizeof(aHdr[0]);
|
||||||
int i = pOp->p1;
|
int i = pOp->p1;
|
||||||
int p2 = pOp->p2;
|
int p2 = pOp->p2;
|
||||||
int tos = ++p->tos;
|
int tos = p->tos+1;
|
||||||
BtCursor *pCrsr;
|
BtCursor *pCrsr;
|
||||||
char *z;
|
char *z;
|
||||||
|
|
||||||
VERIFY( if( NeedStack(p, tos) ) goto no_mem; )
|
VERIFY( if( NeedStack(p, tos+1) ) goto no_mem; )
|
||||||
if( VERIFY( i>=0 && i<p->nCursor && ) (pCrsr = p->aCsr[i].pCursor)!=0 ){
|
if( VERIFY( i>=0 && i<p->nCursor && ) (pCrsr = p->aCsr[i].pCursor)!=0 ){
|
||||||
int (*xSize)(BtCursor*, int*);
|
int (*xSize)(BtCursor*, int*);
|
||||||
int (*xRead)(BtCursor*, int, int, char*);
|
int (*xRead)(BtCursor*, int, int, char*);
|
||||||
@@ -2371,6 +2376,7 @@ case OP_Column: {
|
|||||||
zStack[tos] = z;
|
zStack[tos] = z;
|
||||||
aStack[tos].n = amt;
|
aStack[tos].n = amt;
|
||||||
}
|
}
|
||||||
|
p->tos = tos;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2530,8 +2536,13 @@ case OP_NextIdx: {
|
|||||||
zStack[tos] = 0;
|
zStack[tos] = 0;
|
||||||
if( VERIFY( i>=0 && i<p->nCursor && ) (pCrsr = &p->aCsr[i])->pCursor!=0 ){
|
if( VERIFY( i>=0 && i<p->nCursor && ) (pCrsr = &p->aCsr[i])->pCursor!=0 ){
|
||||||
pCur = pCrsr->pCursor;
|
pCur = pCrsr->pCursor;
|
||||||
|
if( pCrsr->atFirst ){
|
||||||
|
pCrsr->atFirst = 0;
|
||||||
|
res = 0;
|
||||||
|
}else{
|
||||||
rx = sqliteBtreeNext(pCur, &res);
|
rx = sqliteBtreeNext(pCur, &res);
|
||||||
if( rx!=SQLITE_OK ) goto abort_due_to_error;
|
if( rx!=SQLITE_OK ) goto abort_due_to_error;
|
||||||
|
}
|
||||||
sqliteBtreeKeySize(pCur, &size);
|
sqliteBtreeKeySize(pCur, &size);
|
||||||
if( res>0 || size!=pCrsr->nKey+sizeof(int) ||
|
if( res>0 || size!=pCrsr->nKey+sizeof(int) ||
|
||||||
sqliteBtreeKey(pCur, 0, pCrsr->nKey, pCrsr->zBuf)!=pCrsr->nKey ||
|
sqliteBtreeKey(pCur, 0, pCrsr->nKey, pCrsr->zBuf)!=pCrsr->nKey ||
|
||||||
@@ -2599,6 +2610,17 @@ case OP_Destroy: {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Opcode: Clear P1 * *
|
||||||
|
**
|
||||||
|
** Delete all contents of the database table or index whose root page
|
||||||
|
** in the database file is given by P1. But, unlike OP_Destroy, do not
|
||||||
|
** remove the table or index from the database file.
|
||||||
|
*/
|
||||||
|
case OP_Clear: {
|
||||||
|
sqliteBtreeClearTable(pBt, pOp->p1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Opcode: CreateTable * * *
|
/* Opcode: CreateTable * * *
|
||||||
**
|
**
|
||||||
** Allocate a new table in the main database file. Push the page number
|
** Allocate a new table in the main database file. Push the page number
|
||||||
@@ -2634,6 +2656,8 @@ case OP_CreateTable: {
|
|||||||
** Allocate a new Index in the main database file. Push the page number
|
** Allocate a new Index in the main database file. Push the page number
|
||||||
** for the root page of the new table onto the stack.
|
** for the root page of the new table onto the stack.
|
||||||
**
|
**
|
||||||
|
** If P1>=0 then open a cursor named P1 on the newly created index.
|
||||||
|
**
|
||||||
** The root page number is also written to a memory location which has
|
** The root page number is also written to a memory location which has
|
||||||
** be set up by the parser. The difference between CreateTable and
|
** be set up by the parser. The difference between CreateTable and
|
||||||
** CreateIndex is that each writes its root page number into a different
|
** CreateIndex is that each writes its root page number into a different
|
||||||
@@ -3684,7 +3708,7 @@ default: {
|
|||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
Cleanup(p);
|
Cleanup(p);
|
||||||
if( p->pTableRoot || p->pIndexRoot ){
|
if( (p->pTableRoot || p->pIndexRoot) && rc==SQLITE_OK ){
|
||||||
rc = SQLITE_INTERNAL;
|
rc = SQLITE_INTERNAL;
|
||||||
sqliteSetString(pzErrMsg, "table or index root page not set", 0);
|
sqliteSetString(pzErrMsg, "table or index root page not set", 0);
|
||||||
}
|
}
|
||||||
|
159
src/vdbe.h
159
src/vdbe.h
@@ -27,7 +27,7 @@
|
|||||||
** or VDBE. The VDBE implements an abstract machine that runs a
|
** or VDBE. The VDBE implements an abstract machine that runs a
|
||||||
** simple program to access and modify the underlying database.
|
** simple program to access and modify the underlying database.
|
||||||
**
|
**
|
||||||
** $Id: vdbe.h,v 1.20 2001/09/13 14:46:11 drh Exp $
|
** $Id: vdbe.h,v 1.21 2001/09/13 21:53:10 drh Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef _SQLITE_VDBE_H_
|
#ifndef _SQLITE_VDBE_H_
|
||||||
#define _SQLITE_VDBE_H_
|
#define _SQLITE_VDBE_H_
|
||||||
@@ -94,98 +94,99 @@ typedef struct VdbeOp VdbeOp;
|
|||||||
#define OP_Next 20
|
#define OP_Next 20
|
||||||
|
|
||||||
#define OP_Destroy 21
|
#define OP_Destroy 21
|
||||||
#define OP_CreateIndex 22
|
#define OP_Clear 22
|
||||||
#define OP_CreateTable 23
|
#define OP_CreateIndex 23
|
||||||
#define OP_Reorganize 24
|
#define OP_CreateTable 24
|
||||||
|
#define OP_Reorganize 25
|
||||||
|
|
||||||
#define OP_BeginIdx 25
|
#define OP_BeginIdx 26
|
||||||
#define OP_NextIdx 26
|
#define OP_NextIdx 27
|
||||||
#define OP_PutIdx 27
|
#define OP_PutIdx 28
|
||||||
#define OP_DeleteIdx 28
|
#define OP_DeleteIdx 29
|
||||||
|
|
||||||
#define OP_MemLoad 29
|
#define OP_MemLoad 30
|
||||||
#define OP_MemStore 30
|
#define OP_MemStore 31
|
||||||
|
|
||||||
#define OP_ListOpen 31
|
#define OP_ListOpen 32
|
||||||
#define OP_ListWrite 32
|
#define OP_ListWrite 33
|
||||||
#define OP_ListRewind 33
|
#define OP_ListRewind 34
|
||||||
#define OP_ListRead 34
|
#define OP_ListRead 35
|
||||||
#define OP_ListClose 35
|
#define OP_ListClose 36
|
||||||
|
|
||||||
#define OP_SortOpen 36
|
#define OP_SortOpen 37
|
||||||
#define OP_SortPut 37
|
#define OP_SortPut 38
|
||||||
#define OP_SortMakeRec 38
|
#define OP_SortMakeRec 39
|
||||||
#define OP_SortMakeKey 39
|
#define OP_SortMakeKey 40
|
||||||
#define OP_Sort 40
|
#define OP_Sort 41
|
||||||
#define OP_SortNext 41
|
#define OP_SortNext 42
|
||||||
#define OP_SortKey 42
|
#define OP_SortKey 43
|
||||||
#define OP_SortCallback 43
|
#define OP_SortCallback 44
|
||||||
#define OP_SortClose 44
|
#define OP_SortClose 45
|
||||||
|
|
||||||
#define OP_FileOpen 45
|
#define OP_FileOpen 46
|
||||||
#define OP_FileRead 46
|
#define OP_FileRead 47
|
||||||
#define OP_FileColumn 47
|
#define OP_FileColumn 48
|
||||||
#define OP_FileClose 48
|
#define OP_FileClose 49
|
||||||
|
|
||||||
#define OP_AggReset 49
|
#define OP_AggReset 50
|
||||||
#define OP_AggFocus 50
|
#define OP_AggFocus 51
|
||||||
#define OP_AggIncr 51
|
#define OP_AggIncr 52
|
||||||
#define OP_AggNext 52
|
#define OP_AggNext 53
|
||||||
#define OP_AggSet 53
|
#define OP_AggSet 54
|
||||||
#define OP_AggGet 54
|
#define OP_AggGet 55
|
||||||
|
|
||||||
#define OP_SetInsert 55
|
#define OP_SetInsert 56
|
||||||
#define OP_SetFound 56
|
#define OP_SetFound 57
|
||||||
#define OP_SetNotFound 57
|
#define OP_SetNotFound 58
|
||||||
#define OP_SetClear 58
|
#define OP_SetClear 59
|
||||||
|
|
||||||
#define OP_MakeRecord 59
|
#define OP_MakeRecord 60
|
||||||
#define OP_MakeKey 60
|
#define OP_MakeKey 61
|
||||||
#define OP_MakeIdxKey 61
|
#define OP_MakeIdxKey 62
|
||||||
|
|
||||||
#define OP_Goto 62
|
#define OP_Goto 63
|
||||||
#define OP_If 63
|
#define OP_If 64
|
||||||
#define OP_Halt 64
|
#define OP_Halt 65
|
||||||
|
|
||||||
#define OP_ColumnCount 65
|
#define OP_ColumnCount 66
|
||||||
#define OP_ColumnName 66
|
#define OP_ColumnName 67
|
||||||
#define OP_Callback 67
|
#define OP_Callback 68
|
||||||
|
|
||||||
#define OP_Integer 68
|
#define OP_Integer 69
|
||||||
#define OP_String 69
|
#define OP_String 70
|
||||||
#define OP_Null 70
|
#define OP_Null 71
|
||||||
#define OP_Pop 71
|
#define OP_Pop 72
|
||||||
#define OP_Dup 72
|
#define OP_Dup 73
|
||||||
#define OP_Pull 73
|
#define OP_Pull 74
|
||||||
|
|
||||||
#define OP_Add 74
|
#define OP_Add 75
|
||||||
#define OP_AddImm 75
|
#define OP_AddImm 76
|
||||||
#define OP_Subtract 76
|
#define OP_Subtract 77
|
||||||
#define OP_Multiply 77
|
#define OP_Multiply 78
|
||||||
#define OP_Divide 78
|
#define OP_Divide 79
|
||||||
#define OP_Min 79
|
#define OP_Min 80
|
||||||
#define OP_Max 80
|
#define OP_Max 81
|
||||||
#define OP_Like 81
|
#define OP_Like 82
|
||||||
#define OP_Glob 82
|
#define OP_Glob 83
|
||||||
#define OP_Eq 83
|
#define OP_Eq 84
|
||||||
#define OP_Ne 84
|
#define OP_Ne 85
|
||||||
#define OP_Lt 85
|
#define OP_Lt 86
|
||||||
#define OP_Le 86
|
#define OP_Le 87
|
||||||
#define OP_Gt 87
|
#define OP_Gt 88
|
||||||
#define OP_Ge 88
|
#define OP_Ge 89
|
||||||
#define OP_IsNull 89
|
#define OP_IsNull 90
|
||||||
#define OP_NotNull 90
|
#define OP_NotNull 91
|
||||||
#define OP_Negative 91
|
#define OP_Negative 92
|
||||||
#define OP_And 92
|
#define OP_And 93
|
||||||
#define OP_Or 93
|
#define OP_Or 94
|
||||||
#define OP_Not 94
|
#define OP_Not 95
|
||||||
#define OP_Concat 95
|
#define OP_Concat 96
|
||||||
#define OP_Noop 96
|
#define OP_Noop 97
|
||||||
|
|
||||||
#define OP_Strlen 97
|
#define OP_Strlen 98
|
||||||
#define OP_Substr 98
|
#define OP_Substr 99
|
||||||
|
|
||||||
#define OP_MAX 98
|
#define OP_MAX 99
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Prototypes for the VDBE interface. See comments on the implementation
|
** Prototypes for the VDBE interface. See comments on the implementation
|
||||||
|
@@ -22,7 +22,7 @@
|
|||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
# This file runs all tests.
|
# This file runs all tests.
|
||||||
#
|
#
|
||||||
# $Id: all.test,v 1.7 2001/04/12 23:21:59 drh Exp $
|
# $Id: all.test,v 1.8 2001/09/13 21:53:10 drh Exp $
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@@ -35,12 +35,6 @@ if {[file exists ./sqlite_test_count]} {
|
|||||||
set COUNT 3
|
set COUNT 3
|
||||||
}
|
}
|
||||||
|
|
||||||
if {[file exists ./sqlite_test_prefixes]} {
|
|
||||||
set PREFIXES [exec cat ./sqlite_test_prefixes]
|
|
||||||
} else {
|
|
||||||
set PREFIXES {memory: gdbm:}
|
|
||||||
}
|
|
||||||
|
|
||||||
# LeakList will hold a list of the number of unfreed mallocs after
|
# LeakList will hold a list of the number of unfreed mallocs after
|
||||||
# each round of the test. This number should be constant. If it
|
# each round of the test. This number should be constant. If it
|
||||||
# grows, it may mean there is a memory leak in the library.
|
# grows, it may mean there is a memory leak in the library.
|
||||||
@@ -49,14 +43,11 @@ set LeakList {}
|
|||||||
|
|
||||||
|
|
||||||
for {set Counter 0} {$Counter<$COUNT} {incr Counter} {
|
for {set Counter 0} {$Counter<$COUNT} {incr Counter} {
|
||||||
foreach p $PREFIXES {
|
|
||||||
set dbprefix $p
|
|
||||||
foreach testfile [lsort -dictionary [glob $testdir/*.test]] {
|
foreach testfile [lsort -dictionary [glob $testdir/*.test]] {
|
||||||
if {[file tail $testfile]=="all.test"} continue
|
if {[file tail $testfile]=="all.test"} continue
|
||||||
if {[file tail $testfile]=="malloc.test"} continue
|
if {[file tail $testfile]=="malloc.test"} continue
|
||||||
source $testfile
|
source $testfile
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if {[info exists Leak]} {
|
if {[info exists Leak]} {
|
||||||
lappend LeakList $Leak
|
lappend LeakList $Leak
|
||||||
}
|
}
|
||||||
@@ -81,10 +72,7 @@ if {$LeakList!=""} {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if {[file readable $testdir/malloc.test]} {
|
if {[file readable $testdir/malloc.test]} {
|
||||||
foreach p $PREFIXES {
|
|
||||||
set dbprefix $p
|
|
||||||
source $testdir/malloc.test
|
source $testdir/malloc.test
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
really_finish_test
|
really_finish_test
|
||||||
|
140
test/dbbe.test
140
test/dbbe.test
@@ -1,140 +0,0 @@
|
|||||||
# Copyright (c) 1999, 2000 D. Richard Hipp
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or
|
|
||||||
# modify it under the terms of the GNU General Public
|
|
||||||
# License as published by the Free Software Foundation; either
|
|
||||||
# version 2 of the License, or (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
# General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public
|
|
||||||
# License along with this library; if not, write to the
|
|
||||||
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
||||||
# Boston, MA 02111-1307, USA.
|
|
||||||
#
|
|
||||||
# Author contact information:
|
|
||||||
# drh@hwaci.com
|
|
||||||
# http://www.hwaci.com/drh/
|
|
||||||
#
|
|
||||||
#***********************************************************************
|
|
||||||
# This file implements regression tests for SQLite library. The
|
|
||||||
# focus of this file is exercising the code in dbbe.c.
|
|
||||||
#
|
|
||||||
# $Id: dbbe.test,v 1.7 2001/04/03 16:53:22 drh Exp $
|
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
|
||||||
source $testdir/tester.tcl
|
|
||||||
|
|
||||||
# Try to open a database that does not exist.
|
|
||||||
#
|
|
||||||
do_test dbbe-1.1 {
|
|
||||||
catch {db close}
|
|
||||||
forcedelete testdb
|
|
||||||
set v [catch {sqlite db testdb 0444} msg]
|
|
||||||
lappend v $msg
|
|
||||||
} {1 {can't find directory "testdb"}}
|
|
||||||
do_test dbbe-1.2 {
|
|
||||||
catch {db close}
|
|
||||||
forcedelete testdb
|
|
||||||
set v [catch {sqlite db testdb/dummy 0666} msg]
|
|
||||||
lappend v $msg
|
|
||||||
} {1 {can't find or create directory "testdb/dummy"}}
|
|
||||||
|
|
||||||
# Try to open a database for writing in a directory that
|
|
||||||
# doesn't exist but for which the parent directory does
|
|
||||||
# exist. This should work!
|
|
||||||
#
|
|
||||||
do_test dbbe-1.3 {
|
|
||||||
catch {db close}
|
|
||||||
forcedelete testdb
|
|
||||||
set v [catch {sqlite db testdb 0666} msg]
|
|
||||||
lappend v $msg
|
|
||||||
} {0 {}}
|
|
||||||
|
|
||||||
# Try to open a file instead of a directory.
|
|
||||||
#
|
|
||||||
do_test dbbe-1.4 {
|
|
||||||
catch {db close}
|
|
||||||
forcedelete testdb
|
|
||||||
set fd [open testdb w]
|
|
||||||
puts $fd hi!
|
|
||||||
close $fd
|
|
||||||
set v [catch {sqlite db testdb 0666} msg]
|
|
||||||
lappend v $msg
|
|
||||||
} {1 {not a directory: "testdb"}}
|
|
||||||
|
|
||||||
if {$::tcl_platform(platform)!="windows"} {
|
|
||||||
|
|
||||||
# Access permission denied on the directory.
|
|
||||||
#
|
|
||||||
do_test dbbe-1.5 {
|
|
||||||
catch {db close}
|
|
||||||
forcedelete testdb
|
|
||||||
file mkdir testdb
|
|
||||||
file attributes testdb -permissions 0
|
|
||||||
set v [catch {sqlite db testdb 0666} msg]
|
|
||||||
lappend v $msg
|
|
||||||
} {1 {access permission denied}}
|
|
||||||
|
|
||||||
# Access permission denied on the master file
|
|
||||||
#
|
|
||||||
do_test dbbe-1.6 {
|
|
||||||
catch {db close}
|
|
||||||
forcedelete testdb
|
|
||||||
sqlite db testdb 0666
|
|
||||||
execsql {CREATE TABLE t1(x int)}
|
|
||||||
db close
|
|
||||||
file attributes testdb/sqlite_master.tbl -permission 0444
|
|
||||||
set v [catch {sqlite db testdb 0666} msg]
|
|
||||||
lappend v $msg
|
|
||||||
} {1 {access permission denied for testdb/sqlite_master.tbl}}
|
|
||||||
do_test dbbe-1.6b {
|
|
||||||
catch {db close}
|
|
||||||
forcedelete testdb
|
|
||||||
sqlite db testdb 0666
|
|
||||||
execsql {CREATE TABLE t1(x int)}
|
|
||||||
db close
|
|
||||||
file attributes testdb/sqlite_master.tbl -permission 0444
|
|
||||||
set v [catch {sqlite db testdb 0444} msg]
|
|
||||||
lappend v $msg
|
|
||||||
} {0 {}}
|
|
||||||
|
|
||||||
} ;# End of if( platform!=windows )
|
|
||||||
|
|
||||||
# Make sure a table can be accessed by either uppercase or lowercase
|
|
||||||
# names
|
|
||||||
#
|
|
||||||
do_test dbbe-2.1 {
|
|
||||||
catch {db close}
|
|
||||||
forcedelete testdb
|
|
||||||
sqlite db testdb 0666
|
|
||||||
execsql {
|
|
||||||
CREATE TABLE t1(x int);
|
|
||||||
INSERT INTO t1 VALUES(1);
|
|
||||||
}
|
|
||||||
db close
|
|
||||||
sqlite db testdb 0444
|
|
||||||
set r [execsql {SELECT * FROM T1}]
|
|
||||||
db close
|
|
||||||
sqlite db testdb 0666
|
|
||||||
lappend r [execsql {SELECT * FROM t1}]
|
|
||||||
} {1 1}
|
|
||||||
|
|
||||||
# Try to change a table after opening the database readonly
|
|
||||||
#
|
|
||||||
do_test dbbe-3.1 {
|
|
||||||
catch {db close}
|
|
||||||
forcedelete testdb
|
|
||||||
sqlite db testdb 0666
|
|
||||||
execsql {CREATE TABLE t1(x int)}
|
|
||||||
db close
|
|
||||||
sqlite db testdb 0444
|
|
||||||
set v [catch {execsql {INSERT INTO t1 VALUES(1)}} msg]
|
|
||||||
lappend v $msg
|
|
||||||
} {1 {table t1 is readonly}}
|
|
||||||
|
|
||||||
|
|
||||||
finish_test
|
|
@@ -23,7 +23,7 @@
|
|||||||
# This file implements regression tests for SQLite library. The
|
# This file implements regression tests for SQLite library. The
|
||||||
# focus of this file is testing the CREATE INDEX statement.
|
# focus of this file is testing the CREATE INDEX statement.
|
||||||
#
|
#
|
||||||
# $Id: index.test,v 1.10 2001/08/19 18:19:46 drh Exp $
|
# $Id: index.test,v 1.11 2001/09/13 21:53:10 drh Exp $
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@@ -39,17 +39,15 @@ do_test index-1.1b {
|
|||||||
execsql {SELECT name, sql, tbl_name, type FROM sqlite_master
|
execsql {SELECT name, sql, tbl_name, type FROM sqlite_master
|
||||||
WHERE name='index1'}
|
WHERE name='index1'}
|
||||||
} {index1 {CREATE INDEX index1 ON test1(f1)} test1 index}
|
} {index1 {CREATE INDEX index1 ON test1(f1)} test1 index}
|
||||||
skipif memory:
|
|
||||||
do_test index-1.1c {
|
do_test index-1.1c {
|
||||||
db close
|
db close
|
||||||
sqlite db testdb
|
sqlite db test.db
|
||||||
execsql {SELECT name, sql, tbl_name, type FROM sqlite_master
|
execsql {SELECT name, sql, tbl_name, type FROM sqlite_master
|
||||||
WHERE name='index1'}
|
WHERE name='index1'}
|
||||||
} {index1 {CREATE INDEX index1 ON test1(f1)} test1 index}
|
} {index1 {CREATE INDEX index1 ON test1(f1)} test1 index}
|
||||||
skipif memory:
|
|
||||||
do_test index-1.1d {
|
do_test index-1.1d {
|
||||||
db close
|
db close
|
||||||
sqlite db testdb
|
sqlite db test.db
|
||||||
execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
|
execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
|
||||||
} {index1 test1}
|
} {index1 test1}
|
||||||
|
|
||||||
@@ -101,18 +99,6 @@ do_test index-3.1 {
|
|||||||
ORDER BY name}
|
ORDER BY name}
|
||||||
} $r
|
} $r
|
||||||
|
|
||||||
# Add a single entry to the table. Verify that files are created
|
|
||||||
# for every index.
|
|
||||||
#
|
|
||||||
set r {}
|
|
||||||
for {set i 1} {$i<100} {incr i} {
|
|
||||||
lappend r testdb/index$i.tbl
|
|
||||||
}
|
|
||||||
skipif memory:
|
|
||||||
do_test index-3.2 {
|
|
||||||
execsql {INSERT INTO test1 VALUES(1,2,3,4,5)}
|
|
||||||
lsort -dictionary [glob testdb/index*.tbl]
|
|
||||||
} $r
|
|
||||||
|
|
||||||
# Verify that all the indices go away when we drop the table.
|
# Verify that all the indices go away when we drop the table.
|
||||||
#
|
#
|
||||||
@@ -122,9 +108,6 @@ do_test index-3.3 {
|
|||||||
WHERE type='index' AND tbl_name='test1'
|
WHERE type='index' AND tbl_name='test1'
|
||||||
ORDER BY name}
|
ORDER BY name}
|
||||||
} {}
|
} {}
|
||||||
do_test index-3.4 {
|
|
||||||
lsort -dictionary [glob -nocomplain testdb/index*.tbl]
|
|
||||||
} {}
|
|
||||||
|
|
||||||
# Create a table and insert values into that table. Then create
|
# Create a table and insert values into that table. Then create
|
||||||
# an index on that table. Verify that we can select values
|
# an index on that table. Verify that we can select values
|
||||||
@@ -228,10 +211,6 @@ do_test index-7.1 {
|
|||||||
}
|
}
|
||||||
execsql {SELECT count(*) FROM test1}
|
execsql {SELECT count(*) FROM test1}
|
||||||
} {19}
|
} {19}
|
||||||
skipif memory:
|
|
||||||
do_test index-7.1b {
|
|
||||||
lsort -dictionary [glob testdb/test1*.tbl]
|
|
||||||
} {testdb/test1.tbl testdb/test1__primary_key.tbl}
|
|
||||||
do_test index-7.2 {
|
do_test index-7.2 {
|
||||||
execsql {SELECT f1 FROM test1 WHERE f2=65536}
|
execsql {SELECT f1 FROM test1 WHERE f2=65536}
|
||||||
} {16}
|
} {16}
|
||||||
|
@@ -23,7 +23,7 @@
|
|||||||
# This file implements regression tests for SQLite library. The
|
# This file implements regression tests for SQLite library. The
|
||||||
# focus of this file is testing the SELECT statement.
|
# focus of this file is testing the SELECT statement.
|
||||||
#
|
#
|
||||||
# $Id: select2.test,v 1.11 2001/08/19 18:19:46 drh Exp $
|
# $Id: select2.test,v 1.12 2001/09/13 21:53:10 drh Exp $
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@@ -112,7 +112,6 @@ do_test select2-3.2e {
|
|||||||
|
|
||||||
# omit the time-dependent tests
|
# omit the time-dependent tests
|
||||||
#
|
#
|
||||||
testif gdbm:
|
|
||||||
do_probtest select2-3.2f {
|
do_probtest select2-3.2f {
|
||||||
set t1 [lindex [time {execsql {SELECT f1 FROM tbl2 WHERE 1000=f2}} 1] 0]
|
set t1 [lindex [time {execsql {SELECT f1 FROM tbl2 WHERE 1000=f2}} 1] 0]
|
||||||
set t2 [lindex [time {execsql {SELECT f1 FROM tbl2 WHERE f2=1000}} 1] 0]
|
set t2 [lindex [time {execsql {SELECT f1 FROM tbl2 WHERE f2=1000}} 1] 0]
|
||||||
|
@@ -23,7 +23,7 @@
|
|||||||
# This file implements regression tests for SQLite library. The
|
# This file implements regression tests for SQLite library. The
|
||||||
# focus of this file is testing the CREATE TABLE statement.
|
# focus of this file is testing the CREATE TABLE statement.
|
||||||
#
|
#
|
||||||
# $Id: table.test,v 1.9 2001/04/12 23:21:59 drh Exp $
|
# $Id: table.test,v 1.10 2001/09/13 21:53:10 drh Exp $
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@@ -45,15 +45,6 @@ do_test table-1.1 {
|
|||||||
two text
|
two text
|
||||||
)}}
|
)}}
|
||||||
|
|
||||||
# Verify that both table files exists in the database directory
|
|
||||||
#
|
|
||||||
do_test table-1.2 {
|
|
||||||
execsql {INSERT INTO test1 VALUES('hi', 'y''all')}
|
|
||||||
} {}
|
|
||||||
testif gdbm:
|
|
||||||
do_test table-1.2b {
|
|
||||||
lsort [glob -nocomplain testdb/*.tbl]
|
|
||||||
} {testdb/sqlite_master.tbl testdb/test1.tbl}
|
|
||||||
|
|
||||||
# Verify the other fields of the sqlite_master file.
|
# Verify the other fields of the sqlite_master file.
|
||||||
#
|
#
|
||||||
@@ -64,7 +55,6 @@ do_test table-1.3 {
|
|||||||
# Close and reopen the database. Verify that everything is
|
# Close and reopen the database. Verify that everything is
|
||||||
# still the same.
|
# still the same.
|
||||||
#
|
#
|
||||||
skipif memory:
|
|
||||||
do_test table-1.4 {
|
do_test table-1.4 {
|
||||||
db close
|
db close
|
||||||
sqlite db testdb
|
sqlite db testdb
|
||||||
@@ -80,7 +70,6 @@ do_test table-1.5 {
|
|||||||
|
|
||||||
# Verify that the file associated with the database is gone.
|
# Verify that the file associated with the database is gone.
|
||||||
#
|
#
|
||||||
testif gdbm:
|
|
||||||
do_test table-1.5 {
|
do_test table-1.5 {
|
||||||
lsort [glob -nocomplain testdb/*.tbl]
|
lsort [glob -nocomplain testdb/*.tbl]
|
||||||
} {testdb/sqlite_master.tbl}
|
} {testdb/sqlite_master.tbl}
|
||||||
@@ -88,7 +77,6 @@ do_test table-1.5 {
|
|||||||
# Close and reopen the database. Verify that the table is
|
# Close and reopen the database. Verify that the table is
|
||||||
# still gone.
|
# still gone.
|
||||||
#
|
#
|
||||||
skipif memory:
|
|
||||||
do_test table-1.6 {
|
do_test table-1.6 {
|
||||||
db close
|
db close
|
||||||
sqlite db testdb
|
sqlite db testdb
|
||||||
@@ -127,7 +115,6 @@ do_test table-2.1b {
|
|||||||
set v [catch {execsql {CREATE TABLE sqlite_master(two text)}} msg]
|
set v [catch {execsql {CREATE TABLE sqlite_master(two text)}} msg]
|
||||||
lappend v $msg
|
lappend v $msg
|
||||||
} {1 {table sqlite_master already exists}}
|
} {1 {table sqlite_master already exists}}
|
||||||
skipif memory:
|
|
||||||
do_test table-2.1c {
|
do_test table-2.1c {
|
||||||
db close
|
db close
|
||||||
sqlite db testdb
|
sqlite db testdb
|
||||||
@@ -145,7 +132,6 @@ do_test table-2.2a {
|
|||||||
set v [catch {execsql {CREATE TABLE test3(two text)}} msg]
|
set v [catch {execsql {CREATE TABLE test3(two text)}} msg]
|
||||||
lappend v $msg
|
lappend v $msg
|
||||||
} {1 {there is already an index named test3}}
|
} {1 {there is already an index named test3}}
|
||||||
skipif memory:
|
|
||||||
do_test table-2.2b {
|
do_test table-2.2b {
|
||||||
db close
|
db close
|
||||||
sqlite db testdb
|
sqlite db testdb
|
||||||
@@ -206,7 +192,6 @@ do_test table-3.4 {
|
|||||||
set v [catch {execsql {CREATE TABLE bIg(xyz foo)}} msg]
|
set v [catch {execsql {CREATE TABLE bIg(xyz foo)}} msg]
|
||||||
lappend v $msg
|
lappend v $msg
|
||||||
} {1 {table bIg already exists}}
|
} {1 {table bIg already exists}}
|
||||||
skipif memory:
|
|
||||||
do_test table-3.5 {
|
do_test table-3.5 {
|
||||||
db close
|
db close
|
||||||
sqlite db testdb
|
sqlite db testdb
|
||||||
@@ -235,7 +220,6 @@ do_test table-4.1 {
|
|||||||
}
|
}
|
||||||
execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
|
execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
|
||||||
} $r
|
} $r
|
||||||
skipif memory:
|
|
||||||
do_test table-4.1b {
|
do_test table-4.1b {
|
||||||
db close
|
db close
|
||||||
sqlite db testdb
|
sqlite db testdb
|
||||||
@@ -297,7 +281,6 @@ do_test table-5.4 {
|
|||||||
|
|
||||||
# Create a table with a goofy name
|
# Create a table with a goofy name
|
||||||
#
|
#
|
||||||
testif gdbm:
|
|
||||||
do_test table-6.1 {
|
do_test table-6.1 {
|
||||||
execsql {CREATE TABLE 'Spaces In This Name!'(x int)}
|
execsql {CREATE TABLE 'Spaces In This Name!'(x int)}
|
||||||
execsql {INSERT INTO 'spaces in this name!' VALUES(1)}
|
execsql {INSERT INTO 'spaces in this name!' VALUES(1)}
|
||||||
|
@@ -23,7 +23,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.15 2001/04/11 14:28:43 drh Exp $
|
# $Id: tester.tcl,v 1.16 2001/09/13 21:53:10 drh Exp $
|
||||||
|
|
||||||
# Make sure tclsqlite was compiled correctly. Abort now with an
|
# Make sure tclsqlite was compiled correctly. Abort now with an
|
||||||
# error message if not.
|
# error message if not.
|
||||||
@@ -54,28 +54,9 @@ if {[sqlite -tcl-uses-utf]} {
|
|||||||
|
|
||||||
# Create a test database
|
# Create a test database
|
||||||
#
|
#
|
||||||
if {![info exists dbprefix]} {
|
file delete -force ./test.db
|
||||||
if {[info exists env(SQLITE_PREFIX)]} {
|
file delete -force ./test.db-journal
|
||||||
set dbprefix $env(SQLITE_PREFIX):
|
sqlite db ./test.db
|
||||||
} else {
|
|
||||||
set dbprefix "gdbm:"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
switch $dbprefix {
|
|
||||||
gdbm: {
|
|
||||||
foreach f [glob -nocomplain testdb/*] {
|
|
||||||
catch {file delete -force $f}
|
|
||||||
}
|
|
||||||
if {[catch {file delete -force testdb}]} {
|
|
||||||
exec rm -rf testdb
|
|
||||||
}
|
|
||||||
file mkdir testdb
|
|
||||||
}
|
|
||||||
memory: {
|
|
||||||
# do nothing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sqlite db ${dbprefix}testdb
|
|
||||||
|
|
||||||
# Abort early if this script has been run before.
|
# Abort early if this script has been run before.
|
||||||
#
|
#
|
||||||
@@ -109,14 +90,16 @@ proc do_test {name cmd expected} {
|
|||||||
}
|
}
|
||||||
if {!$go} return
|
if {!$go} return
|
||||||
incr nTest
|
incr nTest
|
||||||
puts -nonewline $::dbprefix$name...
|
puts -nonewline $name...
|
||||||
flush stdout
|
flush stdout
|
||||||
if {[catch {uplevel #0 "$cmd;\n"} result]} {
|
if {[catch {uplevel #0 "$cmd;\n"} result]} {
|
||||||
puts "\nError: $result"
|
puts "\nError: $result"
|
||||||
incr nErr
|
incr nErr
|
||||||
|
if {$nErr>10} {puts "*** Giving up..."; exit 1}
|
||||||
} elseif {[string compare $result $expected]} {
|
} elseif {[string compare $result $expected]} {
|
||||||
puts "\nExpected: \[$expected\]\n Got: \[$result\]"
|
puts "\nExpected: \[$expected\]\n Got: \[$result\]"
|
||||||
incr nErr
|
incr nErr
|
||||||
|
if {$nErr>10} {puts "*** Giving up..."; exit 1}
|
||||||
} else {
|
} else {
|
||||||
puts " Ok"
|
puts " Ok"
|
||||||
}
|
}
|
||||||
@@ -144,7 +127,7 @@ proc do_probtest {name cmd expected} {
|
|||||||
}
|
}
|
||||||
if {!$go} return
|
if {!$go} return
|
||||||
incr nTest
|
incr nTest
|
||||||
puts -nonewline $::dbprefix$name...
|
puts -nonewline $name...
|
||||||
flush stdout
|
flush stdout
|
||||||
if {[catch {uplevel #0 "$cmd;\n"} result]} {
|
if {[catch {uplevel #0 "$cmd;\n"} result]} {
|
||||||
puts "\nError: $result"
|
puts "\nError: $result"
|
||||||
@@ -160,29 +143,6 @@ proc do_probtest {name cmd expected} {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Skip a test based on the dbprefix
|
|
||||||
#
|
|
||||||
proc skipif {args} {
|
|
||||||
foreach a $args {
|
|
||||||
if {$::dbprefix==$a} {
|
|
||||||
set ::skip_test 1
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Run the next test only if the dbprefix is among the listed arguments
|
|
||||||
#
|
|
||||||
proc testif {args} {
|
|
||||||
foreach a $args {
|
|
||||||
if {$::dbprefix==$a} {
|
|
||||||
set ::skip_test 0
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
set ::skip_test 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# The procedure uses the special "sqlite_malloc_stat" command
|
# The procedure uses the special "sqlite_malloc_stat" command
|
||||||
# (which is only available if SQLite is compiled with -DMEMORY_DEBUG=1)
|
# (which is only available if SQLite is compiled with -DMEMORY_DEBUG=1)
|
||||||
# to see how many malloc()s have not been free()ed. The number
|
# to see how many malloc()s have not been free()ed. The number
|
||||||
|
@@ -23,7 +23,7 @@
|
|||||||
# This file implements regression tests for SQLite library. The
|
# This file implements regression tests for SQLite library. The
|
||||||
# focus of this file is testing the VACUUM statement.
|
# focus of this file is testing the VACUUM statement.
|
||||||
#
|
#
|
||||||
# $Id: vacuum.test,v 1.3 2001/03/20 12:55:14 drh Exp $
|
# $Id: vacuum.test,v 1.4 2001/09/13 21:53:10 drh Exp $
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@@ -53,7 +53,6 @@ execsql {INSERT INTO test1 VALUES(2)}
|
|||||||
execsql {INSERT INTO test1 VALUES(3)}
|
execsql {INSERT INTO test1 VALUES(3)}
|
||||||
execsql {INSERT INTO test2 VALUES(4)}
|
execsql {INSERT INTO test2 VALUES(4)}
|
||||||
|
|
||||||
testif gdbm:
|
|
||||||
do_test vacuum-1.3 {
|
do_test vacuum-1.3 {
|
||||||
set b1 [file mtime testdb/test1.tbl]
|
set b1 [file mtime testdb/test1.tbl]
|
||||||
set b2 [file mtime testdb/test2.tbl]
|
set b2 [file mtime testdb/test2.tbl]
|
||||||
@@ -66,7 +65,6 @@ do_test vacuum-1.3 {
|
|||||||
expr {$a1>$b1 && $a2==$b2 && $a3==$b3}
|
expr {$a1>$b1 && $a2==$b2 && $a3==$b3}
|
||||||
} {1}
|
} {1}
|
||||||
if {$::tcl_platform(platform)!="windows"} {
|
if {$::tcl_platform(platform)!="windows"} {
|
||||||
testif gdbm:
|
|
||||||
do_test vacuum-1.4 {
|
do_test vacuum-1.4 {
|
||||||
set b1 [file mtime testdb/test1.tbl]
|
set b1 [file mtime testdb/test1.tbl]
|
||||||
set b2 [file mtime testdb/test2.tbl]
|
set b2 [file mtime testdb/test2.tbl]
|
||||||
|
Reference in New Issue
Block a user