From 1e968a0cbf30ea1b0f4d4c5927a8b173d36956d9 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 25 Mar 2008 00:22:21 +0000 Subject: [PATCH] Removed the direct btree tests - part of the ongoing effort to test by calling only public interfaces. Modify the sqlite3VdbeRecordCompare interface to used a pre-parsed second key - resulting in a 13% performance improvement on speed1p.test. (CVS 4911) FossilOrigin-Name: 0e1d84f2f456e7680bb667266745b629ddf3605f --- manifest | 38 +- manifest.uuid | 2 +- src/btree.c | 89 ++-- src/btree.h | 13 +- src/btreeInt.h | 5 +- src/prepare.c | 6 +- src/test3.c | 4 +- src/vdbe.c | 19 +- src/vdbe.h | 8 +- src/vdbeInt.h | 1 - src/vdbeaux.c | 195 ++++++++- test/btree.test | 1066 ---------------------------------------------- test/btree2.test | 502 ---------------------- test/btree4.test | 101 ----- test/btree5.test | 292 ------------- test/btree6.test | 128 ------ test/btree7.test | 50 --- test/btree8.test | 43 -- test/btree9.test | 49 --- test/quick.test | 7 +- 20 files changed, 274 insertions(+), 2344 deletions(-) delete mode 100644 test/btree.test delete mode 100644 test/btree2.test delete mode 100644 test/btree4.test delete mode 100644 test/btree5.test delete mode 100644 test/btree6.test delete mode 100644 test/btree7.test delete mode 100644 test/btree8.test delete mode 100644 test/btree9.test diff --git a/manifest b/manifest index 5dcd7e345d..5e186a34f1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\sdocumentation\sof\ssqlite3_blob_open().\s(CVS\s4910) -D 2008-03-24T12:51:46 +C Removed\sthe\sdirect\sbtree\stests\s-\spart\sof\sthe\songoing\seffort\sto\stest\sby\ncalling\sonly\spublic\sinterfaces.\s\sModify\sthe\ssqlite3VdbeRecordCompare\ninterface\sto\sused\sa\spre-parsed\ssecond\skey\s-\sresulting\sin\sa\s13%\nperformance\simprovement\son\sspeed1p.test.\s(CVS\s4911) +D 2008-03-25T00:22:21 F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7 F Makefile.in cf434ce8ca902e69126ae0f94fc9f7dc7428a5fa F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -86,9 +86,9 @@ F src/attach.c bdc75e759ca25a16f4dc7fbdbc6d37ad2561bb24 F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627 F src/bitvec.c 49817d442e51e4123585f3cf3c2afc293a3c91e2 F src/btmutex.c 483ced3c52205b04b97df69161fadbf87f4f1ea2 -F src/btree.c 15424f41344ad96ab56a3322f5930cfb7a8ee24e -F src/btree.h 19dcf5ad23c17b98855da548e9a8e3eb4429d5eb -F src/btreeInt.h d7d2f4d9d7f2e72c455326d48b2b478b842a81f6 +F src/btree.c 984962aa403be49d79784f01cc9887d16cd841ed +F src/btree.h ca065a5910e6dd3b91b88ff9d729450a8b8eda1f +F src/btreeInt.h c2deca3e778e2a1e6196343b8087a868f4faa19a F src/build.c 31ed5af4e8ac40c30bb0f88d7fec75e72cc16e0e F src/callback.c 77b302b0d41468dcda78c70e706e5b84577f0fa0 F src/complete.c 4cf68fd75d60257524cbe74f87351b9848399131 @@ -132,7 +132,7 @@ F src/pager.c 22241b59c80ca083a96816df434adb8c097afcd4 F src/pager.h b1e2258f03878c14b06a95bfa362e8c5c9638170 F src/parse.y b0ee84d94218046ea88c2a6561005710d127ca7d F src/pragma.c f64eed914518c28d1863356163dea1e6f58e28f2 -F src/prepare.c 1b71b5d43ba3d88f2d3c2a6d084f28ac209df956 +F src/prepare.c f7fc2eb7418dcaa63e22b66c5ecf478e658ecd8f F src/printf.c 05d2b44d7b5b80c8a4a09108ddad9c20e254370d F src/random.c 2b2db2de4ab491f5a14d3480466f8f4b5a5db74a F src/select.c 35063b078beafe9aa35344a8ce039210920d7fea @@ -146,7 +146,7 @@ F src/table.c 2c48c575dd59b3a6c5c306bc55f51a9402cf429a F src/tclsqlite.c d42912617d4734b8f9195416badf5b27e512ded2 F src/test1.c 342a2628310fa709074d979e695a28a3bb570834 F src/test2.c f0808cc643528b9620e4059ca9bda8346f526121 -F src/test3.c 5c7452038ab27aa698070799b10132f26cdd2a80 +F src/test3.c 9bf750645412effca0b2567b8b833e1e91377b47 F src/test4.c c2c0f5dc907f1346f5d4b65eb5799f11eb9e4071 F src/test5.c 3a6a5717a149d7ca2e6d14f5be72cf7555d54dc4 F src/test6.c 62281c0a9ac0265e579065942f7de4e080f8eb05 @@ -174,11 +174,11 @@ F src/update.c d2c59643af98f966c2a04d392463089b715ca18f F src/utf.c 32b00d6e19010025e58f2ecb2f921d5e126771b4 F src/util.c dba9e04121eb17ec4643d6ca231ff859452cf0e2 F src/vacuum.c 3524411bfb58aac0d87eadd3e5b7cd532772af30 -F src/vdbe.c 43b261f50be60c758430a9072f960715f2ff0852 -F src/vdbe.h 93acc03fe8002173cb6affad2bf5d5c5305ba229 -F src/vdbeInt.h 76c81d057a39813de0fda3cad1498655d53ec69d +F src/vdbe.c d81771c67e67f9a25af1d53e5c22299becef1322 +F src/vdbe.h 0fef6798be121ed2b5a547a5cb85e0824ec3971f +F src/vdbeInt.h 4bbec80d55d179ab8438ac9822416d9111638919 F src/vdbeapi.c b9e9d7a58690c1e1ae66de7232edccf4793ad817 -F src/vdbeaux.c 82f3c8913e68b4928de28c3fa117464356d59df6 +F src/vdbeaux.c f3ee532bfdf191f0d2a8c4d1a50816cdd1a235d2 F src/vdbeblob.c 63c750acc7b5012479f508c0e9627372a82cb65d F src/vdbefifo.c a30c237b2a3577e1415fb6e288cbb6b8ed1e5736 F src/vdbemem.c 67662aac917b627356262f9501591206db2a8845 @@ -215,14 +215,6 @@ F test/bind.test 261fd1603613e7f877a516d29f281c9d8c2ecf52 F test/bindxfer.test 995d2cf8df61204d748cde6960443121c4ccd2e1 F test/bitvec.test 62a512c3f7041d1df12558eb25990e5a19820571 F test/blob.test f2dbdbf1159674283645c2636436839313ee7131 -F test/btree.test d22b1b2cc9becc36f6b1f2f91b9fca1e48060979 -F test/btree2.test 4b56a2a4a4f84d68c77aef271223a713bf5ebafc -F test/btree4.test 3797b4305694c7af6828675b0f4b1424b8ca30e4 -F test/btree5.test 8e5ff32c02e685d36516c6499add9375fe1377f2 -F test/btree6.test a5ede6bfbbb2ec8b27e62813612c0f28e8f3e027 -F test/btree7.test a6d3b842db22af97dd14b989e90a2fd96066b72f -F test/btree8.test fadc112bcbd6a0c622d34c813fc8a648eacf8804 -F test/btree9.test 5d8711b241145b90f65dd1795d5dd8290846fa5e F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0 F test/cache.test 3ff445c445742a7b6b9ba6e1d62a25263f9424b9 F test/capi2.test cc64df7560a96f848f919ea2926c60acf639684b @@ -419,7 +411,7 @@ F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47 F test/printf.test c3405535b418d454e8a52196a0fc592ec9eec58d F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 x F test/ptrchng.test 83150cb7b513e33cce90fdc68f4b1817551857c0 -F test/quick.test 037a953ccc4e5419c89528e7b93742db29bc3ec1 +F test/quick.test fcd8fb7aeee4b8bc7a5be56c25104f6f39258eb1 F test/quote.test 215897dbe8de1a6f701265836d6601cc6ed103e6 F test/rdonly.test b34db316525440d3b42c32e83942c02c37d28ef0 F test/reindex.test 38b138abe36bf9a08c791ed44d9f76cd6b97b78b @@ -625,7 +617,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 -P a807e7184b857414ce203af129ac1adf2012096c -R 4101d535e06a9619e1c68b648b338bf6 +P 1ed695f560a58786f2a8467c601f281c67034fd4 +R 4b7a149e165aca7212e2405c0ae3196c U drh -Z c87ff7d608d92b0ae8912212b9742706 +Z f27434cb523b0af2e9a84163450beba5 diff --git a/manifest.uuid b/manifest.uuid index d8c8bf83f1..da0b9c2f08 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1ed695f560a58786f2a8467c601f281c67034fd4 \ No newline at end of file +0e1d84f2f456e7680bb667266745b629ddf3605f \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index ccbed2938a..38aa3474e3 100644 --- a/src/btree.c +++ b/src/btree.c @@ -9,7 +9,7 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: btree.c,v 1.442 2008/03/23 00:20:36 drh Exp $ +** $Id: btree.c,v 1.443 2008/03/25 00:22:21 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** See the header comment on "btreeInt.h" for additional information. @@ -2649,23 +2649,6 @@ int sqlite3BtreeRollbackStmt(Btree *p){ return rc; } -/* -** Default key comparison function to be used if no comparison function -** is specified on the sqlite3BtreeCursor() call. -*/ -static int dfltCompare( - void *NotUsed, /* User data is not used */ - int n1, const void *p1, /* First key to compare */ - int n2, const void *p2 /* Second key to compare */ -){ - int c; - c = memcmp(p1, p2, n1xCompare = xCmp ? xCmp : dfltCompare; - pCur->pArg = pArg; + pCur->pKeyInfo = pKeyInfo; pCur->pBtree = p; pCur->pBt = pBt; pCur->wrFlag = wrFlag; @@ -2774,17 +2749,16 @@ create_cursor_exception: return rc; } int sqlite3BtreeCursor( - Btree *p, /* The btree */ - int iTable, /* Root page of table to open */ - int wrFlag, /* 1 to write. 0 read-only */ - int (*xCmp)(void*,int,const void*,int,const void*), /* Key Comparison func */ - void *pArg, /* First arg to xCompare() */ - BtCursor **ppCur /* Write new cursor here */ + Btree *p, /* The btree */ + int iTable, /* Root page of table to open */ + int wrFlag, /* 1 to write. 0 read-only */ + struct KeyInfo *pKeyInfo, /* First arg to xCompare() */ + BtCursor **ppCur /* Write new cursor here */ ){ int rc; sqlite3BtreeEnter(p); p->pBt->db = p->db; - rc = btreeCursor(p, iTable, wrFlag, xCmp, pArg, ppCur); + rc = btreeCursor(p, iTable, wrFlag, pKeyInfo, ppCur); sqlite3BtreeLeave(p); return rc; } @@ -3578,8 +3552,7 @@ int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ ** ** For INTKEY tables, only the nKey parameter is used. pKey is ** ignored. For other tables, nKey is the number of bytes of data -** in pKey. The comparison function specified when the cursor was -** created is used to compare keys. +** in pKey. ** ** If an exact match is not found, then the cursor is always ** left pointing at a leaf page which would hold the entry if it @@ -3609,6 +3582,8 @@ int sqlite3BtreeMoveto( int *pRes /* Search result flag */ ){ int rc; + VdbeParsedRecord *pPKey; + char aSpace[200]; assert( cursorHoldsMutex(pCur) ); assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); @@ -3623,6 +3598,13 @@ int sqlite3BtreeMoveto( assert( pCur->pPage->nCell==0 ); return SQLITE_OK; } + if( pCur->pPage->intKey ){ + pPKey = 0; + }else{ + pPKey = sqlite3VdbeRecordParse(pCur->pKeyInfo, nKey, pKey, + aSpace, sizeof(aSpace)); + if( pPKey==0 ) return SQLITE_NOMEM; + } for(;;){ int lwr, upr; Pgno chldPg; @@ -3631,7 +3613,8 @@ int sqlite3BtreeMoveto( lwr = 0; upr = pPage->nCell-1; if( !pPage->intKey && pKey==0 ){ - return SQLITE_CORRUPT_BKPT; + rc = SQLITE_CORRUPT_BKPT; + goto moveto_finish; } if( biasRight ){ pCur->idx = upr; @@ -3662,16 +3645,14 @@ int sqlite3BtreeMoveto( pCellKey = (void *)fetchPayload(pCur, &available, 0); nCellKey = pCur->info.nKey; if( available>=nCellKey ){ - c = pCur->xCompare(pCur->pArg, nCellKey, pCellKey, nKey, pKey); + c = sqlite3VdbeRecordCompareParsed(nCellKey, pCellKey, pPKey); }else{ pCellKey = sqlite3_malloc( nCellKey ); if( pCellKey==0 ) return SQLITE_NOMEM; rc = sqlite3BtreeKey(pCur, 0, nCellKey, (void *)pCellKey); - c = pCur->xCompare(pCur->pArg, nCellKey, pCellKey, nKey, pKey); + c = sqlite3VdbeRecordCompareParsed(nCellKey, pCellKey, pPKey); sqlite3_free(pCellKey); - if( rc ){ - return rc; - } + if( rc ) goto moveto_finish; } } if( c==0 ){ @@ -3681,7 +3662,8 @@ int sqlite3BtreeMoveto( break; }else{ if( pRes ) *pRes = 0; - return SQLITE_OK; + rc = SQLITE_OK; + goto moveto_finish; } } if( c<0 ){ @@ -3706,16 +3688,17 @@ int sqlite3BtreeMoveto( if( chldPg==0 ){ assert( pCur->idx>=0 && pCur->idxpPage->nCell ); if( pRes ) *pRes = c; - return SQLITE_OK; + rc = SQLITE_OK; + goto moveto_finish; } pCur->idx = lwr; pCur->info.nSize = 0; rc = moveToChild(pCur, chldPg); - if( rc ){ - return rc; - } + if( rc ) goto moveto_finish; } - /* NOT REACHED */ +moveto_finish: + sqlite3VdbeRecordUnparse(pPKey); + return rc; } diff --git a/src/btree.h b/src/btree.h index 3bfebdb651..51d0b7717c 100644 --- a/src/btree.h +++ b/src/btree.h @@ -13,7 +13,7 @@ ** subsystem. See comments in the source code for a detailed description ** of what each interface routine does. ** -** @(#) $Id: btree.h,v 1.94 2007/12/07 18:55:28 drh Exp $ +** @(#) $Id: btree.h,v 1.95 2008/03/25 00:22:21 drh Exp $ */ #ifndef _BTREE_H_ #define _BTREE_H_ @@ -128,12 +128,11 @@ int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value); void sqlite3BtreeTripAllCursors(Btree*, int); int sqlite3BtreeCursor( - Btree*, /* BTree containing table to open */ - int iTable, /* Index of root page */ - int wrFlag, /* 1 for writing. 0 for read-only */ - int(*)(void*,int,const void*,int,const void*), /* Key comparison function */ - void*, /* First argument to compare function */ - BtCursor **ppCursor /* Returned cursor */ + Btree*, /* BTree containing table to open */ + int iTable, /* Index of root page */ + int wrFlag, /* 1 for writing. 0 for read-only */ + struct KeyInfo*, /* First argument to compare function */ + BtCursor **ppCursor /* Returned cursor */ ); int sqlite3BtreeCloseCursor(BtCursor*); diff --git a/src/btreeInt.h b/src/btreeInt.h index 90a5bdcb1b..b4f9854b92 100644 --- a/src/btreeInt.h +++ b/src/btreeInt.h @@ -9,7 +9,7 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: btreeInt.h,v 1.17 2008/03/04 17:45:01 mlcreech Exp $ +** $Id: btreeInt.h,v 1.18 2008/03/25 00:22:21 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to @@ -435,8 +435,7 @@ struct BtCursor { Btree *pBtree; /* The Btree to which this cursor belongs */ BtShared *pBt; /* The BtShared this cursor points to */ BtCursor *pNext, *pPrev; /* Forms a linked list of all cursors */ - int (*xCompare)(void*,int,const void*,int,const void*); /* Key comp func */ - void *pArg; /* First arg to xCompare() */ + struct KeyInfo *pKeyInfo; /* Argument passed to comparison function */ Pgno pgnoRoot; /* The root page of this tree */ MemPage *pPage; /* Page that contains the entry */ int idx; /* Index of the entry in pPage->aCell[] */ diff --git a/src/prepare.c b/src/prepare.c index e70e4f0969..19eb4dfa0a 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -13,7 +13,7 @@ ** interface, and routines that contribute to loading the database schema ** from disk. ** -** $Id: prepare.c,v 1.80 2008/03/20 14:03:29 drh Exp $ +** $Id: prepare.c,v 1.81 2008/03/25 00:22:21 drh Exp $ */ #include "sqliteInt.h" #include @@ -208,7 +208,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ return SQLITE_OK; } sqlite3BtreeEnter(pDb->pBt); - rc = sqlite3BtreeCursor(pDb->pBt, MASTER_ROOT, 0, 0, 0, &curMain); + rc = sqlite3BtreeCursor(pDb->pBt, MASTER_ROOT, 0, 0, &curMain); if( rc!=SQLITE_OK && rc!=SQLITE_EMPTY ){ sqlite3SetString(pzErrMsg, sqlite3ErrStr(rc), (char*)0); sqlite3BtreeLeave(pDb->pBt); @@ -446,7 +446,7 @@ static int schemaIsValid(sqlite3 *db){ Btree *pBt; pBt = db->aDb[iDb].pBt; if( pBt==0 ) continue; - rc = sqlite3BtreeCursor(pBt, MASTER_ROOT, 0, 0, 0, &curTemp); + rc = sqlite3BtreeCursor(pBt, MASTER_ROOT, 0, 0, &curTemp); if( rc==SQLITE_OK ){ rc = sqlite3BtreeGetMeta(pBt, 1, (u32 *)&cookie); if( rc==SQLITE_OK && cookie!=db->aDb[iDb].pSchema->schema_cookie ){ diff --git a/src/test3.c b/src/test3.c index f578e2607d..8a907070bc 100644 --- a/src/test3.c +++ b/src/test3.c @@ -13,7 +13,7 @@ ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** -** $Id: test3.c,v 1.91 2008/03/04 17:45:02 mlcreech Exp $ +** $Id: test3.c,v 1.92 2008/03/25 00:22:21 drh Exp $ */ #include "sqliteInt.h" #include "btreeInt.h" @@ -712,7 +712,7 @@ static int btree_cursor( if( Tcl_GetInt(interp, argv[2], &iTable) ) return TCL_ERROR; if( Tcl_GetBoolean(interp, argv[3], &wrFlag) ) return TCL_ERROR; sqlite3BtreeEnter(pBt); - rc = sqlite3BtreeCursor(pBt, iTable, wrFlag, 0, 0, &pCur); + rc = sqlite3BtreeCursor(pBt, iTable, wrFlag, 0, &pCur); sqlite3BtreeLeave(pBt); if( rc ){ Tcl_AppendResult(interp, errorName(rc), 0); diff --git a/src/vdbe.c b/src/vdbe.c index d52efc7047..5256b655df 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -43,7 +43,7 @@ ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** -** $Id: vdbe.c,v 1.715 2008/03/21 17:13:13 drh Exp $ +** $Id: vdbe.c,v 1.716 2008/03/25 00:22:21 drh Exp $ */ #include "sqliteInt.h" #include @@ -2054,9 +2054,8 @@ op_column_out: ** Convert P2 registers beginning with P1 into a single entry ** suitable for use as a data record in a database table or as a key ** in an index. The details of the format are irrelavant as long as -** the OP_Column opcode can decode the record later and as long as the -** sqlite3VdbeRecordCompare function will correctly compare two encoded -** records. Refer to source code comments for the details of the record +** the OP_Column opcode can decode the record later. +** Refer to source code comments for the details of the record ** format. ** ** P4 may be a string that is P1 characters long. The nth character of the @@ -2519,11 +2518,7 @@ case OP_OpenWrite: { pCur = allocateCursor(p, i, iDb); if( pCur==0 ) goto no_mem; pCur->nullRow = 1; - /* We always provide a key comparison function. If the table being - ** opened is of type INTKEY, the comparision function will be ignored. */ - rc = sqlite3BtreeCursor(pX, p2, wrFlag, - sqlite3VdbeRecordCompare, pOp->p4.p, - &pCur->pCursor); + rc = sqlite3BtreeCursor(pX, p2, wrFlag, pOp->p4.p, &pCur->pCursor); if( pOp->p4type==P4_KEYINFO ){ pCur->pKeyInfo = pOp->p4.pKeyInfo; pCur->pIncrKey = &pCur->pKeyInfo->incrKey; @@ -2625,15 +2620,15 @@ case OP_OpenEphemeral: { rc = sqlite3BtreeCreateTable(pCx->pBt, &pgno, BTREE_ZERODATA); if( rc==SQLITE_OK ){ assert( pgno==MASTER_ROOT+1 ); - rc = sqlite3BtreeCursor(pCx->pBt, pgno, 1, sqlite3VdbeRecordCompare, - pOp->p4.z, &pCx->pCursor); + rc = sqlite3BtreeCursor(pCx->pBt, pgno, 1, + (KeyInfo*)pOp->p4.z, &pCx->pCursor); pCx->pKeyInfo = pOp->p4.pKeyInfo; pCx->pKeyInfo->enc = ENC(p->db); pCx->pIncrKey = &pCx->pKeyInfo->incrKey; } pCx->isTable = 0; }else{ - rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, 1, 0, 0, &pCx->pCursor); + rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, 1, 0, &pCx->pCursor); pCx->isTable = 1; pCx->pIncrKey = &pCx->bogusIncrKey; } diff --git a/src/vdbe.h b/src/vdbe.h index bcc8cd9a53..5a5193ebaa 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -15,7 +15,7 @@ ** or VDBE. The VDBE implements an abstract machine that runs a ** simple program to access and modify the underlying database. ** -** $Id: vdbe.h,v 1.126 2008/03/22 01:07:18 drh Exp $ +** $Id: vdbe.h,v 1.127 2008/03/25 00:22:21 drh Exp $ */ #ifndef _SQLITE_VDBE_H_ #define _SQLITE_VDBE_H_ @@ -34,6 +34,7 @@ typedef struct Vdbe Vdbe; */ typedef struct VdbeFunc VdbeFunc; typedef struct Mem Mem; +typedef struct VdbeParsedRecord VdbeParsedRecord; /* ** A single instruction of the virtual machine has an opcode @@ -181,6 +182,11 @@ sqlite3 *sqlite3VdbeDb(Vdbe*); void sqlite3VdbeSetSql(Vdbe*, const char *z, int n); void sqlite3VdbeSwap(Vdbe*,Vdbe*); +VdbeParsedRecord *sqlite3VdbeRecordParse(KeyInfo*,int,const void*,void*,int); +void sqlite3VdbeRecordUnparse(VdbeParsedRecord*); +int sqlite3VdbeRecordCompareParsed(int,const void*,VdbeParsedRecord*); + + #ifndef NDEBUG void sqlite3VdbeComment(Vdbe*, const char*, ...); # define VdbeComment(X) sqlite3VdbeComment X diff --git a/src/vdbeInt.h b/src/vdbeInt.h index ca9c39f079..4985283cc7 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -362,7 +362,6 @@ int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *); int sqlite3VdbeIdxKeyCompare(Cursor*,int,const unsigned char*,int*); int sqlite3VdbeIdxRowid(BtCursor *, i64 *); int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); -int sqlite3VdbeRecordCompare(void*,int,const void*,int, const void*); int sqlite3VdbeIdxRowidLen(const u8*); int sqlite3VdbeExec(Vdbe*); int sqlite3VdbeList(Vdbe*); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 7f6ea1f6f7..be7c276422 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2130,6 +2130,7 @@ int sqlite3VdbeSerialGet( */ #define GetVarint(A,B) ((B = *(A))<=0x7f ? 1 : sqlite3GetVarint32(A, &B)) +#if 0 /* ** This function compares the two table rows or index records specified by ** {nKey1, pKey1} and {nKey2, pKey2}, returning a negative, zero @@ -2216,6 +2217,190 @@ int sqlite3VdbeRecordCompare( return rc; } +#endif + +/* +** An instance of the following structure holds information about a +** single index record that has already been parsed out into individual +** values. +** +** A record is an object that contains one or more fields of data. +** Records are used to store the content of a table row and to store +** the key of an index. A blob encoding of a record is created by +** the OP_MakeRecord opcode of the VDBE and is disassemblied by the +** OP_Column opcode. +** +** This structure holds a record that has already been disassembled +** into its constitutent fields. +*/ +struct VdbeParsedRecord { + KeyInfo *pKeyInfo; /* Collation and sort-order information */ + u16 nField; /* Number of entries in apMem[] */ + u8 needFree; /* True if memory obtained from sqlite3_malloc() */ + u8 needDestroy; /* True if apMem[]s should be destroyed on close */ + Mem *apMem[1]; /* Values */ +}; + +/* +** Given the nKey-byte encoding of a record in pKey[], parse the +** record into a VdbeParsedRecord structure. Return a pointer to +** that structure. +** +** The calling function might provide szSpace bytes of memory +** space at pSpace. This space can be used to hold the returned +** VDbeParsedRecord structure if it is large enough. If it is +** not big enough, space is obtained from sqlite3_malloc(). +** +** The returned structure should be closed by a call to +** sqlite3VdbeRecordUnparse(). +*/ +VdbeParsedRecord *sqlite3VdbeRecordParse( + KeyInfo *pKeyInfo, /* Information about the record format */ + int nKey, /* Size of the binary record */ + const void *pKey, /* The binary record */ + void *pSpace, /* Space available to hold resulting object */ + int szSpace /* Size of pSpace[] in bytes */ +){ + const unsigned char *aKey = (const unsigned char *)pKey; + VdbeParsedRecord *p; + int nByte; + int i, idx, d; + u32 szHdr; + Mem *pMem; + + nByte = sizeof(*p) + sizeof(Mem*)*pKeyInfo->nField + + sizeof(Mem)*(pKeyInfo->nField+1); + if( nByte>szSpace ){ + p = sqlite3DbMallocRaw(pKeyInfo->db, nByte); + if( p==0 ) return 0; + p->needFree = 1; + }else{ + p = pSpace; + p->needFree = 0; + } + p->pKeyInfo = pKeyInfo; + p->nField = pKeyInfo->nField + 1; + p->needDestroy = 1; + pMem = (Mem*)&p->apMem[pKeyInfo->nField+1]; + idx = GetVarint(aKey, szHdr); + d = szHdr; + i = 0; + while( idxnField ){ + u32 serial_type; + + idx += GetVarint( aKey+idx, serial_type); + if( d>=nKey && sqlite3VdbeSerialTypeLen(serial_type)>0 ) break; + pMem->enc = pKeyInfo->enc; + pMem->db = pKeyInfo->db; + pMem->flags = 0; + d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem); + p->apMem[i++] = pMem++; + } + p->nField = i; + return (void*)p; +} + +/* +** This routine destroys a VdbeParsedRecord object +*/ +void sqlite3VdbeRecordUnparse(VdbeParsedRecord *p){ + if( p ){ + if( p->needDestroy ){ + int i; + for(i=0; inField; i++){ + if( p->apMem[i]->flags & MEM_Dyn ){ + sqlite3VdbeMemRelease(p->apMem[i]); + } + } + } + if( p->needFree ){ + sqlite3_free(p); + } + } +} + +/* +** This function compares the two table rows or index records +** specified by {nKey1, pKey1} and pPKey2. It returns a negative, zero +** or positive integer if {nKey1, pKey1} is less than, equal to or +** greater than pPKey2. The {nKey1, pKey1} key must be a blob +** created by th OP_MakeRecord opcode of the VDBE. The pPKey2 +** key must be a parsed key such as obtained from +** sqlite3VdbeParseRecord. +** +** Key1 and Key2 do not have to contain the same number of fields. +** But if the lengths differ, Key2 must be the shorter of the two. +** +** Historical note: In earlier versions of this routine both Key1 +** and Key2 were blobs obtained from OP_MakeRecord. But we found +** that in typical use the same Key2 would be submitted multiple times +** in a row. So an optimization was added to parse the Key2 key +** separately and submit the parsed version. In this way, we avoid +** parsing the same Key2 multiple times in a row. +*/ +int sqlite3VdbeRecordCompareParsed( + int nKey1, const void *pKey1, + VdbeParsedRecord *pPKey2 +){ + u32 d1; /* Offset into aKey[] of next data element */ + u32 idx1; /* Offset into aKey[] of next header element */ + u32 szHdr1; /* Number of bytes in header */ + int i = 0; + int nField; + int rc = 0; + const unsigned char *aKey1 = (const unsigned char *)pKey1; + KeyInfo *pKeyInfo; + Mem mem1; + + pKeyInfo = pPKey2->pKeyInfo; + mem1.enc = pKeyInfo->enc; + mem1.db = pKeyInfo->db; + mem1.flags = 0; + + idx1 = GetVarint(aKey1, szHdr1); + d1 = szHdr1; + nField = pKeyInfo->nField; + while( idx1nField ){ + u32 serial_type1; + + /* Read the serial types for the next element in each key. */ + idx1 += GetVarint( aKey1+idx1, serial_type1 ); + if( d1>=nKey1 && sqlite3VdbeSerialTypeLen(serial_type1)>0 ) break; + + /* Extract the values to be compared. + */ + d1 += sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1); + + /* Do the comparison + */ + rc = sqlite3MemCompare(&mem1, pPKey2->apMem[i], + iaColl[i] : 0); + if( mem1.flags&MEM_Dyn ) sqlite3VdbeMemRelease(&mem1); + if( rc!=0 ){ + break; + } + i++; + } + + /* One of the keys ran out of fields, but all the fields up to that point + ** were equal. If the incrKey flag is true, then the second key is + ** treated as larger. + */ + if( rc==0 ){ + if( pKeyInfo->incrKey ){ + rc = -1; + }else if( !pKeyInfo->prefixIsEqual ){ + if( d1aSortOrder && inField + && pKeyInfo->aSortOrder[i] ){ + rc = -rc; + } + + return rc; +} /* ** The argument is an index entry composed using the OP_MakeRecord opcode. @@ -2285,6 +2470,8 @@ int sqlite3VdbeIdxKeyCompare( BtCursor *pCur = pC->pCursor; int lenRowid; Mem m; + VdbeParsedRecord *pRec; + char zSpace[200]; sqlite3BtreeKeySize(pCur, &nCellKey); if( nCellKey<=0 ){ @@ -2298,7 +2485,13 @@ int sqlite3VdbeIdxKeyCompare( return rc; } lenRowid = sqlite3VdbeIdxRowidLen((u8*)m.z); - *res = sqlite3VdbeRecordCompare(pC->pKeyInfo, m.n-lenRowid, m.z, nKey, pKey); + pRec = sqlite3VdbeRecordParse(pC->pKeyInfo, nKey, pKey, + zSpace, sizeof(zSpace)); + if( pRec==0 ){ + return SQLITE_NOMEM; + } + *res = sqlite3VdbeRecordCompareParsed(m.n-lenRowid, m.z, pRec); + sqlite3VdbeRecordUnparse(pRec); sqlite3VdbeMemRelease(&m); return SQLITE_OK; } diff --git a/test/btree.test b/test/btree.test deleted file mode 100644 index 57c73e3157..0000000000 --- a/test/btree.test +++ /dev/null @@ -1,1066 +0,0 @@ -# 2001 September 15 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#*********************************************************************** -# This file implements regression tests for SQLite library. The -# focus of this script is btree database backend -# -# $Id: btree.test,v 1.43 2008/02/02 20:47:38 drh Exp $ - - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -ifcapable default_autovacuum { - finish_test - return -} - -# Basic functionality. Open and close a database. -# -do_test btree-1.1 { - file delete -force test1.bt - file delete -force test1.bt-journal - set rc [catch {btree_open test1.bt 2000 0} ::b1] -} {0} - -# The second element of the list returned by btree_pager_stats is the -# number of pages currently checked out. We'll be checking this value -# frequently during this test script, to make sure the btree library -# is properly releasing the pages it checks out, and thus avoiding -# page leaks. -# -do_test btree-1.1.1 { - lindex [btree_pager_stats $::b1] 1 -} {0} -do_test btree-1.2 { - set rc [catch {btree_open test1.bt 2000 0} ::b2] -} {0} -do_test btree-1.3 { - set rc [catch {btree_close $::b2} msg] - lappend rc $msg -} {0 {}} - -# Do an insert and verify that the database file grows in size. -# -do_test btree-1.4 { - set rc [catch {btree_begin_transaction $::b1} msg] - lappend rc $msg -} {0 {}} -do_test btree-1.4.1 { - lindex [btree_pager_stats $::b1] 1 -} {1} -do_test btree-1.5 { - set rc [catch {btree_cursor $::b1 1 1} ::c1] - if {$rc} {lappend rc $::c1} - set rc -} {0} -do_test btree-1.6 { - set rc [catch {btree_insert $::c1 100 1.00} msg] - lappend rc $msg -} {0 {}} -do_test btree-1.7 { - btree_move_to $::c1 100 - btree_key $::c1 -} {100} -do_test btree-1.8 { - btree_data $::c1 -} {1.00} -do_test btree-1.9 { - set rc [catch {btree_close_cursor $::c1} msg] - lappend rc $msg -} {0 {}} -do_test btree-1.10 { - set rc [catch {btree_commit $::b1} msg] - lappend rc $msg -} {0 {}} -do_test btree-1.11 { - file size test1.bt -} {1024} -do_test btree-1.12 { - lindex [btree_pager_stats $::b1] 1 -} {0} - -# Reopen the database and attempt to read the record that we wrote. -# -do_test btree-2.1 { - set rc [catch {btree_cursor $::b1 1 1} ::c1] - if {$rc} {lappend rc $::c1} - set rc -} {0} -do_test btree-2.1.1 { - btree_cursor_list $::b1 -} {} -do_test btree-2.2 { - btree_move_to $::c1 99 -} {1} -do_test btree-2.3 { - btree_move_to $::c1 101 -} {-1} -do_test btree-2.4 { - btree_move_to $::c1 100 -} {0} -do_test btree-2.5 { - btree_key $::c1 -} {100} -do_test btree-2.6 { - btree_data $::c1 -} {1.00} -do_test btree-2.7 { - lindex [btree_pager_stats $::b1] 1 -} {1} - -# Do some additional inserts -# -do_test btree-3.1 { - btree_begin_transaction $::b1 - btree_insert $::c1 200 2.00 - btree_move_to $::c1 200 - btree_key $::c1 -} {200} -do_test btree-3.1.1 { - lindex [btree_pager_stats $::b1] 1 -} {1} -do_test btree-3.2 { - btree_insert $::c1 300 3.00 - btree_move_to $::c1 300 - btree_key $::c1 -} {300} -do_test btree-3.4 { - btree_insert $::c1 400 4.00 - btree_move_to $::c1 400 - btree_key $::c1 -} {400} -do_test btree-3.5 { - btree_insert $::c1 500 5.00 - btree_move_to $::c1 500 - btree_key $::c1 -} {500} -do_test btree-3.6 { - btree_insert $::c1 600 6.00 - btree_move_to $::c1 600 - btree_key $::c1 -} {600} -#btree_page_dump $::b1 2 -do_test btree-3.7 { - set rc [btree_move_to $::c1 0] - expr {$rc>0} -} {1} -do_test btree-3.8 { - btree_key $::c1 -} {100} -do_test btree-3.9 { - btree_data $::c1 -} {1.00} -do_test btree-3.10 { - btree_next $::c1 - btree_key $::c1 -} {200} -do_test btree-3.11 { - btree_data $::c1 -} {2.00} -do_test btree-3.12 { - btree_next $::c1 - btree_key $::c1 -} {300} -do_test btree-3.13 { - btree_data $::c1 -} {3.00} -do_test btree-3.14 { - btree_next $::c1 - btree_key $::c1 -} {400} -do_test btree-3.15 { - btree_data $::c1 -} {4.00} -do_test btree-3.16 { - btree_next $::c1 - btree_key $::c1 -} {500} -do_test btree-3.17 { - btree_data $::c1 -} {5.00} -do_test btree-3.18 { - btree_next $::c1 - btree_key $::c1 -} {600} -do_test btree-3.19 { - btree_data $::c1 -} {6.00} -do_test btree-3.20.1 { - btree_next $::c1 - btree_key $::c1 -} {0} -do_test btree-3.20.2 { - btree_eof $::c1 -} {1} -# This test case used to test that one couldn't request data from an -# invalid cursor. That is now an assert()ed condition. -# -# do_test btree-3.21 { -# set rc [catch {btree_data $::c1} res] -# lappend rc $res -# } {1 SQLITE_INTERNAL} - -# Commit the changes, reopen and reread the data -# -do_test btree-3.22 { - set rc [catch {btree_close_cursor $::c1} msg] - lappend rc $msg -} {0 {}} -do_test btree-3.22.1 { - lindex [btree_pager_stats $::b1] 1 -} {1} -do_test btree-3.23 { - set rc [catch {btree_commit $::b1} msg] - lappend rc $msg -} {0 {}} -do_test btree-3.23.1 { - lindex [btree_pager_stats $::b1] 1 -} {0} -do_test btree-3.24 { - file size test1.bt -} {1024} -do_test btree-3.25 { - set rc [catch {btree_cursor $::b1 1 1} ::c1] - if {$rc} {lappend rc $::c1} - set rc -} {0} -do_test btree-3.25.1 { - lindex [btree_pager_stats $::b1] 1 -} {1} -do_test btree-3.26 { - set rc [btree_move_to $::c1 0] - expr {$rc>0} -} {1} -do_test btree-3.27 { - btree_key $::c1 -} {100} -do_test btree-3.28 { - btree_data $::c1 -} {1.00} -do_test btree-3.29 { - btree_next $::c1 - btree_key $::c1 -} {200} -do_test btree-3.30 { - btree_data $::c1 -} {2.00} -do_test btree-3.31 { - btree_next $::c1 - btree_key $::c1 -} {300} -do_test btree-3.32 { - btree_data $::c1 -} {3.00} -do_test btree-3.33 { - btree_next $::c1 - btree_key $::c1 -} {400} -do_test btree-3.34 { - btree_data $::c1 -} {4.00} -do_test btree-3.35 { - btree_next $::c1 - btree_key $::c1 -} {500} -do_test btree-3.36 { - btree_data $::c1 -} {5.00} -do_test btree-3.37 { - btree_next $::c1 - btree_key $::c1 -} {600} -do_test btree-3.38 { - btree_data $::c1 -} {6.00} -do_test btree-3.39 { - btree_next $::c1 - btree_key $::c1 -} {0} -# This test case used to test that requesting data from an invalid cursor -# returned SQLITE_INTERNAL. That is now an assert()ed condition. -# -# do_test btree-3.40 { -# set rc [catch {btree_data $::c1} res] -# lappend rc $res -# } {1 SQLITE_INTERNAL} -do_test btree-3.41 { - lindex [btree_pager_stats $::b1] 1 -} {1} - - -# Now try a delete -# -do_test btree-4.1 { - btree_begin_transaction $::b1 - btree_move_to $::c1 100 - btree_key $::c1 -} {100} -do_test btree-4.1.1 { - lindex [btree_pager_stats $::b1] 1 -} {1} -do_test btree-4.2 { - btree_delete $::c1 -} {} -do_test btree-4.3 { - btree_move_to $::c1 100 - btree_key $::c1 -} {200} -do_test btree-4.4 { - btree_next $::c1 - btree_key $::c1 -} {300} -do_test btree-4.5 { - btree_next $::c1 - btree_key $::c1 -} {400} -do_test btree-4.4 { - btree_move_to $::c1 0 - set r {} - while 1 { - set key [btree_key $::c1] - if {[btree_eof $::c1]} break - lappend r $key - lappend r [btree_data $::c1] - btree_next $::c1 - } - set r -} {200 2.00 300 3.00 400 4.00 500 5.00 600 6.00} - -# Commit and make sure the delete is still there. -# -do_test btree-4.5 { - btree_commit $::b1 - btree_move_to $::c1 0 - set r {} - while 1 { - set key [btree_key $::c1] - if {[btree_eof $::c1]} break - lappend r $key - lappend r [btree_data $::c1] - btree_next $::c1 - } - set r -} {200 2.00 300 3.00 400 4.00 500 5.00 600 6.00} - -# Completely close the database and reopen it. Then check -# the data again. -# -do_test btree-4.6 { - lindex [btree_pager_stats $::b1] 1 -} {1} -do_test btree-4.7 { - btree_close_cursor $::c1 - lindex [btree_pager_stats $::b1] 1 -} {0} -do_test btree-4.8 { - btree_close $::b1 - set ::b1 [btree_open test1.bt 2000 0] - set ::c1 [btree_cursor $::b1 1 1] - lindex [btree_pager_stats $::b1] 1 -} {1} -do_test btree-4.9 { - set r {} - btree_first $::c1 - while 1 { - set key [btree_key $::c1] - if {[btree_eof $::c1]} break - lappend r $key - lappend r [btree_data $::c1] - btree_next $::c1 - } - set r -} {200 2.00 300 3.00 400 4.00 500 5.00 600 6.00} - -# Try to read and write meta data -# -do_test btree-5.1 { - btree_get_meta $::b1 -} {0 0 0 0 0 0 0 0 0 0} -do_test btree-5.2 { - set rc [catch { - btree_update_meta $::b1 0 1 2 3 4 5 6 7 8 9 - } msg] - lappend rc $msg -} {1 SQLITE_ERROR} -do_test btree-5.3 { - btree_begin_transaction $::b1 - set rc [catch { - btree_update_meta $::b1 0 1 2 3 0 5 6 0 8 9 - } msg] - lappend rc $msg -} {0 {}} -do_test btree-5.4 { - btree_get_meta $::b1 -} {0 1 2 3 0 5 6 0 8 9} -do_test btree-5.5 { - btree_close_cursor $::c1 - btree_rollback $::b1 - btree_get_meta $::b1 -} {0 0 0 0 0 0 0 0 0 0} -do_test btree-5.6 { - btree_begin_transaction $::b1 - btree_update_meta $::b1 0 10 20 30 0 50 60 0 80 90 - btree_commit $::b1 - btree_get_meta $::b1 -} {0 10 20 30 0 50 60 0 80 90} - -proc select_all {cursor} { - set r {} - btree_first $cursor - while {![btree_eof $cursor]} { - set key [btree_key $cursor] - lappend r $key - lappend r [btree_data $cursor] - btree_next $cursor - } - return $r -} -proc select_keys {cursor} { - set r {} - btree_first $cursor - while {![btree_eof $cursor]} { - set key [btree_key $cursor] - lappend r $key - btree_next $cursor - } - return $r -} - -# Try to create a new table in the database file -# -do_test btree-6.1 { - set rc [catch {btree_create_table $::b1 0} msg] - lappend rc $msg -} {1 SQLITE_ERROR} -do_test btree-6.2 { - btree_begin_transaction $::b1 - set ::t2 [btree_create_table $::b1 0] -} {2} -do_test btree-6.2.1 { - lindex [btree_pager_stats $::b1] 1 -} {1} -do_test btree-6.2.2 { - set ::c2 [btree_cursor $::b1 $::t2 1] - lindex [btree_pager_stats $::b1] 1 -} {2} -do_test btree-6.2.3 { - btree_insert $::c2 ten 10 - btree_move_to $::c2 ten - btree_key $::c2 -} {ten} -do_test btree-6.3 { - btree_commit $::b1 - set ::c1 [btree_cursor $::b1 1 1] - lindex [btree_pager_stats $::b1] 1 -} {2} -do_test btree-6.3.1 { - select_all $::c1 -} {200 2.00 300 3.00 400 4.00 500 5.00 600 6.00} -#btree_page_dump $::b1 3 -do_test btree-6.4 { - select_all $::c2 -} {ten 10} - -# Drop the new table, then create it again anew. -# -do_test btree-6.5 { - btree_begin_transaction $::b1 -} {} -do_test btree-6.6 { - btree_close_cursor $::c2 -} {} -do_test btree-6.6.1 { - lindex [btree_pager_stats $::b1] 1 -} {1} -do_test btree-6.7 { - btree_close_cursor $::c1 - btree_drop_table $::b1 $::t2 -} {} -do_test btree-6.7.1 { - lindex [btree_get_meta $::b1] 0 -} {1} -do_test btree-6.8 { - set ::t2 [btree_create_table $::b1 0] -} {2} -do_test btree-6.8.1 { - lindex [btree_get_meta $::b1] 0 -} {0} -do_test btree-6.9 { - set ::c2 [btree_cursor $::b1 $::t2 1] - lindex [btree_pager_stats $::b1] 1 -} {2} - -# This test case used to test that requesting the key from an invalid cursor -# returned an empty string. But that is now an assert()ed condition. -# -# do_test btree-6.9.1 { -# btree_move_to $::c2 {} -# btree_key $::c2 -# } {} - -# If we drop table 1 it just clears the table. Table 1 always exists. -# -do_test btree-6.10 { - btree_close_cursor $::c2 - btree_drop_table $::b1 1 - set ::c2 [btree_cursor $::b1 $::t2 1] - set ::c1 [btree_cursor $::b1 1 1] - btree_first $::c1 - btree_eof $::c1 -} {1} -do_test btree-6.11 { - btree_commit $::b1 - select_all $::c1 -} {} -do_test btree-6.12 { - select_all $::c2 -} {} -do_test btree-6.13 { - btree_close_cursor $::c2 - lindex [btree_pager_stats $::b1] 1 -} {1} - -# Check to see that pages defragment properly. To do this test we will -# -# 1. Fill the first page of table 1 with data. -# 2. Delete every other entry of table 1. -# 3. Insert a single entry that requires more contiguous -# space than is available. -# -do_test btree-7.1 { - btree_begin_transaction $::b1 -} {} -catch {unset key} -catch {unset data} - -# Check to see that data on overflow pages work correctly. -# -do_test btree-8.1 { - set data "*** This is a very long key " - while {[string length $data]<1234} {append data $data} - set ::data $data - btree_insert $::c1 2020 $data -} {} -btree_page_dump $::b1 1 -btree_page_dump $::b1 2 -do_test btree-8.1.1 { - lindex [btree_pager_stats $::b1] 1 -} {1} -btree_pager_ref_dump $::b1 -do_test btree-8.2 { - btree_move_to $::c1 2020 - string length [btree_data $::c1] -} [string length $::data] -do_test btree-8.3 { - btree_data $::c1 -} $::data -do_test btree-8.4 { - btree_delete $::c1 -} {} -do_test btree-8.4.1 { - lindex [btree_get_meta $::b1] 0 -} [expr {int(([string length $::data]-238+1019)/1020)}] -do_test btree-8.4.2 { - btree_integrity_check $::b1 1 2 -} {} -do_test btree-8.5 { - set data "*** This is an even longer key " - while {[string length $data]<2000} {append data $data} - append data END - set ::data $data - btree_insert $::c1 2030 $data -} {} -do_test btree-8.6 { - btree_move_to $::c1 2030 - string length [btree_data $::c1] -} [string length $::data] -do_test btree-8.7 { - btree_data $::c1 -} $::data -do_test btree-8.8 { - btree_commit $::b1 - btree_data $::c1 -} $::data -do_test btree-8.9.1 { - btree_close_cursor $::c1 - btree_close $::b1 - set ::b1 [btree_open test1.bt 2000 0] - set ::c1 [btree_cursor $::b1 1 1] - btree_move_to $::c1 2030 - btree_data $::c1 -} $::data -do_test btree-8.9.2 { - btree_integrity_check $::b1 1 2 -} {} -do_test btree-8.10 { - btree_begin_transaction $::b1 - btree_delete $::c1 -} {} -do_test btree-8.11 { - lindex [btree_get_meta $::b1] 0 -} {4} - -# Now check out keys on overflow pages. -# -do_test btree-8.12.1 { - set ::keyprefix "This is a long prefix to a key " - while {[string length $::keyprefix]<256} {append ::keyprefix $::keyprefix} - btree_close_cursor $::c1 - btree_clear_table $::b1 2 - lindex [btree_get_meta $::b1] 0 -} {4} -do_test btree-8.12.2 { - btree_integrity_check $::b1 1 2 -} {} -do_test btree-8.12.3 { - set ::c1 [btree_cursor $::b1 2 1] - btree_insert $::c1 ${::keyprefix}1 1 - btree_first $::c1 - btree_data $::c1 -} {1} -do_test btree-8.13 { - btree_key $::c1 -} ${keyprefix}1 -do_test btree-8.14 { - btree_insert $::c1 ${::keyprefix}2 2 - btree_insert $::c1 ${::keyprefix}3 3 - btree_last $::c1 - btree_key $::c1 -} ${keyprefix}3 -do_test btree-8.15 { - btree_move_to $::c1 ${::keyprefix}2 - btree_data $::c1 -} {2} -do_test btree-8.16 { - btree_move_to $::c1 ${::keyprefix}1 - btree_data $::c1 -} {1} -do_test btree-8.17 { - btree_move_to $::c1 ${::keyprefix}3 - btree_data $::c1 -} {3} -do_test btree-8.18 { - lindex [btree_get_meta $::b1] 0 -} {1} -do_test btree-8.19 { - btree_move_to $::c1 ${::keyprefix}2 - btree_key $::c1 -} ${::keyprefix}2 -#btree_page_dump $::b1 2 -do_test btree-8.20 { - btree_delete $::c1 - btree_next $::c1 - btree_key $::c1 -} ${::keyprefix}3 -#btree_page_dump $::b1 2 -do_test btree-8.21 { - lindex [btree_get_meta $::b1] 0 -} {2} -do_test btree-8.22 { - lindex [btree_pager_stats $::b1] 1 -} {2} -do_test btree-8.23.1 { - btree_close_cursor $::c1 - btree_drop_table $::b1 2 - btree_integrity_check $::b1 1 -} {} -do_test btree-8.23.2 { - btree_create_table $::b1 0 -} {2} -do_test btree-8.23.3 { - set ::c1 [btree_cursor $::b1 2 1] - lindex [btree_get_meta $::b1] 0 -} {4} -do_test btree-8.24 { - lindex [btree_pager_stats $::b1] 1 -} {2} -#btree_pager_ref_dump $::b1 -do_test btree-8.25 { - btree_integrity_check $::b1 1 2 -} {} - -# Check page splitting logic -# -do_test btree-9.1 { - for {set i 1} {$i<=19} {incr i} { - set key [format %03d $i] - set data "*** $key *** $key *** $key *** $key ***" - btree_insert $::c1 $key $data - } -} {} -do_test btree-9.2 { - btree_insert $::c1 020 {*** 020 *** 020 *** 020 *** 020 ***} - select_keys $::c1 -} {001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020} - -# The previous "select_keys" command left the cursor pointing at the root -# page. So there should only be two pages checked out. 2 (the root) and -# page 1. -do_test btree-9.2.1 { - lindex [btree_pager_stats $::b1] 1 -} {2} -for {set i 1} {$i<=20} {incr i} { - do_test btree-9.3.$i.1 [subst { - btree_move_to $::c1 [format %03d $i] - btree_key $::c1 - }] [format %03d $i] - do_test btree-9.3.$i.2 [subst { - btree_move_to $::c1 [format %03d $i] - string range \[btree_data $::c1\] 0 10 - }] "*** [format %03d $i] ***" -} -do_test btree-9.4.1 { - lindex [btree_pager_stats $::b1] 1 -} {2} - -# Check the page joining logic. -# -#btree_page_dump $::b1 2 -#btree_pager_ref_dump $::b1 -do_test btree-9.4.2 { - btree_move_to $::c1 005 - btree_delete $::c1 -} {} -#btree_page_dump $::b1 2 -for {set i 1} {$i<=19} {incr i} { - if {$i==5} continue - do_test btree-9.5.$i.1 [subst { - btree_move_to $::c1 [format %03d $i] - btree_key $::c1 - }] [format %03d $i] - do_test btree-9.5.$i.2 [subst { - btree_move_to $::c1 [format %03d $i] - string range \[btree_data $::c1\] 0 10 - }] "*** [format %03d $i] ***" -} -#btree_pager_ref_dump $::b1 -do_test btree-9.6 { - btree_close_cursor $::c1 - lindex [btree_pager_stats $::b1] 1 -} {1} -do_test btree-9.7 { - btree_integrity_check $::b1 1 2 -} {} -do_test btree-9.8 { - btree_rollback $::b1 - lindex [btree_pager_stats $::b1] 1 -} {0} -do_test btree-9.9 { - btree_integrity_check $::b1 1 2 -} {} -do_test btree-9.10 { - btree_close $::b1 - set ::b1 [btree_open test1.bt 2000 0] - btree_integrity_check $::b1 1 2 -} {} - -# Create a tree of depth two. That is, there is a single divider entry -# on the root pages and two leaf pages. Then delete the divider entry -# see what happens. -# -do_test btree-10.1 { - btree_begin_transaction $::b1 - btree_clear_table $::b1 2 - lindex [btree_pager_stats $::b1] 1 -} {1} -do_test btree-10.2 { - set ::c1 [btree_cursor $::b1 2 1] - lindex [btree_pager_stats $::b1] 1 -} {2} -do_test btree-10.3 { -btree_breakpoint - for {set i 1} {$i<=30} {incr i} { - set key [format %03d $i] - set data "*** $key *** $key *** $key *** $key ***" - btree_insert $::c1 $key $data - } - select_keys $::c1 -} {001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030} -#btree_tree_dump $::b1 2 -do_test btree-10.4 { - # The divider entry is 012. This is found by uncommenting the - # btree_tree_dump call above and looking at the tree. If the page size - # changes, this test will no longer work. - btree_move_to $::c1 012 - btree_delete $::c1 - select_keys $::c1 -} {001 002 003 004 005 006 007 008 009 010 011 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030} -#btree_pager_ref_dump $::b1 -#btree_tree_dump $::b1 2 -for {set i 1} {$i<=30} {incr i} { - # Check the number of unreference pages. This should be 3 in most cases, - # but 2 when the cursor is pointing to the divider entry which is now 013. - do_test btree-10.5.$i { - btree_move_to $::c1 [format %03d $i] - lindex [btree_pager_stats $::b1] 1 - } [expr {$i==13?2:3}] - #btree_pager_ref_dump $::b1 - #btree_tree_dump $::b1 2 -} - -# Create a tree with lots more pages -# -catch {unset ::data} -catch {unset ::key} -for {set i 31} {$i<=2000} {incr i} { - do_test btree-11.1.$i.1 { - set key [format %03d $i] - set ::data "*** $key *** $key *** $key *** $key ***" - btree_insert $::c1 $key $data - btree_move_to $::c1 $key - btree_key $::c1 - } [format %03d $i] - do_test btree-11.1.$i.2 { - btree_data $::c1 - } $::data - set ::key [format %03d [expr {$i/2}]] - if {$::key=="012"} {set ::key 013} - do_test btree-11.1.$i.3 { - btree_move_to $::c1 $::key - btree_key $::c1 - } $::key -} -catch {unset ::data} -catch {unset ::key} - -# Make sure our reference count is still correct. -# -do_test btree-11.2 { - btree_close_cursor $::c1 - lindex [btree_pager_stats $::b1] 1 -} {1} -do_test btree-11.3 { - set ::c1 [btree_cursor $::b1 2 1] - lindex [btree_pager_stats $::b1] 1 -} {2} - -# Delete the dividers on the root page -# -#btree_page_dump $::b1 2 -do_test btree-11.4 { - btree_move_to $::c1 1667 - btree_delete $::c1 - btree_move_to $::c1 1667 - set k [btree_key $::c1] - if {$k==1666} { - set k [btree_next $::c1] - } - btree_key $::c1 -} {1668} -#btree_page_dump $::b1 2 - -# Change the data on an intermediate node such that the node becomes overfull -# and has to split. We happen to know that intermediate nodes exist on -# 337, 401 and 465 by the btree_page_dumps above -# -catch {unset ::data} -set ::data {This is going to be a very long data segment} -append ::data $::data -append ::data $::data -do_test btree-12.1 { - btree_insert $::c1 337 $::data - btree_move_to $::c1 337 - btree_data $::c1 -} $::data -do_test btree-12.2 { - btree_insert $::c1 401 $::data - btree_move_to $::c1 401 - btree_data $::c1 -} $::data -do_test btree-12.3 { - btree_insert $::c1 465 $::data - btree_move_to $::c1 465 - btree_data $::c1 -} $::data -do_test btree-12.4 { - btree_move_to $::c1 337 - btree_key $::c1 -} {337} -do_test btree-12.5 { - btree_data $::c1 -} $::data -do_test btree-12.6 { - btree_next $::c1 - btree_key $::c1 -} {338} -do_test btree-12.7 { - btree_move_to $::c1 464 - btree_key $::c1 -} {464} -do_test btree-12.8 { - btree_next $::c1 - btree_data $::c1 -} $::data -do_test btree-12.9 { - btree_next $::c1 - btree_key $::c1 -} {466} -do_test btree-12.10 { - btree_move_to $::c1 400 - btree_key $::c1 -} {400} -do_test btree-12.11 { - btree_next $::c1 - btree_data $::c1 -} $::data -do_test btree-12.12 { - btree_next $::c1 - btree_key $::c1 -} {402} -# btree_commit $::b1 -# btree_tree_dump $::b1 1 -do_test btree-13.1 { - btree_integrity_check $::b1 1 2 -} {} - -# To Do: -# -# 1. Do some deletes from the 3-layer tree -# 2. Commit and reopen the database -# 3. Read every 15th entry and make sure it works -# 4. Implement btree_sanity and put it throughout this script -# - -do_test btree-15.98 { - btree_close_cursor $::c1 - lindex [btree_pager_stats $::b1] 1 -} {1} -do_test btree-15.99 { - btree_rollback $::b1 - lindex [btree_pager_stats $::b1] 1 -} {0} -btree_pager_ref_dump $::b1 - -# Miscellaneous tests. -# -# btree-16.1 - Check that a statement cannot be started if a transaction -# is not active. -# btree-16.2 - Check that it is an error to request more payload from a -# btree entry than the entry contains. -do_test btree-16.1 { - catch {btree_begin_statement $::b1} msg - set msg -} SQLITE_ERROR - -do_test btree-16.2 { - btree_begin_transaction $::b1 - set ::c1 [btree_cursor $::b1 2 1] - btree_insert $::c1 1 helloworld - btree_close_cursor $::c1 - btree_commit $::b1 -} {} -do_test btree-16.3 { - set ::c1 [btree_cursor $::b1 2 1] - btree_first $::c1 -} 0 -do_test btree-16.4 { - catch {btree_data $::c1 [expr [btree_payload_size $::c1] + 10]} msg - set msg -} SQLITE_ERROR - -if {$tcl_platform(platform)=="unix"} { - do_test btree-16.5 { - btree_close $::b1 - set ::origperm [file attributes test1.bt -permissions] - file attributes test1.bt -permissions o-w,g-w,a-w - set ::b1 [btree_open test1.bt 2000 0] - catch {btree_cursor $::b1 2 1} msg - file attributes test1.bt -permissions $::origperm - btree_close $::b1 - set ::b1 [btree_open test1.bt 2000 0] - set msg - } {SQLITE_READONLY} -} - -do_test btree-16.6 { - set ::c1 [btree_cursor $::b1 2 1] - set ::c2 [btree_cursor $::b1 2 1] - btree_begin_transaction $::b1 - for {set i 0} {$i<100} {incr i} { - btree_insert $::c1 $i [string repeat helloworld 10] - } - btree_last $::c2 - btree_insert $::c1 100 [string repeat helloworld 10] -} {} - -do_test btree-16.7 { - btree_close_cursor $::c1 - btree_close_cursor $::c2 - btree_commit $::b1 - set ::c1 [btree_cursor $::b1 2 1] - catch {btree_insert $::c1 101 helloworld} msg - set msg -} {SQLITE_ERROR} -do_test btree-16.8 { - btree_first $::c1 - catch {btree_delete $::c1} msg - set msg -} {SQLITE_ERROR} -do_test btree-16.9 { - btree_close_cursor $::c1 - btree_begin_transaction $::b1 - set ::c1 [btree_cursor $::b1 2 0] - catch {btree_insert $::c1 101 helloworld} msg - set msg -} {SQLITE_PERM} -do_test btree-16.10 { - catch {btree_delete $::c1} msg - set msg -} {SQLITE_PERM} - -# As of 2006-08-16 (version 3.3.7+) a read cursor will no -# longer block a write cursor from the same database -# connectiin. The following three tests uses to return -# the SQLITE_LOCK error, but no more. -# -do_test btree-16.11 { - btree_close_cursor $::c1 - set ::c2 [btree_cursor $::b1 2 1] - set ::c1 [btree_cursor $::b1 2 0] - catch {btree_insert $::c2 101 helloworld} msg - set msg -} {} -do_test btree-16.12 { - btree_first $::c2 - catch {btree_delete $::c2} msg - set msg -} {} -do_test btree-16.13 { - catch {btree_clear_table $::b1 2} msg - set msg -} {} - - -do_test btree-16.14 { - btree_close_cursor $::c1 - btree_close_cursor $::c2 - btree_commit $::b1 - catch {btree_clear_table $::b1 2} msg - set msg -} {SQLITE_ERROR} -do_test btree-16.15 { - catch {btree_drop_table $::b1 2} msg - set msg -} {SQLITE_ERROR} -do_test btree-16.16 { - btree_begin_transaction $::b1 - set ::c1 [btree_cursor $::b1 2 0] - catch {btree_drop_table $::b1 2} msg - set msg -} {SQLITE_LOCKED} - -do_test btree-99.1 { - btree_close $::b1 -} {} -catch {unset data} -catch {unset key} - -finish_test diff --git a/test/btree2.test b/test/btree2.test deleted file mode 100644 index 35263c1d83..0000000000 --- a/test/btree2.test +++ /dev/null @@ -1,502 +0,0 @@ -# 2001 September 15 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#*********************************************************************** -# This file implements regression tests for SQLite library. The -# focus of this script is btree database backend -# -# $Id: btree2.test,v 1.15 2006/03/19 13:00:25 drh Exp $ - - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -if {[info commands btree_open]!=""} { - -# Create a new database file containing no entries. The database should -# contain 5 tables: -# -# 2 The descriptor table -# 3 The foreground table -# 4 The background table -# 5 The long key table -# 6 The long data table -# -# An explanation for what all these tables are used for is provided below. -# -do_test btree2-1.1 { - expr srand(1) - file delete -force test2.bt - file delete -force test2.bt-journal - set ::b [btree_open test2.bt 2000 0] - btree_begin_transaction $::b - btree_create_table $::b 0 -} {2} -do_test btree2-1.2 { - btree_create_table $::b 0 -} {3} -do_test btree2-1.3 { - btree_create_table $::b 0 -} {4} -do_test btree2-1.4 { - btree_create_table $::b 0 -} {5} -do_test btree2-1.5 { - btree_create_table $::b 0 -} {6} -do_test btree2-1.6 { - set ::c2 [btree_cursor $::b 2 1] - btree_insert $::c2 {one} {1} - btree_move_to $::c2 {one} - btree_delete $::c2 - btree_close_cursor $::c2 - btree_commit $::b - btree_integrity_check $::b 1 2 3 4 5 6 -} {} - -# This test module works by making lots of pseudo-random changes to a -# database while simultaneously maintaining an invariant on that database. -# Periodically, the script does a sanity check on the database and verifies -# that the invariant is satisfied. -# -# The invariant is as follows: -# -# 1. The descriptor table always contains 2 enters. An entry keyed by -# "N" is the number of elements in the foreground and background tables -# combined. The entry keyed by "L" is the number of digits in the keys -# for foreground and background tables. -# -# 2. The union of the foreground an background tables consists of N entries -# where each entry has an L-digit key. (Actually, some keys can be longer -# than L characters, but they always start with L digits.) The keys -# cover all integers between 1 and N. Whenever an entry is added to -# the foreground it is removed form the background and vice versa. -# -# 3. Some entries in the foreground and background tables have keys that -# begin with an L-digit number but are followed by additional characters. -# For each such entry there is a corresponding entry in the long key -# table. The long key table entry has a key which is just the L-digit -# number and data which is the length of the key in the foreground and -# background tables. -# -# 4. The data for both foreground and background entries is usually a -# short string. But some entries have long data strings. For each -# such entries there is an entry in the long data type. The key to -# long data table is an L-digit number. (The extension on long keys -# is omitted.) The data is the number of charaters in the data of the -# foreground or background entry. -# -# The following function builds a database that satisfies all of the above -# invariants. -# -proc build_db {N L} { - for {set i 2} {$i<=6} {incr i} { - catch {btree_close_cursor [set ::c$i]} - btree_clear_table $::b $i - set ::c$i [btree_cursor $::b $i 1] - } - btree_insert $::c2 N $N - btree_insert $::c2 L $L - set format %0${L}d - for {set i 1} {$i<=$N} {incr i} { - set key [format $format $i] - set data $key - btree_insert $::c3 $key $data - } -} - -# Given a base key number and a length, construct the full text of the key -# or data. -# -proc make_payload {keynum L len} { - set key [format %0${L}d $keynum] - set r $key - set i 1 - while {[string length $r]<$len} { - append r " ($i) $key" - incr i - } - return [string range $r 0 [expr {$len-1}]] -} - -# Verify the invariants on the database. Return an empty string on -# success or an error message if something is amiss. -# -proc check_invariants {} { - set ck [btree_integrity_check $::b 1 2 3 4 5 6] - if {$ck!=""} { - puts "\n*** SANITY:\n$ck" - exit - return $ck - } - btree_move_to $::c3 {} - btree_move_to $::c4 {} - btree_move_to $::c2 N - set N [btree_data $::c2] - btree_move_to $::c2 L - set L [btree_data $::c2] - set LM1 [expr {$L-1}] - for {set i 1} {$i<=$N} {incr i} { - set key {} - if {![btree_eof $::c3]} { - set key [btree_key $::c3] - } - if {[scan $key %d k]<1} {set k 0} - if {$k!=$i} { - set key {} - if {![btree_eof $::c4]} { - set key [btree_key $::c4] - } - if {[scan $key %d k]<1} {set k 0} - if {$k!=$i} { - return "Key $i is missing from both foreground and background" - } - set data [btree_data $::c4] - btree_next $::c4 - } else { - set data [btree_data $::c3] - btree_next $::c3 - } - set skey [string range $key 0 $LM1] - if {[btree_move_to $::c5 $skey]==0} { - set keylen [btree_data $::c5] - } else { - set keylen $L - } - if {[string length $key]!=$keylen} { - return "Key $i is the wrong size.\ - Is \"$key\" but should be \"[make_payload $k $L $keylen]\"" - } - if {[make_payload $k $L $keylen]!=$key} { - return "Key $i has an invalid extension" - } - if {[btree_move_to $::c6 $skey]==0} { - set datalen [btree_data $::c6] - } else { - set datalen $L - } - if {[string length $data]!=$datalen} { - return "Data for $i is the wrong size.\ - Is [string length $data] but should be $datalen" - } - if {[make_payload $k $L $datalen]!=$data} { - return "Entry $i has an incorrect data" - } - } -} - -# Look at all elements in both the foreground and background tables. -# Make sure the key is always the same as the prefix of the data. -# -# This routine was used for hunting bugs. It is not a part of standard -# tests. -# -proc check_data {n key} { - global c3 c4 - incr n -1 - foreach c [list $c3 $c4] { - btree_first $c ;# move_to $c $key - set cnt 0 - while {![btree_eof $c]} { - set key [btree_key $c] - set data [btree_data $c] - if {[string range $key 0 $n] ne [string range $data 0 $n]} { - puts "key=[list $key] data=[list $data] n=$n" - puts "cursor info = [btree_cursor_info $c]" - btree_page_dump $::b [lindex [btree_cursor_info $c] 0] - exit - } - btree_next $c - } - } -} - -# Make random changes to the database such that each change preserves -# the invariants. The number of changes is $n*N where N is the parameter -# from the descriptor table. Each changes begins with a random key. -# the entry with that key is put in the foreground table with probability -# $I and it is put in background with probability (1.0-$I). It gets -# a long key with probability $K and long data with probability $D. -# -set chngcnt 0 -proc random_changes {n I K D} { - global chngcnt - btree_move_to $::c2 N - set N [btree_data $::c2] - btree_move_to $::c2 L - set L [btree_data $::c2] - set LM1 [expr {$L-1}] - set total [expr {int($N*$n)}] - set format %0${L}d - for {set i 0} {$i<$total} {incr i} { - set k [expr {int(rand()*$N)+1}] - set insert [expr {rand()<=$I}] - set longkey [expr {rand()<=$K}] - set longdata [expr {rand()<=$D}] - if {$longkey} { - set x [expr {rand()}] - set keylen [expr {int($x*$x*$x*$x*3000)+10}] - } else { - set keylen $L - } - set key [make_payload $k $L $keylen] - if {$longdata} { - set x [expr {rand()}] - set datalen [expr {int($x*$x*$x*$x*3000)+10}] - } else { - set datalen $L - } - set data [make_payload $k $L $datalen] - set basekey [format $format $k] - if {[set c [btree_move_to $::c3 $basekey]]==0} { - btree_delete $::c3 - } else { - if {$c<0} {btree_next $::c3} - if {![btree_eof $::c3]} { - if {[string match $basekey* [btree_key $::c3]]} { - btree_delete $::c3 - } - } - } - if {[set c [btree_move_to $::c4 $basekey]]==0} { - btree_delete $::c4 - } else { - if {$c<0} {btree_next $::c4} - if {![btree_eof $::c4]} { - if {[string match $basekey* [btree_key $::c4]]} { - btree_delete $::c4 - } - } - } - set kx -1 - if {![btree_eof $::c4]} { - if {[scan [btree_key $::c4] %d kx]<1} {set kx -1} - } - if {$kx==$k} { - btree_delete $::c4 - } - # For debugging - change the "0" to "1" to integrity check after - # every change. - if 0 { - incr chngcnt - puts check----$chngcnt - set ck [btree_integrity_check $::b 1 2 3 4 5 6] - if {$ck!=""} { - puts "\nSANITY CHECK FAILED!\n$ck" - exit - } - } - if {$insert} { - btree_insert $::c3 $key $data - } else { - btree_insert $::c4 $key $data - } - if {$longkey} { - btree_insert $::c5 $basekey $keylen - } elseif {[btree_move_to $::c5 $basekey]==0} { - btree_delete $::c5 - } - if {$longdata} { - btree_insert $::c6 $basekey $datalen - } elseif {[btree_move_to $::c6 $basekey]==0} { - btree_delete $::c6 - } - # For debugging - change the "0" to "1" to integrity check after - # every change. - if 0 { - incr chngcnt - puts check----$chngcnt - set ck [btree_integrity_check $::b 1 2 3 4 5 6] - if {$ck!=""} { - puts "\nSANITY CHECK FAILED!\n$ck" - exit - } - } - } -} -set btree_trace 0 - -# Repeat this test sequence on database of various sizes -# -set testno 2 -foreach {N L} { - 10 2 - 50 2 - 200 3 - 2000 5 -} { - puts "**** N=$N L=$L ****" - set hash [md5file test2.bt] - do_test btree2-$testno.1 [subst -nocommands { - set ::c2 [btree_cursor $::b 2 1] - set ::c3 [btree_cursor $::b 3 1] - set ::c4 [btree_cursor $::b 4 1] - set ::c5 [btree_cursor $::b 5 1] - set ::c6 [btree_cursor $::b 6 1] - btree_begin_transaction $::b - build_db $N $L - check_invariants - }] {} - do_test btree2-$testno.2 { - btree_close_cursor $::c2 - btree_close_cursor $::c3 - btree_close_cursor $::c4 - btree_close_cursor $::c5 - btree_close_cursor $::c6 - btree_rollback $::b - md5file test2.bt - } $hash - do_test btree2-$testno.3 [subst -nocommands { - btree_begin_transaction $::b - set ::c2 [btree_cursor $::b 2 1] - set ::c3 [btree_cursor $::b 3 1] - set ::c4 [btree_cursor $::b 4 1] - set ::c5 [btree_cursor $::b 5 1] - set ::c6 [btree_cursor $::b 6 1] - build_db $N $L - check_invariants - }] {} - do_test btree2-$testno.4 { - btree_commit $::b - check_invariants - } {} - do_test btree2-$testno.5 { - lindex [btree_pager_stats $::b] 1 - } {6} - do_test btree2-$testno.6 { - btree_cursor_info $::c2 - btree_cursor_info $::c3 - btree_cursor_info $::c4 - btree_cursor_info $::c5 - btree_cursor_info $::c6 - btree_close_cursor $::c2 - btree_close_cursor $::c3 - btree_close_cursor $::c4 - btree_close_cursor $::c5 - btree_close_cursor $::c6 - lindex [btree_pager_stats $::b] 1 - } {0} - do_test btree2-$testno.7 { - btree_close $::b - } {} - - # For each database size, run various changes tests. - # - set num2 1 - foreach {n I K D} { - 0.5 0.5 0.1 0.1 - 1.0 0.2 0.1 0.1 - 1.0 0.8 0.1 0.1 - 2.0 0.0 0.1 0.1 - 2.0 1.0 0.1 0.1 - 2.0 0.0 0.0 0.0 - 2.0 1.0 0.0 0.0 - } { - set testid btree2-$testno.8.$num2 - set hash [md5file test2.bt] - do_test $testid.0 { - set ::b [btree_open test2.bt 2000 0] - set ::c2 [btree_cursor $::b 2 1] - set ::c3 [btree_cursor $::b 3 1] - set ::c4 [btree_cursor $::b 4 1] - set ::c5 [btree_cursor $::b 5 1] - set ::c6 [btree_cursor $::b 6 1] - check_invariants - } {} - set cnt 6 - for {set i 2} {$i<=6} {incr i} { - if {[lindex [btree_cursor_info [set ::c$i]] 0]!=$i} {incr cnt} - } - do_test $testid.1 { - btree_begin_transaction $::b - lindex [btree_pager_stats $::b] 1 - } $cnt - do_test $testid.2 [subst { - random_changes $n $I $K $D - }] {} - do_test $testid.3 { - check_invariants - } {} - do_test $testid.4 { - btree_close_cursor $::c2 - btree_close_cursor $::c3 - btree_close_cursor $::c4 - btree_close_cursor $::c5 - btree_close_cursor $::c6 - btree_rollback $::b - md5file test2.bt - } $hash - btree_begin_transaction $::b - set ::c2 [btree_cursor $::b 2 1] - set ::c3 [btree_cursor $::b 3 1] - set ::c4 [btree_cursor $::b 4 1] - set ::c5 [btree_cursor $::b 5 1] - set ::c6 [btree_cursor $::b 6 1] - do_test $testid.5 [subst { - random_changes $n $I $K $D - }] {} - do_test $testid.6 { - check_invariants - } {} - do_test $testid.7 { - btree_commit $::b - check_invariants - } {} - set hash [md5file test2.bt] - do_test $testid.8 { - btree_close_cursor $::c2 - btree_close_cursor $::c3 - btree_close_cursor $::c4 - btree_close_cursor $::c5 - btree_close_cursor $::c6 - lindex [btree_pager_stats $::b] 1 - } {0} - do_test $testid.9 { - btree_close $::b - set ::b [btree_open test2.bt 2000 0] - set ::c2 [btree_cursor $::b 2 1] - set ::c3 [btree_cursor $::b 3 1] - set ::c4 [btree_cursor $::b 4 1] - set ::c5 [btree_cursor $::b 5 1] - set ::c6 [btree_cursor $::b 6 1] - check_invariants - } {} - do_test $testid.10 { - btree_close_cursor $::c2 - btree_close_cursor $::c3 - btree_close_cursor $::c4 - btree_close_cursor $::c5 - btree_close_cursor $::c6 - lindex [btree_pager_stats $::b] 1 - } {0} - do_test $testid.11 { - btree_close $::b - } {} - incr num2 - } - incr testno - set ::b [btree_open test2.bt 2000 0] -} - -# Testing is complete. Shut everything down. -# -do_test btree-999.1 { - lindex [btree_pager_stats $::b] 1 -} {0} -do_test btree-999.2 { - btree_close $::b -} {} -do_test btree-999.3 { - file delete -force test2.bt - file exists test2.bt-journal -} {0} - -} ;# end if( not mem: and has pager_open command ); - -finish_test diff --git a/test/btree4.test b/test/btree4.test deleted file mode 100644 index 8a08af3d60..0000000000 --- a/test/btree4.test +++ /dev/null @@ -1,101 +0,0 @@ -# 2002 December 03 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#*********************************************************************** -# This file implements regression tests for SQLite library. The -# focus of this script is btree database backend -# -# This file focuses on testing the sqliteBtreeNext() and -# sqliteBtreePrevious() procedures and making sure they are able -# to step through an entire table from either direction. -# -# $Id: btree4.test,v 1.2 2004/05/09 20:40:12 drh Exp $ - - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -if {[info commands btree_open]!=""} { - -# Open a test database. -# -file delete -force test1.bt -file delete -force test1.bt-journal -set b1 [btree_open test1.bt 2000 0] -btree_begin_transaction $b1 -do_test btree4-0.1 { - btree_create_table $b1 0 -} 2 - -set data {abcdefghijklmnopqrstuvwxyz0123456789} -append data $data -append data $data -append data $data -append data $data - -foreach N {10 100 1000} { - btree_clear_table $::b1 2 - set ::c1 [btree_cursor $::b1 2 1] - do_test btree4-$N.1 { - for {set i 1} {$i<=$N} {incr i} { - btree_insert $::c1 [format k-%05d $i] $::data-$i - } - btree_first $::c1 - btree_key $::c1 - } {k-00001} - do_test btree4-$N.2 { - btree_data $::c1 - } $::data-1 - for {set i 2} {$i<=$N} {incr i} { - do_test btree-$N.3.$i.1 { - btree_next $::c1 - } 0 - do_test btree-$N.3.$i.2 { - btree_key $::c1 - } [format k-%05d $i] - do_test btree-$N.3.$i.3 { - btree_data $::c1 - } $::data-$i - } - do_test btree4-$N.4 { - btree_next $::c1 - } 1 - do_test btree4-$N.5 { - btree_last $::c1 - } 0 - do_test btree4-$N.6 { - btree_key $::c1 - } [format k-%05d $N] - do_test btree4-$N.7 { - btree_data $::c1 - } $::data-$N - for {set i [expr {$N-1}]} {$i>=1} {incr i -1} { - do_test btree4-$N.8.$i.1 { - btree_prev $::c1 - } 0 - do_test btree4-$N.8.$i.2 { - btree_key $::c1 - } [format k-%05d $i] - do_test btree4-$N.8.$i.3 { - btree_data $::c1 - } $::data-$i - } - do_test btree4-$N.9 { - btree_prev $::c1 - } 1 - btree_close_cursor $::c1 -} - -btree_rollback $::b1 -btree_pager_ref_dump $::b1 -btree_close $::b1 - -} ;# end if( not mem: and has pager_open command ); - -finish_test diff --git a/test/btree5.test b/test/btree5.test deleted file mode 100644 index 2afcd8425f..0000000000 --- a/test/btree5.test +++ /dev/null @@ -1,292 +0,0 @@ -# 2004 May 10 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#*********************************************************************** -# This file implements regression tests for SQLite library. The -# focus of this script is btree database backend -# -# $Id: btree5.test,v 1.5 2004/05/14 12:17:46 drh Exp $ - - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# Attempting to read table 1 of an empty file gives an SQLITE_EMPTY -# error. -# -do_test btree5-1.1 { - file delete -force test1.bt - file delete -force test1.bt-journal - set rc [catch {btree_open test1.bt 2000 0} ::b1] -} {0} -do_test btree5-1.2 { - set rc [catch {btree_cursor $::b1 1 0} ::c1] -} {1} -do_test btree5-1.3 { - set ::c1 -} {SQLITE_EMPTY} -do_test btree5-1.4 { - set rc [catch {btree_cursor $::b1 1 1} ::c1] -} {1} -do_test btree5-1.5 { - set ::c1 -} {SQLITE_EMPTY} - -# Starting a transaction initializes the first page of the database -# and the error goes away. -# -do_test btree5-1.6 { - btree_begin_transaction $b1 - set rc [catch {btree_cursor $b1 1 0} c1] -} {0} -do_test btree5-1.7 { - btree_first $c1 -} {1} -do_test btree5-1.8 { - btree_close_cursor $c1 - btree_rollback $b1 - set rc [catch {btree_cursor $b1 1 0} c1] -} {1} -do_test btree5-1.9 { - set c1 -} {SQLITE_EMPTY} -do_test btree5-1.10 { - btree_begin_transaction $b1 - set rc [catch {btree_cursor $b1 1 0} c1] -} {0} -do_test btree5-1.11 { - btree_first $c1 -} {1} -do_test btree5-1.12 { - btree_close_cursor $c1 - btree_commit $b1 - set rc [catch {btree_cursor $b1 1 0} c1] -} {0} -do_test btree5-1.13 { - btree_first $c1 -} {1} -do_test btree5-1.14 { - btree_close_cursor $c1 - btree_integrity_check $b1 1 -} {} - -# Insert many entries into table 1. This is designed to test the -# virtual-root logic that comes into play for page one. It is also -# a good test of INTKEY tables. -# -# Stagger the inserts. After the inserts complete, go back and do -# deletes. Stagger the deletes too. Repeat this several times. -# - -# Do N inserts into table 1 using random keys between 0 and 1000000 -# -proc random_inserts {N} { - global c1 - while {$N>0} { - set k [expr {int(rand()*1000000)}] - if {[btree_move_to $c1 $k]==0} continue; # entry already exists - btree_insert $c1 $k data-for-$k - incr N -1 - } -} - -# Do N delete from table 1 -# -proc random_deletes {N} { - global c1 - while {$N>0} { - set k [expr {int(rand()*1000000)}] - btree_move_to $c1 $k - btree_delete $c1 - incr N -1 - } -} - -# Make sure the table has exactly N entries. Make sure the data for -# each entry agrees with its key. -# -proc check_table {N} { - global c1 - btree_first $c1 - set cnt 0 - while {![btree_eof $c1]} { - if {[set data [btree_data $c1]] ne "data-for-[btree_key $c1]"} { - return "wrong data for entry $cnt" - } - set n [string length $data] - set fdata1 [btree_fetch_data $c1 $n] - set fdata2 [btree_fetch_data $c1 -1] - if {$fdata1 ne "" && $fdata1 ne $data} { - return "DataFetch returned the wrong value with amt=$n" - } - if {$fdata1 ne $fdata2} { - return "DataFetch returned the wrong value when amt=-1" - } - if {$n>10} { - set fdata3 [btree_fetch_data $c1 10] - if {$fdata3 ne [string range $data 0 9]} { - return "DataFetch returned the wrong value when amt=10" - } - } - incr cnt - btree_next $c1 - } - if {$cnt!=$N} { - return "wrong number of entries" - } - return {} -} - -# Initialize the database -# -btree_begin_transaction $b1 -set c1 [btree_cursor $b1 1 1] -set btree_trace 0 - -# Do the tests. -# -set cnt 0 -for {set i 1} {$i<=100} {incr i} { - do_test btree5-2.$i.1 { - random_inserts 200 - incr cnt 200 - check_table $cnt - } {} - do_test btree5-2.$i.2 { - btree_integrity_check $b1 1 - } {} - do_test btree5-2.$i.3 { - random_deletes 190 - incr cnt -190 - check_table $cnt - } {} - do_test btree5-2.$i.4 { - btree_integrity_check $b1 1 - } {} -} - -#btree_tree_dump $b1 1 -btree_close_cursor $c1 -btree_commit $b1 -btree_begin_transaction $b1 - -# This procedure converts an integer into a variable-length text key. -# The conversion is reversible. -# -# The first two characters of the string are alphabetics derived from -# the least significant bits of the number. Because they are derived -# from least significant bits, the sort order of the resulting string -# is different from numeric order. After the alphabetic prefix comes -# the original number. A variable-length suffix follows. The length -# of the suffix is based on a hash of the original number. -# -proc num_to_key {n} { - global charset ncharset suffix - set c1 [string index $charset [expr {$n%$ncharset}]] - set c2 [string index $charset [expr {($n/$ncharset)%$ncharset}]] - set nsuf [expr {($n*211)%593}] - return $c1$c2-$n-[string range $suffix 0 $nsuf] -} -set charset {abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ} -set ncharset [string length $charset] -set suffix $charset$charset -while {[string length $suffix]<1000} {append suffix $suffix} - -# This procedures extracts the original integer used to create -# a key by num_to_key -# -proc key_to_num {key} { - regexp {^..-([0-9]+)} $key all n - return $n -} - -# Insert into table $tab keys corresponding to all values between -# $start and $end, inclusive. -# -proc insert_range {tab start end} { - for {set i $start} {$i<=$end} {incr i} { - btree_insert $tab [num_to_key $i] {} - } -} - -# Delete from table $tab keys corresponding to all values between -# $start and $end, inclusive. -# -proc delete_range {tab start end} { - for {set i $start} {$i<=$end} {incr i} { - if {[btree_move_to $tab [num_to_key $i]]==0} { - btree_delete $tab - } - } -} - -# Make sure table $tab contains exactly those keys corresponding -# to values between $start and $end -# -proc check_range {tab start end} { - btree_first $tab - while {![btree_eof $tab]} { - set key [btree_key $tab] - set i [key_to_num $key] - if {[num_to_key $i] ne $key} { - return "malformed key: $key" - } - set got($i) 1 - btree_next $tab - } - set all [lsort -integer [array names got]] - if {[llength $all]!=$end+1-$start} { - return "table contains wrong number of values" - } - if {[lindex $all 0]!=$start} { - return "wrong starting value" - } - if {[lindex $all end]!=$end} { - return "wrong ending value" - } - return {} -} - -# Create a zero-data table and test it out. -# -do_test btree5-3.1 { - set rc [catch {btree_create_table $b1 2} t2] -} {0} -do_test btree5-3.2 { - set rc [catch {btree_cursor $b1 $t2 1} c2] -} {0} -set start 1 -set end 100 -for {set i 1} {$i<=100} {incr i} { - do_test btree5-3.3.$i.1 { - insert_range $c2 $start $end - btree_integrity_check $b1 1 $t2 - } {} - do_test btree5-3.3.$i.2 { - check_range $c2 $start $end - } {} - set nstart $start - incr nstart 89 - do_test btree5-3.3.$i.3 { - delete_range $c2 $start $nstart - btree_integrity_check $b1 1 $t2 - } {} - incr start 90 - do_test btree5-3.3.$i.4 { - check_range $c2 $start $end - } {} - incr end 100 -} - - -btree_close_cursor $c2 -btree_commit $b1 -btree_close $b1 - -finish_test diff --git a/test/btree6.test b/test/btree6.test deleted file mode 100644 index 2d311577b6..0000000000 --- a/test/btree6.test +++ /dev/null @@ -1,128 +0,0 @@ -# 2004 May 10 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#*********************************************************************** -# This file implements regression tests for SQLite library. The -# focus of this script is btree database backend - specifically -# the B+tree tables. B+trees store all data on the leaves rather -# that storing data with keys on interior nodes. -# -# $Id: btree6.test,v 1.4 2004/05/20 22:16:31 drh Exp $ - - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - - -# Insert many entries into the table that cursor $cur points to. -# The table should be an INTKEY table. -# -# Stagger the inserts. After the inserts complete, go back and do -# deletes. Stagger the deletes too. Repeat this several times. -# - -# Do N inserts into table $tab using random keys between 0 and 1000000 -# -proc random_inserts {cur N} { - global inscnt - while {$N>0} { - set k [expr {int(rand()*1000000)}] - if {[btree_move_to $cur $k]==0} { - continue; # entry already exists - } - incr inscnt - btree_insert $cur $k data-for-$k - incr N -1 - } -} -set inscnt 0 - -# Do N delete from the table that $cur points to. -# -proc random_deletes {cur N} { - while {$N>0} { - set k [expr {int(rand()*1000000)}] - btree_move_to $cur $k - btree_delete $cur - incr N -1 - } -} - -# Make sure the table that $cur points to has exactly N entries. -# Make sure the data for each entry agrees with its key. -# -proc check_table {cur N} { - btree_first $cur - set cnt 0 - while {![btree_eof $cur]} { - if {[set data [btree_data $cur]] ne "data-for-[btree_key $cur]"} { - return "wrong data for entry $cnt" - } - set n [string length $data] - set fdata1 [btree_fetch_data $cur $n] - set fdata2 [btree_fetch_data $cur -1] - if {$fdata1 ne "" && $fdata1 ne $data} { - return "DataFetch returned the wrong value with amt=$n" - } - if {$fdata1 ne $fdata2} { - return "DataFetch returned the wrong value when amt=-1" - } - if {$n>10} { - set fdata3 [btree_fetch_data $cur 10] - if {$fdata3 ne [string range $data 0 9]} { - return "DataFetch returned the wrong value when amt=10" - } - } - incr cnt - btree_next $cur - } - if {$cnt!=$N} { - return "wrong number of entries. Got $cnt. Looking for $N" - } - return {} -} - -# Initialize the database -# -file delete -force test1.bt -file delete -force test1.bt-journal -set b1 [btree_open test1.bt 2000 0] -btree_begin_transaction $b1 -set tab [btree_create_table $b1 5] -set cur [btree_cursor $b1 $tab 1] -set btree_trace 0 -expr srand(1) - -# Do the tests. -# -set cnt 0 -for {set i 1} {$i<=40} {incr i} { - do_test btree6-1.$i.1 { - random_inserts $cur 200 - incr cnt 200 - check_table $cur $cnt - } {} - do_test btree6-1.$i.2 { - btree_integrity_check $b1 1 $tab - } {} - do_test btree6-1.$i.3 { - random_deletes $cur 90 - incr cnt -90 - check_table $cur $cnt - } {} - do_test btree6-1.$i.4 { - btree_integrity_check $b1 1 $tab - } {} -} - -btree_close_cursor $cur -btree_commit $b1 -btree_close $b1 - -finish_test diff --git a/test/btree7.test b/test/btree7.test deleted file mode 100644 index eaf37138e1..0000000000 --- a/test/btree7.test +++ /dev/null @@ -1,50 +0,0 @@ -# 2004 Jun 4 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#*********************************************************************** -# This file implements regression tests for SQLite library. The -# focus of this script is btree database backend. -# -# $Id: btree7.test,v 1.2 2004/11/04 14:47:13 drh Exp $ - - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# Stress the balance routine by trying to create situations where -# 3 neighboring nodes split into 5. -# -set bigdata _123456789 ;# 10 -append bigdata $bigdata ;# 20 -append bigdata $bigdata ;# 40 -append bigdata $bigdata ;# 80 -append bigdata $bigdata ;# 160 -append bigdata $bigdata ;# 320 -append bigdata $bigdata ;# 640 -set data450 [string range $bigdata 0 449] -do_test btree7-1.1 { - execsql " - CREATE TABLE t1(x INTEGER PRIMARY KEY, y TEXT); - INSERT INTO t1 VALUES(1, '$bigdata'); - INSERT INTO t1 VALUES(2, '$bigdata'); - INSERT INTO t1 VALUES(3, '$data450'); - INSERT INTO t1 VALUES(5, '$data450'); - INSERT INTO t1 VALUES(8, '$bigdata'); - INSERT INTO t1 VALUES(9, '$bigdata'); - " -} {} -integrity_check btree7-1.2 -do_test btree7-1.3 { - execsql " - INSERT INTO t1 VALUES(4, '$bigdata'); - " -} {} -integrity_check btree7-1.4 - -finish_test diff --git a/test/btree8.test b/test/btree8.test deleted file mode 100644 index f54727117f..0000000000 --- a/test/btree8.test +++ /dev/null @@ -1,43 +0,0 @@ -# 2005 August 2 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#*********************************************************************** -# This file implements regression tests for SQLite library. The -# focus of this script is btree database backend. -# -# $Id: btree8.test,v 1.6 2005/08/02 17:13:12 drh Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# Ticket #1346: If the table rooted on page 1 contains a single entry -# and that single entries has to flow out into another page because -# page 1 is 100-bytes smaller than most other pages, then you delete that -# one entry, everything should still work. -# -do_test btree8-1.1 { - execsql { -CREATE TABLE t1(x - ---------------------------------------------------------------------------- - ---------------------------------------------------------------------------- - ---------------------------------------------------------------------------- - ---------------------------------------------------------------------------- - ---------------------------------------------------------------------------- - ---------------------------------------------------------------------------- - ---------------------------------------------------------------------------- - ---------------------------------------------------------------------------- - ---------------------------------------------------------------------------- - ---------------------------------------------------------------------------- - ---------------------------------------------------------------------------- - ---------------------------------------------------------------------------- -); -DROP table t1; - } -} {} -integrity_check btree8-1.2 diff --git a/test/btree9.test b/test/btree9.test deleted file mode 100644 index 678a12c91f..0000000000 --- a/test/btree9.test +++ /dev/null @@ -1,49 +0,0 @@ -# 2007 May 01 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#*********************************************************************** -# This file implements regression tests for SQLite library. The -# focus of this script is btree database backend. -# -# $Id: btree9.test,v 1.1 2007/05/02 01:34:32 drh Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# The sqlite3BtreeInsert() API now has an additional "nZero" parameter -# which specifies the number of zero bytes to append to the end of the -# data. This feature allows large zero-filled BLOBs to be created without -# having to allocate a big chunk of memory to instantiate the blob. -# -# The following code tests the new feature. -# - -# Create the database -# -do_test btree9-1.1 { - file delete -force test1.bt - file delete -force test1.bt-journal - set b1 [btree_open test1.bt 2000 0] - btree_begin_transaction $b1 - set t1 [btree_create_table $b1 5] - set c1 [btree_cursor $b1 $t1 1] - btree_insert $c1 1 data-for-1 20000 - btree_move_to $c1 1 - btree_key $c1 -} {1} -do_test btree9-1.2 { - btree_payload_size $c1 -} {20010} - - -btree_close_cursor $c1 -btree_commit $b1 -btree_close $b1 - -finish_test diff --git a/test/quick.test b/test/quick.test index 7e8d58d66d..68e86ddb9a 100644 --- a/test/quick.test +++ b/test/quick.test @@ -6,7 +6,7 @@ #*********************************************************************** # This file runs all tests. # -# $Id: quick.test,v 1.72 2008/03/22 01:08:01 drh Exp $ +# $Id: quick.test,v 1.73 2008/03/25 00:22:22 drh Exp $ proc lshift {lvar} { upvar $lvar l @@ -39,11 +39,6 @@ set EXCLUDE { all.test async.test async2.test - btree2.test - btree3.test - btree4.test - btree5.test - btree6.test corrupt.test crash.test crash2.test