1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-12 13:01:09 +03:00

Improvements to IN operator code generator comments. Avoid unnecessary

Copy operations on the LHS of the IN operator.

FossilOrigin-Name: b6344298783a1207cba3f635939ddc9ba922ab67
This commit is contained in:
drh
2016-08-25 15:46:25 +00:00
parent ee0f22fd3b
commit ecb87ac88d
3 changed files with 42 additions and 26 deletions

View File

@@ -1,5 +1,5 @@
C Corrections\sto\sthe\sIN-operator\snotes. C Improvements\sto\sIN\soperator\scode\sgenerator\scomments.\s\sAvoid\sunnecessary\nCopy\soperations\son\sthe\sLHS\sof\sthe\sIN\soperator.
D 2016-08-25T14:23:59.673 D 2016-08-25T15:46:25.026
F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a
@@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7
F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b
F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d
F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05
F src/expr.c 866bcb6e85806beb0f96e651e9d17811e1ecbda5 F src/expr.c 1c003fcb9c5a6f8c54f6392378225d578be2a086
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8
F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771
@@ -1521,7 +1521,7 @@ 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 d256b2caeb9e3eb5dd88bb569ec71f91e9991c81 P 25033ee94538289ba7e0147da30a18300047123f
R e83420368d9fa99d84d7c5701ecba45b R e1cedb5c8edd4d27c5fcda8527491fbe
U drh U drh
Z a8948efc181e8ffaf5af6c9f4ff55b46 Z c3029179ef3a13ce81541f0730bc01a8

View File

@@ -1 +1 @@
25033ee94538289ba7e0147da30a18300047123f b6344298783a1207cba3f635939ddc9ba922ab67

View File

@@ -2637,16 +2637,19 @@ int sqlite3ExprCheckIN(Parse *pParse, Expr *pIn){
** x IN (SELECT ...) ** x IN (SELECT ...)
** x IN (value, value, ...) ** x IN (value, value, ...)
** **
** The left-hand side (LHS) is a scalar expression. The right-hand side (RHS) ** The left-hand side (LHS) is a scalar or vector expression. The
** is an array of zero or more values. The expression is true if the LHS is ** right-hand side (RHS) is an array of zero or more values. The IN operator
** contained within the RHS. The value of the expression is unknown (NULL) ** is true if the LHS is contained within the RHS. The result is false
** if the LHS is NULL or if the LHS is not contained within the RHS and the ** if the LHS is definitely not in the RHS. The result is NULL if the presence
** RHS contains one or more NULL values. ** of the LHS in the RHS cannot be determined due to NULLs.
** **
** This routine generates code that jumps to destIfFalse if the LHS is not ** This routine generates code that jumps to destIfFalse if the LHS is not
** contained within the RHS. If due to NULLs we cannot determine if the LHS ** contained within the RHS. If due to NULLs we cannot determine if the LHS
** is contained in the RHS then jump to destIfNull. If the LHS is contained ** is contained in the RHS then jump to destIfNull. If the LHS is contained
** within the RHS then fall through. ** within the RHS then fall through.
**
** See the separate in-operator.md documentation file in the canonical
** SQLite source tree for additional information.
*/ */
static void sqlite3ExprCodeIN( static void sqlite3ExprCodeIN(
Parse *pParse, /* Parsing and code generating context */ Parse *pParse, /* Parsing and code generating context */
@@ -2660,22 +2663,18 @@ static void sqlite3ExprCodeIN(
Vdbe *v; /* Statement under construction */ Vdbe *v; /* Statement under construction */
int *aiMap = 0; /* Map from vector field to index column */ int *aiMap = 0; /* Map from vector field to index column */
char *zAff = 0; /* Affinity string for comparisons */ char *zAff = 0; /* Affinity string for comparisons */
int nVector; /* Size of vectors for this IN(...) op */ int nVector; /* Size of vectors for this IN operator */
int iDummy; /* Dummy parameter to exprCodeVector() */ int iDummy; /* Dummy parameter to exprCodeVector() */
Expr *pLeft = pExpr->pLeft; Expr *pLeft = pExpr->pLeft; /* The LHS of the IN operator */
int i; int i; /* loop counter */
if( sqlite3ExprCheckIN(pParse, pExpr) ) return; if( sqlite3ExprCheckIN(pParse, pExpr) ) return;
zAff = exprINAffinity(pParse, pExpr); zAff = exprINAffinity(pParse, pExpr);
if( zAff==0 ) return;
nVector = sqlite3ExprVectorSize(pExpr->pLeft); nVector = sqlite3ExprVectorSize(pExpr->pLeft);
aiMap = (int*)sqlite3DbMallocZero( aiMap = (int*)sqlite3DbMallocZero(
pParse->db, nVector*(sizeof(int) + sizeof(char)) + 1 pParse->db, nVector*(sizeof(int) + sizeof(char)) + 1
); );
if( aiMap==0 ){ if( pParse->db->mallocFailed ) goto end_code_IN_op;
sqlite3DbFree(pParse->db, zAff);
return;
}
/* Attempt to compute the RHS. After this step, if anything other than /* Attempt to compute the RHS. After this step, if anything other than
** IN_INDEX_NOOP is returned, the table opened ith cursor pExpr->iTable ** IN_INDEX_NOOP is returned, the table opened ith cursor pExpr->iTable
@@ -2691,17 +2690,33 @@ static void sqlite3ExprCodeIN(
assert( pParse->nErr || nVector==1 || eType==IN_INDEX_EPH assert( pParse->nErr || nVector==1 || eType==IN_INDEX_EPH
|| eType==IN_INDEX_INDEX_ASC || eType==IN_INDEX_INDEX_DESC || eType==IN_INDEX_INDEX_ASC || eType==IN_INDEX_INDEX_DESC
); );
#ifdef SQLITE_DEBUG
/* Confirm that aiMap[] contains nVector integer values between 0 and
** nVector-1. */
for(i=0; i<nVector; i++){
int j, cnt;
for(cnt=j=0; j<nVector; j++) if( aiMap[j]==i ) cnt++;
assert( cnt==1 );
}
#endif
/* Code the LHS, the <expr> from "<expr> IN (...)". If the LHS is a /* Code the LHS, the <expr> from "<expr> IN (...)". If the LHS is a
** vector, then it is stored in an array of nVector registers starting ** vector, then it is stored in an array of nVector registers starting
** at r1. ** at r1.
*/ */
r1 = sqlite3GetTempRange(pParse, nVector);
sqlite3ExprCachePush(pParse); sqlite3ExprCachePush(pParse);
r2 = exprCodeVector(pParse, pLeft, &iDummy); r2 = exprCodeVector(pParse, pLeft, &iDummy);
for(i=0; i<nVector && aiMap[i]==i; i++){}
if( i==nVector ){
/* LHS fields are already in the correct order */
r1 = r2;
}else{
/* Need to reorder the LHS fields according to aiMap */
r1 = sqlite3GetTempRange(pParse, nVector);
for(i=0; i<nVector; i++){ for(i=0; i<nVector; i++){
sqlite3VdbeAddOp3(v, OP_Copy, r2+i, r1+aiMap[i], 0); sqlite3VdbeAddOp3(v, OP_Copy, r2+i, r1+aiMap[i], 0);
} }
}
/* If sqlite3FindInIndex() did not find or create an index that is /* If sqlite3FindInIndex() did not find or create an index that is
** suitable for evaluating the IN operator, then evaluate using a ** suitable for evaluating the IN operator, then evaluate using a
@@ -2861,11 +2876,12 @@ static void sqlite3ExprCodeIN(
} }
} }
} }
sqlite3ReleaseTempReg(pParse, r1); if( r2!=r1 ) sqlite3ReleaseTempReg(pParse, r1);
sqlite3ExprCachePop(pParse); sqlite3ExprCachePop(pParse);
VdbeComment((v, "end IN expr"));
end_code_IN_op:
sqlite3DbFree(pParse->db, aiMap); sqlite3DbFree(pParse->db, aiMap);
sqlite3DbFree(pParse->db, zAff); sqlite3DbFree(pParse->db, zAff);
VdbeComment((v, "end IN expr"));
} }
#endif /* SQLITE_OMIT_SUBQUERY */ #endif /* SQLITE_OMIT_SUBQUERY */