mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
Fix for ticket #136: Added the OP_RenameCursor VDBE instruction and used it
to make cursor numbers right on nested subqueries. Also added OP_Gosub and OP_Return but have not actually used them for anything yet. (CVS 727) FossilOrigin-Name: c602603e7cd8dc5c8bb9db2748eacab650de5bf0
This commit is contained in:
20
manifest
20
manifest
@ -1,5 +1,5 @@
|
|||||||
C Fix\sthe\smemory\sleak\sintroduced\sby\scheck-in\s(725).\s(CVS\s726)
|
C Fix\sfor\sticket\s#136:\s\sAdded\sthe\sOP_RenameCursor\sVDBE\sinstruction\sand\sused\sit\nto\smake\scursor\snumbers\sright\son\snested\ssubqueries.\s\sAlso\sadded\sOP_Gosub\sand\nOP_Return\sbut\shave\snot\sactually\sused\sthem\sfor\sanything\syet.\s(CVS\s727)
|
||||||
D 2002-08-25T18:29:12
|
D 2002-08-25T19:20:40
|
||||||
F Makefile.in bcb81f40d9a17bd94f59e67157b1e1c54c046c2b
|
F Makefile.in bcb81f40d9a17bd94f59e67157b1e1c54c046c2b
|
||||||
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
|
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
|
||||||
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
|
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
|
||||||
@ -37,7 +37,7 @@ F src/pager.h 6991c9c2dc5e4c7f2df4d4ba47d1c6458f763a32
|
|||||||
F src/parse.y 1b180e14b6346e323bd4279469748716f412cc1c
|
F src/parse.y 1b180e14b6346e323bd4279469748716f412cc1c
|
||||||
F src/printf.c 5c50fc1da75c8f5bf432b1ad17d91d6653acd167
|
F src/printf.c 5c50fc1da75c8f5bf432b1ad17d91d6653acd167
|
||||||
F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe
|
F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe
|
||||||
F src/select.c bef25919ad813685d60d03a393728bf5766ec0cb
|
F src/select.c e79db94a78368e981af31be4f186bb78ca4081ce
|
||||||
F src/shell.c 9e9a6eb6bca07f01e6472a603f908a0127ea50ff
|
F src/shell.c 9e9a6eb6bca07f01e6472a603f908a0127ea50ff
|
||||||
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
|
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
|
||||||
F src/sqlite.h.in d3999a9c6374675779058d6cfe5431131618e92b
|
F src/sqlite.h.in d3999a9c6374675779058d6cfe5431131618e92b
|
||||||
@ -49,11 +49,11 @@ F src/test2.c 279057a854359665b89122070ac1fc472acce1b2
|
|||||||
F src/test3.c b99d5ab68ee672f1fbb00520723b5c21bac35822
|
F src/test3.c b99d5ab68ee672f1fbb00520723b5c21bac35822
|
||||||
F src/threadtest.c 72bce0a284647314847bbea44616ceb056bfb77f
|
F src/threadtest.c 72bce0a284647314847bbea44616ceb056bfb77f
|
||||||
F src/tokenize.c 8bd6251e5237c9a16d0bbfb9894925eb129985fa
|
F src/tokenize.c 8bd6251e5237c9a16d0bbfb9894925eb129985fa
|
||||||
F src/trigger.c cc8c6769c2ca37166490ed2b305986268faa3bf8
|
F src/trigger.c c90a292a4bef25e478fd5deda6d300319be6a023
|
||||||
F src/update.c f07e6ed2c517c92871e54d3f5886d1cf56121b11
|
F src/update.c f07e6ed2c517c92871e54d3f5886d1cf56121b11
|
||||||
F src/util.c 60bc91db77cf488618ec4720cb06eedb7f959268
|
F src/util.c 60bc91db77cf488618ec4720cb06eedb7f959268
|
||||||
F src/vdbe.c 92bcd4661641fba76680c762971bdca7995594d6
|
F src/vdbe.c 99b5714751b541a1c64c2c4dede83a474ca6b7e2
|
||||||
F src/vdbe.h a9292f2b5fcecef924fa255fb74609e9cbc776c2
|
F src/vdbe.h 52ec880c63c6ca74bb6377432149260b1b237873
|
||||||
F src/where.c ce42cce65d7bf42341627f3fb0a17f69fea6a4f4
|
F src/where.c ce42cce65d7bf42341627f3fb0a17f69fea6a4f4
|
||||||
F test/all.test efd958d048c70a3247997c482f0b33561f7759f0
|
F test/all.test efd958d048c70a3247997c482f0b33561f7759f0
|
||||||
F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578
|
F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578
|
||||||
@ -109,7 +109,7 @@ F test/unique.test 572aa791327c1e8d797932263e9d67f176cfdb44
|
|||||||
F test/update.test 7ffb062d580a972e7870d0f51d5af3ab9bfeae08
|
F test/update.test 7ffb062d580a972e7870d0f51d5af3ab9bfeae08
|
||||||
F test/vacuum.test 059871b312eb910bbe49dafde1d01490cc2c6bbe
|
F test/vacuum.test 059871b312eb910bbe49dafde1d01490cc2c6bbe
|
||||||
F test/version.test c7057526e14c7e3da5718b88e7f566f4182fd5c5
|
F test/version.test c7057526e14c7e3da5718b88e7f566f4182fd5c5
|
||||||
F test/view.test ed18cebaa19fa949cad4bc7e7f2d8d71001153cf
|
F test/view.test 76d3fe155f1215f9dde1ccad1d1bce5c803132d0
|
||||||
F test/where.test c7aba40ad9178acf9c898e53aac9e447e2d2f2f7
|
F test/where.test c7aba40ad9178acf9c898e53aac9e447e2d2f2f7
|
||||||
F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b
|
F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b
|
||||||
F tool/lemon.c 022adc2830c2705828f744d2c59798bd462eb465
|
F tool/lemon.c 022adc2830c2705828f744d2c59798bd462eb465
|
||||||
@ -147,7 +147,7 @@ F www/speed.tcl a20a792738475b68756ea7a19321600f23d1d803
|
|||||||
F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098
|
F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098
|
||||||
F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
|
F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
|
||||||
F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
|
F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
|
||||||
P 22d8726e61eec0e53893f492cb2163824b87a23e
|
P b957dafc26383af514795df18bc7b8f367c9bd21
|
||||||
R 4234452349011dbb44aad5f2e4ed57e1
|
R 1508fec7d872ab78a02b8e4a6441e47b
|
||||||
U drh
|
U drh
|
||||||
Z 4b5d6fc436ecc6188dd50e32ce24f78e
|
Z b7a5fabc6af8b4c88e87d19c813a614d
|
||||||
|
@ -1 +1 @@
|
|||||||
b957dafc26383af514795df18bc7b8f367c9bd21
|
c602603e7cd8dc5c8bb9db2748eacab650de5bf0
|
27
src/select.c
27
src/select.c
@ -12,7 +12,7 @@
|
|||||||
** This file contains C code routines that are called by the parser
|
** This file contains C code routines that are called by the parser
|
||||||
** to handle SELECT statements in SQLite.
|
** to handle SELECT statements in SQLite.
|
||||||
**
|
**
|
||||||
** $Id: select.c,v 1.109 2002/08/25 18:29:12 drh Exp $
|
** $Id: select.c,v 1.110 2002/08/25 19:20:40 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@ -1403,7 +1403,13 @@ substExprList(ExprList *pList, int iTable, ExprList *pEList, int iSub){
|
|||||||
** All of the expression analysis must occur on both the outer query and
|
** All of the expression analysis must occur on both the outer query and
|
||||||
** the subquery before this routine runs.
|
** the subquery before this routine runs.
|
||||||
*/
|
*/
|
||||||
int flattenSubquery(Select *p, int iFrom, int isAgg, int subqueryIsAgg){
|
static int flattenSubquery(
|
||||||
|
Parse *pParse, /* The parsing context */
|
||||||
|
Select *p, /* The parent or outer SELECT statement */
|
||||||
|
int iFrom, /* Index in p->pSrc->a[] of the inner subquery */
|
||||||
|
int isAgg, /* True if outer SELECT uses aggregate functions */
|
||||||
|
int subqueryIsAgg /* True if the subquery uses aggregate functions */
|
||||||
|
){
|
||||||
Select *pSub; /* The inner query or "subquery" */
|
Select *pSub; /* The inner query or "subquery" */
|
||||||
SrcList *pSrc; /* The FROM clause of the outer query */
|
SrcList *pSrc; /* The FROM clause of the outer query */
|
||||||
SrcList *pSubSrc; /* The FROM clause of the subquery */
|
SrcList *pSubSrc; /* The FROM clause of the subquery */
|
||||||
@ -1486,6 +1492,7 @@ int flattenSubquery(Select *p, int iFrom, int isAgg, int subqueryIsAgg){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
p->isDistinct = p->isDistinct || pSub->isDistinct;
|
p->isDistinct = p->isDistinct || pSub->isDistinct;
|
||||||
|
|
||||||
if( pSub->nLimit>=0 ){
|
if( pSub->nLimit>=0 ){
|
||||||
if( p->nLimit<0 ){
|
if( p->nLimit<0 ){
|
||||||
p->nLimit = pSub->nLimit;
|
p->nLimit = pSub->nLimit;
|
||||||
@ -1494,6 +1501,20 @@ int flattenSubquery(Select *p, int iFrom, int isAgg, int subqueryIsAgg){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
p->nOffset += pSub->nOffset;
|
p->nOffset += pSub->nOffset;
|
||||||
|
|
||||||
|
/* If the subquery contains subqueries of its own, that were not
|
||||||
|
** flattened, then code will have already been generated to put
|
||||||
|
** the results of those sub-subqueries into VDBE cursors relative
|
||||||
|
** to the subquery. We must translate the cursor number into values
|
||||||
|
** suitable for use by the outer query.
|
||||||
|
*/
|
||||||
|
for(i=0; i<pSubSrc->nSrc; i++){
|
||||||
|
Vdbe *v;
|
||||||
|
if( pSubSrc->a[i].pSelect==0 ) continue;
|
||||||
|
v = sqliteGetVdbe(pParse);
|
||||||
|
sqliteVdbeAddOp(v, OP_RenameCursor, pSub->base+i, p->base+i);
|
||||||
|
}
|
||||||
|
|
||||||
if( pSrc->a[iFrom].pTab && pSrc->a[iFrom].pTab->isTransient ){
|
if( pSrc->a[iFrom].pTab && pSrc->a[iFrom].pTab->isTransient ){
|
||||||
sqliteDeleteTable(0, pSrc->a[iFrom].pTab);
|
sqliteDeleteTable(0, pSrc->a[iFrom].pTab);
|
||||||
}
|
}
|
||||||
@ -1883,7 +1904,7 @@ int sqliteSelect(
|
|||||||
** If flattening is a possiblity, do so and return immediately.
|
** If flattening is a possiblity, do so and return immediately.
|
||||||
*/
|
*/
|
||||||
if( pParent && pParentAgg &&
|
if( pParent && pParentAgg &&
|
||||||
flattenSubquery(pParent, parentTab, *pParentAgg, isAgg) ){
|
flattenSubquery(pParse, pParent, parentTab, *pParentAgg, isAgg) ){
|
||||||
if( isAgg ) *pParentAgg = 1;
|
if( isAgg ) *pParentAgg = 1;
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ static void sqliteDeleteTriggerStep(TriggerStep *pTriggerStep){
|
|||||||
TriggerStep * pTmp = pTriggerStep;
|
TriggerStep * pTmp = pTriggerStep;
|
||||||
pTriggerStep = pTriggerStep->pNext;
|
pTriggerStep = pTriggerStep->pNext;
|
||||||
|
|
||||||
if( pTmp->target.dyn ) sqliteFree(pTmp->target.z);
|
if( pTmp->target.dyn ) sqliteFree((char*)pTmp->target.z);
|
||||||
sqliteExprDelete(pTmp->pWhere);
|
sqliteExprDelete(pTmp->pWhere);
|
||||||
sqliteExprListDelete(pTmp->pExprList);
|
sqliteExprListDelete(pTmp->pExprList);
|
||||||
sqliteSelectDelete(pTmp->pSelect);
|
sqliteSelectDelete(pTmp->pSelect);
|
||||||
@ -312,8 +312,6 @@ TriggerStep *sqliteTriggerDeleteStep(Token *pTableName, Expr *pWhere){
|
|||||||
** Recursively delete a Trigger structure
|
** Recursively delete a Trigger structure
|
||||||
*/
|
*/
|
||||||
void sqliteDeleteTrigger(Trigger *pTrigger){
|
void sqliteDeleteTrigger(Trigger *pTrigger){
|
||||||
TriggerStep *pTriggerStep;
|
|
||||||
|
|
||||||
sqliteDeleteTriggerStep(pTrigger->step_list);
|
sqliteDeleteTriggerStep(pTrigger->step_list);
|
||||||
sqliteFree(pTrigger->name);
|
sqliteFree(pTrigger->name);
|
||||||
sqliteFree(pTrigger->table);
|
sqliteFree(pTrigger->table);
|
||||||
|
163
src/vdbe.c
163
src/vdbe.c
@ -30,7 +30,7 @@
|
|||||||
** But other routines are also provided to help in building up
|
** But other routines are also provided to help in building up
|
||||||
** a program instruction by instruction.
|
** a program instruction by instruction.
|
||||||
**
|
**
|
||||||
** $Id: vdbe.c,v 1.170 2002/08/25 18:29:13 drh Exp $
|
** $Id: vdbe.c,v 1.171 2002/08/25 19:20:40 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -1067,35 +1067,36 @@ static char *zOpName[] = { 0,
|
|||||||
"Transaction", "Checkpoint", "Commit", "Rollback",
|
"Transaction", "Checkpoint", "Commit", "Rollback",
|
||||||
"ReadCookie", "SetCookie", "VerifyCookie", "Open",
|
"ReadCookie", "SetCookie", "VerifyCookie", "Open",
|
||||||
"OpenTemp", "OpenWrite", "OpenAux", "OpenWrAux",
|
"OpenTemp", "OpenWrite", "OpenAux", "OpenWrAux",
|
||||||
"Close", "MoveTo", "NewRecno", "PutIntKey",
|
"RenameCursor", "Close", "MoveTo", "NewRecno",
|
||||||
"PutStrKey", "Distinct", "Found", "NotFound",
|
"PutIntKey", "PutStrKey", "Distinct", "Found",
|
||||||
"IsUnique", "NotExists", "Delete", "Column",
|
"NotFound", "IsUnique", "NotExists", "Delete",
|
||||||
"KeyAsData", "Recno", "FullKey", "NullRow",
|
"Column", "KeyAsData", "Recno", "FullKey",
|
||||||
"Last", "Rewind", "Next", "Destroy",
|
"NullRow", "Last", "Rewind", "Next",
|
||||||
"Clear", "CreateIndex", "CreateTable", "IntegrityCk",
|
"Destroy", "Clear", "CreateIndex", "CreateTable",
|
||||||
"IdxPut", "IdxDelete", "IdxRecno", "IdxGT",
|
"IntegrityCk", "IdxPut", "IdxDelete", "IdxRecno",
|
||||||
"IdxGE", "MemLoad", "MemStore", "MemIncr",
|
"IdxGT", "IdxGE", "MemLoad", "MemStore",
|
||||||
"ListWrite", "ListRewind", "ListRead", "ListReset",
|
"MemIncr", "ListWrite", "ListRewind", "ListRead",
|
||||||
"ListPush", "ListPop", "SortPut", "SortMakeRec",
|
"ListReset", "ListPush", "ListPop", "SortPut",
|
||||||
"SortMakeKey", "Sort", "SortNext", "SortCallback",
|
"SortMakeRec", "SortMakeKey", "Sort", "SortNext",
|
||||||
"SortReset", "FileOpen", "FileRead", "FileColumn",
|
"SortCallback", "SortReset", "FileOpen", "FileRead",
|
||||||
"AggReset", "AggFocus", "AggNext", "AggSet",
|
"FileColumn", "AggReset", "AggFocus", "AggNext",
|
||||||
"AggGet", "AggFunc", "AggInit", "AggPush",
|
"AggSet", "AggGet", "AggFunc", "AggInit",
|
||||||
"AggPop", "SetInsert", "SetFound", "SetNotFound",
|
"AggPush", "AggPop", "SetInsert", "SetFound",
|
||||||
"SetFirst", "SetNext", "MakeRecord", "MakeKey",
|
"SetNotFound", "SetFirst", "SetNext", "MakeRecord",
|
||||||
"MakeIdxKey", "IncrKey", "Goto", "If",
|
"MakeKey", "MakeIdxKey", "IncrKey", "Goto",
|
||||||
"IfNot", "Halt", "ColumnCount", "ColumnName",
|
"If", "IfNot", "Halt", "Gosub",
|
||||||
"Callback", "NullCallback", "Integer", "String",
|
"Return", "ColumnCount", "ColumnName", "Callback",
|
||||||
"Pop", "Dup", "Pull", "Push",
|
"NullCallback", "Integer", "String", "Pop",
|
||||||
"MustBeInt", "Add", "AddImm", "Subtract",
|
"Dup", "Pull", "Push", "MustBeInt",
|
||||||
"Multiply", "Divide", "Remainder", "BitAnd",
|
"Add", "AddImm", "Subtract", "Multiply",
|
||||||
"BitOr", "BitNot", "ShiftLeft", "ShiftRight",
|
"Divide", "Remainder", "BitAnd", "BitOr",
|
||||||
"AbsValue", "Eq", "Ne", "Lt",
|
"BitNot", "ShiftLeft", "ShiftRight", "AbsValue",
|
||||||
"Le", "Gt", "Ge", "StrEq",
|
"Eq", "Ne", "Lt", "Le",
|
||||||
"StrNe", "StrLt", "StrLe", "StrGt",
|
"Gt", "Ge", "StrEq", "StrNe",
|
||||||
"StrGe", "IsNull", "NotNull", "Negative",
|
"StrLt", "StrLe", "StrGt", "StrGe",
|
||||||
"And", "Or", "Not", "Concat",
|
"IsNull", "NotNull", "Negative", "And",
|
||||||
"Noop", "Function",
|
"Or", "Not", "Concat", "Noop",
|
||||||
|
"Function",
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1302,6 +1303,25 @@ static void vdbePrintOp(FILE *pOut, int pc, Op *pOp){
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Make sure there is space in the Vdbe structure to hold at least
|
||||||
|
** mxCursor cursors. If there is not currently enough space, then
|
||||||
|
** allocate more.
|
||||||
|
**
|
||||||
|
** If a memory allocation error occurs, return 1. Return 0 if
|
||||||
|
** everything works.
|
||||||
|
*/
|
||||||
|
static int expandCursorArraySize(Vdbe *p, int mxCursor){
|
||||||
|
if( mxCursor>=p->nCursor ){
|
||||||
|
Cursor *aCsr = sqliteRealloc( p->aCsr, (mxCursor+1)*sizeof(Cursor) );
|
||||||
|
if( aCsr==0 ) return 1;
|
||||||
|
p->aCsr = aCsr;
|
||||||
|
memset(&p->aCsr[p->nCursor], 0, sizeof(Cursor)*(mxCursor+1-p->nCursor));
|
||||||
|
p->nCursor = mxCursor+1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Execute the program in the VDBE.
|
** Execute the program in the VDBE.
|
||||||
**
|
**
|
||||||
@ -1347,6 +1367,8 @@ int sqliteVdbeExec(
|
|||||||
int errorAction = OE_Abort; /* Recovery action to do in case of an error */
|
int errorAction = OE_Abort; /* Recovery action to do in case of an error */
|
||||||
int undoTransOnError = 0; /* If error, either ROLLBACK or COMMIT */
|
int undoTransOnError = 0; /* If error, either ROLLBACK or COMMIT */
|
||||||
char zBuf[100]; /* Space to sprintf() an integer */
|
char zBuf[100]; /* Space to sprintf() an integer */
|
||||||
|
int returnStack[100]; /* Return address stack for OP_Gosub & OP_Return */
|
||||||
|
int returnDepth = 0; /* Next unused element in returnStack[] */
|
||||||
|
|
||||||
|
|
||||||
/* No instruction ever pushes more than a single element onto the
|
/* No instruction ever pushes more than a single element onto the
|
||||||
@ -1422,6 +1444,44 @@ case OP_Goto: {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Opcode: Gosub * P2 *
|
||||||
|
**
|
||||||
|
** Push the current address plus 1 onto the return address stack
|
||||||
|
** and then jump to address P2.
|
||||||
|
**
|
||||||
|
** The return address stack is of limited depth. If too many
|
||||||
|
** OP_Gosub operations occur without intervening OP_Returns, then
|
||||||
|
** the return address stack will fill up and processing will abort
|
||||||
|
** with a fatal error.
|
||||||
|
*/
|
||||||
|
case OP_Gosub: {
|
||||||
|
if( returnDepth>=sizeof(returnStack)/sizeof(returnStack[0]) ){
|
||||||
|
sqliteSetString(pzErrMsg, "return address stack overflow", 0);
|
||||||
|
rc = SQLITE_INTERNAL;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
returnStack[returnDepth++] = pc+1;
|
||||||
|
pc = pOp->p2 - 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Opcode: Return * * *
|
||||||
|
**
|
||||||
|
** Jump immediately to the next instruction after the last unreturned
|
||||||
|
** OP_Gosub. If an OP_Return has occurred for all OP_Gosubs, then
|
||||||
|
** processing aborts with a fatal error.
|
||||||
|
*/
|
||||||
|
case OP_Return: {
|
||||||
|
if( returnDepth<=0 ){
|
||||||
|
sqliteSetString(pzErrMsg, "return address stack underflow", 0);
|
||||||
|
rc = SQLITE_INTERNAL;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
returnDepth--;
|
||||||
|
pc = returnStack[returnDepth] - 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Opcode: Halt P1 P2 *
|
/* Opcode: Halt P1 P2 *
|
||||||
**
|
**
|
||||||
** Exit immediately. All open cursors, Lists, Sorts, etc are closed
|
** Exit immediately. All open cursors, Lists, Sorts, etc are closed
|
||||||
@ -3105,16 +3165,7 @@ case OP_Open: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
VERIFY( if( i<0 ) goto bad_instruction; )
|
VERIFY( if( i<0 ) goto bad_instruction; )
|
||||||
if( i>=p->nCursor ){
|
if( expandCursorArraySize(p, i) ) goto no_mem;
|
||||||
int j;
|
|
||||||
Cursor *aCsr = sqliteRealloc( p->aCsr, (i+1)*sizeof(Cursor) );
|
|
||||||
if( aCsr==0 ) goto no_mem;
|
|
||||||
p->aCsr = aCsr;
|
|
||||||
for(j=p->nCursor; j<=i; j++){
|
|
||||||
memset(&p->aCsr[j], 0, sizeof(Cursor));
|
|
||||||
}
|
|
||||||
p->nCursor = i+1;
|
|
||||||
}
|
|
||||||
cleanupCursor(&p->aCsr[i]);
|
cleanupCursor(&p->aCsr[i]);
|
||||||
memset(&p->aCsr[i], 0, sizeof(Cursor));
|
memset(&p->aCsr[i], 0, sizeof(Cursor));
|
||||||
p->aCsr[i].nullRow = 1;
|
p->aCsr[i].nullRow = 1;
|
||||||
@ -3163,16 +3214,7 @@ case OP_OpenTemp: {
|
|||||||
int i = pOp->p1;
|
int i = pOp->p1;
|
||||||
Cursor *pCx;
|
Cursor *pCx;
|
||||||
VERIFY( if( i<0 ) goto bad_instruction; )
|
VERIFY( if( i<0 ) goto bad_instruction; )
|
||||||
if( i>=p->nCursor ){
|
if( expandCursorArraySize(p, i) ) goto no_mem;
|
||||||
int j;
|
|
||||||
Cursor *aCsr = sqliteRealloc( p->aCsr, (i+1)*sizeof(Cursor) );
|
|
||||||
if( aCsr==0 ){ goto no_mem; }
|
|
||||||
p->aCsr = aCsr;
|
|
||||||
for(j=p->nCursor; j<=i; j++){
|
|
||||||
memset(&p->aCsr[j], 0, sizeof(Cursor));
|
|
||||||
}
|
|
||||||
p->nCursor = i+1;
|
|
||||||
}
|
|
||||||
pCx = &p->aCsr[i];
|
pCx = &p->aCsr[i];
|
||||||
cleanupCursor(pCx);
|
cleanupCursor(pCx);
|
||||||
memset(pCx, 0, sizeof(*pCx));
|
memset(pCx, 0, sizeof(*pCx));
|
||||||
@ -3195,6 +3237,27 @@ case OP_OpenTemp: {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Opcode: RenameCursor P1 P2 *
|
||||||
|
**
|
||||||
|
** Rename cursor number P1 as cursor number P2. If P2 was previously
|
||||||
|
** opened is is closed before the renaming occurs.
|
||||||
|
*/
|
||||||
|
case OP_RenameCursor: {
|
||||||
|
int from = pOp->p1;
|
||||||
|
int to = pOp->p2;
|
||||||
|
VERIFY( if( from<0 || to<0 ) goto bad_instruction; )
|
||||||
|
if( to<p->nCursor && p->aCsr[to].pCursor ){
|
||||||
|
cleanupCursor(&p->aCsr[to]);
|
||||||
|
}
|
||||||
|
expandCursorArraySize(p, to);
|
||||||
|
if( from<p->nCursor ){
|
||||||
|
memcpy(&p->aCsr[to], &p->aCsr[from], sizeof(p->aCsr[0]));
|
||||||
|
memset(&p->aCsr[from], 0, sizeof(p->aCsr[0]));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Opcode: Close P1 * *
|
/* Opcode: Close P1 * *
|
||||||
**
|
**
|
||||||
** Close a cursor previously opened as P1. If P1 is not
|
** Close a cursor previously opened as P1. If P1 is not
|
||||||
|
239
src/vdbe.h
239
src/vdbe.h
@ -15,7 +15,7 @@
|
|||||||
** or VDBE. The VDBE implements an abstract machine that runs a
|
** or VDBE. The VDBE implements an abstract machine that runs a
|
||||||
** simple program to access and modify the underlying database.
|
** simple program to access and modify the underlying database.
|
||||||
**
|
**
|
||||||
** $Id: vdbe.h,v 1.57 2002/06/21 23:01:50 drh Exp $
|
** $Id: vdbe.h,v 1.58 2002/08/25 19:20:42 drh Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef _SQLITE_VDBE_H_
|
#ifndef _SQLITE_VDBE_H_
|
||||||
#define _SQLITE_VDBE_H_
|
#define _SQLITE_VDBE_H_
|
||||||
@ -82,139 +82,142 @@ typedef struct VdbeOp VdbeOp;
|
|||||||
#define OP_OpenWrite 10
|
#define OP_OpenWrite 10
|
||||||
#define OP_OpenAux 11
|
#define OP_OpenAux 11
|
||||||
#define OP_OpenWrAux 12
|
#define OP_OpenWrAux 12
|
||||||
#define OP_Close 13
|
#define OP_RenameCursor 13
|
||||||
#define OP_MoveTo 14
|
#define OP_Close 14
|
||||||
#define OP_NewRecno 15
|
#define OP_MoveTo 15
|
||||||
#define OP_PutIntKey 16
|
#define OP_NewRecno 16
|
||||||
#define OP_PutStrKey 17
|
#define OP_PutIntKey 17
|
||||||
#define OP_Distinct 18
|
#define OP_PutStrKey 18
|
||||||
#define OP_Found 19
|
#define OP_Distinct 19
|
||||||
#define OP_NotFound 20
|
#define OP_Found 20
|
||||||
#define OP_IsUnique 21
|
#define OP_NotFound 21
|
||||||
#define OP_NotExists 22
|
#define OP_IsUnique 22
|
||||||
#define OP_Delete 23
|
#define OP_NotExists 23
|
||||||
#define OP_Column 24
|
#define OP_Delete 24
|
||||||
#define OP_KeyAsData 25
|
#define OP_Column 25
|
||||||
#define OP_Recno 26
|
#define OP_KeyAsData 26
|
||||||
#define OP_FullKey 27
|
#define OP_Recno 27
|
||||||
#define OP_NullRow 28
|
#define OP_FullKey 28
|
||||||
#define OP_Last 29
|
#define OP_NullRow 29
|
||||||
#define OP_Rewind 30
|
#define OP_Last 30
|
||||||
#define OP_Next 31
|
#define OP_Rewind 31
|
||||||
|
#define OP_Next 32
|
||||||
|
|
||||||
#define OP_Destroy 32
|
#define OP_Destroy 33
|
||||||
#define OP_Clear 33
|
#define OP_Clear 34
|
||||||
#define OP_CreateIndex 34
|
#define OP_CreateIndex 35
|
||||||
#define OP_CreateTable 35
|
#define OP_CreateTable 36
|
||||||
#define OP_IntegrityCk 36
|
#define OP_IntegrityCk 37
|
||||||
|
|
||||||
#define OP_IdxPut 37
|
#define OP_IdxPut 38
|
||||||
#define OP_IdxDelete 38
|
#define OP_IdxDelete 39
|
||||||
#define OP_IdxRecno 39
|
#define OP_IdxRecno 40
|
||||||
#define OP_IdxGT 40
|
#define OP_IdxGT 41
|
||||||
#define OP_IdxGE 41
|
#define OP_IdxGE 42
|
||||||
|
|
||||||
#define OP_MemLoad 42
|
#define OP_MemLoad 43
|
||||||
#define OP_MemStore 43
|
#define OP_MemStore 44
|
||||||
#define OP_MemIncr 44
|
#define OP_MemIncr 45
|
||||||
|
|
||||||
#define OP_ListWrite 45
|
#define OP_ListWrite 46
|
||||||
#define OP_ListRewind 46
|
#define OP_ListRewind 47
|
||||||
#define OP_ListRead 47
|
#define OP_ListRead 48
|
||||||
#define OP_ListReset 48
|
#define OP_ListReset 49
|
||||||
#define OP_ListPush 49
|
#define OP_ListPush 50
|
||||||
#define OP_ListPop 50
|
#define OP_ListPop 51
|
||||||
|
|
||||||
#define OP_SortPut 51
|
#define OP_SortPut 52
|
||||||
#define OP_SortMakeRec 52
|
#define OP_SortMakeRec 53
|
||||||
#define OP_SortMakeKey 53
|
#define OP_SortMakeKey 54
|
||||||
#define OP_Sort 54
|
#define OP_Sort 55
|
||||||
#define OP_SortNext 55
|
#define OP_SortNext 56
|
||||||
#define OP_SortCallback 56
|
#define OP_SortCallback 57
|
||||||
#define OP_SortReset 57
|
#define OP_SortReset 58
|
||||||
|
|
||||||
#define OP_FileOpen 58
|
#define OP_FileOpen 59
|
||||||
#define OP_FileRead 59
|
#define OP_FileRead 60
|
||||||
#define OP_FileColumn 60
|
#define OP_FileColumn 61
|
||||||
|
|
||||||
#define OP_AggReset 61
|
#define OP_AggReset 62
|
||||||
#define OP_AggFocus 62
|
#define OP_AggFocus 63
|
||||||
#define OP_AggNext 63
|
#define OP_AggNext 64
|
||||||
#define OP_AggSet 64
|
#define OP_AggSet 65
|
||||||
#define OP_AggGet 65
|
#define OP_AggGet 66
|
||||||
#define OP_AggFunc 66
|
#define OP_AggFunc 67
|
||||||
#define OP_AggInit 67
|
#define OP_AggInit 68
|
||||||
#define OP_AggPush 68
|
#define OP_AggPush 69
|
||||||
#define OP_AggPop 69
|
#define OP_AggPop 70
|
||||||
|
|
||||||
#define OP_SetInsert 70
|
#define OP_SetInsert 71
|
||||||
#define OP_SetFound 71
|
#define OP_SetFound 72
|
||||||
#define OP_SetNotFound 72
|
#define OP_SetNotFound 73
|
||||||
#define OP_SetFirst 73
|
#define OP_SetFirst 74
|
||||||
#define OP_SetNext 74
|
#define OP_SetNext 75
|
||||||
|
|
||||||
#define OP_MakeRecord 75
|
#define OP_MakeRecord 76
|
||||||
#define OP_MakeKey 76
|
#define OP_MakeKey 77
|
||||||
#define OP_MakeIdxKey 77
|
#define OP_MakeIdxKey 78
|
||||||
#define OP_IncrKey 78
|
#define OP_IncrKey 79
|
||||||
|
|
||||||
#define OP_Goto 79
|
#define OP_Goto 80
|
||||||
#define OP_If 80
|
#define OP_If 81
|
||||||
#define OP_IfNot 81
|
#define OP_IfNot 82
|
||||||
#define OP_Halt 82
|
#define OP_Halt 83
|
||||||
|
#define OP_Gosub 84
|
||||||
|
#define OP_Return 85
|
||||||
|
|
||||||
#define OP_ColumnCount 83
|
#define OP_ColumnCount 86
|
||||||
#define OP_ColumnName 84
|
#define OP_ColumnName 87
|
||||||
#define OP_Callback 85
|
#define OP_Callback 88
|
||||||
#define OP_NullCallback 86
|
#define OP_NullCallback 89
|
||||||
|
|
||||||
#define OP_Integer 87
|
#define OP_Integer 90
|
||||||
#define OP_String 88
|
#define OP_String 91
|
||||||
#define OP_Pop 89
|
#define OP_Pop 92
|
||||||
#define OP_Dup 90
|
#define OP_Dup 93
|
||||||
#define OP_Pull 91
|
#define OP_Pull 94
|
||||||
#define OP_Push 92
|
#define OP_Push 95
|
||||||
#define OP_MustBeInt 93
|
#define OP_MustBeInt 96
|
||||||
|
|
||||||
#define OP_Add 94
|
#define OP_Add 97
|
||||||
#define OP_AddImm 95
|
#define OP_AddImm 98
|
||||||
#define OP_Subtract 96
|
#define OP_Subtract 99
|
||||||
#define OP_Multiply 97
|
#define OP_Multiply 100
|
||||||
#define OP_Divide 98
|
#define OP_Divide 101
|
||||||
#define OP_Remainder 99
|
#define OP_Remainder 102
|
||||||
#define OP_BitAnd 100
|
#define OP_BitAnd 103
|
||||||
#define OP_BitOr 101
|
#define OP_BitOr 104
|
||||||
#define OP_BitNot 102
|
#define OP_BitNot 105
|
||||||
#define OP_ShiftLeft 103
|
#define OP_ShiftLeft 106
|
||||||
#define OP_ShiftRight 104
|
#define OP_ShiftRight 107
|
||||||
#define OP_AbsValue 105
|
#define OP_AbsValue 108
|
||||||
|
|
||||||
/* Note: The code generator assumes that OP_XX+6==OP_StrXX */
|
/***** IMPORTANT NOTE: The code generator assumes that OP_XX+6==OP_StrXX *****/
|
||||||
#define OP_Eq 106
|
#define OP_Eq 109
|
||||||
#define OP_Ne 107
|
#define OP_Ne 110
|
||||||
#define OP_Lt 108
|
#define OP_Lt 111
|
||||||
#define OP_Le 109
|
#define OP_Le 112
|
||||||
#define OP_Gt 110
|
#define OP_Gt 113
|
||||||
#define OP_Ge 111
|
#define OP_Ge 114
|
||||||
#define OP_StrEq 112
|
#define OP_StrEq 115
|
||||||
#define OP_StrNe 113
|
#define OP_StrNe 116
|
||||||
#define OP_StrLt 114
|
#define OP_StrLt 117
|
||||||
#define OP_StrLe 115
|
#define OP_StrLe 118
|
||||||
#define OP_StrGt 116
|
#define OP_StrGt 119
|
||||||
#define OP_StrGe 117
|
#define OP_StrGe 120
|
||||||
/* Note: the code generator assumes that OP_XX+6==OP_StrXX */
|
/***** IMPORTANT NOTE: the code generator assumes that OP_XX+6==OP_StrXX *****/
|
||||||
|
|
||||||
#define OP_IsNull 118
|
#define OP_IsNull 121
|
||||||
#define OP_NotNull 119
|
#define OP_NotNull 122
|
||||||
#define OP_Negative 120
|
#define OP_Negative 123
|
||||||
#define OP_And 121
|
#define OP_And 124
|
||||||
#define OP_Or 122
|
#define OP_Or 125
|
||||||
#define OP_Not 123
|
#define OP_Not 126
|
||||||
#define OP_Concat 124
|
#define OP_Concat 127
|
||||||
#define OP_Noop 125
|
#define OP_Noop 128
|
||||||
#define OP_Function 126
|
#define OP_Function 129
|
||||||
|
|
||||||
#define OP_MAX 126
|
#define OP_MAX 129
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Prototypes for the VDBE interface. See comments on the implementation
|
** Prototypes for the VDBE interface. See comments on the implementation
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
# This file implements regression tests for SQLite library. The
|
# This file implements regression tests for SQLite library. The
|
||||||
# focus of this file is testing VIEW statements.
|
# focus of this file is testing VIEW statements.
|
||||||
#
|
#
|
||||||
# $Id: view.test,v 1.10 2002/08/25 18:29:16 drh Exp $
|
# $Id: view.test,v 1.11 2002/08/25 19:20:43 drh Exp $
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
|
|
||||||
@ -284,14 +284,17 @@ do_test view-8.3 {
|
|||||||
SELECT * FROM v7 ORDER BY a;
|
SELECT * FROM v7 ORDER BY a;
|
||||||
}
|
}
|
||||||
} {9 18 27 39}
|
} {9 18 27 39}
|
||||||
if 0 {
|
|
||||||
do_test view-8.4 {
|
do_test view-8.4 {
|
||||||
execsql { PRAGMA vdbe_trace=on;
|
execsql {
|
||||||
CREATE VIEW v8 AS SELECT max(cnt) FROM
|
CREATE VIEW v8 AS SELECT max(cnt) AS mx FROM
|
||||||
(SELECT a%2 AS eo, count(*) AS cnt FROM t1 GROUP BY eo);
|
(SELECT a%2 AS eo, count(*) AS cnt FROM t1 GROUP BY eo);
|
||||||
SELECT * FROM v8;
|
SELECT * FROM v8;
|
||||||
}
|
}
|
||||||
} 3
|
} 3
|
||||||
}
|
do_test view-8.5 {
|
||||||
|
execsql {
|
||||||
|
SELECT mx+10, mx*2 FROM v8;
|
||||||
|
}
|
||||||
|
} {13 6}
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
Reference in New Issue
Block a user