1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-03 16:53:36 +03:00

Change the OP_Rowid opcode so that a deferred OP_Seek is pending, it simply

pulls the rowid from the deferred seek target and does not actually move
the cursor or do a seek.  Other where.c cleanups. (CVS 6536)

FossilOrigin-Name: 1c508a99822caa383e7e24b5d09a9bddd2ee3a00
This commit is contained in:
drh
2009-04-22 15:32:59 +00:00
parent 1b26c7ccfa
commit 6149526c25
7 changed files with 65 additions and 70 deletions

View File

@@ -1,5 +1,5 @@
C Remove\sthe\srowhash\sobject\sfrom\sthe\scode.\s\sRowset\snow\sfills\sits\srole.\s(CVS\s6535) C Change\sthe\sOP_Rowid\sopcode\sso\sthat\sa\sdeferred\sOP_Seek\sis\spending,\sit\ssimply\npulls\sthe\srowid\sfrom\sthe\sdeferred\sseek\starget\sand\sdoes\snot\sactually\smove\nthe\scursor\sor\sdo\sa\sseek.\s\sOther\swhere.c\scleanups.\s(CVS\s6536)
D 2009-04-22T02:15:48 D 2009-04-22T15:32:59
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in 583e87706abc3026960ed759aff6371faf84c211 F Makefile.in 583e87706abc3026960ed759aff6371faf84c211
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -154,12 +154,12 @@ F src/prepare.c 72d74e6d3b9c8eb0663b33ec6438aa718096ac79
F src/printf.c ea2d76000cc5f4579d7e9cb2f5460433eec0d384 F src/printf.c ea2d76000cc5f4579d7e9cb2f5460433eec0d384
F src/random.c 676b9d7ac820fe81e6fb2394ac8c10cff7f38628 F src/random.c 676b9d7ac820fe81e6fb2394ac8c10cff7f38628
F src/resolve.c 094e44450371fb27869eb8bf679aacbe51fdc56d F src/resolve.c 094e44450371fb27869eb8bf679aacbe51fdc56d
F src/rowset.c ee0f774f20bf3fd27470603d2d56d1767bbe1013 F src/rowset.c 14d12b5e81b5907b87d511f6f4219805f96a4b55
F src/select.c 35225756c247484f473678e5bd191d70a6e4dba0 F src/select.c 35225756c247484f473678e5bd191d70a6e4dba0
F src/shell.c 0a11f831603f17fea20ca97133c0f64e716af4a7 F src/shell.c 0a11f831603f17fea20ca97133c0f64e716af4a7
F src/sqlite.h.in 8e0e256079bac2319380bdfebf403fcbe630510f F src/sqlite.h.in 8e0e256079bac2319380bdfebf403fcbe630510f
F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17 F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17
F src/sqliteInt.h dc64bc8198a2ad3532a996fcecda71ff89a578f0 F src/sqliteInt.h b663bb04bc2d71d8f156f559ff267045de64787a
F src/sqliteLimit.h ffe93f5a0c4e7bd13e70cd7bf84cfb5c3465f45d F src/sqliteLimit.h ffe93f5a0c4e7bd13e70cd7bf84cfb5c3465f45d
F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76 F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76
F src/table.c cc86ad3d6ad54df7c63a3e807b5783c90411a08d F src/table.c cc86ad3d6ad54df7c63a3e807b5783c90411a08d
@@ -200,16 +200,16 @@ F src/update.c 8ededddcde6f7b6da981dd0429a5d34518a475b7
F src/utf.c 9541d28f40441812c0b40f00334372a0542c00ff F src/utf.c 9541d28f40441812c0b40f00334372a0542c00ff
F src/util.c 828c552a22a1d5b650b8a5ea0009546715c45d93 F src/util.c 828c552a22a1d5b650b8a5ea0009546715c45d93
F src/vacuum.c 07121a727beeee88f27d704a00313ad6a7c9bef0 F src/vacuum.c 07121a727beeee88f27d704a00313ad6a7c9bef0
F src/vdbe.c 13f976672cd9d7fce04f9847d74da8c3b869a013 F src/vdbe.c ff8870fd2a4a5a3f7f8d24e5d0f4e73c22402c4f
F src/vdbe.h 35a648bc3279a120da24f34d9a25213ec15daf8a F src/vdbe.h 35a648bc3279a120da24f34d9a25213ec15daf8a
F src/vdbeInt.h 8726f7b4e3b55c8acf6d304a5b5f727ac1b6c5ab F src/vdbeInt.h 8726f7b4e3b55c8acf6d304a5b5f727ac1b6c5ab
F src/vdbeapi.c 015c9d0fb7047657a13a7bb6aa886f75e43db02d F src/vdbeapi.c 015c9d0fb7047657a13a7bb6aa886f75e43db02d
F src/vdbeaux.c fdad66c73adb1c6ca6a0cd7a0f9517e5df758122 F src/vdbeaux.c 34524d499fc6081e97771dcfdf6c2523d5877ef5
F src/vdbeblob.c e67757450ae8581a8b354d9d7e467e41502dfe38 F src/vdbeblob.c e67757450ae8581a8b354d9d7e467e41502dfe38
F src/vdbemem.c 111d8193859d16aefd5d3cb57472808584ea5503 F src/vdbemem.c 111d8193859d16aefd5d3cb57472808584ea5503
F src/vtab.c 6118d71c5137e20a7ac51fb5d9beb0361fbedb89 F src/vtab.c 6118d71c5137e20a7ac51fb5d9beb0361fbedb89
F src/walker.c 7cdf63223c953d4343c6833e940f110281a378ee F src/walker.c 7cdf63223c953d4343c6833e940f110281a378ee
F src/where.c 48f711d293486b43bf87ab3d1eeeebae50cb6839 F src/where.c 576a21f6e0bb6651f3354b5cee7ecc67b935b2a5
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/alias.test 597662c5d777a122f9a3df0047ea5c5bd383a911 F test/alias.test 597662c5d777a122f9a3df0047ea5c5bd383a911
F test/all.test 14165b3e32715b700b5f0cbf8f6e3833dda0be45 F test/all.test 14165b3e32715b700b5f0cbf8f6e3833dda0be45
@@ -720,7 +720,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
P b101cf70b75c9772aaf50e0eadd0cfa37c84d193 P e963bed0fe3ce5fa32f04b930e5ed0956dc2aa47
R 4b293c104cb64e8cb94e481dce760f86 R 1585578003f3d07014cf9b3e3edcfb74
U drh U drh
Z 77e80e656a1a39cdd643ee53416f4c84 Z e0df7c75ae1c0bc5ef9879b2922e6098

View File

@@ -1 +1 @@
e963bed0fe3ce5fa32f04b930e5ed0956dc2aa47 1c508a99822caa383e7e24b5d09a9bddd2ee3a00

View File

@@ -60,7 +60,7 @@
** There is an added cost of O(N) when switching between TEST and ** There is an added cost of O(N) when switching between TEST and
** SMALLEST primitives. ** SMALLEST primitives.
** **
** $Id: rowset.c,v 1.5 2009/04/22 00:47:01 drh Exp $ ** $Id: rowset.c,v 1.6 2009/04/22 15:32:59 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
@@ -277,9 +277,7 @@ static void rowSetTreeToList(
struct RowSetEntry **ppFirst, /* Write head of the output list here */ struct RowSetEntry **ppFirst, /* Write head of the output list here */
struct RowSetEntry **ppLast /* Write tail of the output list here */ struct RowSetEntry **ppLast /* Write tail of the output list here */
){ ){
if( pIn==0 ){ assert( pIn!=0 );
*ppFirst = *ppLast = 0;
}
if( pIn->pLeft ){ if( pIn->pLeft ){
struct RowSetEntry *p; struct RowSetEntry *p;
rowSetTreeToList(pIn->pLeft, ppFirst, &p); rowSetTreeToList(pIn->pLeft, ppFirst, &p);
@@ -344,9 +342,7 @@ static struct RowSetEntry *rowSetListToTree(struct RowSetEntry *pList){
struct RowSetEntry *p; /* Current tree root */ struct RowSetEntry *p; /* Current tree root */
struct RowSetEntry *pLeft; /* Left subtree */ struct RowSetEntry *pLeft; /* Left subtree */
if( pList==0 ){ assert( pList!=0 );
return 0;
}
p = pList; p = pList;
pList = p->pRight; pList = p->pRight;
p->pLeft = p->pRight = 0; p->pLeft = p->pRight = 0;

View File

@@ -11,7 +11,7 @@
************************************************************************* *************************************************************************
** Internal interface definitions for SQLite. ** Internal interface definitions for SQLite.
** **
** @(#) $Id: sqliteInt.h,v 1.858 2009/04/22 02:15:48 drh Exp $ ** @(#) $Id: sqliteInt.h,v 1.859 2009/04/22 15:32:59 drh Exp $
*/ */
#ifndef _SQLITEINT_H_ #ifndef _SQLITEINT_H_
#define _SQLITEINT_H_ #define _SQLITEINT_H_
@@ -219,6 +219,20 @@
# define TESTONLY(X) # define TESTONLY(X)
#endif #endif
/*
** Sometimes we need a small amount of code such as a variable initialization
** to setup for a later assert() statement. We do not want this code to
** appear when assert() is disabled. The following macro is therefore
** used to contain that setup code. The "VVA" acronym stands for
** "Verification, Validation, and Accreditation". In other words, the
** code within VVA_ONLY() will only run during verification processes.
*/
#ifndef NDEBUG
# define VVA_ONLY(X) X
#else
# define VVA_ONLY(X)
#endif
/* /*
** The ALWAYS and NEVER macros surround boolean expressions which ** The ALWAYS and NEVER macros surround boolean expressions which
** are intended to always be true or false, respectively. Such ** are intended to always be true or false, respectively. Such
@@ -260,20 +274,6 @@
# define unlikely(X) !!(X) # define unlikely(X) !!(X)
#endif #endif
/*
** Sometimes we need a small amount of code such as a variable initialization
** to setup for a later assert() statement. We do not want this code to
** appear when assert() is disabled. The following macro is therefore
** used to contain that setup code. The "VVA" acronym stands for
** "Verification, Validation, and Accreditation". In other words, the
** code within VVA_ONLY() will only run during verification processes.
*/
#ifndef NDEBUG
# define VVA_ONLY(X) X
#else
# define VVA_ONLY(X)
#endif
#include "sqlite3.h" #include "sqlite3.h"
#include "hash.h" #include "hash.h"
#include "parse.h" #include "parse.h"

View File

@@ -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.837 2009/04/22 02:15:48 drh Exp $ ** $Id: vdbe.c,v 1.838 2009/04/22 15:32:59 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include "vdbeInt.h" #include "vdbeInt.h"
@@ -3905,6 +3905,9 @@ case OP_Rowid: { /* out2-prerelease */
assert( i>=0 && i<p->nCursor ); assert( i>=0 && i<p->nCursor );
pC = p->apCsr[i]; pC = p->apCsr[i];
assert( pC!=0 ); assert( pC!=0 );
if( pC->deferredMoveto ){
v = pC->movetoTarget;
}else{
rc = sqlite3VdbeCursorMoveto(pC); rc = sqlite3VdbeCursorMoveto(pC);
if( rc ) goto abort_due_to_error; if( rc ) goto abort_due_to_error;
if( pC->rowidIsValid ){ if( pC->rowidIsValid ){
@@ -3919,6 +3922,7 @@ case OP_Rowid: { /* out2-prerelease */
sqlite3BtreeKeySize(pC->pCursor, &v); sqlite3BtreeKeySize(pC->pCursor, &v);
v = keyToInt(v); v = keyToInt(v);
} }
}
pOut->u.i = v; pOut->u.i = v;
MemSetTypeFlag(pOut, MEM_Int); MemSetTypeFlag(pOut, MEM_Int);
break; break;

View File

@@ -14,7 +14,7 @@
** to version 2.8.7, all this code was combined into the vdbe.c source file. ** to version 2.8.7, all this code was combined into the vdbe.c source file.
** But that file was getting too big so this subroutines were split out. ** But that file was getting too big so this subroutines were split out.
** **
** $Id: vdbeaux.c,v 1.453 2009/04/22 02:15:48 drh Exp $ ** $Id: vdbeaux.c,v 1.454 2009/04/22 15:32:59 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include "vdbeInt.h" #include "vdbeInt.h"
@@ -2002,8 +2002,8 @@ int sqlite3VdbeCursorMoveto(VdbeCursor *p){
rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res); rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res);
if( rc ) return rc; if( rc ) return rc;
p->lastRowid = keyToInt(p->movetoTarget); p->lastRowid = keyToInt(p->movetoTarget);
p->rowidIsValid = res==0 ?1:0; p->rowidIsValid = ALWAYS(res==0) ?1:0;
if( res<0 ){ if( NEVER(res<0) ){
rc = sqlite3BtreeNext(p->pCursor, &res); rc = sqlite3BtreeNext(p->pCursor, &res);
if( rc ) return rc; if( rc ) return rc;
} }

View File

@@ -16,7 +16,7 @@
** so is applicable. Because this module is responsible for selecting ** so is applicable. Because this module is responsible for selecting
** indices, you might also think of this module as the "query optimizer". ** indices, you might also think of this module as the "query optimizer".
** **
** $Id: where.c,v 1.385 2009/04/22 02:15:49 drh Exp $ ** $Id: where.c,v 1.386 2009/04/22 15:32:59 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
@@ -43,10 +43,8 @@ typedef struct WhereCost WhereCost;
/* /*
** The query generator uses an array of instances of this structure to ** The query generator uses an array of instances of this structure to
** help it analyze the subexpressions of the WHERE clause. Each WHERE ** help it analyze the subexpressions of the WHERE clause. Each WHERE
** clause subexpression is separated from the others by AND operators. ** clause subexpression is separated from the others by AND operators,
** (Note: the same data structure is also reused to hold a group of terms ** usually, or sometimes subexpressions separated by OR.
** separated by OR operators. But at the top-level, everything is AND
** separated.)
** **
** All WhereTerms are collected into a single WhereClause structure. ** All WhereTerms are collected into a single WhereClause structure.
** The following identity holds: ** The following identity holds:
@@ -375,7 +373,7 @@ static void whereSplit(WhereClause *pWC, Expr *pExpr, int op){
} }
/* /*
** Initialize an expression mask set ** Initialize an expression mask set (a WhereMaskSet object)
*/ */
#define initMaskSet(P) memset(P, 0, sizeof(*P)) #define initMaskSet(P) memset(P, 0, sizeof(*P))
@@ -2406,24 +2404,21 @@ static Bitmask codeOneLoopStart(
int addrBrk; /* Jump here to break out of the loop */ int addrBrk; /* Jump here to break out of the loop */
int addrCont; /* Jump here to continue with next cycle */ int addrCont; /* Jump here to continue with next cycle */
int regRowSet; /* Write rowids to this RowSet if non-negative */ int regRowSet; /* Write rowids to this RowSet if non-negative */
int codeRowSetEarly; /* True if index fully constrains the search */
/* Sometimes, this function is required to generate code to do /* Sometimes, this function is required to generate code to do
** something with the rowid of each row scanned. Specifically: ** something with the rowid of each row scanned. Specifically,
** ** If pWInfo->regRowSet is non-zero, then the rowid must be inserted
** 1) If pWInfo->regRowSet is non-zero, then the rowid must be inserted
** into the RowSet object stored in register pWInfo->regRowSet. ** into the RowSet object stored in register pWInfo->regRowSet.
** **
** Extracting a rowid value from a VDBE cursor is not always a cheap ** Extracting a rowid value from a VDBE cursor is not always a cheap
** operation, especially if the rowid is being extracted from an index ** operation, especially if the rowid is being extracted from an index
** cursor. If the rowid value is available as a by-product of the code ** cursor. If the rowid value is available as a by-product of the code
** generated to create the top of the scan loop, then it can be reused ** generated to create the top of the scan loop, then it can be reused
** without extracting ** without extracting it from a cursor. The following two variables are
** it from a cursor. The following two variables are used to communicate ** used to communicate the availability of the rowid value to the C-code
** the availability of the rowid value to the C-code at the end of this ** at the end of this function that generates the rowid-handling VDBE code.
** function that generates the rowid-handling VDBE code.
*/ */
int iRowidReg = 0; /* Rowid is stored in this register */ int iRowidReg = 0; /* Rowid is stored in this register, if not zero */
int iReleaseReg = 0; /* Temp register to free before returning */ int iReleaseReg = 0; /* Temp register to free before returning */
pParse = pWInfo->pParse; pParse = pWInfo->pParse;
@@ -2436,7 +2431,6 @@ static Bitmask codeOneLoopStart(
omitTable = (pLevel->plan.wsFlags & WHERE_IDX_ONLY)!=0 omitTable = (pLevel->plan.wsFlags & WHERE_IDX_ONLY)!=0
&& (wctrlFlags & WHERE_FILL_ROWTEST)==0; && (wctrlFlags & WHERE_FILL_ROWTEST)==0;
regRowSet = pWInfo->regRowSet; regRowSet = pWInfo->regRowSet;
codeRowSetEarly = 0;
/* Create labels for the "break" and "continue" instructions /* Create labels for the "break" and "continue" instructions
** for the current loop. Jump to addrBrk to break out of a loop. ** for the current loop. Jump to addrBrk to break out of a loop.
@@ -2877,7 +2871,6 @@ static Bitmask codeOneLoopStart(
sqlite3VdbeAddOp2(v, OP_Null, 0, regRowset); sqlite3VdbeAddOp2(v, OP_Null, 0, regRowset);
iRetInit = sqlite3VdbeAddOp2(v, OP_Integer, 0, regReturn); iRetInit = sqlite3VdbeAddOp2(v, OP_Integer, 0, regReturn);
/* iReleaseReg = iRowidReg = sqlite3GetTempReg(pParse); */
for(ii=0; ii<pOrWc->nTerm; ii++){ for(ii=0; ii<pOrWc->nTerm; ii++){
WhereTerm *pOrTerm = &pOrWc->a[ii]; WhereTerm *pOrTerm = &pOrWc->a[ii];
if( pOrTerm->leftCursor==iCur || pOrTerm->eOperator==WO_AND ){ if( pOrTerm->leftCursor==iCur || pOrTerm->eOperator==WO_AND ){
@@ -2895,6 +2888,7 @@ static Bitmask codeOneLoopStart(
** loop is not executed. ** loop is not executed.
*/ */
int iRowSet = pSubWInfo->iRowidHandler; int iRowSet = pSubWInfo->iRowidHandler;
assert( iRowSet>0 || pWInfo->pParse->db->mallocFailed );
sqlite3VdbeChangeP2(v, iRowSet, sqlite3VdbeCurrentAddr(v) + 1); sqlite3VdbeChangeP2(v, iRowSet, sqlite3VdbeCurrentAddr(v) + 1);
sqlite3VdbeChangeP4(v, iRowSet, (char *)iSet, P4_INT32); sqlite3VdbeChangeP4(v, iRowSet, (char *)iSet, P4_INT32);
sqlite3VdbeAddOp2(v, OP_Gosub, regReturn, iLoopBody); sqlite3VdbeAddOp2(v, OP_Gosub, regReturn, iLoopBody);
@@ -2991,11 +2985,12 @@ static Bitmask codeOneLoopStart(
} }
} }
pWInfo->iRowidHandler = sqlite3VdbeCurrentAddr(v);
if( pWInfo->wctrlFlags&WHERE_FILL_ROWSET ){ if( pWInfo->wctrlFlags&WHERE_FILL_ROWSET ){
sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, iRowidReg); sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, iRowidReg);
VVA_ONLY( pWInfo->iRowidHandler = 0; )
}else{ }else{
assert( pWInfo->wctrlFlags&WHERE_FILL_ROWTEST ); assert( pWInfo->wctrlFlags&WHERE_FILL_ROWTEST );
pWInfo->iRowidHandler =
sqlite3VdbeAddOp3(v, OP_RowSetTest, regRowSet, 0, iRowidReg); sqlite3VdbeAddOp3(v, OP_RowSetTest, regRowSet, 0, iRowidReg);
} }
} }