diff options
author | drh <drh@noemail.net> | 2009-11-12 19:59:44 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2009-11-12 19:59:44 +0000 |
commit | 8cff69df110a7b53281b94b33306d7c7e92c438c (patch) | |
tree | 2a31b7e1b0db9bed2bfde57b3e03d0c16017f6c7 /src/expr.c | |
parent | e3365e6c3762a6bb09f58f371a06797c3cd5e391 (diff) | |
download | sqlite-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.c | 18 |
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); |