Small performance optimization in the codeEqualityTerm() routine of the

code generator.

FossilOrigin-Name: 8080c6eafd1280ea870a6ab1ba715ac5af67387e69771be6cbd46dda77c3eaa8
This commit is contained in:
drh 2024-06-05 20:41:36 +00:00
parent 6d98c55b56
commit 0de7da1998
3 changed files with 151 additions and 124 deletions

View File

@ -1,5 +1,5 @@
C Fix\san\sfts5\sproblem\swith\ssecure-delete\smode\scausing\sintegrity-check\sto\serroneously\sreport\sa\scorrupt\sindex. C Small\sperformance\soptimization\sin\sthe\scodeEqualityTerm()\sroutine\sof\sthe\ncode\sgenerator.
D 2024-06-05T14:47:54.677 D 2024-06-05T20:41:36.552
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@ -842,7 +842,7 @@ F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452
F src/walker.c 7c7ea0115345851c3da4e04e2e239a29983b61fb5b038b94eede6aba462640e2 F src/walker.c 7c7ea0115345851c3da4e04e2e239a29983b61fb5b038b94eede6aba462640e2
F src/where.c 343e74d65856665f2aac59a9fcefecfc988e9af4aafa0bd1b8332a89c6c725b4 F src/where.c 343e74d65856665f2aac59a9fcefecfc988e9af4aafa0bd1b8332a89c6c725b4
F src/whereInt.h 002adc3aa2cc10733b9b27958fdbe893987cd989fab25a9853941c1f9b9b0a65 F src/whereInt.h 002adc3aa2cc10733b9b27958fdbe893987cd989fab25a9853941c1f9b9b0a65
F src/wherecode.c 5ad509221ebb4d3b35a8a6ef361f2c5b54129b8c273aa434dd3053d2e25d1794 F src/wherecode.c c9cac0b0b8e809c5e7e79d7796918907fb685ad99be2aaa9737f9787aa47349c
F src/whereexpr.c 67d15caf88a1a9528283d68ff578e024cf9fe810b517bb0343e5aaf695ad97dd F src/whereexpr.c 67d15caf88a1a9528283d68ff578e024cf9fe810b517bb0343e5aaf695ad97dd
F src/window.c 5d95122dd330bfaebd732358c8ef067c5a9394a53ac249470d611d0ce2c52be2 F src/window.c 5d95122dd330bfaebd732358c8ef067c5a9394a53ac249470d611d0ce2c52be2
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
@ -2194,8 +2194,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P a096eb7554952f8137c6e9330c328164719fb27e958787fbd503bcd1364e6ae4 P 80bef4d60ba9e3679ea66655ca36fcfaa888775a3d1598d50e9649ad84a95b63
R 0a424bef53f9d9c6999e5b99ba3f491f R 2c603113ce745efce0c45179f5a33586
U dan U drh
Z bc999b30c47bb6a6c63f18a66f996a4c Z 49fdb8ccd67e18818e3ecc829cf527f5
# Remove this line to create a well-formed Fossil manifest. # Remove this line to create a well-formed Fossil manifest.

View File

@ -1 +1 @@
80bef4d60ba9e3679ea66655ca36fcfaa888775a3d1598d50e9649ad84a95b63 8080c6eafd1280ea870a6ab1ba715ac5af67387e69771be6cbd46dda77c3eaa8

View File

@ -604,22 +604,19 @@ static Expr *removeUnindexableInClauseTerms(
} }
#ifndef SQLITE_OMIT_SUBQUERY
/* /*
** Generate code for a single equality term of the WHERE clause. An equality ** Generate code for a single X IN (....) term of the WHERE clause.
** term can be either X=expr or X IN (...). pTerm is the term to be
** coded.
** **
** The current value for the constraint is left in a register, the index ** This is a special-case of codeEqualityTerm() that works for IN operators
** of which is returned. An attempt is made store the result in iTarget but ** only. It is broken out into a subroutine because this case is
** this is only guaranteed for TK_ISNULL and TK_IN constraints. If the ** uncommon and by splitting it off into a subroutine, the common case
** constraint is a TK_EQ or TK_IS, then the current value might be left in ** runs faster.
** some other register and it is the caller's responsibility to compensate.
** **
** For a constraint of the form X=expr, the expression is evaluated in ** The current value for the constraint is left in register iTarget.
** straight-line code. For constraints of the form X IN (...) ** This routine sets up a loop that will iterate over all values of X.
** this routine sets up a loop that will iterate over all values of X.
*/ */
static int codeEqualityTerm( static SQLITE_NOINLINE void codeINTerm(
Parse *pParse, /* The parsing context */ Parse *pParse, /* The parsing context */
WhereTerm *pTerm, /* The term of the WHERE clause to be coded */ WhereTerm *pTerm, /* The term of the WHERE clause to be coded */
WhereLevel *pLevel, /* The level of the FROM clause we are working on */ WhereLevel *pLevel, /* The level of the FROM clause we are working on */
@ -628,22 +625,11 @@ static int codeEqualityTerm(
int iTarget /* Attempt to leave results in this register */ int iTarget /* Attempt to leave results in this register */
){ ){
Expr *pX = pTerm->pExpr; Expr *pX = pTerm->pExpr;
Vdbe *v = pParse->pVdbe;
int iReg; /* Register holding results */
assert( pLevel->pWLoop->aLTerm[iEq]==pTerm );
assert( iTarget>0 );
if( pX->op==TK_EQ || pX->op==TK_IS ){
iReg = sqlite3ExprCodeTarget(pParse, pX->pRight, iTarget);
}else if( pX->op==TK_ISNULL ){
iReg = iTarget;
sqlite3VdbeAddOp2(v, OP_Null, 0, iReg);
#ifndef SQLITE_OMIT_SUBQUERY
}else{
int eType = IN_INDEX_NOOP; int eType = IN_INDEX_NOOP;
int iTab; int iTab;
struct InLoop *pIn; struct InLoop *pIn;
WhereLoop *pLoop = pLevel->pWLoop; WhereLoop *pLoop = pLevel->pWLoop;
Vdbe *v = pParse->pVdbe;
int i; int i;
int nEq = 0; int nEq = 0;
int *aiMap = 0; int *aiMap = 0;
@ -657,12 +643,11 @@ static int codeEqualityTerm(
bRev = !bRev; bRev = !bRev;
} }
assert( pX->op==TK_IN ); assert( pX->op==TK_IN );
iReg = iTarget;
for(i=0; i<iEq; i++){ for(i=0; i<iEq; i++){
if( pLoop->aLTerm[i] && pLoop->aLTerm[i]->pExpr==pX ){ if( pLoop->aLTerm[i] && pLoop->aLTerm[i]->pExpr==pX ){
disableTerm(pLevel, pTerm); disableTerm(pLevel, pTerm);
return iTarget; return;
} }
} }
for(i=iEq;i<pLoop->nLTerm; i++){ for(i=iEq;i<pLoop->nLTerm; i++){
@ -721,7 +706,7 @@ static int codeEqualityTerm(
pIn += i; pIn += i;
for(i=iEq;i<pLoop->nLTerm; i++){ for(i=iEq;i<pLoop->nLTerm; i++){
if( pLoop->aLTerm[i]->pExpr==pX ){ if( pLoop->aLTerm[i]->pExpr==pX ){
int iOut = iReg + i - iEq; int iOut = iTarget + i - iEq;
if( eType==IN_INDEX_ROWID ){ if( eType==IN_INDEX_ROWID ){
pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iOut); pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iOut);
}else{ }else{
@ -733,7 +718,7 @@ static int codeEqualityTerm(
pIn->iCur = iTab; pIn->iCur = iTab;
pIn->eEndLoopOp = bRev ? OP_Prev : OP_Next; pIn->eEndLoopOp = bRev ? OP_Prev : OP_Next;
if( iEq>0 ){ if( iEq>0 ){
pIn->iBase = iReg - i; pIn->iBase = iTarget - i;
pIn->nPrefix = i; pIn->nPrefix = i;
}else{ }else{
pIn->nPrefix = 0; pIn->nPrefix = 0;
@ -756,6 +741,48 @@ static int codeEqualityTerm(
pLevel->u.in.nIn = 0; pLevel->u.in.nIn = 0;
} }
sqlite3DbFree(pParse->db, aiMap); sqlite3DbFree(pParse->db, aiMap);
}
#endif
/*
** Generate code for a single equality term of the WHERE clause. An equality
** term can be either X=expr or X IN (...). pTerm is the term to be
** coded.
**
** The current value for the constraint is left in a register, the index
** of which is returned. An attempt is made store the result in iTarget but
** this is only guaranteed for TK_ISNULL and TK_IN constraints. If the
** constraint is a TK_EQ or TK_IS, then the current value might be left in
** some other register and it is the caller's responsibility to compensate.
**
** For a constraint of the form X=expr, the expression is evaluated in
** straight-line code. For constraints of the form X IN (...)
** this routine sets up a loop that will iterate over all values of X.
*/
static int codeEqualityTerm(
Parse *pParse, /* The parsing context */
WhereTerm *pTerm, /* The term of the WHERE clause to be coded */
WhereLevel *pLevel, /* The level of the FROM clause we are working on */
int iEq, /* Index of the equality term within this level */
int bRev, /* True for reverse-order IN operations */
int iTarget /* Attempt to leave results in this register */
){
Expr *pX = pTerm->pExpr;
int iReg; /* Register holding results */
assert( pLevel->pWLoop->aLTerm[iEq]==pTerm );
assert( iTarget>0 );
if( pX->op==TK_EQ || pX->op==TK_IS ){
iReg = sqlite3ExprCodeTarget(pParse, pX->pRight, iTarget);
}else if( pX->op==TK_ISNULL ){
iReg = iTarget;
sqlite3VdbeAddOp2(pParse->pVdbe, OP_Null, 0, iReg);
#ifndef SQLITE_OMIT_SUBQUERY
}else{
assert( pX->op==TK_IN );
iReg = iTarget;
codeINTerm(pParse, pTerm, pLevel, iEq, bRev, iTarget);
#endif #endif
} }