-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
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
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
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
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
** 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 <ctype.h>
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 */
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.
**
sqliteFree(p->aMem);
p->aMem = 0;
p->nMem = 0;
- for(i=0; i<p->nList; i++){
- KeylistFree(p->apList[i]);
- p->apList[i] = 0;
- }
- sqliteFree(p->apList);
- p->apList = 0;
- p->nList = 0;
- for(i=0; i<p->nSort; i++){
- Sorter *pSorter;
- while( (pSorter = p->apSort[i])!=0 ){
- p->apSort[i] = pSorter->pNext;
- sqliteFree(pSorter->zKey);
- sqliteFree(pSorter->pData);
- sqliteFree(pSorter);
- }
+ if( p->pList ){
+ KeylistFree(p->pList);
+ p->pList = 0;
}
- sqliteFree(p->apSort);
- p->apSort = 0;
- p->nSort = 0;
+ SorterReset(p);
if( p->pFile ){
if( p->pFile!=stdin ) fclose(p->pFile);
p->pFile = 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",
};
/*
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;
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
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{
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;
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
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( j<p->nSort ){
- int i;
- Sorter *pElem;
- Sorter *apSorter[NSORT];
- for(i=0; i<NSORT; i++){
- apSorter[i] = 0;
- }
- while( p->apSort[j] ){
- pElem = p->apSort[j];
- p->apSort[j] = pElem->pNext;
- pElem->pNext = 0;
- for(i=0; i<NSORT-1; i++){
- if( apSorter[i]==0 ){
- apSorter[i] = pElem;
- break;
- }else{
- pElem = Merge(apSorter[i], pElem);
- apSorter[i] = 0;
- }
- }
- if( i>=NSORT-1 ){
- apSorter[NSORT-1] = Merge(apSorter[NSORT-1],pElem);
+ int i;
+ Sorter *pElem;
+ Sorter *apSorter[NSORT];
+ for(i=0; i<NSORT; i++){
+ apSorter[i] = 0;
+ }
+ while( p->pSort ){
+ pElem = p->pSort;
+ p->pSort = pElem->pNext;
+ pElem->pNext = 0;
+ for(i=0; i<NSORT-1; i++){
+ if( apSorter[i]==0 ){
+ apSorter[i] = pElem;
+ break;
+ }else{
+ pElem = Merge(apSorter[i], pElem);
+ apSorter[i] = 0;
}
}
- pElem = 0;
- for(i=0; i<NSORT; i++){
- pElem = Merge(apSorter[i], pElem);
+ if( i>=NSORT-1 ){
+ apSorter[NSORT-1] = Merge(apSorter[NSORT-1],pElem);
}
- p->apSort[j] = pElem;
}
+ pElem = 0;
+ for(i=0; i<NSORT; i++){
+ pElem = Merge(apSorter[i], pElem);
+ }
+ p->pSort = 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( i<p->nSort && ) 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;
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( i<p->nSort && 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
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( i<p->nSort ){
- 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;
}