The unified diff between revisions [5587f68e..] and [95cbeaa8..] is displayed below. It can also be downloaded as a raw diff.

This diff has been restricted to the following files: 'sqlite/where.c'

#
#
# patch "sqlite/where.c"
#  from [1cc55c9aa142c7ef09b427f5fd0bf0488e365fc4]
#    to [3ed72ca029b3010a76e3a41b7b02ec1bdf849f00]
#
============================================================
--- sqlite/where.c	1cc55c9aa142c7ef09b427f5fd0bf0488e365fc4
+++ sqlite/where.c	3ed72ca029b3010a76e3a41b7b02ec1bdf849f00
@@ -16,7 +16,7 @@
 ** so is applicable.  Because this module is responsible for selecting
 ** indices, you might also think of this module as the "query optimizer".
 **
-** $Id: where.c,v 1.174 2005/09/17 13:29:24 drh Exp $
+** $Id: where.c,v 1.179 2005/09/20 17:42:23 drh Exp $
 */
 #include "sqliteInt.h"

@@ -232,7 +232,7 @@ static int whereClauseInsert(WhereClause

 /*
 ** This routine identifies subexpressions in the WHERE clause where
-** each subexpression is separate by the AND operator or some other
+** each subexpression is separated by the AND operator or some other
 ** operator specified in the op parameter.  The WhereClause structure
 ** is filled with pointers to subexpressions.  For example:
 **
@@ -281,7 +281,7 @@ static Bitmask getMask(ExprMaskSet *pMas
 **
 ** There is one cursor per table in the FROM clause.  The number of
 ** tables in the FROM clause is limited by a test early in the
-** sqlite3WhereBegin() routien.  So we know that the pMaskSet->ix[]
+** sqlite3WhereBegin() routine.  So we know that the pMaskSet->ix[]
 ** array will never overflow.
 */
 static void createMask(ExprMaskSet *pMaskSet, int iCursor){
@@ -532,7 +532,7 @@ static int isLikeOrGlob(
 ** to the standard form of "X <op> <expr>".  If the expression is of
 ** the form "X <op> Y" where both X and Y are columns, then the original
 ** expression is unchanged and a new virtual expression of the form
-** "Y <op> X" is added to the WHERE clause.
+** "Y <op> X" is added to the WHERE clause and analyzed separately.
 */
 static void exprAnalyze(
   SrcList *pSrc,            /* the FROM clause */
@@ -556,14 +556,17 @@ static void exprAnalyze(
   }else{
     pTerm->prereqRight = exprTableUsage(pMaskSet, pExpr->pRight);
   }
-  pTerm->prereqAll = prereqAll = exprTableUsage(pMaskSet, pExpr);
+  prereqAll = exprTableUsage(pMaskSet, pExpr);
+  if( ExprHasProperty(pExpr, EP_FromJoin) ){
+    prereqAll |= getMask(pMaskSet, pExpr->iRightJoinTable);
+  }
+  pTerm->prereqAll = prereqAll;
   pTerm->leftCursor = -1;
   pTerm->iParent = -1;
   pTerm->operator = 0;
   if( allowedOp(pExpr->op) && (pTerm->prereqRight & prereqLeft)==0 ){
     Expr *pLeft = pExpr->pLeft;
     Expr *pRight = pExpr->pRight;
-    assert( prereqAll == (pTerm->prereqRight | prereqLeft) ); /* ticket 1433 */
     if( pLeft->op==TK_COLUMN ){
       pTerm->leftCursor = pLeft->iTable;
       pTerm->leftColumn = pLeft->iColumn;
@@ -844,7 +847,7 @@ static int sortableByRowid(
 }

 /*
-** Prepare a crude estimate of the logorithm of the input value.
+** Prepare a crude estimate of the logarithm of the input value.
 ** The results need not be exact.  This is only used for estimating
 ** the total cost of performing operatings with O(logN) or O(NlogN)
 ** complexity.  Because N is just a guess, it is no great tragedy if
@@ -1103,11 +1106,12 @@ static double bestIndex(
 ** of a LEFT OUTER JOIN.  In (1), the term is not disabled.
 **
 ** Disabling a term causes that term to not be tested in the inner loop
-** of the join.  Disabling is an optimization.  We would get the correct
-** results if nothing were ever disabled, but joins might run a little
-** slower.  The trick is to disable as much as we can without disabling
-** too much.  If we disabled in (1), we'd get the wrong answer.
-** See ticket #813.
+** of the join.  Disabling is an optimization.  When terms are satisfied
+** by indices, we disable them to prevent redundant tests in the inner
+** loop.  We would get the correct results if nothing were ever disabled,
+** but joins might run a little slower.  The trick is to disable as much
+** as we can without disabling too much.  If we disabled in (1), we'd get
+** the wrong answer.  See ticket #813.
 */
 static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){
   if( pTerm
@@ -1264,7 +1268,7 @@ static void codeAllEqualityTerms(
   }
 }

-#ifdef SQLITE_TEST
+#if defined(SQLITE_TEST)
 /*
 ** The following variable holds a text description of query plan generated
 ** by the most recent call to sqlite3WhereBegin().  Each call to WhereBegin
@@ -1422,7 +1426,7 @@ WhereInfo *sqlite3WhereBegin(
   /* Analyze all of the subexpressions.  Note that exprAnalyze() might
   ** add new virtual terms onto the end of the WHERE clause.  We do not
   ** want to analyze these virtual terms, so start analyzing at the end
-  ** and work forward so that they added virtual terms are never processed.
+  ** and work forward so that the added virtual terms are never processed.
   */
   for(i=0; i<pTabList->nSrc; i++){
     createMask(&maskSet, pTabList->a[i].iCursor);
@@ -1593,8 +1597,7 @@ WhereInfo *sqlite3WhereBegin(
     if( pLevel->iFrom>0 && (pTabItem[-1].jointype & JT_LEFT)!=0 ){
       if( !pParse->nMem ) pParse->nMem++;
       pLevel->iLeftJoin = pParse->nMem++;
-      sqlite3VdbeAddOp(v, OP_Null, 0, 0);
-      sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iLeftJoin, 1);
+      sqlite3VdbeAddOp(v, OP_MemInt, 0, pLevel->iLeftJoin);
       VdbeComment((v, "# init LEFT JOIN no-match flag"));
     }

@@ -1874,8 +1877,7 @@ WhereInfo *sqlite3WhereBegin(
     */
     if( pLevel->iLeftJoin ){
       pLevel->top = sqlite3VdbeCurrentAddr(v);
-      sqlite3VdbeAddOp(v, OP_Integer, 1, 0);
-      sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iLeftJoin, 1);
+      sqlite3VdbeAddOp(v, OP_MemInt, 1, pLevel->iLeftJoin);
       VdbeComment((v, "# record LEFT JOIN hit"));
       for(pTerm=wc.a, j=0; j<wc.nTerm; j++, pTerm++){
         if( pTerm->flags & (TERM_VIRTUAL|TERM_CODED) ) continue;
@@ -1977,13 +1979,13 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
     }
     if( pLevel->iLeftJoin ){
       int addr;
-      addr = sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iLeftJoin, 0);
-      sqlite3VdbeAddOp(v, OP_NotNull, 1, addr+4 + (pLevel->iIdxCur>=0));
+      addr = sqlite3VdbeAddOp(v, OP_IfMemPos, pLevel->iLeftJoin, 0);
       sqlite3VdbeAddOp(v, OP_NullRow, pTabList->a[i].iCursor, 0);
       if( pLevel->iIdxCur>=0 ){
         sqlite3VdbeAddOp(v, OP_NullRow, pLevel->iIdxCur, 0);
       }
       sqlite3VdbeAddOp(v, OP_Goto, 0, pLevel->top);
+      sqlite3VdbeJumpHere(v, addr);
     }
   }