Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e3bf194c0e |
@@ -1,5 +1,5 @@
|
||||
C Merge\supdates\sfrom\strunk.
|
||||
D 2015-04-16T04:20:10.533
|
||||
C Add\sthe\sBtCursor.pPage\sfield\swhich\sis\sthe\scurrent\spage\sto\swhich\sthe\scursor\npoints,\sfor\sa\svery\ssmall\sperformance\sgain.
|
||||
D 2015-04-15T19:13:26.759
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in 5f78b1ab81b64e7c57a75d170832443e66c0880a
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@@ -173,9 +173,9 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
|
||||
F src/backup.c ff743689c4d6c5cb55ad42ed9d174b2b3e71f1e3
|
||||
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
|
||||
F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79
|
||||
F src/btree.c c6e32d84442f79d5b96965265d65b3baa231dffc
|
||||
F src/btree.c 485e357f2409b1d23f21e542190764ea707d567f
|
||||
F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1
|
||||
F src/btreeInt.h 973a22a6fd61350b454ad614832b1f0a5e25a1e4
|
||||
F src/btreeInt.h 3c791196f75a737b234aee7ba36b37160373fc18
|
||||
F src/build.c 01b969b20a44a3d9620e597d9af8242348123540
|
||||
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
|
||||
F src/complete.c a5cf5b4b56390cfb7b8636e8f7ddef90258dd575
|
||||
@@ -225,13 +225,13 @@ F src/pcache.h b44658c9c932d203510279439d891a2a83e12ba8
|
||||
F src/pcache1.c 69d137620a305f814398bd29a0c998038c0695e9
|
||||
F src/pragma.c 3965ae4e82bed39fb97ce04c5fe18c9bc3ee6a88
|
||||
F src/pragma.h 09c89bca58e9a44de2116cc8272b8d454657129f
|
||||
F src/prepare.c 1fffbdcd6f8a0173a8f70d71f22528f4c0e1e3d3
|
||||
F src/prepare.c 173a5a499138451b2561614ecb87d78f9f4644b9
|
||||
F src/printf.c 08fa675c200aac29e561c6153f91f909ed17612f
|
||||
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
|
||||
F src/resolve.c 66cfe49a9c3b449ef13b89a8c47036a4ed167eab
|
||||
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
|
||||
F src/select.c 93260bc9e7e0e6dfe1b7cb8815b0ed4cad8be9e3
|
||||
F src/shell.c 04706b14b737229cfba359cc1f46dd03b53a59be
|
||||
F src/shell.c 84a1593bd86aaa14f4da8a8f9b16fbc239d262aa
|
||||
F src/sqlite.h.in ca27603a36fcacdaac5a19d8ee35aaff8ce8516f
|
||||
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
|
||||
F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
|
||||
@@ -320,7 +320,7 @@ F test/alter3.test 49c9d9fba2b8fcdce2dedeca97bbf1f369cc548d
|
||||
F test/alter4.test c461150723ac957f3b2214aa0b11552cd72023ec
|
||||
F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc
|
||||
F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f
|
||||
F test/analyze.test 3eb35a4af972f98422e5dc0586501b17d103d321
|
||||
F test/analyze.test 1772936d66471c65221e437b6d1999c3a03166c4
|
||||
F test/analyze3.test 75b9e42ea1e4edc919250450dc5762186965d4e6
|
||||
F test/analyze4.test eff2df19b8dd84529966420f29ea52edc6b56213
|
||||
F test/analyze5.test 765c4e284aa69ca172772aa940946f55629bc8c4
|
||||
@@ -655,7 +655,7 @@ F test/incrvacuum3.test 75256fb1377e7c39ef2de62bfc42bbff67be295a
|
||||
F test/incrvacuum_ioerr.test 6ae2f783424e47a0033304808fe27789cf93e635
|
||||
F test/index.test 4d990005a67a36984e4f1a5f1bdccea8d08da4ee
|
||||
F test/index2.test ee83c6b5e3173a3d7137140d945d9a5d4fdfb9d6
|
||||
F test/index3.test b6ec456cf3b81d9a32123fe7e449bde434db338b
|
||||
F test/index3.test 55a90cff99834305e8141df7afaef39674b57062
|
||||
F test/index4.test ab92e736d5946840236cd61ac3191f91a7856bf6
|
||||
F test/index5.test 25b0b451aceed4ac5f7d49f856f6de7257470b3e
|
||||
F test/index6.test 3ae54e53c53f2adcacda269237d8e52bdb05a481
|
||||
@@ -865,7 +865,7 @@ F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5
|
||||
F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e
|
||||
F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506
|
||||
F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
|
||||
F test/shell1.test ce5e744870387164703bf2dee2cc9753e4a71513
|
||||
F test/shell1.test ca88b14a8fc8b1f3543a24e519d019585ac9c903
|
||||
F test/shell2.test 12b8bf901b0e3a8ac58cf5c0c63a0a388d4d1862
|
||||
F test/shell3.test 5e8545ec72c4413a0e8d4c6be56496e3c257ca29
|
||||
F test/shell4.test ddf0a99044e2245a87fc17423e3aaa1445b3243b
|
||||
@@ -915,7 +915,7 @@ F test/tclsqlite.test 7fb866443c7deceed22b63948ccd6f76b52ad054
|
||||
F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c
|
||||
F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
|
||||
F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1
|
||||
F test/tester.tcl 51211254f2ee2340d3e4fa0a83bd5381b9e1a227
|
||||
F test/tester.tcl ed77454e6c7b40eb501db7e79d1c6fbfd3eebbff
|
||||
F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5
|
||||
F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58
|
||||
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
|
||||
@@ -1082,7 +1082,7 @@ F test/trigger3.test aa640bb2bbb03edd5ff69c055117ea088f121945
|
||||
F test/trigger4.test 74700b76ebf3947b2f7a92405141eb2cf2a5d359
|
||||
F test/trigger5.test 619391a3e9fc194081d22cefd830d811e7badf83
|
||||
F test/trigger6.test 0e411654f122552da6590f0b4e6f781048a4a9b9
|
||||
F test/trigger7.test 200dd51e728c9cdc20c72d99d9e9d45c667248f8
|
||||
F test/trigger7.test b39e6dee1debe0ff9c2ef66326668f149f07c9c4
|
||||
F test/trigger8.test 30cb0530bd7c4728055420e3f739aa00412eafa4
|
||||
F test/trigger9.test 2226ec795a33b0460ab5cf8891e9054cc7edef41
|
||||
F test/triggerA.test fe5597f47ee21bacb4936dc827994ed94161e332
|
||||
@@ -1250,7 +1250,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P c458db41bbb6bd13d47531685e25a09f512c7f5f d3c00d61581c8ba6dce5618391432d3af8d324d4
|
||||
R 2c042385d701fe541a26946cba425218
|
||||
U mistachkin
|
||||
Z e84ee44408bcf2cec5bcea635dbd30f2
|
||||
P f71053cf658b3260a32ac06f8ba5c2cde0ea54dd
|
||||
R a88b52422fda2f2ea905aaa2e3a17ff4
|
||||
T *branch * btree-current-page-cache
|
||||
T *sym-btree-current-page-cache *
|
||||
T -sym-trunk *
|
||||
U drh
|
||||
Z 4cafb2843490ebe751738bc5633d8f3a
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
22827542a5c7aeac4385ba647f45bd500e787fe6
|
||||
a200e1eae9a1350ed2aed9bfe70042fec05dd98b
|
||||
+82
-49
@@ -587,6 +587,7 @@ static void btreeReleaseAllCursorPages(BtCursor *pCur){
|
||||
pCur->apPage[i] = 0;
|
||||
}
|
||||
pCur->iPage = -1;
|
||||
pCur->pPage = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -3651,6 +3652,7 @@ int sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode, int writeOnly){
|
||||
releasePage(p->apPage[i]);
|
||||
p->apPage[i] = 0;
|
||||
}
|
||||
p->pPage = 0;
|
||||
}
|
||||
sqlite3BtreeLeave(pBtree);
|
||||
}
|
||||
@@ -3865,6 +3867,7 @@ static int btreeCursor(
|
||||
** variables and link the cursor into the BtShared list. */
|
||||
pCur->pgnoRoot = (Pgno)iTable;
|
||||
pCur->iPage = -1;
|
||||
pCur->pPage = 0;
|
||||
pCur->pKeyInfo = pKeyInfo;
|
||||
pCur->pBtree = p;
|
||||
pCur->pBt = pBt;
|
||||
@@ -3966,7 +3969,8 @@ int sqlite3BtreeCloseCursor(BtCursor *pCur){
|
||||
CellInfo info;
|
||||
int iPage = pCur->iPage;
|
||||
memset(&info, 0, sizeof(info));
|
||||
btreeParseCell(pCur->apPage[iPage], pCur->aiIdx[iPage], &info);
|
||||
assert( pCur->pPage==pCur->apPage[iPage] );
|
||||
btreeParseCell(pCur->pPage, pCur->aiIdx[iPage], &info);
|
||||
assert( CORRUPT_DB || memcmp(&info, &pCur->info, sizeof(info))==0 );
|
||||
}
|
||||
#else
|
||||
@@ -3977,7 +3981,8 @@ int sqlite3BtreeCloseCursor(BtCursor *pCur){
|
||||
static void getCellInfo(BtCursor *pCur){
|
||||
if( pCur->info.nSize==0 ){
|
||||
int iPage = pCur->iPage;
|
||||
btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info);
|
||||
assert( pCur->pPage==pCur->apPage[iPage] );
|
||||
btreeParseCell(pCur->pPage,pCur->aiIdx[iPage],&pCur->info);
|
||||
pCur->curFlags |= BTCF_ValidNKey;
|
||||
}else{
|
||||
assertCellInfo(pCur);
|
||||
@@ -3988,7 +3993,8 @@ int sqlite3BtreeCloseCursor(BtCursor *pCur){
|
||||
#define getCellInfo(pCur) \
|
||||
if( pCur->info.nSize==0 ){ \
|
||||
int iPage = pCur->iPage; \
|
||||
btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info); \
|
||||
assert( pCur->pPage==pCur->apPage[iPage] ); \
|
||||
btreeParseCell(pCur->pPage,pCur->aiIdx[iPage],&pCur->info); \
|
||||
pCur->curFlags |= BTCF_ValidNKey; \
|
||||
}else{ \
|
||||
assertCellInfo(pCur); \
|
||||
@@ -4043,7 +4049,8 @@ int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
|
||||
assert( pCur->eState==CURSOR_VALID );
|
||||
assert( pCur->iPage>=0 );
|
||||
assert( pCur->iPage<BTCURSOR_MAX_DEPTH );
|
||||
assert( pCur->apPage[pCur->iPage]->intKeyLeaf==1 );
|
||||
assert( pCur->pPage==pCur->apPage[pCur->iPage] );
|
||||
assert( pCur->pPage->intKeyLeaf==1 );
|
||||
getCellInfo(pCur);
|
||||
*pSize = pCur->info.nPayload;
|
||||
return SQLITE_OK;
|
||||
@@ -4197,14 +4204,15 @@ static int accessPayload(
|
||||
unsigned char *aPayload;
|
||||
int rc = SQLITE_OK;
|
||||
int iIdx = 0;
|
||||
MemPage *pPage = pCur->apPage[pCur->iPage]; /* Btree page of current entry */
|
||||
BtShared *pBt = pCur->pBt; /* Btree this cursor belongs to */
|
||||
MemPage *pPage = pCur->pPage; /* Btree page of current entry */
|
||||
BtShared *pBt = pCur->pBt; /* Btree this cursor belongs to */
|
||||
#ifdef SQLITE_DIRECT_OVERFLOW_READ
|
||||
unsigned char * const pBufStart = pBuf;
|
||||
int bEnd; /* True if reading to end of data */
|
||||
#endif
|
||||
|
||||
assert( pPage );
|
||||
assert( pPage==pCur->apPage[pCur->iPage] );
|
||||
assert( pCur->eState==CURSOR_VALID );
|
||||
assert( pCur->aiIdx[pCur->iPage]<pPage->nCell );
|
||||
assert( cursorHoldsMutex(pCur) );
|
||||
@@ -4394,8 +4402,10 @@ static int accessPayload(
|
||||
int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
|
||||
assert( cursorHoldsMutex(pCur) );
|
||||
assert( pCur->eState==CURSOR_VALID );
|
||||
assert( pCur->iPage>=0 && pCur->apPage[pCur->iPage] );
|
||||
assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
|
||||
assert( pCur->iPage>=0 );
|
||||
assert( pCur->apPage[pCur->iPage]==pCur->pPage );
|
||||
assert( pCur->pPage!=0 );
|
||||
assert( pCur->aiIdx[pCur->iPage]<pCur->pPage->nCell );
|
||||
return accessPayload(pCur, offset, amt, (unsigned char*)pBuf, 0);
|
||||
}
|
||||
|
||||
@@ -4421,8 +4431,10 @@ int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
|
||||
rc = restoreCursorPosition(pCur);
|
||||
if( rc==SQLITE_OK ){
|
||||
assert( pCur->eState==CURSOR_VALID );
|
||||
assert( pCur->iPage>=0 && pCur->apPage[pCur->iPage] );
|
||||
assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
|
||||
assert( pCur->iPage>=0 );
|
||||
assert( pCur->apPage[pCur->iPage]==pCur->pPage );
|
||||
assert( pCur->pPage!=0 );
|
||||
assert( pCur->aiIdx[pCur->iPage]<pCur->pPage->nCell );
|
||||
rc = accessPayload(pCur, offset, amt, pBuf, 0);
|
||||
}
|
||||
return rc;
|
||||
@@ -4452,15 +4464,18 @@ static const void *fetchPayload(
|
||||
u32 *pAmt /* Write the number of available bytes here */
|
||||
){
|
||||
u32 amt;
|
||||
assert( pCur!=0 && pCur->iPage>=0 && pCur->apPage[pCur->iPage]);
|
||||
assert( pCur!=0 );
|
||||
assert( pCur->iPage>=0 );
|
||||
assert( pCur->apPage[pCur->iPage]==pCur->pPage );
|
||||
assert( pCur->pPage!=0 );
|
||||
assert( pCur->eState==CURSOR_VALID );
|
||||
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
|
||||
assert( cursorHoldsMutex(pCur) );
|
||||
assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
|
||||
assert( pCur->aiIdx[pCur->iPage]<pCur->pPage->nCell );
|
||||
assert( pCur->info.nSize>0 );
|
||||
assert( pCur->info.pPayload>pCur->apPage[pCur->iPage]->aData || CORRUPT_DB );
|
||||
assert( pCur->info.pPayload<pCur->apPage[pCur->iPage]->aDataEnd ||CORRUPT_DB);
|
||||
amt = (int)(pCur->apPage[pCur->iPage]->aDataEnd - pCur->info.pPayload);
|
||||
assert( pCur->info.pPayload>pCur->pPage->aData || CORRUPT_DB );
|
||||
assert( pCur->info.pPayload<pCur->pPage->aDataEnd || CORRUPT_DB );
|
||||
amt = (int)(pCur->pPage->aDataEnd - pCur->info.pPayload);
|
||||
if( pCur->info.nLocal<amt ) amt = pCur->info.nLocal;
|
||||
*pAmt = amt;
|
||||
return (void*)pCur->info.pPayload;
|
||||
@@ -4514,7 +4529,7 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){
|
||||
rc = getAndInitPage(pBt, newPgno, &pNewPage,
|
||||
(pCur->curFlags & BTCF_WriteFlag)==0 ? PAGER_GET_READONLY : 0);
|
||||
if( rc ) return rc;
|
||||
pCur->apPage[i+1] = pNewPage;
|
||||
pCur->apPage[i+1] = pCur->pPage = pNewPage;
|
||||
pCur->aiIdx[i+1] = 0;
|
||||
pCur->iPage++;
|
||||
|
||||
@@ -4560,16 +4575,18 @@ static void moveToParent(BtCursor *pCur){
|
||||
assert( cursorHoldsMutex(pCur) );
|
||||
assert( pCur->eState==CURSOR_VALID );
|
||||
assert( pCur->iPage>0 );
|
||||
assert( pCur->apPage[pCur->iPage] );
|
||||
assert( pCur->pPage==pCur->apPage[pCur->iPage] );
|
||||
assert( pCur->pPage!=0 );
|
||||
assertParentIndex(
|
||||
pCur->apPage[pCur->iPage-1],
|
||||
pCur->aiIdx[pCur->iPage-1],
|
||||
pCur->apPage[pCur->iPage]->pgno
|
||||
pCur->pPage->pgno
|
||||
);
|
||||
testcase( pCur->aiIdx[pCur->iPage-1] > pCur->apPage[pCur->iPage-1]->nCell );
|
||||
|
||||
releasePage(pCur->apPage[pCur->iPage]);
|
||||
releasePage(pCur->pPage);
|
||||
pCur->iPage--;
|
||||
pCur->pPage = pCur->apPage[pCur->iPage];
|
||||
pCur->info.nSize = 0;
|
||||
pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
|
||||
}
|
||||
@@ -4625,7 +4642,8 @@ static int moveToRoot(BtCursor *pCur){
|
||||
}
|
||||
pCur->iPage = 0;
|
||||
}
|
||||
pRoot = pCur->apPage[0];
|
||||
assert( pCur->iPage==0 );
|
||||
pRoot = pCur->pPage = pCur->apPage[0];
|
||||
assert( pRoot->pgno==pCur->pgnoRoot );
|
||||
|
||||
/* If pCur->pKeyInfo is not NULL, then the caller that opened this cursor
|
||||
@@ -4675,7 +4693,7 @@ static int moveToLeftmost(BtCursor *pCur){
|
||||
|
||||
assert( cursorHoldsMutex(pCur) );
|
||||
assert( pCur->eState==CURSOR_VALID );
|
||||
while( rc==SQLITE_OK && !(pPage = pCur->apPage[pCur->iPage])->leaf ){
|
||||
while( rc==SQLITE_OK && !(pPage = pCur->pPage)->leaf ){
|
||||
assert( pCur->aiIdx[pCur->iPage]<pPage->nCell );
|
||||
pgno = get4byte(findCell(pPage, pCur->aiIdx[pCur->iPage]));
|
||||
rc = moveToChild(pCur, pgno);
|
||||
@@ -4700,7 +4718,7 @@ static int moveToRightmost(BtCursor *pCur){
|
||||
|
||||
assert( cursorHoldsMutex(pCur) );
|
||||
assert( pCur->eState==CURSOR_VALID );
|
||||
while( !(pPage = pCur->apPage[pCur->iPage])->leaf ){
|
||||
while( !(pPage = pCur->pPage)->leaf ){
|
||||
pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
|
||||
pCur->aiIdx[pCur->iPage] = pPage->nCell;
|
||||
rc = moveToChild(pCur, pgno);
|
||||
@@ -4723,11 +4741,12 @@ int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){
|
||||
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
|
||||
rc = moveToRoot(pCur);
|
||||
if( rc==SQLITE_OK ){
|
||||
assert( pCur->pPage==pCur->apPage[pCur->iPage] );
|
||||
if( pCur->eState==CURSOR_INVALID ){
|
||||
assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 );
|
||||
assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 );
|
||||
*pRes = 1;
|
||||
}else{
|
||||
assert( pCur->apPage[pCur->iPage]->nCell>0 );
|
||||
assert( pCur->pPage->nCell>0 );
|
||||
*pRes = 0;
|
||||
rc = moveToLeftmost(pCur);
|
||||
}
|
||||
@@ -4754,8 +4773,9 @@ int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
|
||||
for(ii=0; ii<pCur->iPage; ii++){
|
||||
assert( pCur->aiIdx[ii]==pCur->apPage[ii]->nCell );
|
||||
}
|
||||
assert( pCur->aiIdx[pCur->iPage]==pCur->apPage[pCur->iPage]->nCell-1 );
|
||||
assert( pCur->apPage[pCur->iPage]->leaf );
|
||||
assert( pCur->pPage==pCur->apPage[pCur->iPage] );
|
||||
assert( pCur->aiIdx[pCur->iPage]==pCur->pPage->nCell-1 );
|
||||
assert( pCur->pPage->leaf );
|
||||
#endif
|
||||
return SQLITE_OK;
|
||||
}
|
||||
@@ -4853,19 +4873,20 @@ int sqlite3BtreeMovetoUnpacked(
|
||||
if( rc ){
|
||||
return rc;
|
||||
}
|
||||
assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage] );
|
||||
assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->isInit );
|
||||
assert( pCur->eState==CURSOR_INVALID || pCur->apPage[pCur->iPage]->nCell>0 );
|
||||
assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]==pCur->pPage );
|
||||
assert( pCur->pgnoRoot==0 || pCur->pPage!=0 );
|
||||
assert( pCur->pgnoRoot==0 || pCur->pPage->isInit );
|
||||
assert( pCur->eState==CURSOR_INVALID || pCur->pPage->nCell>0 );
|
||||
if( pCur->eState==CURSOR_INVALID ){
|
||||
*pRes = -1;
|
||||
assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 );
|
||||
assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 );
|
||||
return SQLITE_OK;
|
||||
}
|
||||
assert( pCur->apPage[0]->intKey || pIdxKey );
|
||||
assert( pCur->pPage->intKey || pIdxKey );
|
||||
for(;;){
|
||||
int lwr, upr, idx, c;
|
||||
Pgno chldPg;
|
||||
MemPage *pPage = pCur->apPage[pCur->iPage];
|
||||
MemPage *pPage = pCur->pPage;
|
||||
u8 *pCell; /* Pointer to current cell in pPage */
|
||||
|
||||
/* pPage->nCell must be greater than zero. If this is the root-page
|
||||
@@ -4988,7 +5009,7 @@ int sqlite3BtreeMovetoUnpacked(
|
||||
assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) );
|
||||
assert( pPage->isInit );
|
||||
if( pPage->leaf ){
|
||||
assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
|
||||
assert( pCur->aiIdx[pCur->iPage]<pCur->pPage->nCell );
|
||||
pCur->aiIdx[pCur->iPage] = (u16)idx;
|
||||
*pRes = c;
|
||||
rc = SQLITE_OK;
|
||||
@@ -5076,7 +5097,7 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur, int *pRes){
|
||||
}
|
||||
}
|
||||
|
||||
pPage = pCur->apPage[pCur->iPage];
|
||||
pPage = pCur->pPage;
|
||||
idx = ++pCur->aiIdx[pCur->iPage];
|
||||
assert( pPage->isInit );
|
||||
|
||||
@@ -5100,7 +5121,7 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur, int *pRes){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
moveToParent(pCur);
|
||||
pPage = pCur->apPage[pCur->iPage];
|
||||
pPage = pCur->pPage;
|
||||
}while( pCur->aiIdx[pCur->iPage]>=pPage->nCell );
|
||||
if( pPage->intKey ){
|
||||
return sqlite3BtreeNext(pCur, pRes);
|
||||
@@ -5124,7 +5145,7 @@ int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
|
||||
pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
|
||||
*pRes = 0;
|
||||
if( pCur->eState!=CURSOR_VALID ) return btreeNext(pCur, pRes);
|
||||
pPage = pCur->apPage[pCur->iPage];
|
||||
pPage = pCur->pPage;
|
||||
if( (++pCur->aiIdx[pCur->iPage])>=pPage->nCell ){
|
||||
pCur->aiIdx[pCur->iPage]--;
|
||||
return btreeNext(pCur, pRes);
|
||||
@@ -5187,7 +5208,8 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur, int *pRes){
|
||||
}
|
||||
}
|
||||
|
||||
pPage = pCur->apPage[pCur->iPage];
|
||||
pPage = pCur->pPage;
|
||||
assert( pPage==pCur->apPage[pCur->iPage] );
|
||||
assert( pPage->isInit );
|
||||
if( !pPage->leaf ){
|
||||
int idx = pCur->aiIdx[pCur->iPage];
|
||||
@@ -5207,7 +5229,8 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur, int *pRes){
|
||||
assert( (pCur->curFlags & (BTCF_ValidNKey|BTCF_ValidOvfl))==0 );
|
||||
|
||||
pCur->aiIdx[pCur->iPage]--;
|
||||
pPage = pCur->apPage[pCur->iPage];
|
||||
assert( pCur->apPage[pCur->iPage]==pCur->pPage );
|
||||
pPage = pCur->pPage;
|
||||
if( pPage->intKey && !pPage->leaf ){
|
||||
rc = sqlite3BtreePrevious(pCur, pRes);
|
||||
}else{
|
||||
@@ -5226,7 +5249,7 @@ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
|
||||
pCur->info.nSize = 0;
|
||||
if( pCur->eState!=CURSOR_VALID
|
||||
|| pCur->aiIdx[pCur->iPage]==0
|
||||
|| pCur->apPage[pCur->iPage]->leaf==0
|
||||
|| pCur->pPage->leaf==0
|
||||
){
|
||||
return btreePrevious(pCur, pRes);
|
||||
}
|
||||
@@ -7419,7 +7442,8 @@ static int balance(BtCursor *pCur){
|
||||
|
||||
do {
|
||||
int iPage = pCur->iPage;
|
||||
MemPage *pPage = pCur->apPage[iPage];
|
||||
MemPage *pPage = pCur->pPage;
|
||||
assert( pPage==pCur->apPage[iPage] );
|
||||
|
||||
if( iPage==0 ){
|
||||
if( pPage->nOverflow ){
|
||||
@@ -7434,7 +7458,8 @@ static int balance(BtCursor *pCur){
|
||||
pCur->iPage = 1;
|
||||
pCur->aiIdx[0] = 0;
|
||||
pCur->aiIdx[1] = 0;
|
||||
assert( pCur->apPage[1]->nOverflow );
|
||||
pCur->pPage = pCur->apPage[1];
|
||||
assert( pCur->pPage->nOverflow );
|
||||
}
|
||||
}else{
|
||||
break;
|
||||
@@ -7513,6 +7538,7 @@ static int balance(BtCursor *pCur){
|
||||
releasePage(pPage);
|
||||
pCur->iPage--;
|
||||
assert( pCur->iPage>=0 );
|
||||
pCur->pPage = pCur->apPage[pCur->iPage];
|
||||
}
|
||||
}while( rc==SQLITE_OK );
|
||||
|
||||
@@ -7615,7 +7641,8 @@ int sqlite3BtreeInsert(
|
||||
}
|
||||
assert( pCur->eState==CURSOR_VALID || (pCur->eState==CURSOR_INVALID && loc) );
|
||||
|
||||
pPage = pCur->apPage[pCur->iPage];
|
||||
assert( pCur->pPage==pCur->apPage[pCur->iPage] );
|
||||
pPage = pCur->pPage;
|
||||
assert( pPage->intKey || nKey>=0 );
|
||||
assert( pPage->leaf || !pPage->intKey );
|
||||
|
||||
@@ -7682,10 +7709,11 @@ int sqlite3BtreeInsert(
|
||||
** fails. Internal data structure corruption will result otherwise.
|
||||
** Also, set the cursor state to invalid. This stops saveCursorPosition()
|
||||
** from trying to save the current position of the cursor. */
|
||||
pCur->apPage[pCur->iPage]->nOverflow = 0;
|
||||
assert( pCur->pPage==pCur->apPage[pCur->iPage] );
|
||||
pCur->pPage->nOverflow = 0;
|
||||
pCur->eState = CURSOR_INVALID;
|
||||
}
|
||||
assert( pCur->apPage[pCur->iPage]->nOverflow==0 );
|
||||
assert( pCur->pPage->nOverflow==0 );
|
||||
|
||||
end_insert:
|
||||
return rc;
|
||||
@@ -7711,8 +7739,9 @@ int sqlite3BtreeDelete(BtCursor *pCur){
|
||||
assert( pCur->curFlags & BTCF_WriteFlag );
|
||||
assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
|
||||
assert( !hasReadConflicts(p, pCur->pgnoRoot) );
|
||||
assert( pCur->pPage==pCur->apPage[pCur->iPage] );
|
||||
|
||||
if( NEVER(pCur->aiIdx[pCur->iPage]>=pCur->apPage[pCur->iPage]->nCell)
|
||||
if( NEVER(pCur->aiIdx[pCur->iPage]>=pCur->pPage->nCell)
|
||||
|| NEVER(pCur->eState!=CURSOR_VALID)
|
||||
){
|
||||
return SQLITE_ERROR; /* Something has gone awry. */
|
||||
@@ -7762,7 +7791,7 @@ int sqlite3BtreeDelete(BtCursor *pCur){
|
||||
** node. The cell from the leaf node needs to be moved to the internal
|
||||
** node to replace the deleted cell. */
|
||||
if( !pPage->leaf ){
|
||||
MemPage *pLeaf = pCur->apPage[pCur->iPage];
|
||||
MemPage *pLeaf = pCur->pPage;
|
||||
int nCell;
|
||||
Pgno n = pCur->apPage[iCellDepth+1]->pgno;
|
||||
unsigned char *pTmp;
|
||||
@@ -7798,6 +7827,7 @@ int sqlite3BtreeDelete(BtCursor *pCur){
|
||||
while( pCur->iPage>iCellDepth ){
|
||||
releasePage(pCur->apPage[pCur->iPage--]);
|
||||
}
|
||||
pCur->pPage = pCur->apPage[pCur->iPage];
|
||||
rc = balance(pCur);
|
||||
}
|
||||
|
||||
@@ -8302,7 +8332,8 @@ int sqlite3BtreeCount(BtCursor *pCur, i64 *pnEntry){
|
||||
** this page contains countable entries. Increment the entry counter
|
||||
** accordingly.
|
||||
*/
|
||||
pPage = pCur->apPage[pCur->iPage];
|
||||
assert( pCur->pPage==pCur->apPage[pCur->iPage] );
|
||||
pPage = pCur->pPage;
|
||||
if( pPage->leaf || !pPage->intKey ){
|
||||
nEntry += pPage->nCell;
|
||||
}
|
||||
@@ -8325,10 +8356,11 @@ int sqlite3BtreeCount(BtCursor *pCur, i64 *pnEntry){
|
||||
return moveToRoot(pCur);
|
||||
}
|
||||
moveToParent(pCur);
|
||||
}while ( pCur->aiIdx[pCur->iPage]>=pCur->apPage[pCur->iPage]->nCell );
|
||||
}while ( pCur->aiIdx[pCur->iPage]>=pCur->pPage->nCell );
|
||||
|
||||
pCur->aiIdx[pCur->iPage]++;
|
||||
pPage = pCur->apPage[pCur->iPage];
|
||||
assert( pCur->pPage==pCur->apPage[pCur->iPage] );
|
||||
pPage = pCur->pPage;
|
||||
}
|
||||
|
||||
/* Descend to the child node of the cell that the cursor currently
|
||||
@@ -9111,6 +9143,7 @@ int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){
|
||||
assert( hasSharedCacheTableLock(pCsr->pBtree, pCsr->pgnoRoot, 0, 2) );
|
||||
assert( !hasReadConflicts(pCsr->pBtree, pCsr->pgnoRoot) );
|
||||
assert( pCsr->apPage[pCsr->iPage]->intKey );
|
||||
assert( pCsr->pPage==pCsr->apPage[pCsr->iPage] );
|
||||
|
||||
return accessPayload(pCsr, offset, amt, (unsigned char *)z, 1);
|
||||
}
|
||||
|
||||
@@ -518,6 +518,7 @@ struct BtCursor {
|
||||
u8 hints; /* As configured by CursorSetHints() */
|
||||
i16 iPage; /* Index of current page in apPage */
|
||||
u16 aiIdx[BTCURSOR_MAX_DEPTH]; /* Current index in apPage[i] */
|
||||
MemPage *pPage; /* Current page */
|
||||
MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */
|
||||
};
|
||||
|
||||
|
||||
+3
-3
@@ -67,7 +67,7 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){
|
||||
if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */
|
||||
if( argv[1]==0 ){
|
||||
corruptSchema(pData, argv[0], 0);
|
||||
}else if( sqlite3_strnicmp(argv[2],"create ",7)==0 ){
|
||||
}else if( argv[2] && argv[2][0] ){
|
||||
/* Call the parser to process a CREATE TABLE, INDEX or VIEW.
|
||||
** But because db->init.busy is set to 1, no VDBE code is generated
|
||||
** or executed. All the parser does is build the internal data
|
||||
@@ -98,8 +98,8 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){
|
||||
}
|
||||
}
|
||||
sqlite3_finalize(pStmt);
|
||||
}else if( argv[0]==0 || (argv[2]!=0 && argv[2][0]!=0) ){
|
||||
corruptSchema(pData, argv[0], 0);
|
||||
}else if( argv[0]==0 ){
|
||||
corruptSchema(pData, 0, 0);
|
||||
}else{
|
||||
/* If the SQL column is blank it means this is an index that
|
||||
** was created to be the PRIMARY KEY or to fulfill a UNIQUE
|
||||
|
||||
+5
-46
@@ -989,16 +989,7 @@ static int shell_callback(
|
||||
case MODE_Insert: {
|
||||
p->cnt++;
|
||||
if( azArg==0 ) break;
|
||||
fprintf(p->out,"INSERT INTO %s",p->zDestTable);
|
||||
if( p->showHeader ){
|
||||
fprintf(p->out,"(");
|
||||
for(i=0; i<nArg; i++){
|
||||
char *zSep = i>0 ? ",": "";
|
||||
fprintf(p->out, "%s%s", zSep, azCol[i]);
|
||||
}
|
||||
fprintf(p->out,")");
|
||||
}
|
||||
fprintf(p->out," VALUES(");
|
||||
fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
|
||||
for(i=0; i<nArg; i++){
|
||||
char *zSep = i>0 ? ",": "";
|
||||
if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
|
||||
@@ -1780,7 +1771,6 @@ static int run_schema_dump_query(
|
||||
static char zHelp[] =
|
||||
".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
|
||||
".bail on|off Stop after hitting an error. Default OFF\n"
|
||||
".binary on|off Turn binary output on or off. Default OFF\n"
|
||||
".clone NEWDB Clone data into NEWDB from the existing database\n"
|
||||
".databases List names and files of attached databases\n"
|
||||
".dbinfo ?DB? Show status information about the database\n"
|
||||
@@ -1942,44 +1932,26 @@ static void open_db(ShellState *p, int keepAlive){
|
||||
/*
|
||||
** Do C-language style dequoting.
|
||||
**
|
||||
** \a -> alarm
|
||||
** \b -> backspace
|
||||
** \t -> tab
|
||||
** \n -> newline
|
||||
** \v -> vertical tab
|
||||
** \f -> form feed
|
||||
** \r -> carriage return
|
||||
** \s -> space
|
||||
** \" -> "
|
||||
** \' -> '
|
||||
** \\ -> backslash
|
||||
** \NNN -> ascii character NNN in octal
|
||||
** \\ -> backslash
|
||||
*/
|
||||
static void resolve_backslashes(char *z){
|
||||
int i, j;
|
||||
char c;
|
||||
while( *z && *z!='\\' ) z++;
|
||||
for(i=j=0; (c = z[i])!=0; i++, j++){
|
||||
if( c=='\\' && z[i+1]!=0 ){
|
||||
if( c=='\\' ){
|
||||
c = z[++i];
|
||||
if( c=='a' ){
|
||||
c = '\a';
|
||||
}else if( c=='b' ){
|
||||
c = '\b';
|
||||
if( c=='n' ){
|
||||
c = '\n';
|
||||
}else if( c=='t' ){
|
||||
c = '\t';
|
||||
}else if( c=='n' ){
|
||||
c = '\n';
|
||||
}else if( c=='v' ){
|
||||
c = '\v';
|
||||
}else if( c=='f' ){
|
||||
c = '\f';
|
||||
}else if( c=='r' ){
|
||||
c = '\r';
|
||||
}else if( c=='"' ){
|
||||
c = '"';
|
||||
}else if( c=='\'' ){
|
||||
c = '\'';
|
||||
}else if( c=='\\' ){
|
||||
c = '\\';
|
||||
}else if( c>='0' && c<='7' ){
|
||||
@@ -2713,19 +2685,6 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}
|
||||
}else
|
||||
|
||||
if( c=='b' && n>=3 && strncmp(azArg[0], "binary", n)==0 ){
|
||||
if( nArg==2 ){
|
||||
if( booleanValue(azArg[1]) ){
|
||||
setBinaryMode(p->out);
|
||||
}else{
|
||||
setTextMode(p->out);
|
||||
}
|
||||
}else{
|
||||
fprintf(stderr, "Usage: .binary on|off\n");
|
||||
rc = 1;
|
||||
}
|
||||
}else
|
||||
|
||||
/* The undocumented ".breakpoint" command causes a call to the no-op
|
||||
** routine named test_breakpoint().
|
||||
*/
|
||||
|
||||
+1
-1
@@ -359,6 +359,6 @@ do_test analyze-99.1 {
|
||||
catchsql {
|
||||
ANALYZE
|
||||
}
|
||||
} {1 {malformed database schema (sqlite_stat1)}}
|
||||
} {1 {malformed database schema (sqlite_stat1) - near "nonsense": syntax error}}
|
||||
|
||||
finish_test
|
||||
|
||||
+1
-1
@@ -51,6 +51,6 @@ do_test index3-99.1 {
|
||||
db close
|
||||
catch { sqlite3 db test.db }
|
||||
catchsql { DROP INDEX i1 }
|
||||
} {1 {malformed database schema (t1)}}
|
||||
} {1 {malformed database schema (t1) - near "nonsense": syntax error}}
|
||||
|
||||
finish_test
|
||||
|
||||
+1
-101
@@ -738,9 +738,6 @@ do_test shell1-4.1 {
|
||||
PRAGMA encoding=UTF16;
|
||||
CREATE TABLE t1(x);
|
||||
INSERT INTO t1 VALUES(null), (''), (1), (2.25), ('hello'), (x'807f');
|
||||
CREATE TABLE t3(x,y);
|
||||
INSERT INTO t3 VALUES(1,null), (2,''), (3,1),
|
||||
(4,2.25), (5,'hello'), (6,x'807f');
|
||||
}
|
||||
catchcmd test.db {.dump}
|
||||
} {0 {PRAGMA foreign_keys=OFF;
|
||||
@@ -752,18 +749,11 @@ INSERT INTO "t1" VALUES(1);
|
||||
INSERT INTO "t1" VALUES(2.25);
|
||||
INSERT INTO "t1" VALUES('hello');
|
||||
INSERT INTO "t1" VALUES(X'807F');
|
||||
CREATE TABLE t3(x,y);
|
||||
INSERT INTO "t3" VALUES(1,NULL);
|
||||
INSERT INTO "t3" VALUES(2,'');
|
||||
INSERT INTO "t3" VALUES(3,1);
|
||||
INSERT INTO "t3" VALUES(4,2.25);
|
||||
INSERT INTO "t3" VALUES(5,'hello');
|
||||
INSERT INTO "t3" VALUES(6,X'807F');
|
||||
COMMIT;}}
|
||||
|
||||
# Test the output of ".mode insert"
|
||||
#
|
||||
do_test shell1-4.2.1 {
|
||||
do_test shell1-4.2 {
|
||||
catchcmd test.db ".mode insert t1\nselect * from t1;"
|
||||
} {0 {INSERT INTO t1 VALUES(NULL);
|
||||
INSERT INTO t1 VALUES('');
|
||||
@@ -772,39 +762,6 @@ INSERT INTO t1 VALUES(2.25);
|
||||
INSERT INTO t1 VALUES('hello');
|
||||
INSERT INTO t1 VALUES(X'807f');}}
|
||||
|
||||
# Test the output of ".mode insert" with headers
|
||||
#
|
||||
do_test shell1-4.2.2 {
|
||||
catchcmd test.db ".mode insert t1\n.headers on\nselect * from t1;"
|
||||
} {0 {INSERT INTO t1(x) VALUES(NULL);
|
||||
INSERT INTO t1(x) VALUES('');
|
||||
INSERT INTO t1(x) VALUES(1);
|
||||
INSERT INTO t1(x) VALUES(2.25);
|
||||
INSERT INTO t1(x) VALUES('hello');
|
||||
INSERT INTO t1(x) VALUES(X'807f');}}
|
||||
|
||||
# Test the output of ".mode insert"
|
||||
#
|
||||
do_test shell1-4.2.3 {
|
||||
catchcmd test.db ".mode insert t3\nselect * from t3;"
|
||||
} {0 {INSERT INTO t3 VALUES(1,NULL);
|
||||
INSERT INTO t3 VALUES(2,'');
|
||||
INSERT INTO t3 VALUES(3,1);
|
||||
INSERT INTO t3 VALUES(4,2.25);
|
||||
INSERT INTO t3 VALUES(5,'hello');
|
||||
INSERT INTO t3 VALUES(6,X'807f');}}
|
||||
|
||||
# Test the output of ".mode insert" with headers
|
||||
#
|
||||
do_test shell1-4.2.4 {
|
||||
catchcmd test.db ".mode insert t3\n.headers on\nselect * from t3;"
|
||||
} {0 {INSERT INTO t3(x,y) VALUES(1,NULL);
|
||||
INSERT INTO t3(x,y) VALUES(2,'');
|
||||
INSERT INTO t3(x,y) VALUES(3,1);
|
||||
INSERT INTO t3(x,y) VALUES(4,2.25);
|
||||
INSERT INTO t3(x,y) VALUES(5,'hello');
|
||||
INSERT INTO t3(x,y) VALUES(6,X'807f');}}
|
||||
|
||||
# Test the output of ".mode tcl"
|
||||
#
|
||||
do_test shell1-4.3 {
|
||||
@@ -861,61 +818,4 @@ do_test shell1-4.6 {
|
||||
";"
|
||||
"$"} 7}
|
||||
|
||||
# Test using arbitrary byte data with the shell via standard input/output.
|
||||
#
|
||||
do_test shell1-5.0 {
|
||||
#
|
||||
# NOTE: Skip NUL byte because it appears to be incompatible with command
|
||||
# shell argument parsing.
|
||||
#
|
||||
for {set i 1} {$i < 256} {incr i} {
|
||||
#
|
||||
# NOTE: Due to how the Tcl [exec] command works (i.e. where it treats
|
||||
# command channels opened for it as textual ones), the carriage
|
||||
# return character (and on Windows, the end-of-file character)
|
||||
# cannot be used here.
|
||||
#
|
||||
if {$i==0x0D || ($tcl_platform(platform)=="windows" && $i==0x1A)} {
|
||||
continue
|
||||
}
|
||||
set hex [format %02X $i]
|
||||
set char [subst \\x$hex]; set oldChar $char
|
||||
set escapes [list]
|
||||
if {$tcl_platform(platform)=="windows"} {
|
||||
#
|
||||
# NOTE: On Windows, we need to escape all the whitespace characters,
|
||||
# the alarm (\a) character, and those with special meaning to
|
||||
# the SQLite shell itself.
|
||||
#
|
||||
set escapes [list \
|
||||
\a \\a \b \\b \t \\t \n \\n \v \\v \f \\f \r \\r \
|
||||
" " "\" \"" \" \\\" ' \"'\" \\ \\\\]
|
||||
} else {
|
||||
#
|
||||
# NOTE: On Unix, we need to escape most of the whitespace characters
|
||||
# and those with special meaning to the SQLite shell itself.
|
||||
# The alarm (\a), backspace (\b), and carriage-return (\r)
|
||||
# characters do not appear to require escaping on Unix. For
|
||||
# the alarm and backspace characters, this is probably due to
|
||||
# differences in the command shell. For the carriage-return,
|
||||
# it is probably due to differences in how Tcl handles command
|
||||
# channel end-of-line translations.
|
||||
#
|
||||
set escapes [list \
|
||||
\t \\t \n \\n \v \\v \f \\f \
|
||||
" " "\" \"" \" \\\" ' \"'\" \\ \\\\]
|
||||
}
|
||||
set char [string map $escapes $char]
|
||||
set x [catchcmdex test.db ".print $char\n"]
|
||||
set code [lindex $x 0]
|
||||
set res [lindex $x 1]
|
||||
if {$code ne "0"} {
|
||||
error "failed with error: $res"
|
||||
}
|
||||
if {$res ne "$oldChar\n"} {
|
||||
error "failed with byte $hex mismatch"
|
||||
}
|
||||
}
|
||||
} {}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -666,15 +666,6 @@ proc do_test {name cmd expected} {
|
||||
flush stdout
|
||||
}
|
||||
|
||||
proc dumpbytes {s} {
|
||||
set r ""
|
||||
for {set i 0} {$i < [string length $s]} {incr i} {
|
||||
if {$i > 0} {append r " "}
|
||||
append r [format %02X [scan [string index $s $i] %c]]
|
||||
}
|
||||
return $r
|
||||
}
|
||||
|
||||
proc catchcmd {db {cmd ""}} {
|
||||
global CLI
|
||||
set out [open cmds.txt w]
|
||||
@@ -685,30 +676,6 @@ proc catchcmd {db {cmd ""}} {
|
||||
list $rc $msg
|
||||
}
|
||||
|
||||
proc catchcmdex {db {cmd ""}} {
|
||||
global CLI
|
||||
set out [open cmds.txt w]
|
||||
fconfigure $out -encoding binary -translation binary
|
||||
puts -nonewline $out $cmd
|
||||
close $out
|
||||
set line "exec -keepnewline -- $CLI $db < cmds.txt"
|
||||
set chans [list stdin stdout stderr]
|
||||
foreach chan $chans {
|
||||
catch {
|
||||
set modes($chan) [fconfigure $chan]
|
||||
fconfigure $chan -encoding binary -translation binary -buffering none
|
||||
}
|
||||
}
|
||||
set rc [catch { eval $line } msg]
|
||||
foreach chan $chans {
|
||||
catch {
|
||||
eval fconfigure [list $chan] $modes($chan)
|
||||
}
|
||||
}
|
||||
# puts [dumpbytes $msg]
|
||||
list $rc $msg
|
||||
}
|
||||
|
||||
proc filepath_normalize {p} {
|
||||
# test cases should be written to assume "unix"-like file paths
|
||||
if {$::tcl_platform(platform)!="unix"} {
|
||||
|
||||
+1
-1
@@ -114,6 +114,6 @@ do_test trigger7-99.1 {
|
||||
db close
|
||||
catch { sqlite3 db test.db }
|
||||
catchsql { DROP TRIGGER t2r5 }
|
||||
} {1 {malformed database schema (t2r12)}}
|
||||
} {1 {malformed database schema (t2r12) - near "nonsense": syntax error}}
|
||||
|
||||
finish_test
|
||||
|
||||
Reference in New Issue
Block a user