| Index: third_party/sqlite/src/src/whereexpr.c
 | 
| diff --git a/third_party/sqlite/src/src/whereexpr.c b/third_party/sqlite/src/src/whereexpr.c
 | 
| index 99a97079be378d654311847305e2b4cd93460208..826d329b7f1d8f91c942e053ef531e38815093b3 100644
 | 
| --- a/third_party/sqlite/src/src/whereexpr.c
 | 
| +++ b/third_party/sqlite/src/src/whereexpr.c
 | 
| @@ -64,7 +64,7 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, u16 wtFlags){
 | 
|    if( pWC->nTerm>=pWC->nSlot ){
 | 
|      WhereTerm *pOld = pWC->a;
 | 
|      sqlite3 *db = pWC->pWInfo->pParse->db;
 | 
| -    pWC->a = sqlite3DbMallocRaw(db, sizeof(pWC->a[0])*pWC->nSlot*2 );
 | 
| +    pWC->a = sqlite3DbMallocRawNN(db, sizeof(pWC->a[0])*pWC->nSlot*2 );
 | 
|      if( pWC->a==0 ){
 | 
|        if( wtFlags & TERM_DYNAMIC ){
 | 
|          sqlite3ExprDelete(db, p);
 | 
| @@ -77,7 +77,6 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, u16 wtFlags){
 | 
|        sqlite3DbFree(db, pOld);
 | 
|      }
 | 
|      pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]);
 | 
| -    memset(&pWC->a[pWC->nTerm], 0, sizeof(pWC->a[0])*(pWC->nSlot-pWC->nTerm));
 | 
|    }
 | 
|    pTerm = &pWC->a[idx = pWC->nTerm++];
 | 
|    if( p && ExprHasProperty(p, EP_Unlikely) ){
 | 
| @@ -89,13 +88,15 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, u16 wtFlags){
 | 
|    pTerm->wtFlags = wtFlags;
 | 
|    pTerm->pWC = pWC;
 | 
|    pTerm->iParent = -1;
 | 
| +  memset(&pTerm->eOperator, 0,
 | 
| +         sizeof(WhereTerm) - offsetof(WhereTerm,eOperator));
 | 
|    return idx;
 | 
|  }
 | 
|  
 | 
|  /*
 | 
|  ** Return TRUE if the given operator is one of the operators that is
 | 
|  ** allowed for an indexable WHERE clause term.  The allowed operators are
 | 
| -** "=", "<", ">", "<=", ">=", "IN", and "IS NULL"
 | 
| +** "=", "<", ">", "<=", ">=", "IN", "IS", and "IS NULL"
 | 
|  */
 | 
|  static int allowedOp(int op){
 | 
|    assert( TK_GT>TK_EQ && TK_GT<TK_GE );
 | 
| @@ -202,6 +203,7 @@ static int isLikeOrGlob(
 | 
|    sqlite3 *db = pParse->db;  /* Database connection */
 | 
|    sqlite3_value *pVal = 0;
 | 
|    int op;                    /* Opcode of pRight */
 | 
| +  int rc;                    /* Result code to return */
 | 
|  
 | 
|    if( !sqlite3IsLikeFunction(db, pExpr, pnoCase, wc) ){
 | 
|      return 0;
 | 
| @@ -267,8 +269,9 @@ static int isLikeOrGlob(
 | 
|      }
 | 
|    }
 | 
|  
 | 
| +  rc = (z!=0);
 | 
|    sqlite3ValueFree(pVal);
 | 
| -  return (z!=0);
 | 
| +  return rc;
 | 
|  }
 | 
|  #endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */
 | 
|  
 | 
| @@ -288,7 +291,7 @@ static int isMatchOfColumn(
 | 
|    Expr *pExpr,                    /* Test this expression */
 | 
|    unsigned char *peOp2            /* OUT: 0 for MATCH, or else an op2 value */
 | 
|  ){
 | 
| -  struct Op2 {
 | 
| +  static const struct Op2 {
 | 
|      const char *zOp;
 | 
|      unsigned char eOp2;
 | 
|    } aOp[] = {
 | 
| @@ -531,6 +534,7 @@ static void exprAnalyzeOrTerm(
 | 
|    if( pOrInfo==0 ) return;
 | 
|    pTerm->wtFlags |= TERM_ORINFO;
 | 
|    pOrWc = &pOrInfo->wc;
 | 
| +  memset(pOrWc->aStatic, 0, sizeof(pOrWc->aStatic));
 | 
|    sqlite3WhereClauseInit(pOrWc, pWInfo);
 | 
|    sqlite3WhereSplit(pOrWc, pExpr, TK_OR);
 | 
|    sqlite3WhereExprAnalyze(pSrc, pOrWc);
 | 
| @@ -547,7 +551,7 @@ static void exprAnalyzeOrTerm(
 | 
|        WhereAndInfo *pAndInfo;
 | 
|        assert( (pOrTerm->wtFlags & (TERM_ANDINFO|TERM_ORINFO))==0 );
 | 
|        chngToIN = 0;
 | 
| -      pAndInfo = sqlite3DbMallocRaw(db, sizeof(*pAndInfo));
 | 
| +      pAndInfo = sqlite3DbMallocRawNN(db, sizeof(*pAndInfo));
 | 
|        if( pAndInfo ){
 | 
|          WhereClause *pAndWC;
 | 
|          WhereTerm *pAndTerm;
 | 
| @@ -557,15 +561,17 @@ static void exprAnalyzeOrTerm(
 | 
|          pOrTerm->wtFlags |= TERM_ANDINFO;
 | 
|          pOrTerm->eOperator = WO_AND;
 | 
|          pAndWC = &pAndInfo->wc;
 | 
| +        memset(pAndWC->aStatic, 0, sizeof(pAndWC->aStatic));
 | 
|          sqlite3WhereClauseInit(pAndWC, pWC->pWInfo);
 | 
|          sqlite3WhereSplit(pAndWC, pOrTerm->pExpr, TK_AND);
 | 
|          sqlite3WhereExprAnalyze(pSrc, pAndWC);
 | 
|          pAndWC->pOuter = pWC;
 | 
| -        testcase( db->mallocFailed );
 | 
|          if( !db->mallocFailed ){
 | 
|            for(j=0, pAndTerm=pAndWC->a; j<pAndWC->nTerm; j++, pAndTerm++){
 | 
|              assert( pAndTerm->pExpr );
 | 
| -            if( allowedOp(pAndTerm->pExpr->op) ){
 | 
| +            if( allowedOp(pAndTerm->pExpr->op) 
 | 
| +             || pAndTerm->eOperator==WO_MATCH 
 | 
| +            ){
 | 
|                b |= sqlite3WhereGetMask(&pWInfo->sMaskSet, pAndTerm->leftCursor);
 | 
|              }
 | 
|            }
 | 
| @@ -728,7 +734,7 @@ static void exprAnalyzeOrTerm(
 | 
|        }
 | 
|        assert( pLeft!=0 );
 | 
|        pDup = sqlite3ExprDup(db, pLeft, 0);
 | 
| -      pNew = sqlite3PExpr(pParse, TK_IN, pDup, 0, 0);
 | 
| +      pNew = sqlite3PExpr(pParse, TK_IN, pDup, 0);
 | 
|        if( pNew ){
 | 
|          int idxNew;
 | 
|          transferJoinMarkings(pNew, pExpr);
 | 
| @@ -780,12 +786,10 @@ static int termIsEquivalence(Parse *pParse, Expr *pExpr){
 | 
|    pColl = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pRight);
 | 
|    if( pColl==0 || sqlite3StrICmp(pColl->zName, "BINARY")==0 ) return 1;
 | 
|    pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
 | 
| -  /* Since pLeft and pRight are both a column references, their collating
 | 
| -  ** sequence should always be defined. */
 | 
| -  zColl1 = ALWAYS(pColl) ? pColl->zName : 0;
 | 
| +  zColl1 = pColl ? pColl->zName : 0;
 | 
|    pColl = sqlite3ExprCollSeq(pParse, pExpr->pRight);
 | 
| -  zColl2 = ALWAYS(pColl) ? pColl->zName : 0;
 | 
| -  return sqlite3StrICmp(zColl1, zColl2)==0;
 | 
| +  zColl2 = pColl ? pColl->zName : 0;
 | 
| +  return sqlite3_stricmp(zColl1, zColl2)==0;
 | 
|  }
 | 
|  
 | 
|  /*
 | 
| @@ -820,7 +824,8 @@ static Bitmask exprSelectUsage(WhereMaskSet *pMaskSet, Select *pS){
 | 
|  ** in any index.  Return TRUE (1) if pExpr is an indexed term and return
 | 
|  ** FALSE (0) if not.  If TRUE is returned, also set *piCur to the cursor
 | 
|  ** number of the table that is indexed and *piColumn to the column number
 | 
| -** of the column that is indexed, or -2 if an expression is being indexed.
 | 
| +** of the column that is indexed, or XN_EXPR (-2) if an expression is being
 | 
| +** indexed.
 | 
|  **
 | 
|  ** If pExpr is a TK_COLUMN column reference, then this routine always returns
 | 
|  ** true even if that particular column is not indexed, because the column
 | 
| @@ -828,6 +833,7 @@ static Bitmask exprSelectUsage(WhereMaskSet *pMaskSet, Select *pS){
 | 
|  */
 | 
|  static int exprMightBeIndexed(
 | 
|    SrcList *pFrom,        /* The FROM clause */
 | 
| +  int op,                /* The specific comparison operator */
 | 
|    Bitmask mPrereq,       /* Bitmask of FROM clause terms referenced by pExpr */
 | 
|    Expr *pExpr,           /* An operand of a comparison operator */
 | 
|    int *piCur,            /* Write the referenced table cursor number here */
 | 
| @@ -836,6 +842,17 @@ static int exprMightBeIndexed(
 | 
|    Index *pIdx;
 | 
|    int i;
 | 
|    int iCur;
 | 
| +
 | 
| +  /* If this expression is a vector to the left or right of a 
 | 
| +  ** inequality constraint (>, <, >= or <=), perform the processing 
 | 
| +  ** on the first element of the vector.  */
 | 
| +  assert( TK_GT+1==TK_LE && TK_GT+2==TK_LT && TK_GT+3==TK_GE );
 | 
| +  assert( TK_IS<TK_GE && TK_ISNULL<TK_GE && TK_IN<TK_GE );
 | 
| +  assert( op<=TK_GE );
 | 
| +  if( pExpr->op==TK_VECTOR && (op>=TK_GT && ALWAYS(op<=TK_GE)) ){
 | 
| +    pExpr = pExpr->x.pList->a[0].pExpr;
 | 
| +  }
 | 
| +
 | 
|    if( pExpr->op==TK_COLUMN ){
 | 
|      *piCur = pExpr->iTable;
 | 
|      *piColumn = pExpr->iColumn;
 | 
| @@ -848,10 +865,10 @@ static int exprMightBeIndexed(
 | 
|    for(pIdx=pFrom->a[i].pTab->pIndex; pIdx; pIdx=pIdx->pNext){
 | 
|      if( pIdx->aColExpr==0 ) continue;
 | 
|      for(i=0; i<pIdx->nKeyCol; i++){
 | 
| -      if( pIdx->aiColumn[i]!=(-2) ) continue;
 | 
| +      if( pIdx->aiColumn[i]!=XN_EXPR ) continue;
 | 
|        if( sqlite3ExprCompare(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){
 | 
|          *piCur = iCur;
 | 
| -        *piColumn = -2;
 | 
| +        *piColumn = XN_EXPR;
 | 
|          return 1;
 | 
|        }
 | 
|      }
 | 
| @@ -896,6 +913,7 @@ static void exprAnalyze(
 | 
|    Parse *pParse = pWInfo->pParse;  /* Parsing context */
 | 
|    sqlite3 *db = pParse->db;        /* Database connection */
 | 
|    unsigned char eOp2;              /* op2 value for LIKE/REGEXP/GLOB */
 | 
| +  int nLeft;                       /* Number of elements on left side vector */
 | 
|  
 | 
|    if( db->mallocFailed ){
 | 
|      return;
 | 
| @@ -908,6 +926,7 @@ static void exprAnalyze(
 | 
|    op = pExpr->op;
 | 
|    if( op==TK_IN ){
 | 
|      assert( pExpr->pRight==0 );
 | 
| +    if( sqlite3ExprCheckIN(pParse, pExpr) ) return;
 | 
|      if( ExprHasProperty(pExpr, EP_xIsSelect) ){
 | 
|        pTerm->prereqRight = exprSelectUsage(pMaskSet, pExpr->x.pSelect);
 | 
|      }else{
 | 
| @@ -924,6 +943,10 @@ static void exprAnalyze(
 | 
|      prereqAll |= x;
 | 
|      extraRight = x-1;  /* ON clause terms may not be used with an index
 | 
|                         ** on left table of a LEFT JOIN.  Ticket #3015 */
 | 
| +    if( (prereqAll>>1)>=x ){
 | 
| +      sqlite3ErrorMsg(pParse, "ON clause references tables to its right");
 | 
| +      return;
 | 
| +    }
 | 
|    }
 | 
|    pTerm->prereqAll = prereqAll;
 | 
|    pTerm->leftCursor = -1;
 | 
| @@ -934,18 +957,26 @@ static void exprAnalyze(
 | 
|      Expr *pLeft = sqlite3ExprSkipCollate(pExpr->pLeft);
 | 
|      Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight);
 | 
|      u16 opMask = (pTerm->prereqRight & prereqLeft)==0 ? WO_ALL : WO_EQUIV;
 | 
| -    if( exprMightBeIndexed(pSrc, prereqLeft, pLeft, &iCur, &iColumn) ){
 | 
| +
 | 
| +    if( pTerm->iField>0 ){
 | 
| +      assert( op==TK_IN );
 | 
| +      assert( pLeft->op==TK_VECTOR );
 | 
| +      pLeft = pLeft->x.pList->a[pTerm->iField-1].pExpr;
 | 
| +    }
 | 
| +
 | 
| +    if( exprMightBeIndexed(pSrc, op, prereqLeft, pLeft, &iCur, &iColumn) ){
 | 
|        pTerm->leftCursor = iCur;
 | 
|        pTerm->u.leftColumn = iColumn;
 | 
|        pTerm->eOperator = operatorMask(op) & opMask;
 | 
|      }
 | 
|      if( op==TK_IS ) pTerm->wtFlags |= TERM_IS;
 | 
|      if( pRight 
 | 
| -     && exprMightBeIndexed(pSrc, pTerm->prereqRight, pRight, &iCur, &iColumn)
 | 
| +     && exprMightBeIndexed(pSrc, op, pTerm->prereqRight, pRight, &iCur,&iColumn)
 | 
|      ){
 | 
|        WhereTerm *pNew;
 | 
|        Expr *pDup;
 | 
|        u16 eExtraOp = 0;        /* Extra bits for pNew->eOperator */
 | 
| +      assert( pTerm->iField==0 );
 | 
|        if( pTerm->leftCursor>=0 ){
 | 
|          int idxNew;
 | 
|          pDup = sqlite3ExprDup(db, pExpr, 0);
 | 
| @@ -1006,7 +1037,7 @@ static void exprAnalyze(
 | 
|        int idxNew;
 | 
|        pNewExpr = sqlite3PExpr(pParse, ops[i], 
 | 
|                               sqlite3ExprDup(db, pExpr->pLeft, 0),
 | 
| -                             sqlite3ExprDup(db, pList->a[i].pExpr, 0), 0);
 | 
| +                             sqlite3ExprDup(db, pList->a[i].pExpr, 0));
 | 
|        transferJoinMarkings(pNewExpr, pExpr);
 | 
|        idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
 | 
|        testcase( idxNew==0 );
 | 
| @@ -1091,7 +1122,7 @@ static void exprAnalyze(
 | 
|      pNewExpr1 = sqlite3ExprDup(db, pLeft, 0);
 | 
|      pNewExpr1 = sqlite3PExpr(pParse, TK_GE,
 | 
|             sqlite3ExprAddCollateString(pParse,pNewExpr1,zCollSeqName),
 | 
| -           pStr1, 0);
 | 
| +           pStr1);
 | 
|      transferJoinMarkings(pNewExpr1, pExpr);
 | 
|      idxNew1 = whereClauseInsert(pWC, pNewExpr1, wtFlags);
 | 
|      testcase( idxNew1==0 );
 | 
| @@ -1099,7 +1130,7 @@ static void exprAnalyze(
 | 
|      pNewExpr2 = sqlite3ExprDup(db, pLeft, 0);
 | 
|      pNewExpr2 = sqlite3PExpr(pParse, TK_LT,
 | 
|             sqlite3ExprAddCollateString(pParse,pNewExpr2,zCollSeqName),
 | 
| -           pStr2, 0);
 | 
| +           pStr2);
 | 
|      transferJoinMarkings(pNewExpr2, pExpr);
 | 
|      idxNew2 = whereClauseInsert(pWC, pNewExpr2, wtFlags);
 | 
|      testcase( idxNew2==0 );
 | 
| @@ -1119,7 +1150,7 @@ static void exprAnalyze(
 | 
|    ** virtual tables.  The native query optimizer does not attempt
 | 
|    ** to do anything with MATCH functions.
 | 
|    */
 | 
| -  if( isMatchOfColumn(pExpr, &eOp2) ){
 | 
| +  if( pWC->op==TK_AND && isMatchOfColumn(pExpr, &eOp2) ){
 | 
|      int idxNew;
 | 
|      Expr *pRight, *pLeft;
 | 
|      WhereTerm *pNewTerm;
 | 
| @@ -1132,7 +1163,7 @@ static void exprAnalyze(
 | 
|      if( (prereqExpr & prereqColumn)==0 ){
 | 
|        Expr *pNewExpr;
 | 
|        pNewExpr = sqlite3PExpr(pParse, TK_MATCH, 
 | 
| -                              0, sqlite3ExprDup(db, pRight, 0), 0);
 | 
| +                              0, sqlite3ExprDup(db, pRight, 0));
 | 
|        idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
 | 
|        testcase( idxNew==0 );
 | 
|        pNewTerm = &pWC->a[idxNew];
 | 
| @@ -1149,6 +1180,59 @@ static void exprAnalyze(
 | 
|    }
 | 
|  #endif /* SQLITE_OMIT_VIRTUALTABLE */
 | 
|  
 | 
| +  /* If there is a vector == or IS term - e.g. "(a, b) == (?, ?)" - create
 | 
| +  ** new terms for each component comparison - "a = ?" and "b = ?".  The
 | 
| +  ** new terms completely replace the original vector comparison, which is
 | 
| +  ** no longer used.
 | 
| +  **
 | 
| +  ** This is only required if at least one side of the comparison operation
 | 
| +  ** is not a sub-select.  */
 | 
| +  if( pWC->op==TK_AND 
 | 
| +  && (pExpr->op==TK_EQ || pExpr->op==TK_IS)
 | 
| +  && (nLeft = sqlite3ExprVectorSize(pExpr->pLeft))>1
 | 
| +  && sqlite3ExprVectorSize(pExpr->pRight)==nLeft
 | 
| +  && ( (pExpr->pLeft->flags & EP_xIsSelect)==0 
 | 
| +    || (pExpr->pRight->flags & EP_xIsSelect)==0)
 | 
| +  ){
 | 
| +    int i;
 | 
| +    for(i=0; i<nLeft; i++){
 | 
| +      int idxNew;
 | 
| +      Expr *pNew;
 | 
| +      Expr *pLeft = sqlite3ExprForVectorField(pParse, pExpr->pLeft, i);
 | 
| +      Expr *pRight = sqlite3ExprForVectorField(pParse, pExpr->pRight, i);
 | 
| +
 | 
| +      pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight);
 | 
| +      transferJoinMarkings(pNew, pExpr);
 | 
| +      idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC);
 | 
| +      exprAnalyze(pSrc, pWC, idxNew);
 | 
| +    }
 | 
| +    pTerm = &pWC->a[idxTerm];
 | 
| +    pTerm->wtFlags = TERM_CODED|TERM_VIRTUAL;  /* Disable the original */
 | 
| +    pTerm->eOperator = 0;
 | 
| +  }
 | 
| +
 | 
| +  /* If there is a vector IN term - e.g. "(a, b) IN (SELECT ...)" - create
 | 
| +  ** a virtual term for each vector component. The expression object
 | 
| +  ** used by each such virtual term is pExpr (the full vector IN(...) 
 | 
| +  ** expression). The WhereTerm.iField variable identifies the index within
 | 
| +  ** the vector on the LHS that the virtual term represents.
 | 
| +  **
 | 
| +  ** This only works if the RHS is a simple SELECT, not a compound
 | 
| +  */
 | 
| +  if( pWC->op==TK_AND && pExpr->op==TK_IN && pTerm->iField==0
 | 
| +   && pExpr->pLeft->op==TK_VECTOR
 | 
| +   && pExpr->x.pSelect->pPrior==0
 | 
| +  ){
 | 
| +    int i;
 | 
| +    for(i=0; i<sqlite3ExprVectorSize(pExpr->pLeft); i++){
 | 
| +      int idxNew;
 | 
| +      idxNew = whereClauseInsert(pWC, pExpr, TERM_VIRTUAL);
 | 
| +      pWC->a[idxNew].iField = i+1;
 | 
| +      exprAnalyze(pSrc, pWC, idxNew);
 | 
| +      markTermAsChild(pWC, idxNew, idxTerm);
 | 
| +    }
 | 
| +  }
 | 
| +
 | 
|  #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
 | 
|    /* When sqlite_stat3 histogram data is available an operator of the
 | 
|    ** form "x IS NOT NULL" can sometimes be evaluated more efficiently
 | 
| @@ -1169,7 +1253,7 @@ static void exprAnalyze(
 | 
|  
 | 
|      pNewExpr = sqlite3PExpr(pParse, TK_GT,
 | 
|                              sqlite3ExprDup(db, pLeft, 0),
 | 
| -                            sqlite3PExpr(pParse, TK_NULL, 0, 0, 0), 0);
 | 
| +                            sqlite3ExprAlloc(db, TK_NULL, 0, 0));
 | 
|  
 | 
|      idxNew = whereClauseInsert(pWC, pNewExpr,
 | 
|                                TERM_VIRTUAL|TERM_DYNAMIC|TERM_VNULL);
 | 
| @@ -1190,6 +1274,8 @@ static void exprAnalyze(
 | 
|    /* Prevent ON clause terms of a LEFT JOIN from being used to drive
 | 
|    ** an index for tables to the left of the join.
 | 
|    */
 | 
| +  testcase( pTerm!=&pWC->a[idxTerm] );
 | 
| +  pTerm = &pWC->a[idxTerm];
 | 
|    pTerm->prereqRight |= extraRight;
 | 
|  }
 | 
|  
 | 
| @@ -1272,17 +1358,18 @@ void sqlite3WhereClauseClear(WhereClause *pWC){
 | 
|  ** tree.
 | 
|  */
 | 
|  Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){
 | 
| -  Bitmask mask = 0;
 | 
| +  Bitmask mask;
 | 
|    if( p==0 ) return 0;
 | 
|    if( p->op==TK_COLUMN ){
 | 
|      mask = sqlite3WhereGetMask(pMaskSet, p->iTable);
 | 
|      return mask;
 | 
|    }
 | 
| -  mask = sqlite3WhereExprUsage(pMaskSet, p->pRight);
 | 
| -  mask |= sqlite3WhereExprUsage(pMaskSet, p->pLeft);
 | 
| +  assert( !ExprHasProperty(p, EP_TokenOnly) );
 | 
| +  mask = p->pRight ? sqlite3WhereExprUsage(pMaskSet, p->pRight) : 0;
 | 
| +  if( p->pLeft ) mask |= sqlite3WhereExprUsage(pMaskSet, p->pLeft);
 | 
|    if( ExprHasProperty(p, EP_xIsSelect) ){
 | 
|      mask |= exprSelectUsage(pMaskSet, p->x.pSelect);
 | 
| -  }else{
 | 
| +  }else if( p->x.pList ){
 | 
|      mask |= sqlite3WhereExprListUsage(pMaskSet, p->x.pList);
 | 
|    }
 | 
|    return mask;
 | 
| @@ -1346,13 +1433,13 @@ void sqlite3WhereTabFuncArgs(
 | 
|                        pTab->zName, j);
 | 
|        return;
 | 
|      }
 | 
| -    pColRef = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0);
 | 
| +    pColRef = sqlite3ExprAlloc(pParse->db, TK_COLUMN, 0, 0);
 | 
|      if( pColRef==0 ) return;
 | 
|      pColRef->iTable = pItem->iCursor;
 | 
|      pColRef->iColumn = k++;
 | 
|      pColRef->pTab = pTab;
 | 
|      pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef,
 | 
| -                         sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0);
 | 
| +                         sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0));
 | 
|      whereClauseInsert(pWC, pTerm, TERM_DYNAMIC);
 | 
|    }
 | 
|  }
 | 
| 
 |