/ Check-in [7fdf26da]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Further enhancements to IN-operator processing.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | IN-operator-improvements
Files: files | file ages | folders
SHA1:7fdf26da1d2f40b80f9e44ff6f5af22ace8f95f3
User & Date: drh 2014-08-04 18:50:54
Context
2014-08-04
21:26
Part of the change in the previous check-in was incorrect and can result in an incorrect UPDATE for WITHOUT ROWID tables. This check-in fixes the problem. check-in: ee5f6eae user: drh tags: IN-operator-improvements
18:50
Further enhancements to IN-operator processing. check-in: 7fdf26da user: drh tags: IN-operator-improvements
16:39
Refinements to the enhanced IN-operator logic. check-in: 92ba2821 user: drh tags: IN-operator-improvements
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/expr.c.

  1364   1364     if( op==TK_REGISTER ) op = p->op2;
  1365   1365     switch( op ){
  1366   1366       case TK_INTEGER:
  1367   1367       case TK_STRING:
  1368   1368       case TK_FLOAT:
  1369   1369       case TK_BLOB:
  1370   1370         return 0;
         1371  +    case TK_COLUMN:
         1372  +      assert( p->pTab!=0 );
         1373  +      return p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==0;
  1371   1374       default:
  1372   1375         return 1;
  1373   1376     }
  1374   1377   }
  1375   1378   
  1376   1379   /*
  1377   1380   ** Return TRUE if the given expression is a constant which would be
................................................................................
  2034   2037       sqlite3VdbeResolveLabel(v, labelOk);
  2035   2038       sqlite3ReleaseTempReg(pParse, regCkNull);
  2036   2039     }else{
  2037   2040     
  2038   2041       /* If the LHS is NULL, then the result is either false or NULL depending
  2039   2042       ** on whether the RHS is empty or not, respectively.
  2040   2043       */
  2041         -    if( destIfNull==destIfFalse ){
  2042         -      /* Shortcut for the common case where the false and NULL outcomes are
  2043         -      ** the same. */
  2044         -      sqlite3VdbeAddOp2(v, OP_IsNull, r1, destIfNull); VdbeCoverage(v);
  2045         -    }else{
  2046         -      int addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, r1); VdbeCoverage(v);
  2047         -      sqlite3VdbeAddOp2(v, OP_Rewind, pExpr->iTable, destIfFalse);
  2048         -      VdbeCoverage(v);
  2049         -      sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull);
  2050         -      sqlite3VdbeJumpHere(v, addr1);
         2044  +    if( sqlite3ExprCanBeNull(pExpr->pLeft) ){
         2045  +      if( destIfNull==destIfFalse ){
         2046  +        /* Shortcut for the common case where the false and NULL outcomes are
         2047  +        ** the same. */
         2048  +        sqlite3VdbeAddOp2(v, OP_IsNull, r1, destIfNull); VdbeCoverage(v);
         2049  +      }else{
         2050  +        int addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, r1); VdbeCoverage(v);
         2051  +        sqlite3VdbeAddOp2(v, OP_Rewind, pExpr->iTable, destIfFalse);
         2052  +        VdbeCoverage(v);
         2053  +        sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull);
         2054  +        sqlite3VdbeJumpHere(v, addr1);
         2055  +      }
  2051   2056       }
  2052   2057     
  2053   2058       if( eType==IN_INDEX_ROWID ){
  2054   2059         /* In this case, the RHS is the ROWID of table b-tree
  2055   2060         */
  2056   2061         sqlite3VdbeAddOp2(v, OP_MustBeInt, r1, destIfFalse); VdbeCoverage(v);
  2057   2062         sqlite3VdbeAddOp3(v, OP_NotExists, pExpr->iTable, destIfFalse, r1);

Changes to src/update.c.

   433    433     if( okOnePass ){
   434    434       if( aToOpen[iDataCur-iBaseCur] ){
   435    435         assert( pPk!=0 );
   436    436         sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey);
   437    437         VdbeCoverageNeverTaken(v);
   438    438       }
   439    439       labelContinue = labelBreak;
   440         -    sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak);
   441         -    VdbeCoverage(v);
          440  +    if( pPk==0 ){
          441  +      sqlite3VdbeAddOp2(v, OP_IsNull, regOldRowid, labelBreak); VdbeCoverage(v);
          442  +    }
   442    443     }else if( pPk ){
   443    444       labelContinue = sqlite3VdbeMakeLabel(v);
   444    445       sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v);
   445    446       addrTop = sqlite3VdbeAddOp2(v, OP_RowKey, iEph, regKey);
   446    447       sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey, 0);
   447    448       VdbeCoverage(v);
   448    449     }else{