From a8b38d286e97aedae43fabdf14b819454a323423 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 1 Nov 2001 14:41:34 +0000 Subject: [PATCH] Remove cruft: restrict the number of sorters and lists in the VDBE to one since no more than one was ever used anyway. This eliminates several op-codes and simplifies the implementation of several others. (CVS 297) FossilOrigin-Name: e1370276c2a0d045b29c981ddcb59f737e19a91c --- README | 10 ++ manifest | 30 ++--- manifest.uuid | 2 +- publish.sh | 3 +- src/delete.c | 5 +- src/select.c | 13 +-- src/update.c | 5 +- src/vdbe.c | 296 +++++++++++++++++------------------------------- src/vdbe.h | 155 +++++++++++++------------ www/changes.tcl | 4 + www/index.tcl | 34 +----- www/opcode.tcl | 22 ++-- 12 files changed, 230 insertions(+), 349 deletions(-) diff --git a/README b/README index eae657bc77..7beb62e8e4 100644 --- a/README +++ b/README @@ -21,3 +21,13 @@ script does not work out for you, there is a generic makefile named "Makefile.template" in the top directory of the source tree that you can copy and edit to suite your needs. Comments on the generic makefile show what changes are needed. + +The windows binaries on the website are created using MinGW32 configured +as a cross-compiler running under Linux. For details, see the ./publish.sh +script at the top-level of the source tree. + +Contacts: + + http://www.hwaci.com/sw/sqlite/ + http://groups.yahoo.com/group/sqlite/ + drh@hwaci.com diff --git a/manifest b/manifest index f4cadce69d..f061dad58a 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Comment\schanges\sonly.\s(CVS\s296) -D 2001-11-01T13:52:53 +C Remove\scruft:\srestrict\sthe\snumber\sof\ssorters\sand\slists\sin\sthe\sVDBE\sto\sone\nsince\sno\smore\sthan\sone\swas\sever\sused\sanyway.\s\sThis\seliminates\sseveral\nop-codes\sand\ssimplifies\sthe\simplementation\sof\sseveral\sothers.\s(CVS\s297) +D 2001-11-01T14:41:34 F Makefile.in 6801df952cb1df64aa32e4de85fed24511d28efd F Makefile.template 1fdb891f14083ee0b63cf7282f91529634438e7a -F README 93d2977cc5c6595c448de16bdefc312b9d401533 +F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0 F VERSION 46489bc13fe8b494327fecb3c9a05f4db2e284b3 F aclocal.m4 11faa843caa38fd451bc6aeb43e248d1723a269d F config.guess f38b1e93d1e0fa6f5a6913e9e7b12774b9232588 @@ -17,12 +17,12 @@ F doc/report1.txt a031aaf37b185e4fa540223cb516d3bccec7eeac F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 F libtool c56e618713c9510a103bda6b95f3ea3900dcacd6 F ltmain.sh e9ed72eb1d690f447c13945eaf69e28af531eda1 -F publish.sh badcd69b8e3a8bc69b162c4c9d7c209b2a0b119e +F publish.sh 33cbe6798969f637698044023c139080e5d772a6 F src/TODO af7f3cab0228e34149cf98e073aa83d45878e7e6 F src/btree.c f5b3bf49c98a90754097e8f0a946931d9cc857ef F src/btree.h 57d653ef5137b91f2a068aaf71a2905468dd2cb7 F src/build.c 8857c16751a5e9c5ee845e1b3cf2da78935c8cb3 -F src/delete.c 6fe2191c49c4a31336e2fac11b3ad665ddcd4246 +F src/delete.c a4c13c444544f315703d5fbed6419c8786f66581 F src/expr.c 2dd0252ced345c1e64db015b94dc6b5d7a57eef3 F src/hash.c d0110e6da70a5962e21575fccf8206f7d9d75e00 F src/hash.h a5f5b3ce2d086a172c5879b0b06a27a82eac9fac @@ -36,7 +36,7 @@ F src/pager.h a0d4c5ae271914aa07b62aee0707997d6932b6ca F src/parse.y 148e4cd134d3cbd816dcb0df50e49e498faa6ba4 F src/printf.c 167fbfb192b4dce48154398f22dbc614e9f5d088 F src/random.c 2a9cc2c9716d14815fd4c2accf89d87a1143e46b -F src/select.c d14511afacf788bf4a0c517011c2c53038539388 +F src/select.c c34b02eafaa69fde6b4428df7861c3417b3079f9 F src/shell.c 71597951753b56a97fea1c7a30908f31e635c00c F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e F src/sqlite.h.in f2c40c869ff40ad3e60d8a3b1f72777fa28b32fc @@ -47,10 +47,10 @@ F src/test1.c e4b31f62ea71963cbae44338acf477a04fc8fc49 F src/test2.c e9f99aa5ee73872819259d6612c11e55e1644321 F src/test3.c 4a0d7b882fdae731dbb759f512ad867122452f96 F src/tokenize.c 8f4c2b5e7fb471ba194979fb4dd5f947402fd792 -F src/update.c c916182c6bfbc8a6f20c24920c4560fece6c9569 +F src/update.c 4eeb154a2da8a934d180e2d9e4211ac0a7a4ce8b F src/util.c aa4d2de60cb2445239b71c79c3a8c0b7c0d3336a -F src/vdbe.c 4b0df66646648a7f60037926015ec2c181536f53 -F src/vdbe.h f8407fd6b644bc001b1e7c65460c9962f6a15f6b +F src/vdbe.c 9e4fd512dd3e66d37f5b53ae88138fda4f9aa227 +F src/vdbe.h 4a587ec56943d34698edf507ad5a746e87cb8cf4 F src/where.c 22fe910c7c8e2736eb37e9861343e90c0b513c86 F test/all.test 2a51e5395ac7c2c539689b123b9782a05e3837fe F test/bigrow.test a35f2de9948b24e427fb292c35947795efe182d0 @@ -102,19 +102,19 @@ F www/arch.fig d5f9752a4dbf242e9cfffffd3f5762b6c63b3bcf F www/arch.png 82ef36db1143828a7abc88b1e308a5f55d4336f4 F www/arch.tcl 03b521d252575f93b9c52f7c8b0007011512fcfb F www/c_interface.tcl d446234c1d3ed747fcefd30e972a19f2b2fc0e05 -F www/changes.tcl 995d934eb54762d766923241a5a2e6023a0f3c6e +F www/changes.tcl 37ca708eb350dc41fcf3ea0ae8ecc705c0c218bf F www/crosscompile.tcl c99efacb3aefaa550c6e80d91b240f55eb9fd33e F www/download.tcl 3e51c9ff1326b0a182846134987301310dff7d60 F www/dynload.tcl 02eb8273aa78cfa9070dd4501dca937fb22b466c -F www/index.tcl 7c7df8d73c751897b643018fd21317269f10e023 +F www/index.tcl b9d166d09fa4237d31d78be49f2b8b205e6e7678 F www/lang.tcl 1899ec4fb77cd69de335ebd998253de869f34d8e F www/mingw.tcl fc5f4ba9d336b6e8c97347cc6496d6162461ef60 -F www/opcode.tcl 4365ad9798872491dbd7d3071510ebe461785ac3 +F www/opcode.tcl 7989ed328316454c7030dcdb60f09ae1e017286d F www/speed.tcl 212a91d555384e01873160d6a189f1490c791bc2 F www/sqlite.tcl 6a21242a272e9c0939a04419a51c3d50cae33e3e F www/tclsqlite.tcl 13d50723f583888fc80ae1a38247c0ab415066fa F www/vdbe.tcl bb7d620995f0a987293e9d4fb6185a3b077e9b44 -P f65df59e554c281ad1efa830f13f87488eb16845 -R 50f675a2d3f94fcb2f093eaf90b1247b +P b2cb118fb7c6713684d32a48a7ba8ffffe596687 +R 11be61d659c8d3b7f97b8d20e188eb7e U drh -Z 77ddce4c95e7ba412288de1a3a02ea29 +Z 1756e792427d370fb3a08a33a148f36d diff --git a/manifest.uuid b/manifest.uuid index 2948d021f5..e0508722c4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b2cb118fb7c6713684d32a48a7ba8ffffe596687 \ No newline at end of file +e1370276c2a0d045b29c981ddcb59f737e19a91c \ No newline at end of file diff --git a/publish.sh b/publish.sh index 7fa5d5c81c..38feee50ea 100644 --- a/publish.sh +++ b/publish.sh @@ -90,7 +90,8 @@ zip sqlite.zip sqlite.exe ORIGIN=`pwd` cd $srcdir cd .. -tar czf $ORIGIN/sqlite.tar.gz sqlite +EXCLUDE=`find sqlite -print | grep CVS | sed 's,sqlite/, --exclude sqlite/,'` +tar czf $ORIGIN/sqlite.tar.gz $EXCLUDE sqlite cd $ORIGIN vers=`cat $srcdir/VERSION` rm -f sqlite-$vers.tar.gz diff --git a/src/delete.c b/src/delete.c index cd4694b618..62dc19f570 100644 --- a/src/delete.c +++ b/src/delete.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle DELETE FROM statements. ** -** $Id: delete.c,v 1.18 2001/10/15 00:44:36 drh Exp $ +** $Id: delete.c,v 1.19 2001/11/01 14:41:34 drh Exp $ */ #include "sqliteInt.h" @@ -125,7 +125,6 @@ void sqliteDeleteFrom( else{ /* Begin the database scan */ - sqliteVdbeAddOp(v, OP_ListOpen, 0, 0); pWInfo = sqliteWhereBegin(pParse, pTabList, pWhere, 1); if( pWInfo==0 ) goto delete_from_cleanup; @@ -168,7 +167,7 @@ void sqliteDeleteFrom( sqliteVdbeAddOp(v, OP_Delete, base, 0); sqliteVdbeAddOp(v, OP_Goto, 0, addr); sqliteVdbeResolveLabel(v, end); - sqliteVdbeAddOp(v, OP_ListClose, 0, 0); + sqliteVdbeAddOp(v, OP_ListReset, 0, 0); } if( (db->flags & SQLITE_InTrans)==0 ){ sqliteVdbeAddOp(v, OP_Commit, 0, 0); diff --git a/src/select.c b/src/select.c index 5efd3054c7..bf17fa920d 100644 --- a/src/select.c +++ b/src/select.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** -** $Id: select.c,v 1.44 2001/10/22 02:58:10 drh Exp $ +** $Id: select.c,v 1.45 2001/11/01 14:41:34 drh Exp $ */ #include "sqliteInt.h" @@ -222,7 +222,7 @@ static void generateSortTail(Vdbe *v, int nColumn){ sqliteVdbeAddOp(v, OP_SortCallback, nColumn, 0); sqliteVdbeAddOp(v, OP_Goto, 0, addr); sqliteVdbeResolveLabel(v, end); - sqliteVdbeAddOp(v, OP_SortClose, 0, 0); + sqliteVdbeAddOp(v, OP_SortReset, 0, 0); } /* @@ -551,9 +551,6 @@ static int multiSelect(Parse *pParse, Select *p, int eDest, int iParm){ int iCont, iBreak; assert( p->pEList ); generateColumnNames(pParse, 0, p->pEList); - if( p->pOrderBy ){ - sqliteVdbeAddOp(v, OP_SortOpen, 0, 0); - } sqliteVdbeAddOp(v, OP_Rewind, unionTab, 0); iBreak = sqliteVdbeMakeLabel(v); iCont = sqliteVdbeAddOp(v, OP_Next, unionTab, iBreak); @@ -605,9 +602,6 @@ static int multiSelect(Parse *pParse, Select *p, int eDest, int iParm){ */ assert( p->pEList ); generateColumnNames(pParse, 0, p->pEList); - if( p->pOrderBy ){ - sqliteVdbeAddOp(v, OP_SortOpen, 0, 0); - } sqliteVdbeAddOp(v, OP_Rewind, tab1, 0); iBreak = sqliteVdbeMakeLabel(v); iCont = sqliteVdbeAddOp(v, OP_Next, tab1, iBreak); @@ -859,9 +853,6 @@ int sqliteSelect( */ v = sqliteGetVdbe(pParse); if( v==0 ) return 1; - if( pOrderBy ){ - sqliteVdbeAddOp(v, OP_SortOpen, 0, 0); - } /* Identify column names if we will be using in the callback. This ** step is skipped if the output is going to a table or a memory cell. diff --git a/src/update.c b/src/update.c index f7061fce2a..b4dea0ddea 100644 --- a/src/update.c +++ b/src/update.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. ** -** $Id: update.c,v 1.19 2001/10/15 00:44:36 drh Exp $ +** $Id: update.c,v 1.20 2001/11/01 14:41:34 drh Exp $ */ #include "sqliteInt.h" @@ -143,7 +143,6 @@ void sqliteUpdate( /* Begin the database scan */ - sqliteVdbeAddOp(v, OP_ListOpen, 0, 0); pWInfo = sqliteWhereBegin(pParse, pTabList, pWhere, 1); if( pWInfo==0 ) goto update_cleanup; @@ -233,7 +232,7 @@ void sqliteUpdate( */ sqliteVdbeAddOp(v, OP_Goto, 0, addr); sqliteVdbeResolveLabel(v, end); - sqliteVdbeAddOp(v, OP_ListClose, 0, 0); + sqliteVdbeAddOp(v, OP_ListReset, 0, 0); if( (db->flags & SQLITE_InTrans)==0 ){ sqliteVdbeAddOp(v, OP_Commit, 0, 0); } diff --git a/src/vdbe.c b/src/vdbe.c index 1e658fa57a..8f8ce00cf3 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -30,7 +30,7 @@ ** But other routines are also provided to help in building up ** a program instruction by instruction. ** -** $Id: vdbe.c,v 1.90 2001/11/01 13:52:54 drh Exp $ +** $Id: vdbe.c,v 1.91 2001/11/01 14:41:34 drh Exp $ */ #include "sqliteInt.h" #include @@ -187,10 +187,8 @@ struct Vdbe { char **azColName; /* Becomes the 4th parameter to callbacks */ int nCursor; /* Number of slots in aCsr[] */ Cursor *aCsr; /* On element of this array for each open cursor */ - int nList; /* Number of slots in apList[] */ - Keylist **apList; /* For each Keylist */ - int nSort; /* Number of slots in apSort[] */ - Sorter **apSort; /* An open sorter list */ + Keylist *pList; /* A list of ROWIDs */ + Sorter *pSort; /* A linked list of objects to be sorted */ FILE *pFile; /* At most one open file handler */ int nField; /* Number of file fields */ char **azField; /* Data for each file field */ @@ -718,6 +716,19 @@ static void closeAllCursors(Vdbe *p){ p->nCursor = 0; } +/* +** Remove any elements that remain on the sorter for the VDBE given. +*/ +static void SorterReset(Vdbe *p){ + while( p->pSort ){ + Sorter *pSorter = p->pSort; + p->pSort = pSorter->pNext; + sqliteFree(pSorter->zKey); + sqliteFree(pSorter->pData); + sqliteFree(pSorter); + } +} + /* ** Clean up the VM after execution. ** @@ -738,25 +749,11 @@ static void Cleanup(Vdbe *p){ sqliteFree(p->aMem); p->aMem = 0; p->nMem = 0; - for(i=0; inList; i++){ - KeylistFree(p->apList[i]); - p->apList[i] = 0; + if( p->pList ){ + KeylistFree(p->pList); + p->pList = 0; } - sqliteFree(p->apList); - p->apList = 0; - p->nList = 0; - for(i=0; inSort; i++){ - Sorter *pSorter; - while( (pSorter = p->apSort[i])!=0 ){ - p->apSort[i] = pSorter->pNext; - sqliteFree(pSorter->zKey); - sqliteFree(pSorter->pData); - sqliteFree(pSorter); - } - } - sqliteFree(p->apSort); - p->apSort = 0; - p->nSort = 0; + SorterReset(p); if( p->pFile ){ if( p->pFile!=stdin ) fclose(p->pFile); p->pFile = 0; @@ -822,26 +819,25 @@ static char *zOpName[] = { 0, "Rewind", "Next", "Destroy", "Clear", "CreateIndex", "CreateTable", "Reorganize", "BeginIdx", "NextIdx", "PutIdx", "DeleteIdx", "MemLoad", - "MemStore", "ListOpen", "ListWrite", "ListRewind", - "ListRead", "ListClose", "SortOpen", "SortPut", - "SortMakeRec", "SortMakeKey", "Sort", "SortNext", - "SortKey", "SortCallback", "SortClose", "FileOpen", - "FileRead", "FileColumn", "FileClose", "AggReset", - "AggFocus", "AggIncr", "AggNext", "AggSet", - "AggGet", "SetInsert", "SetFound", "SetNotFound", - "SetClear", "MakeRecord", "MakeKey", "MakeIdxKey", - "Goto", "If", "Halt", "ColumnCount", - "ColumnName", "Callback", "NullCallback", "Integer", - "String", "Null", "Pop", "Dup", - "Pull", "Add", "AddImm", "Subtract", - "Multiply", "Divide", "Remainder", "BitAnd", - "BitOr", "BitNot", "ShiftLeft", "ShiftRight", - "AbsValue", "Precision", "Min", "Max", - "Like", "Glob", "Eq", "Ne", - "Lt", "Le", "Gt", "Ge", - "IsNull", "NotNull", "Negative", "And", - "Or", "Not", "Concat", "Noop", - "Strlen", "Substr", + "MemStore", "ListWrite", "ListRewind", "ListRead", + "ListReset", "SortPut", "SortMakeRec", "SortMakeKey", + "Sort", "SortNext", "SortCallback", "SortReset", + "FileOpen", "FileRead", "FileColumn", "FileClose", + "AggReset", "AggFocus", "AggIncr", "AggNext", + "AggSet", "AggGet", "SetInsert", "SetFound", + "SetNotFound", "SetClear", "MakeRecord", "MakeKey", + "MakeIdxKey", "Goto", "If", "Halt", + "ColumnCount", "ColumnName", "Callback", "NullCallback", + "Integer", "String", "Null", "Pop", + "Dup", "Pull", "Add", "AddImm", + "Subtract", "Multiply", "Divide", "Remainder", + "BitAnd", "BitOr", "BitNot", "ShiftLeft", + "ShiftRight", "AbsValue", "Precision", "Min", + "Max", "Like", "Glob", "Eq", + "Ne", "Lt", "Le", "Gt", + "Ge", "IsNull", "NotNull", "Negative", + "And", "Or", "Not", "Concat", + "Noop", "Strlen", "Substr", }; /* @@ -3085,50 +3081,23 @@ case OP_Reorganize: { break; } -/* Opcode: ListOpen P1 * * -** -** Open a "List" structure used for temporary storage of integer -** record numbers. P1 will server as a handle to this list for future -** interactions. If another list with the P1 handle is -** already opened, the prior list is closed and a new one opened -** in its place. -*/ -case OP_ListOpen: { - int i = pOp->p1; - VERIFY( if( i<0 ) goto bad_instruction; ) - if( i>=p->nList ){ - int j; - Keylist **apList = sqliteRealloc( p->apList, (i+1)*sizeof(Keylist*) ); - if( apList==0 ){ goto no_mem; } - p->apList = apList; - for(j=p->nList; j<=i; j++) p->apList[j] = 0; - p->nList = i+1; - }else if( p->apList[i] ){ - KeylistFree(p->apList[i]); - p->apList[i] = 0; - } - break; -} - -/* Opcode: ListWrite P1 * * +/* Opcode: ListWrite * * * ** ** Write the integer on the top of the stack -** into the temporary storage list P1. +** into the temporary storage list. */ case OP_ListWrite: { - int i = pOp->p1; Keylist *pKeylist; - VERIFY( if( i<0 || i>=p->nList ) goto bad_instruction; ) VERIFY( if( p->tos<0 ) goto not_enough_stack; ) - pKeylist = p->apList[i]; + pKeylist = p->pList; if( pKeylist==0 || pKeylist->nUsed>=pKeylist->nKey ){ pKeylist = sqliteMalloc( sizeof(Keylist)+999*sizeof(pKeylist->aKey[0]) ); if( pKeylist==0 ) goto no_mem; pKeylist->nKey = 1000; pKeylist->nRead = 0; pKeylist->nUsed = 0; - pKeylist->pNext = p->apList[i]; - p->apList[i] = pKeylist; + pKeylist->pNext = p->pList; + p->pList = pKeylist; } Integerify(p, p->tos); pKeylist->aKey[pKeylist->nUsed++] = aStack[p->tos].i; @@ -3136,28 +3105,24 @@ case OP_ListWrite: { break; } -/* Opcode: ListRewind P1 * * +/* Opcode: ListRewind * * * ** -** Rewind the temporary buffer P1 back to the beginning. +** Rewind the temporary buffer back to the beginning. */ case OP_ListRewind: { - int i = pOp->p1; - VERIFY( if( i<0 ) goto bad_instruction; ) /* This is now a no-op */ break; } -/* Opcode: ListRead P1 P2 * +/* Opcode: ListRead * P2 * ** -** Attempt to read an integer from temporary storage buffer P1 +** Attempt to read an integer from the temporary storage buffer ** and push it onto the stack. If the storage buffer is empty, ** push nothing but instead jump to P2. */ case OP_ListRead: { - int i = pOp->p1; Keylist *pKeylist; - VERIFY(if( i<0 || i>=p->nList ) goto bad_instruction;) - pKeylist = p->apList[i]; + pKeylist = p->pList; if( pKeylist!=0 ){ VERIFY( if( pKeylist->nRead<0 @@ -3170,7 +3135,7 @@ case OP_ListRead: { aStack[p->tos].flags = STK_Int; zStack[p->tos] = 0; if( pKeylist->nRead>=pKeylist->nUsed ){ - p->apList[i] = pKeylist->pNext; + p->pList = pKeylist->pNext; sqliteFree(pKeylist); } }else{ @@ -3179,54 +3144,33 @@ case OP_ListRead: { break; } -/* Opcode: ListClose P1 * * +/* Opcode: ListReset * * * ** -** Close the temporary storage buffer and discard its contents. +** Reset the temporary storage buffer so that it holds nothing. */ -case OP_ListClose: { - int i = pOp->p1; - VERIFY( if( i<0 ) goto bad_instruction; ) - VERIFY( if( i>=p->nList ) goto bad_instruction; ) - KeylistFree(p->apList[i]); - p->apList[i] = 0; - break; -} - -/* Opcode: SortOpen P1 * * -** -** Create a new sorter with index P1 -*/ -case OP_SortOpen: { - int i = pOp->p1; - VERIFY( if( i<0 ) goto bad_instruction; ) - if( i>=p->nSort ){ - int j; - Sorter **apSort = sqliteRealloc( p->apSort, (i+1)*sizeof(Sorter*) ); - if( apSort==0 ){ goto no_mem; } - p->apSort = apSort; - for(j=p->nSort; j<=i; j++) p->apSort[j] = 0; - p->nSort = i+1; +case OP_ListReset: { + if( p->pList ){ + KeylistFree(p->pList); + p->pList = 0; } break; } -/* Opcode: SortPut P1 * * +/* Opcode: SortPut * * * ** ** The TOS is the key and the NOS is the data. Pop both from the stack ** and put them on the sorter. */ case OP_SortPut: { - int i = pOp->p1; int tos = p->tos; int nos = tos - 1; Sorter *pSorter; - VERIFY( if( i<0 || i>=p->nSort ) goto bad_instruction; ) VERIFY( if( tos<1 ) goto not_enough_stack; ) if( Stringify(p, tos) || Stringify(p, nos) ) goto no_mem; pSorter = sqliteMalloc( sizeof(Sorter) ); if( pSorter==0 ) goto no_mem; - pSorter->pNext = p->apSort[i]; - p->apSort[i] = pSorter; + pSorter->pNext = p->pSort; + p->pSort = pSorter; pSorter->nKey = aStack[tos].n; pSorter->zKey = zStack[tos]; pSorter->nData = aStack[nos].n; @@ -3283,7 +3227,7 @@ case OP_SortMakeRec: { break; } -/* Opcode: SortMakeKey P1 * P3 +/* Opcode: SortMakeKey * * P3 ** ** Convert the top few entries of the stack into a sort key. The ** number of stack entries consumed is the number of characters in @@ -3330,59 +3274,54 @@ case OP_SortMakeKey: { break; } -/* Opcode: Sort P1 * * +/* Opcode: Sort * * * ** -** Sort all elements on the given sorter. The algorithm is a +** Sort all elements on the sorter. The algorithm is a ** mergesort. */ case OP_Sort: { - int j; - j = pOp->p1; - VERIFY( if( j<0 ) goto bad_instruction; ) - if( jnSort ){ - int i; - Sorter *pElem; - Sorter *apSorter[NSORT]; - for(i=0; iapSort[j] ){ - pElem = p->apSort[j]; - p->apSort[j] = pElem->pNext; - pElem->pNext = 0; - for(i=0; i=NSORT-1 ){ - apSorter[NSORT-1] = Merge(apSorter[NSORT-1],pElem); - } - } - pElem = 0; - for(i=0; iapSort[j] = pElem; + int i; + Sorter *pElem; + Sorter *apSorter[NSORT]; + for(i=0; ipSort ){ + pElem = p->pSort; + p->pSort = pElem->pNext; + pElem->pNext = 0; + for(i=0; i=NSORT-1 ){ + apSorter[NSORT-1] = Merge(apSorter[NSORT-1],pElem); + } + } + pElem = 0; + for(i=0; ipSort = pElem; break; } -/* Opcode: SortNext P1 P2 * +/* Opcode: SortNext * P2 * ** -** Push the data for the topmost element in the given sorter onto the -** stack, then remove the element from the sorter. +** Push the data for the topmost element in the sorter onto the +** stack, then remove the element from the sorter. If the sorter +** is empty, push nothing on the stack and instead jump immediately +** to instruction P2. */ case OP_SortNext: { - int i = pOp->p1; - VERIFY( if( i<0 ) goto bad_instruction; ) - if( VERIFY( inSort && ) p->apSort[i]!=0 ){ - Sorter *pSorter = p->apSort[i]; - p->apSort[i] = pSorter->pNext; + Sorter *pSorter = p->pSort; + if( pSorter!=0 ){ + p->pSort = pSorter->pNext; p->tos++; VERIFY( NeedStack(p, p->tos); ) zStack[p->tos] = pSorter->pData; @@ -3396,28 +3335,7 @@ case OP_SortNext: { break; } -#if 0 /* NOT USED */ -/* Opcode: SortKey P1 * * -** -** Push the key for the topmost element of the sorter onto the stack. -** But don't change the sorter an any other way. -*/ -case OP_SortKey: { - int i = pOp->p1; - VERIFY( if( i<0 ) goto bad_instruction; ) - if( inSort && p->apSort[i]!=0 ){ - Sorter *pSorter = p->apSort[i]; - p->tos++; - VERIFY( NeedStack(p, p->tos); ) - sqliteSetString(&zStack[p->tos], pSorter->zKey, 0); - aStack[p->tos].n = pSorter->nKey; - aStack[p->tos].flags = STK_Str|STK_Dyn; - } - break; -} -#endif /* NOT USED */ - -/* Opcode: SortCallback P1 P2 * +/* Opcode: SortCallback * P2 * ** ** The top of the stack contains a callback record built using ** the SortMakeRec operation with the same P1 value as this @@ -3438,22 +3356,12 @@ case OP_SortCallback: { break; } -/* Opcode: SortClose P1 * * +/* Opcode: SortReset * * * ** -** Close the given sorter and remove all its elements. +** Remove any elements that remain on the sorter. */ -case OP_SortClose: { - Sorter *pSorter; - int i = pOp->p1; - VERIFY( if( i<0 ) goto bad_instruction; ) - if( inSort ){ - while( (pSorter = p->apSort[i])!=0 ){ - p->apSort[i] = pSorter->pNext; - sqliteFree(pSorter->zKey); - sqliteFree(pSorter->pData); - sqliteFree(pSorter); - } - } +case OP_SortReset: { + SorterReset(p); break; } diff --git a/src/vdbe.h b/src/vdbe.h index 7475a7eac0..81e2356d2a 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.30 2001/10/19 16:44:57 drh Exp $ +** $Id: vdbe.h,v 1.31 2001/11/01 14:41:34 drh Exp $ */ #ifndef _SQLITE_VDBE_H_ #define _SQLITE_VDBE_H_ @@ -111,95 +111,92 @@ typedef struct VdbeOp VdbeOp; #define OP_MemLoad 36 #define OP_MemStore 37 -#define OP_ListOpen 38 -#define OP_ListWrite 39 -#define OP_ListRewind 40 -#define OP_ListRead 41 -#define OP_ListClose 42 +#define OP_ListWrite 38 +#define OP_ListRewind 39 +#define OP_ListRead 40 +#define OP_ListReset 41 -#define OP_SortOpen 43 -#define OP_SortPut 44 -#define OP_SortMakeRec 45 -#define OP_SortMakeKey 46 -#define OP_Sort 47 -#define OP_SortNext 48 -#define OP_SortKey 49 -#define OP_SortCallback 50 -#define OP_SortClose 51 +#define OP_SortPut 42 +#define OP_SortMakeRec 43 +#define OP_SortMakeKey 44 +#define OP_Sort 45 +#define OP_SortNext 46 +#define OP_SortCallback 47 +#define OP_SortReset 48 -#define OP_FileOpen 52 -#define OP_FileRead 53 -#define OP_FileColumn 54 -#define OP_FileClose 55 +#define OP_FileOpen 49 +#define OP_FileRead 50 +#define OP_FileColumn 51 +#define OP_FileClose 52 -#define OP_AggReset 56 -#define OP_AggFocus 57 -#define OP_AggIncr 58 -#define OP_AggNext 59 -#define OP_AggSet 60 -#define OP_AggGet 61 +#define OP_AggReset 53 +#define OP_AggFocus 54 +#define OP_AggIncr 55 +#define OP_AggNext 56 +#define OP_AggSet 57 +#define OP_AggGet 58 -#define OP_SetInsert 62 -#define OP_SetFound 63 -#define OP_SetNotFound 64 -#define OP_SetClear 65 +#define OP_SetInsert 59 +#define OP_SetFound 60 +#define OP_SetNotFound 61 +#define OP_SetClear 62 -#define OP_MakeRecord 66 -#define OP_MakeKey 67 -#define OP_MakeIdxKey 68 +#define OP_MakeRecord 63 +#define OP_MakeKey 64 +#define OP_MakeIdxKey 65 -#define OP_Goto 69 -#define OP_If 70 -#define OP_Halt 71 +#define OP_Goto 66 +#define OP_If 67 +#define OP_Halt 68 -#define OP_ColumnCount 72 -#define OP_ColumnName 73 -#define OP_Callback 74 -#define OP_NullCallback 75 +#define OP_ColumnCount 69 +#define OP_ColumnName 70 +#define OP_Callback 71 +#define OP_NullCallback 72 -#define OP_Integer 76 -#define OP_String 77 -#define OP_Null 78 -#define OP_Pop 79 -#define OP_Dup 80 -#define OP_Pull 81 +#define OP_Integer 73 +#define OP_String 74 +#define OP_Null 75 +#define OP_Pop 76 +#define OP_Dup 77 +#define OP_Pull 78 -#define OP_Add 82 -#define OP_AddImm 83 -#define OP_Subtract 84 -#define OP_Multiply 85 -#define OP_Divide 86 -#define OP_Remainder 87 -#define OP_BitAnd 88 -#define OP_BitOr 89 -#define OP_BitNot 90 -#define OP_ShiftLeft 91 -#define OP_ShiftRight 92 -#define OP_AbsValue 93 -#define OP_Precision 94 -#define OP_Min 95 -#define OP_Max 96 -#define OP_Like 97 -#define OP_Glob 98 -#define OP_Eq 99 -#define OP_Ne 100 -#define OP_Lt 101 -#define OP_Le 102 -#define OP_Gt 103 -#define OP_Ge 104 -#define OP_IsNull 105 -#define OP_NotNull 106 -#define OP_Negative 107 -#define OP_And 108 -#define OP_Or 109 -#define OP_Not 110 -#define OP_Concat 111 -#define OP_Noop 112 +#define OP_Add 79 +#define OP_AddImm 80 +#define OP_Subtract 81 +#define OP_Multiply 82 +#define OP_Divide 83 +#define OP_Remainder 84 +#define OP_BitAnd 85 +#define OP_BitOr 86 +#define OP_BitNot 87 +#define OP_ShiftLeft 88 +#define OP_ShiftRight 89 +#define OP_AbsValue 90 +#define OP_Precision 91 +#define OP_Min 92 +#define OP_Max 93 +#define OP_Like 94 +#define OP_Glob 95 +#define OP_Eq 96 +#define OP_Ne 97 +#define OP_Lt 98 +#define OP_Le 99 +#define OP_Gt 100 +#define OP_Ge 101 +#define OP_IsNull 102 +#define OP_NotNull 103 +#define OP_Negative 104 +#define OP_And 105 +#define OP_Or 106 +#define OP_Not 107 +#define OP_Concat 108 +#define OP_Noop 109 -#define OP_Strlen 113 -#define OP_Substr 114 +#define OP_Strlen 110 +#define OP_Substr 111 -#define OP_MAX 114 +#define OP_MAX 111 /* ** Prototypes for the VDBE interface. See comments on the implementation diff --git a/www/changes.tcl b/www/changes.tcl index ba312af2df..a239d55901 100644 --- a/www/changes.tcl +++ b/www/changes.tcl @@ -19,6 +19,10 @@ proc chng {date desc} { chng {2001 Oct ?? (2.0.8)} {
  • Documentation updates
  • +
  • Simplify the design of the VDBE by restricting the number of sorters + and lists to 1. + In practice, no more than one sorter and one list was every used anyhow. +
  • } chng {2001 Oct 21 (2.0.7)} { diff --git a/www/index.tcl b/www/index.tcl index fdce1e85dd..c59b4a9441 100644 --- a/www/index.tcl +++ b/www/index.tcl @@ -1,7 +1,7 @@ # # Run this TCL script to generate HTML for the index.html file. # -set rcsid {$Id: index.tcl,v 1.45 2001/10/31 15:44:47 drh Exp $} +set rcsid {$Id: index.tcl,v 1.46 2001/11/01 14:41:34 drh Exp $} puts { SQLite: An SQL Database Engine In A C Library @@ -16,7 +16,7 @@ puts {

    } puts {

    Introduction

    -

    SQLite is a C library that implements an SQL database engine. +

    SQLite is a C library that implements an embeddable SQL database engine. Programs that link with the SQLite library can have SQL database access without running a separate RDBMS process. The distribution comes with a standalone command-line @@ -64,8 +64,10 @@ puts {

    Current Status

    A change history is available online. The latest source code is available for download. -There are currently no known memory leaks or debilitating bugs +There are currently no known memory leaks or bugs in the library. +SQLite is currently being used in several mission-critical +applications.

    @@ -158,32 +160,6 @@ $ make test Optional: run regression tests } -puts {

    Command-line Usage Example

    - -

    Download the source archive and compile the sqlite -program as described above. Then type:

    - -
    -bash$ sqlite ~/newdb              Directory ~/newdb created automatically
    -sqlite> create table t1(
    -   ...>    a int,
    -   ...>    b varchar(20)
    -   ...>    c text
    -   ...> );                        End each SQL statement with a ';'
    -sqlite> insert into t1
    -   ...> values(1,'hi','y''all');
    -sqlite> select * from t1;
    -1|hello|world
    -sqlite> .mode columns             Special commands begin with '.'
    -sqlite> .header on                Type ".help" for a list of commands
    -sqlite> select * from t1;
    -a      b       c
    ------- ------- -------
    -1      hi      y'all
    -sqlite> .exit
    -base$
    -
    -} puts {

    Related Sites

      diff --git a/www/opcode.tcl b/www/opcode.tcl index e85f542bf2..cc042d329f 100644 --- a/www/opcode.tcl +++ b/www/opcode.tcl @@ -1,7 +1,7 @@ # # Run this Tcl script to generate the sqlite.html file. # -set rcsid {$Id: opcode.tcl,v 1.6 2001/09/28 23:11:24 drh Exp $} +set rcsid {$Id: opcode.tcl,v 1.7 2001/11/01 14:41:34 drh Exp $} puts { @@ -117,22 +117,18 @@ Each memory location can hold an arbitrary string. The memory cells are typically used to hold the result of a scalar SELECT that is part of a larger expression.

      -

      The virtual machine contains an arbitrary number of sorters. -Each sorter is able to accumulate records, sort those records, -then play the records back in sorted order. Sorters are used -to implement the ORDER BY clause of a SELECT statement. The -fact that the virtual machine allows multiple sorters is an -historical accident. In practice no more than one sorter -(sorter number 0) ever gets used.

      +

      The virtual machine contains a single sorter. +The sorter is able to accumulate records, sort those records, +then play the records back in sorted order. The sorter is used +to implement the ORDER BY clause of a SELECT statement.

      -

      The virtual machine may contain an arbitrary number of "Lists". -Each list stores a list of integers. Lists are used to hold the +

      The virtual machine contains a single "Lists". +The list stores a list of integers. Lists are used to hold the rowids for records of a database table that needs to be modified. The WHERE clause of an UPDATE or DELETE statement scans through the table and writes the rowid of every record to be modified -into a list. Then the list is played back and the table is modified -in a separate step. It is necessary to do this in two steps since -making a change to a database table can alter the scan order.

      +into the list. Then the list is played back and the table is modified +in a separate step.

      The virtual machine can contain an arbitrary number of "Sets". Each set holds an arbitrary number of strings. Sets are used to