mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
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
This commit is contained in:
10
README
10
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
|
||||
|
30
manifest
30
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
|
||||
|
@@ -1 +1 @@
|
||||
b2cb118fb7c6713684d32a48a7ba8ffffe596687
|
||||
e1370276c2a0d045b29c981ddcb59f737e19a91c
|
@@ -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
|
||||
|
@@ -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);
|
||||
|
13
src/select.c
13
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.
|
||||
|
@@ -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);
|
||||
}
|
||||
|
250
src/vdbe.c
250
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 <ctype.h>
|
||||
@@ -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; i<p->nList; 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; 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);
|
||||
}
|
||||
}
|
||||
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,25 +3274,21 @@ 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( 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;
|
||||
while( p->pSort ){
|
||||
pElem = p->pSort;
|
||||
p->pSort = pElem->pNext;
|
||||
pElem->pNext = 0;
|
||||
for(i=0; i<NSORT-1; i++){
|
||||
if( apSorter[i]==0 ){
|
||||
@@ -3367,22 +3307,21 @@ case OP_Sort: {
|
||||
for(i=0; i<NSORT; i++){
|
||||
pElem = Merge(apSorter[i], pElem);
|
||||
}
|
||||
p->apSort[j] = 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;
|
||||
@@ -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( 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
|
||||
@@ -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( 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;
|
||||
}
|
||||
|
||||
|
155
src/vdbe.h
155
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
|
||||
|
@@ -19,6 +19,10 @@ proc chng {date desc} {
|
||||
|
||||
chng {2001 Oct ?? (2.0.8)} {
|
||||
<li>Documentation updates</li>
|
||||
<li>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.
|
||||
</li>
|
||||
}
|
||||
|
||||
chng {2001 Oct 21 (2.0.7)} {
|
||||
|
@@ -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 {<html>
|
||||
<head><title>SQLite: An SQL Database Engine In A C Library</title></head>
|
||||
@@ -16,7 +16,7 @@ puts {</p>}
|
||||
|
||||
puts {<h2>Introduction</h2>
|
||||
|
||||
<p>SQLite is a C library that implements an SQL database engine.
|
||||
<p>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 {<h2>Current Status</h2>
|
||||
<p>A <a href="changes.html">change history</a> is available online.
|
||||
The latest source code is
|
||||
<a href="download.html">available for download</a>.
|
||||
There are currently no <em>known</em> 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.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@@ -158,32 +160,6 @@ $ make test <i> Optional: run regression tests </i>
|
||||
</pre></blockquote>
|
||||
}
|
||||
|
||||
puts {<h2>Command-line Usage Example</h2>
|
||||
|
||||
<p>Download the source archive and compile the <b>sqlite</b>
|
||||
program as described above. Then type:</p>
|
||||
|
||||
<blockquote><pre>
|
||||
bash$ sqlite ~/newdb <i>Directory ~/newdb created automatically</i>
|
||||
sqlite> create table t1(
|
||||
...> a int,
|
||||
...> b varchar(20)
|
||||
...> c text
|
||||
...> ); <i>End each SQL statement with a ';'</i>
|
||||
sqlite> insert into t1
|
||||
...> values(1,'hi','y''all');
|
||||
sqlite> select * from t1;
|
||||
1|hello|world
|
||||
sqlite> .mode columns <i>Special commands begin with '.'</i>
|
||||
sqlite> .header on <i>Type ".help" for a list of commands</i>
|
||||
sqlite> select * from t1;
|
||||
a b c
|
||||
------ ------- -------
|
||||
1 hi y'all
|
||||
sqlite> .exit
|
||||
base$
|
||||
</pre></blockquote>
|
||||
}
|
||||
puts {<h2>Related Sites</h2>
|
||||
|
||||
<ul>
|
||||
|
@@ -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 {<html>
|
||||
<head>
|
||||
@@ -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.</p>
|
||||
|
||||
<p>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.</p>
|
||||
<p>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.</p>
|
||||
|
||||
<p>The virtual machine may contain an arbitrary number of "Lists".
|
||||
Each list stores a list of integers. Lists are used to hold the
|
||||
<p>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.</p>
|
||||
into the list. Then the list is played back and the table is modified
|
||||
in a separate step.</p>
|
||||
|
||||
<p>The virtual machine can contain an arbitrary number of "Sets".
|
||||
Each set holds an arbitrary number of strings. Sets are used to
|
||||
|
Reference in New Issue
Block a user