mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-12 13:01:09 +03:00
Speed up in the handling of VDBE cursors. (CVS 1578)
FossilOrigin-Name: e42316f5708de6f639b7b54e08d4be73b45367e9
This commit is contained in:
16
manifest
16
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Improve\sthe\sspeed\sof\sOP_Column\sthrough\sbetter\scaching.\s(CVS\s1577)
|
C Speed\sup\sin\sthe\shandling\sof\sVDBE\scursors.\s(CVS\s1578)
|
||||||
D 2004-06-12T18:12:16
|
D 2004-06-12T20:12:51
|
||||||
F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a
|
F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a
|
||||||
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
|
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
|
||||||
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
|
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
|
||||||
@@ -71,11 +71,11 @@ F src/update.c 168b6d523087ca4545b74ec9f3102b1f3c6b1e38
|
|||||||
F src/utf.c e16737b3fc4201bf7ce9bd8ced5250596aa31b76
|
F src/utf.c e16737b3fc4201bf7ce9bd8ced5250596aa31b76
|
||||||
F src/util.c 90375fa253137562d536ccdd40b297f0fd7413fc
|
F src/util.c 90375fa253137562d536ccdd40b297f0fd7413fc
|
||||||
F src/vacuum.c b921eb778842592e1fb48a9d4cef7e861103878f
|
F src/vacuum.c b921eb778842592e1fb48a9d4cef7e861103878f
|
||||||
F src/vdbe.c 9f941bbdf0bcbc18fbdfceecbc2322e82084e094
|
F src/vdbe.c c71e47262d3d3539a20a489a03b9cde15ef3acb7
|
||||||
F src/vdbe.h 46f74444a213129bc4b5ce40124dd8ed613b0cde
|
F src/vdbe.h 46f74444a213129bc4b5ce40124dd8ed613b0cde
|
||||||
F src/vdbeInt.h 1cc767a63eefd1d1114e190336588c6d4f70a6a0
|
F src/vdbeInt.h ffc7b8ed911c5bf804796a768fdb6f0568010fa2
|
||||||
F src/vdbeapi.c ee350b552fc4c1c695b760f914f69e9c5556e829
|
F src/vdbeapi.c ee350b552fc4c1c695b760f914f69e9c5556e829
|
||||||
F src/vdbeaux.c 1d0dbaf73c89bd1cc27abad19ee0aa26ab5d03f4
|
F src/vdbeaux.c ff7c66b704dc2c35805657f2cb10ad1b00c8ecd2
|
||||||
F src/vdbemem.c 34f59988831ea032b7f526c2c73175f9f4c0f3ad
|
F src/vdbemem.c 34f59988831ea032b7f526c2c73175f9f4c0f3ad
|
||||||
F src/where.c dda77afaa593cd54e5955ec433076de18faf62f6
|
F src/where.c dda77afaa593cd54e5955ec433076de18faf62f6
|
||||||
F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242
|
F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242
|
||||||
@@ -223,7 +223,7 @@ F www/support.tcl 1801397edd271cc39a2aadd54e701184b5181248
|
|||||||
F www/tclsqlite.tcl 19191cf2a1010eaeff74c51d83fd5f5a4d899075
|
F www/tclsqlite.tcl 19191cf2a1010eaeff74c51d83fd5f5a4d899075
|
||||||
F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
|
F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
|
||||||
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
|
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
|
||||||
P 99a7bd83ac38e14bb936a834634313cf98279a62
|
P f687977a28eda5ce0aa1cba2fdfb0152443032bc
|
||||||
R 1e1692dcb3026c03937468eb4d723051
|
R 088c58f79c616faca7f8012c3563c5db
|
||||||
U drh
|
U drh
|
||||||
Z 511db11f04adc59072cae9559d18a6b6
|
Z 661048d261d615dd2ffa1c2c62f56278
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
f687977a28eda5ce0aa1cba2fdfb0152443032bc
|
e42316f5708de6f639b7b54e08d4be73b45367e9
|
||||||
78
src/vdbe.c
78
src/vdbe.c
@@ -43,7 +43,7 @@
|
|||||||
** in this file for details. If in doubt, do not deviate from existing
|
** in this file for details. If in doubt, do not deviate from existing
|
||||||
** commenting and indentation practices when changing or adding code.
|
** commenting and indentation practices when changing or adding code.
|
||||||
**
|
**
|
||||||
** $Id: vdbe.c,v 1.369 2004/06/12 18:12:16 drh Exp $
|
** $Id: vdbe.c,v 1.370 2004/06/12 20:12:51 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
@@ -271,24 +271,27 @@ static Sorter *Merge(Sorter *pLeft, Sorter *pRight, KeyInfo *pKeyInfo){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Make sure there is space in the Vdbe structure to hold at least
|
** Allocate cursor number iCur. Return a pointer to it. Return NULL
|
||||||
** mxCursor cursors. If there is not currently enough space, then
|
** if we run out of memory.
|
||||||
** allocate more.
|
|
||||||
**
|
|
||||||
** If a memory allocation error occurs, return 1. Return 0 if
|
|
||||||
** everything works.
|
|
||||||
*/
|
*/
|
||||||
static int expandCursorArraySize(Vdbe *p, int mxCursor){
|
static Cursor *allocateCursor(Vdbe *p, int iCur){
|
||||||
if( mxCursor>=p->nCursor ){
|
Cursor *pCx;
|
||||||
p->apCsr = sqliteRealloc( p->apCsr, (mxCursor+1)*sizeof(Cursor*) );
|
if( iCur>=p->nCursor ){
|
||||||
if( p->apCsr==0 ) return 1;
|
int i;
|
||||||
while( p->nCursor<=mxCursor ){
|
p->apCsr = sqliteRealloc( p->apCsr, (iCur+1)*sizeof(Cursor*) );
|
||||||
Cursor *pC;
|
if( p->apCsr==0 ){
|
||||||
p->apCsr[p->nCursor++] = pC = sqliteMalloc( sizeof(Cursor) );
|
p->nCursor = 0;
|
||||||
if( pC==0 ) return 1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
for(i=p->nCursor; i<iCur; i++){
|
||||||
|
p->apCsr[i] = 0;
|
||||||
|
}
|
||||||
|
p->nCursor = iCur+1;
|
||||||
|
}else if( p->apCsr[iCur] ){
|
||||||
|
sqlite3VdbeFreeCursor(p->apCsr[iCur]);
|
||||||
}
|
}
|
||||||
return 0;
|
p->apCsr[iCur] = pCx = sqliteMalloc( sizeof(Cursor) );
|
||||||
|
return pCx;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1867,6 +1870,7 @@ case OP_NotNull: {
|
|||||||
*/
|
*/
|
||||||
case OP_SetNumColumns: {
|
case OP_SetNumColumns: {
|
||||||
assert( (pOp->p1)<p->nCursor );
|
assert( (pOp->p1)<p->nCursor );
|
||||||
|
assert( p->apCsr[pOp->p1]!=0 );
|
||||||
p->apCsr[pOp->p1]->nField = pOp->p2;
|
p->apCsr[pOp->p1]->nField = pOp->p2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1931,6 +1935,7 @@ case OP_Column: {
|
|||||||
** records on the stack, the next entry down on the stack is an integer
|
** records on the stack, the next entry down on the stack is an integer
|
||||||
** which is the number of records.
|
** which is the number of records.
|
||||||
*/
|
*/
|
||||||
|
assert( p1<0 || p->apCsr[p1]!=0 );
|
||||||
if( p1<0 ){
|
if( p1<0 ){
|
||||||
/* Take the record off of the stack */
|
/* Take the record off of the stack */
|
||||||
Mem *pRec = &pTos[p1];
|
Mem *pRec = &pTos[p1];
|
||||||
@@ -2572,9 +2577,8 @@ case OP_OpenWrite: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert( i>=0 );
|
assert( i>=0 );
|
||||||
if( expandCursorArraySize(p, i) ) goto no_mem;
|
pCur = allocateCursor(p, i);
|
||||||
pCur = p->apCsr[i];
|
if( pCur==0 ) goto no_mem;
|
||||||
sqlite3VdbeCleanupCursor(pCur);
|
|
||||||
pCur->nullRow = 1;
|
pCur->nullRow = 1;
|
||||||
if( pX==0 ) break;
|
if( pX==0 ) break;
|
||||||
/* We always provide a key comparison function. If the table being
|
/* We always provide a key comparison function. If the table being
|
||||||
@@ -2635,10 +2639,8 @@ case OP_OpenTemp: {
|
|||||||
int i = pOp->p1;
|
int i = pOp->p1;
|
||||||
Cursor *pCx;
|
Cursor *pCx;
|
||||||
assert( i>=0 );
|
assert( i>=0 );
|
||||||
if( expandCursorArraySize(p, i) ) goto no_mem;
|
pCx = allocateCursor(p, i);
|
||||||
pCx = p->apCsr[i];
|
if( pCx==0 ) goto no_mem;
|
||||||
sqlite3VdbeCleanupCursor(pCx);
|
|
||||||
memset(pCx, 0, sizeof(*pCx));
|
|
||||||
pCx->nullRow = 1;
|
pCx->nullRow = 1;
|
||||||
rc = sqlite3BtreeFactory(db, 0, 1, TEMP_PAGES, &pCx->pBt);
|
rc = sqlite3BtreeFactory(db, 0, 1, TEMP_PAGES, &pCx->pBt);
|
||||||
|
|
||||||
@@ -2686,10 +2688,8 @@ case OP_OpenPseudo: {
|
|||||||
int i = pOp->p1;
|
int i = pOp->p1;
|
||||||
Cursor *pCx;
|
Cursor *pCx;
|
||||||
assert( i>=0 );
|
assert( i>=0 );
|
||||||
if( expandCursorArraySize(p, i) ) goto no_mem;
|
pCx = allocateCursor(p, i);
|
||||||
pCx = p->apCsr[i];
|
if( pCx==0 ) goto no_mem;
|
||||||
sqlite3VdbeCleanupCursor(pCx);
|
|
||||||
memset(pCx, 0, sizeof(*pCx));
|
|
||||||
pCx->nullRow = 1;
|
pCx->nullRow = 1;
|
||||||
pCx->pseudoTable = 1;
|
pCx->pseudoTable = 1;
|
||||||
pCx->pIncrKey = &pCx->bogusIncrKey;
|
pCx->pIncrKey = &pCx->bogusIncrKey;
|
||||||
@@ -2704,7 +2704,8 @@ case OP_OpenPseudo: {
|
|||||||
case OP_Close: {
|
case OP_Close: {
|
||||||
int i = pOp->p1;
|
int i = pOp->p1;
|
||||||
if( i>=0 && i<p->nCursor ){
|
if( i>=0 && i<p->nCursor ){
|
||||||
sqlite3VdbeCleanupCursor(p->apCsr[i]);
|
sqlite3VdbeFreeCursor(p->apCsr[i]);
|
||||||
|
p->apCsr[i] = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2759,6 +2760,7 @@ case OP_MoveGt: {
|
|||||||
assert( pTos>=p->aStack );
|
assert( pTos>=p->aStack );
|
||||||
assert( i>=0 && i<p->nCursor );
|
assert( i>=0 && i<p->nCursor );
|
||||||
pC = p->apCsr[i];
|
pC = p->apCsr[i];
|
||||||
|
assert( pC!=0 );
|
||||||
if( pC->pCursor!=0 ){
|
if( pC->pCursor!=0 ){
|
||||||
int res, oc;
|
int res, oc;
|
||||||
oc = pOp->opcode;
|
oc = pOp->opcode;
|
||||||
@@ -2858,6 +2860,7 @@ case OP_Found: {
|
|||||||
Cursor *pC;
|
Cursor *pC;
|
||||||
assert( pTos>=p->aStack );
|
assert( pTos>=p->aStack );
|
||||||
assert( i>=0 && i<p->nCursor );
|
assert( i>=0 && i<p->nCursor );
|
||||||
|
assert( p->apCsr[i]!=0 );
|
||||||
if( (pC = p->apCsr[i])->pCursor!=0 ){
|
if( (pC = p->apCsr[i])->pCursor!=0 ){
|
||||||
int res, rx;
|
int res, rx;
|
||||||
assert( pC->intKey==0 );
|
assert( pC->intKey==0 );
|
||||||
@@ -2915,6 +2918,7 @@ case OP_IsUnique: {
|
|||||||
pTos--;
|
pTos--;
|
||||||
assert( i>=0 && i<=p->nCursor );
|
assert( i>=0 && i<=p->nCursor );
|
||||||
pCx = p->apCsr[i];
|
pCx = p->apCsr[i];
|
||||||
|
assert( pCx!=0 );
|
||||||
pCrsr = pCx->pCursor;
|
pCrsr = pCx->pCursor;
|
||||||
if( pCrsr!=0 ){
|
if( pCrsr!=0 ){
|
||||||
int res, rc;
|
int res, rc;
|
||||||
@@ -2998,6 +3002,7 @@ case OP_NotExists: {
|
|||||||
BtCursor *pCrsr;
|
BtCursor *pCrsr;
|
||||||
assert( pTos>=p->aStack );
|
assert( pTos>=p->aStack );
|
||||||
assert( i>=0 && i<p->nCursor );
|
assert( i>=0 && i<p->nCursor );
|
||||||
|
assert( p->apCsr[i]!=0 );
|
||||||
if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
|
if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
|
||||||
int res, rx;
|
int res, rx;
|
||||||
u64 iKey;
|
u64 iKey;
|
||||||
@@ -3031,6 +3036,7 @@ case OP_NewRecno: {
|
|||||||
i64 v = 0;
|
i64 v = 0;
|
||||||
Cursor *pC;
|
Cursor *pC;
|
||||||
assert( i>=0 && i<p->nCursor );
|
assert( i>=0 && i<p->nCursor );
|
||||||
|
assert( p->apCsr[i]!=0 );
|
||||||
if( (pC = p->apCsr[i])->pCursor==0 ){
|
if( (pC = p->apCsr[i])->pCursor==0 ){
|
||||||
/* The zero initialization above is all that is needed */
|
/* The zero initialization above is all that is needed */
|
||||||
}else{
|
}else{
|
||||||
@@ -3159,6 +3165,7 @@ case OP_PutStrKey: {
|
|||||||
Cursor *pC;
|
Cursor *pC;
|
||||||
assert( pNos>=p->aStack );
|
assert( pNos>=p->aStack );
|
||||||
assert( i>=0 && i<p->nCursor );
|
assert( i>=0 && i<p->nCursor );
|
||||||
|
assert( p->apCsr[i]!=0 );
|
||||||
if( ((pC = p->apCsr[i])->pCursor!=0 || pC->pseudoTable) ){
|
if( ((pC = p->apCsr[i])->pCursor!=0 || pC->pseudoTable) ){
|
||||||
char *zKey;
|
char *zKey;
|
||||||
i64 nKey;
|
i64 nKey;
|
||||||
@@ -3249,6 +3256,7 @@ case OP_Delete: {
|
|||||||
Cursor *pC;
|
Cursor *pC;
|
||||||
assert( i>=0 && i<p->nCursor );
|
assert( i>=0 && i<p->nCursor );
|
||||||
pC = p->apCsr[i];
|
pC = p->apCsr[i];
|
||||||
|
assert( pC!=0 );
|
||||||
if( pC->pCursor!=0 ){
|
if( pC->pCursor!=0 ){
|
||||||
sqlite3VdbeCursorMoveto(pC);
|
sqlite3VdbeCursorMoveto(pC);
|
||||||
rc = sqlite3BtreeDelete(pC->pCursor);
|
rc = sqlite3BtreeDelete(pC->pCursor);
|
||||||
@@ -3283,6 +3291,7 @@ case OP_KeyAsData: {
|
|||||||
Cursor *pC;
|
Cursor *pC;
|
||||||
assert( i>=0 && i<p->nCursor );
|
assert( i>=0 && i<p->nCursor );
|
||||||
pC = p->apCsr[i];
|
pC = p->apCsr[i];
|
||||||
|
assert( pC!=0 );
|
||||||
pC->keyAsData = pOp->p2;
|
pC->keyAsData = pOp->p2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -3314,6 +3323,7 @@ case OP_RowData: {
|
|||||||
pTos++;
|
pTos++;
|
||||||
assert( i>=0 && i<p->nCursor );
|
assert( i>=0 && i<p->nCursor );
|
||||||
pC = p->apCsr[i];
|
pC = p->apCsr[i];
|
||||||
|
assert( pC!=0 );
|
||||||
if( pC->nullRow ){
|
if( pC->nullRow ){
|
||||||
pTos->flags = MEM_Null;
|
pTos->flags = MEM_Null;
|
||||||
}else if( pC->pCursor!=0 ){
|
}else if( pC->pCursor!=0 ){
|
||||||
@@ -3370,6 +3380,7 @@ case OP_Recno: {
|
|||||||
|
|
||||||
assert( i>=0 && i<p->nCursor );
|
assert( i>=0 && i<p->nCursor );
|
||||||
pC = p->apCsr[i];
|
pC = p->apCsr[i];
|
||||||
|
assert( pC!=0 );
|
||||||
sqlite3VdbeCursorMoveto(pC);
|
sqlite3VdbeCursorMoveto(pC);
|
||||||
pTos++;
|
pTos++;
|
||||||
if( pC->recnoIsValid ){
|
if( pC->recnoIsValid ){
|
||||||
@@ -3405,9 +3416,10 @@ case OP_FullKey: {
|
|||||||
BtCursor *pCrsr;
|
BtCursor *pCrsr;
|
||||||
Cursor *pC;
|
Cursor *pC;
|
||||||
|
|
||||||
|
assert( i>=0 && i<p->nCursor );
|
||||||
|
assert( p->apCsr[i]!=0 );
|
||||||
assert( p->apCsr[i]->keyAsData );
|
assert( p->apCsr[i]->keyAsData );
|
||||||
assert( !p->apCsr[i]->pseudoTable );
|
assert( !p->apCsr[i]->pseudoTable );
|
||||||
assert( i>=0 && i<p->nCursor );
|
|
||||||
pTos++;
|
pTos++;
|
||||||
if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
|
if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
|
||||||
u64 amt;
|
u64 amt;
|
||||||
@@ -3448,6 +3460,7 @@ case OP_NullRow: {
|
|||||||
|
|
||||||
assert( i>=0 && i<p->nCursor );
|
assert( i>=0 && i<p->nCursor );
|
||||||
pC = p->apCsr[i];
|
pC = p->apCsr[i];
|
||||||
|
assert( pC!=0 );
|
||||||
pC->nullRow = 1;
|
pC->nullRow = 1;
|
||||||
pC->recnoIsValid = 0;
|
pC->recnoIsValid = 0;
|
||||||
break;
|
break;
|
||||||
@@ -3468,6 +3481,7 @@ case OP_Last: {
|
|||||||
|
|
||||||
assert( i>=0 && i<p->nCursor );
|
assert( i>=0 && i<p->nCursor );
|
||||||
pC = p->apCsr[i];
|
pC = p->apCsr[i];
|
||||||
|
assert( pC!=0 );
|
||||||
if( (pCrsr = pC->pCursor)!=0 ){
|
if( (pCrsr = pC->pCursor)!=0 ){
|
||||||
int res;
|
int res;
|
||||||
rc = sqlite3BtreeLast(pCrsr, &res);
|
rc = sqlite3BtreeLast(pCrsr, &res);
|
||||||
@@ -3499,6 +3513,7 @@ case OP_Rewind: {
|
|||||||
|
|
||||||
assert( i>=0 && i<p->nCursor );
|
assert( i>=0 && i<p->nCursor );
|
||||||
pC = p->apCsr[i];
|
pC = p->apCsr[i];
|
||||||
|
assert( pC!=0 );
|
||||||
if( (pCrsr = pC->pCursor)!=0 ){
|
if( (pCrsr = pC->pCursor)!=0 ){
|
||||||
rc = sqlite3BtreeFirst(pCrsr, &res);
|
rc = sqlite3BtreeFirst(pCrsr, &res);
|
||||||
pC->atFirst = res==0;
|
pC->atFirst = res==0;
|
||||||
@@ -3538,6 +3553,7 @@ case OP_Next: {
|
|||||||
CHECK_FOR_INTERRUPT;
|
CHECK_FOR_INTERRUPT;
|
||||||
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
|
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
|
||||||
pC = p->apCsr[pOp->p1];
|
pC = p->apCsr[pOp->p1];
|
||||||
|
assert( pC!=0 );
|
||||||
if( (pCrsr = pC->pCursor)!=0 ){
|
if( (pCrsr = pC->pCursor)!=0 ){
|
||||||
int res;
|
int res;
|
||||||
if( pC->nullRow ){
|
if( pC->nullRow ){
|
||||||
@@ -3577,6 +3593,7 @@ case OP_IdxPut: {
|
|||||||
BtCursor *pCrsr;
|
BtCursor *pCrsr;
|
||||||
assert( pTos>=p->aStack );
|
assert( pTos>=p->aStack );
|
||||||
assert( i>=0 && i<p->nCursor );
|
assert( i>=0 && i<p->nCursor );
|
||||||
|
assert( p->apCsr[i]!=0 );
|
||||||
assert( pTos->flags & MEM_Blob );
|
assert( pTos->flags & MEM_Blob );
|
||||||
if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
|
if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
|
||||||
int nKey = pTos->n;
|
int nKey = pTos->n;
|
||||||
@@ -3629,6 +3646,7 @@ case OP_IdxDelete: {
|
|||||||
assert( pTos>=p->aStack );
|
assert( pTos>=p->aStack );
|
||||||
assert( pTos->flags & MEM_Blob );
|
assert( pTos->flags & MEM_Blob );
|
||||||
assert( i>=0 && i<p->nCursor );
|
assert( i>=0 && i<p->nCursor );
|
||||||
|
assert( p->apCsr[i]!=0 );
|
||||||
if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
|
if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
|
||||||
int rx, res;
|
int rx, res;
|
||||||
rx = sqlite3BtreeMoveto(pCrsr, pTos->z, pTos->n, &res);
|
rx = sqlite3BtreeMoveto(pCrsr, pTos->z, pTos->n, &res);
|
||||||
@@ -3657,6 +3675,7 @@ case OP_IdxRecno: {
|
|||||||
Cursor *pC;
|
Cursor *pC;
|
||||||
|
|
||||||
assert( i>=0 && i<p->nCursor );
|
assert( i>=0 && i<p->nCursor );
|
||||||
|
assert( p->apCsr[i]!=0 );
|
||||||
pTos++;
|
pTos++;
|
||||||
if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
|
if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
|
||||||
i64 rowid;
|
i64 rowid;
|
||||||
@@ -3763,6 +3782,7 @@ case OP_IdxGE: {
|
|||||||
Cursor *pC;
|
Cursor *pC;
|
||||||
|
|
||||||
assert( i>=0 && i<p->nCursor );
|
assert( i>=0 && i<p->nCursor );
|
||||||
|
assert( p->apCsr[i]!=0 );
|
||||||
assert( pTos>=p->aStack );
|
assert( pTos>=p->aStack );
|
||||||
if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
|
if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
|
||||||
int res, rc;
|
int res, rc;
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ struct Cursor {
|
|||||||
BtCursor *pCursor; /* The cursor structure of the backend */
|
BtCursor *pCursor; /* The cursor structure of the backend */
|
||||||
i64 lastRecno; /* Last recno from a Next or NextIdx operation */
|
i64 lastRecno; /* Last recno from a Next or NextIdx operation */
|
||||||
i64 nextRowid; /* Next rowid returned by OP_NewRowid */
|
i64 nextRowid; /* Next rowid returned by OP_NewRowid */
|
||||||
|
Bool zeroed; /* True if zeroed out and ready for reuse */
|
||||||
Bool recnoIsValid; /* True if lastRecno is valid */
|
Bool recnoIsValid; /* True if lastRecno is valid */
|
||||||
Bool keyAsData; /* The OP_Column command works on key instead of data */
|
Bool keyAsData; /* The OP_Column command works on key instead of data */
|
||||||
Bool atFirst; /* True if pointing to first entry */
|
Bool atFirst; /* True if pointing to first entry */
|
||||||
@@ -352,7 +353,7 @@ struct Vdbe {
|
|||||||
/*
|
/*
|
||||||
** Function prototypes
|
** Function prototypes
|
||||||
*/
|
*/
|
||||||
void sqlite3VdbeCleanupCursor(Cursor*);
|
void sqlite3VdbeFreeCursor(Cursor*);
|
||||||
void sqlite3VdbeSorterReset(Vdbe*);
|
void sqlite3VdbeSorterReset(Vdbe*);
|
||||||
int sqlite3VdbeAggReset(sqlite *, Agg *, KeyInfo *);
|
int sqlite3VdbeAggReset(sqlite *, Agg *, KeyInfo *);
|
||||||
void sqlite3VdbeKeylistFree(Keylist*);
|
void sqlite3VdbeKeylistFree(Keylist*);
|
||||||
|
|||||||
@@ -826,7 +826,10 @@ void sqlite3VdbeKeylistFree(Keylist *p){
|
|||||||
** Close a cursor and release all the resources that cursor happens
|
** Close a cursor and release all the resources that cursor happens
|
||||||
** to hold.
|
** to hold.
|
||||||
*/
|
*/
|
||||||
void sqlite3VdbeCleanupCursor(Cursor *pCx){
|
void sqlite3VdbeFreeCursor(Cursor *pCx){
|
||||||
|
if( pCx==0 ){
|
||||||
|
return;
|
||||||
|
}
|
||||||
if( pCx->pCursor ){
|
if( pCx->pCursor ){
|
||||||
sqlite3BtreeCloseCursor(pCx->pCursor);
|
sqlite3BtreeCloseCursor(pCx->pCursor);
|
||||||
}
|
}
|
||||||
@@ -835,7 +838,7 @@ void sqlite3VdbeCleanupCursor(Cursor *pCx){
|
|||||||
}
|
}
|
||||||
sqliteFree(pCx->pData);
|
sqliteFree(pCx->pData);
|
||||||
sqliteFree(pCx->aType);
|
sqliteFree(pCx->aType);
|
||||||
memset(pCx, 0, sizeof(*pCx));
|
sqliteFree(pCx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -844,9 +847,7 @@ void sqlite3VdbeCleanupCursor(Cursor *pCx){
|
|||||||
static void closeAllCursors(Vdbe *p){
|
static void closeAllCursors(Vdbe *p){
|
||||||
int i;
|
int i;
|
||||||
for(i=0; i<p->nCursor; i++){
|
for(i=0; i<p->nCursor; i++){
|
||||||
Cursor *pC = p->apCsr[i];
|
sqlite3VdbeFreeCursor(p->apCsr[i]);
|
||||||
sqlite3VdbeCleanupCursor(pC);
|
|
||||||
sqliteFree(pC);
|
|
||||||
}
|
}
|
||||||
sqliteFree(p->apCsr);
|
sqliteFree(p->apCsr);
|
||||||
p->apCsr = 0;
|
p->apCsr = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user