aboutsummaryrefslogtreecommitdiff
path: root/src/expr.c
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2009-11-12 19:59:44 +0000
committerdrh <drh@noemail.net>2009-11-12 19:59:44 +0000
commit8cff69df110a7b53281b94b33306d7c7e92c438c (patch)
tree2a31b7e1b0db9bed2bfde57b3e03d0c16017f6c7 /src/expr.c
parente3365e6c3762a6bb09f58f371a06797c3cd5e391 (diff)
downloadsqlite-8cff69df110a7b53281b94b33306d7c7e92c438c.tar.gz
sqlite-8cff69df110a7b53281b94b33306d7c7e92c438c.zip
Enhance the OP_Found and OP_NotFound opcodes so that they can accept an
array of registers as an unpacked record in addition to a record built using OP_MakeRecord. Use this to avoid OP_MakeRecord calls during IN expression processing. FossilOrigin-Name: b9eab885cd2ca1a1633329e7036c125e8dba62c5
Diffstat (limited to 'src/expr.c')
-rw-r--r--src/expr.c18
1 files changed, 5 insertions, 13 deletions
diff --git a/src/expr.c b/src/expr.c
index 8ff43381b..a50348f2d 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -1546,7 +1546,7 @@ int sqlite3CodeSubselect(
affinity = sqlite3ExprAffinity(pLeft);
/* Whether this is an 'x IN(SELECT...)' or an 'x IN(<exprlist>)'
- ** expression it is handled the same way. A virtual table is
+ ** expression it is handled the same way. An ephemeral table is
** filled with single-field index keys representing the results
** from the SELECT or the <exprlist>.
**
@@ -1754,12 +1754,7 @@ static void sqlite3ExprCodeIN(
}else{
/* In this case, the RHS is an index b-tree.
*/
- int r2; /* Register holding LHS value as a Record */
-
- /* Create a record that can be used for membership testing.
- */
- r2 = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp4(v, OP_MakeRecord, r1, 1, r2, &affinity, 1);
+ sqlite3VdbeAddOp4(v, OP_Affinity, r1, 1, 0, &affinity, 1);
/* If the set membership test fails, then the result of the
** "x IN (...)" expression must be either 0 or NULL. If the set
@@ -1775,21 +1770,20 @@ static void sqlite3ExprCodeIN(
** Also run this branch if NULL is equivalent to FALSE
** for this particular IN operator.
*/
- sqlite3VdbeAddOp3(v, OP_NotFound, pExpr->iTable, destIfFalse, r2);
+ sqlite3VdbeAddOp4Int(v, OP_NotFound, pExpr->iTable, destIfFalse, r1, 1);
}else{
/* In this branch, the RHS of the IN might contain a NULL and
** the presence of a NULL on the RHS makes a difference in the
** outcome.
*/
- static const char nullRecord[] = { 0x02, 0x00 };
int j1, j2, j3;
/* First check to see if the LHS is contained in the RHS. If so,
** then the presence of NULLs in the RHS does not matter, so jump
** over all of the code that follows.
*/
- j1 = sqlite3VdbeAddOp3(v, OP_Found, pExpr->iTable, 0, r2);
+ j1 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, r1, 1);
/* Here we begin generating code that runs if the LHS is not
** contained within the RHS. Generate additional code that
@@ -1798,8 +1792,7 @@ static void sqlite3ExprCodeIN(
** jump to destIfFalse.
*/
j2 = sqlite3VdbeAddOp1(v, OP_NotNull, rRhsHasNull);
- sqlite3VdbeAddOp4(v, OP_Blob, 2, r2, 0, nullRecord, P4_STATIC);
- j3 = sqlite3VdbeAddOp3(v, OP_Found, pExpr->iTable, 0, r2);
+ j3 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, rRhsHasNull, 1);
sqlite3VdbeAddOp2(v, OP_Integer, -1, rRhsHasNull);
sqlite3VdbeJumpHere(v, j3);
sqlite3VdbeAddOp2(v, OP_AddImm, rRhsHasNull, 1);
@@ -1816,7 +1809,6 @@ static void sqlite3ExprCodeIN(
*/
sqlite3VdbeJumpHere(v, j1);
}
- sqlite3ReleaseTempReg(pParse, r2);
}
sqlite3ReleaseTempReg(pParse, r1);
sqlite3ExprCachePop(pParse, 1);