| Index: third_party/sqlite/src/src/resolve.c | 
| diff --git a/third_party/sqlite/src/src/resolve.c b/third_party/sqlite/src/src/resolve.c | 
| index 74d6aaef93bdcc6c62d4b0c6e35ca5d7ad2b72ae..068e3355680ca050fc9f8fb2ef58a14d42918e1e 100644 | 
| --- a/third_party/sqlite/src/src/resolve.c | 
| +++ b/third_party/sqlite/src/src/resolve.c | 
| @@ -19,6 +19,29 @@ | 
| #include <string.h> | 
|  | 
| /* | 
| +** Walk the expression tree pExpr and increase the aggregate function | 
| +** depth (the Expr.op2 field) by N on every TK_AGG_FUNCTION node. | 
| +** This needs to occur when copying a TK_AGG_FUNCTION node from an | 
| +** outer query into an inner subquery. | 
| +** | 
| +** incrAggFunctionDepth(pExpr,n) is the main routine.  incrAggDepth(..) | 
| +** is a helper function - a callback for the tree walker. | 
| +*/ | 
| +static int incrAggDepth(Walker *pWalker, Expr *pExpr){ | 
| +  if( pExpr->op==TK_AGG_FUNCTION ) pExpr->op2 += pWalker->u.i; | 
| +  return WRC_Continue; | 
| +} | 
| +static void incrAggFunctionDepth(Expr *pExpr, int N){ | 
| +  if( N>0 ){ | 
| +    Walker w; | 
| +    memset(&w, 0, sizeof(w)); | 
| +    w.xExprCallback = incrAggDepth; | 
| +    w.u.i = N; | 
| +    sqlite3WalkExpr(&w, pExpr); | 
| +  } | 
| +} | 
| + | 
| +/* | 
| ** Turn the pExpr expression into an alias for the iCol-th column of the | 
| ** result set in pEList. | 
| ** | 
| @@ -32,7 +55,7 @@ | 
| ** column reference is so that the column reference will be recognized as | 
| ** usable by indices within the WHERE clause processing logic. | 
| ** | 
| -** Hack:  The TK_AS operator is inhibited if zType[0]=='G'.  This means | 
| +** The TK_AS operator is inhibited if zType[0]=='G'.  This means | 
| ** that in a GROUP BY clause, the expression is evaluated twice.  Hence: | 
| ** | 
| **     SELECT random()%5 AS x, count(*) FROM tab GROUP BY x | 
| @@ -42,15 +65,32 @@ | 
| **     SELECT random()%5 AS x, count(*) FROM tab GROUP BY random()%5 | 
| ** | 
| ** The result of random()%5 in the GROUP BY clause is probably different | 
| -** from the result in the result-set.  We might fix this someday.  Or | 
| -** then again, we might not... | 
| +** from the result in the result-set.  On the other hand Standard SQL does | 
| +** not allow the GROUP BY clause to contain references to result-set columns. | 
| +** So this should never come up in well-formed queries. | 
| +** | 
| +** If the reference is followed by a COLLATE operator, then make sure | 
| +** the COLLATE operator is preserved.  For example: | 
| +** | 
| +**     SELECT a+b, c+d FROM t1 ORDER BY 1 COLLATE nocase; | 
| +** | 
| +** Should be transformed into: | 
| +** | 
| +**     SELECT a+b, c+d FROM t1 ORDER BY (a+b) COLLATE nocase; | 
| +** | 
| +** The nSubquery parameter specifies how many levels of subquery the | 
| +** alias is removed from the original expression.  The usually value is | 
| +** zero but it might be more if the alias is contained within a subquery | 
| +** of the original expression.  The Expr.op2 field of TK_AGG_FUNCTION | 
| +** structures must be increased by the nSubquery amount. | 
| */ | 
| static void resolveAlias( | 
| Parse *pParse,         /* Parsing context */ | 
| ExprList *pEList,      /* A result set */ | 
| int iCol,              /* A column in the result set.  0..pEList->nExpr-1 */ | 
| Expr *pExpr,           /* Transform this into an alias to the result set */ | 
| -  const char *zType      /* "GROUP" or "ORDER" or "" */ | 
| +  const char *zType,     /* "GROUP" or "ORDER" or "" */ | 
| +  int nSubquery          /* Number of subqueries that the label is moving */ | 
| ){ | 
| Expr *pOrig;           /* The iCol-th column of the result set */ | 
| Expr *pDup;            /* Copy of pOrig */ | 
| @@ -61,43 +101,87 @@ static void resolveAlias( | 
| assert( pOrig!=0 ); | 
| assert( pOrig->flags & EP_Resolved ); | 
| db = pParse->db; | 
| +  pDup = sqlite3ExprDup(db, pOrig, 0); | 
| +  if( pDup==0 ) return; | 
| if( pOrig->op!=TK_COLUMN && zType[0]!='G' ){ | 
| -    pDup = sqlite3ExprDup(db, pOrig, 0); | 
| +    incrAggFunctionDepth(pDup, nSubquery); | 
| pDup = sqlite3PExpr(pParse, TK_AS, pDup, 0, 0); | 
| if( pDup==0 ) return; | 
| -    if( pEList->a[iCol].iAlias==0 ){ | 
| -      pEList->a[iCol].iAlias = (u16)(++pParse->nAlias); | 
| +    ExprSetProperty(pDup, EP_Skip); | 
| +    if( pEList->a[iCol].u.x.iAlias==0 ){ | 
| +      pEList->a[iCol].u.x.iAlias = (u16)(++pParse->nAlias); | 
| } | 
| -    pDup->iTable = pEList->a[iCol].iAlias; | 
| -  }else if( ExprHasProperty(pOrig, EP_IntValue) || pOrig->u.zToken==0 ){ | 
| -    pDup = sqlite3ExprDup(db, pOrig, 0); | 
| -    if( pDup==0 ) return; | 
| -  }else{ | 
| -    char *zToken = pOrig->u.zToken; | 
| -    assert( zToken!=0 ); | 
| -    pOrig->u.zToken = 0; | 
| -    pDup = sqlite3ExprDup(db, pOrig, 0); | 
| -    pOrig->u.zToken = zToken; | 
| -    if( pDup==0 ) return; | 
| -    assert( (pDup->flags & (EP_Reduced|EP_TokenOnly))==0 ); | 
| -    pDup->flags2 |= EP2_MallocedToken; | 
| -    pDup->u.zToken = sqlite3DbStrDup(db, zToken); | 
| +    pDup->iTable = pEList->a[iCol].u.x.iAlias; | 
| } | 
| -  if( pExpr->flags & EP_ExpCollate ){ | 
| -    pDup->pColl = pExpr->pColl; | 
| -    pDup->flags |= EP_ExpCollate; | 
| +  if( pExpr->op==TK_COLLATE ){ | 
| +    pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken); | 
| } | 
|  | 
| /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This | 
| ** prevents ExprDelete() from deleting the Expr structure itself, | 
| ** allowing it to be repopulated by the memcpy() on the following line. | 
| +  ** The pExpr->u.zToken might point into memory that will be freed by the | 
| +  ** sqlite3DbFree(db, pDup) on the last line of this block, so be sure to | 
| +  ** make a copy of the token before doing the sqlite3DbFree(). | 
| */ | 
| ExprSetProperty(pExpr, EP_Static); | 
| sqlite3ExprDelete(db, pExpr); | 
| memcpy(pExpr, pDup, sizeof(*pExpr)); | 
| +  if( !ExprHasProperty(pExpr, EP_IntValue) && pExpr->u.zToken!=0 ){ | 
| +    assert( (pExpr->flags & (EP_Reduced|EP_TokenOnly))==0 ); | 
| +    pExpr->u.zToken = sqlite3DbStrDup(db, pExpr->u.zToken); | 
| +    pExpr->flags |= EP_MemToken; | 
| +  } | 
| sqlite3DbFree(db, pDup); | 
| } | 
|  | 
| + | 
| +/* | 
| +** Return TRUE if the name zCol occurs anywhere in the USING clause. | 
| +** | 
| +** Return FALSE if the USING clause is NULL or if it does not contain | 
| +** zCol. | 
| +*/ | 
| +static int nameInUsingClause(IdList *pUsing, const char *zCol){ | 
| +  if( pUsing ){ | 
| +    int k; | 
| +    for(k=0; k<pUsing->nId; k++){ | 
| +      if( sqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ) return 1; | 
| +    } | 
| +  } | 
| +  return 0; | 
| +} | 
| + | 
| +/* | 
| +** Subqueries stores the original database, table and column names for their | 
| +** result sets in ExprList.a[].zSpan, in the form "DATABASE.TABLE.COLUMN". | 
| +** Check to see if the zSpan given to this routine matches the zDb, zTab, | 
| +** and zCol.  If any of zDb, zTab, and zCol are NULL then those fields will | 
| +** match anything. | 
| +*/ | 
| +int sqlite3MatchSpanName( | 
| +  const char *zSpan, | 
| +  const char *zCol, | 
| +  const char *zTab, | 
| +  const char *zDb | 
| +){ | 
| +  int n; | 
| +  for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){} | 
| +  if( zDb && (sqlite3StrNICmp(zSpan, zDb, n)!=0 || zDb[n]!=0) ){ | 
| +    return 0; | 
| +  } | 
| +  zSpan += n+1; | 
| +  for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){} | 
| +  if( zTab && (sqlite3StrNICmp(zSpan, zTab, n)!=0 || zTab[n]!=0) ){ | 
| +    return 0; | 
| +  } | 
| +  zSpan += n+1; | 
| +  if( zCol && sqlite3StrICmp(zSpan, zCol)!=0 ){ | 
| +    return 0; | 
| +  } | 
| +  return 1; | 
| +} | 
| + | 
| /* | 
| ** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up | 
| ** that name in the set of source tables in pSrcList and make the pExpr | 
| @@ -133,24 +217,50 @@ static int lookupName( | 
| NameContext *pNC,    /* The name context used to resolve the name */ | 
| Expr *pExpr          /* Make this EXPR node point to the selected column */ | 
| ){ | 
| -  int i, j;            /* Loop counters */ | 
| +  int i, j;                         /* Loop counters */ | 
| int cnt = 0;                      /* Number of matching column names */ | 
| int cntTab = 0;                   /* Number of matching table names */ | 
| +  int nSubquery = 0;                /* How many levels of subquery */ | 
| sqlite3 *db = pParse->db;         /* The database connection */ | 
| struct SrcList_item *pItem;       /* Use for looping over pSrcList items */ | 
| struct SrcList_item *pMatch = 0;  /* The matching pSrcList item */ | 
| NameContext *pTopNC = pNC;        /* First namecontext in the list */ | 
| Schema *pSchema = 0;              /* Schema of the expression */ | 
| -  int isTrigger = 0; | 
| +  int isTrigger = 0;                /* True if resolved to a trigger column */ | 
| +  Table *pTab = 0;                  /* Table hold the row */ | 
| +  Column *pCol;                     /* A column of pTab */ | 
|  | 
| assert( pNC );     /* the name context cannot be NULL. */ | 
| assert( zCol );    /* The Z in X.Y.Z cannot be NULL */ | 
| -  assert( ~ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) ); | 
| +  assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); | 
|  | 
| /* Initialize the node to no-match */ | 
| pExpr->iTable = -1; | 
| pExpr->pTab = 0; | 
| -  ExprSetIrreducible(pExpr); | 
| +  ExprSetVVAProperty(pExpr, EP_NoReduce); | 
| + | 
| +  /* Translate the schema name in zDb into a pointer to the corresponding | 
| +  ** schema.  If not found, pSchema will remain NULL and nothing will match | 
| +  ** resulting in an appropriate error message toward the end of this routine | 
| +  */ | 
| +  if( zDb ){ | 
| +    testcase( pNC->ncFlags & NC_PartIdx ); | 
| +    testcase( pNC->ncFlags & NC_IsCheck ); | 
| +    if( (pNC->ncFlags & (NC_PartIdx|NC_IsCheck))!=0 ){ | 
| +      /* Silently ignore database qualifiers inside CHECK constraints and partial | 
| +      ** indices.  Do not raise errors because that might break legacy and | 
| +      ** because it does not hurt anything to just ignore the database name. */ | 
| +      zDb = 0; | 
| +    }else{ | 
| +      for(i=0; i<db->nDb; i++){ | 
| +        assert( db->aDb[i].zName ); | 
| +        if( sqlite3StrICmp(db->aDb[i].zName,zDb)==0 ){ | 
| +          pSchema = db->aDb[i].pSchema; | 
| +          break; | 
| +        } | 
| +      } | 
| +    } | 
| +  } | 
|  | 
| /* Start at the inner-most context and move outward until a match is found */ | 
| while( pNC && cnt==0 ){ | 
| @@ -159,77 +269,71 @@ static int lookupName( | 
|  | 
| if( pSrcList ){ | 
| for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){ | 
| -        Table *pTab; | 
| -        int iDb; | 
| -        Column *pCol; | 
| - | 
| pTab = pItem->pTab; | 
| assert( pTab!=0 && pTab->zName!=0 ); | 
| -        iDb = sqlite3SchemaToIndex(db, pTab->pSchema); | 
| assert( pTab->nCol>0 ); | 
| -        if( zTab ){ | 
| -          if( pItem->zAlias ){ | 
| -            char *zTabName = pItem->zAlias; | 
| -            if( sqlite3StrICmp(zTabName, zTab)!=0 ) continue; | 
| -          }else{ | 
| -            char *zTabName = pTab->zName; | 
| -            if( NEVER(zTabName==0) || sqlite3StrICmp(zTabName, zTab)!=0 ){ | 
| -              continue; | 
| -            } | 
| -            if( zDb!=0 && sqlite3StrICmp(db->aDb[iDb].zName, zDb)!=0 ){ | 
| -              continue; | 
| +        if( pItem->pSelect && (pItem->pSelect->selFlags & SF_NestedFrom)!=0 ){ | 
| +          int hit = 0; | 
| +          pEList = pItem->pSelect->pEList; | 
| +          for(j=0; j<pEList->nExpr; j++){ | 
| +            if( sqlite3MatchSpanName(pEList->a[j].zSpan, zCol, zTab, zDb) ){ | 
| +              cnt++; | 
| +              cntTab = 2; | 
| +              pMatch = pItem; | 
| +              pExpr->iColumn = j; | 
| +              hit = 1; | 
| } | 
| } | 
| +          if( hit || zTab==0 ) continue; | 
| +        } | 
| +        if( zDb && pTab->pSchema!=pSchema ){ | 
| +          continue; | 
| +        } | 
| +        if( zTab ){ | 
| +          const char *zTabName = pItem->zAlias ? pItem->zAlias : pTab->zName; | 
| +          assert( zTabName!=0 ); | 
| +          if( sqlite3StrICmp(zTabName, zTab)!=0 ){ | 
| +            continue; | 
| +          } | 
| } | 
| if( 0==(cntTab++) ){ | 
| -          pExpr->iTable = pItem->iCursor; | 
| -          pExpr->pTab = pTab; | 
| -          pSchema = pTab->pSchema; | 
| pMatch = pItem; | 
| } | 
| for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){ | 
| if( sqlite3StrICmp(pCol->zName, zCol)==0 ){ | 
| -            IdList *pUsing; | 
| +            /* If there has been exactly one prior match and this match | 
| +            ** is for the right-hand table of a NATURAL JOIN or is in a | 
| +            ** USING clause, then skip this match. | 
| +            */ | 
| +            if( cnt==1 ){ | 
| +              if( pItem->jointype & JT_NATURAL ) continue; | 
| +              if( nameInUsingClause(pItem->pUsing, zCol) ) continue; | 
| +            } | 
| cnt++; | 
| -            pExpr->iTable = pItem->iCursor; | 
| -            pExpr->pTab = pTab; | 
| pMatch = pItem; | 
| -            pSchema = pTab->pSchema; | 
| /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */ | 
| pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j; | 
| -            if( i<pSrcList->nSrc-1 ){ | 
| -              if( pItem[1].jointype & JT_NATURAL ){ | 
| -                /* If this match occurred in the left table of a natural join, | 
| -                ** then skip the right table to avoid a duplicate match */ | 
| -                pItem++; | 
| -                i++; | 
| -              }else if( (pUsing = pItem[1].pUsing)!=0 ){ | 
| -                /* If this match occurs on a column that is in the USING clause | 
| -                ** of a join, skip the search of the right table of the join | 
| -                ** to avoid a duplicate match there. */ | 
| -                int k; | 
| -                for(k=0; k<pUsing->nId; k++){ | 
| -                  if( sqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ){ | 
| -                    pItem++; | 
| -                    i++; | 
| -                    break; | 
| -                  } | 
| -                } | 
| -              } | 
| -            } | 
| break; | 
| } | 
| } | 
| } | 
| -    } | 
| +      if( pMatch ){ | 
| +        pExpr->iTable = pMatch->iCursor; | 
| +        pExpr->pTab = pMatch->pTab; | 
| +        assert( (pMatch->jointype & JT_RIGHT)==0 ); /* RIGHT JOIN not (yet) supported */ | 
| +        if( (pMatch->jointype & JT_LEFT)!=0 ){ | 
| +          ExprSetProperty(pExpr, EP_CanBeNull); | 
| +        } | 
| +        pSchema = pExpr->pTab->pSchema; | 
| +      } | 
| +    } /* if( pSrcList ) */ | 
|  | 
| #ifndef SQLITE_OMIT_TRIGGER | 
| /* If we have not already resolved the name, then maybe | 
| ** it is a new.* or old.* trigger argument reference | 
| */ | 
| -    if( zDb==0 && zTab!=0 && cnt==0 && pParse->pTriggerTab!=0 ){ | 
| +    if( zDb==0 && zTab!=0 && cntTab==0 && pParse->pTriggerTab!=0 ){ | 
| int op = pParse->eTriggerOp; | 
| -      Table *pTab = 0; | 
| assert( op==TK_DELETE || op==TK_UPDATE || op==TK_INSERT ); | 
| if( op!=TK_DELETE && sqlite3StrICmp("new",zTab) == 0 ){ | 
| pExpr->iTable = 1; | 
| @@ -237,14 +341,15 @@ static int lookupName( | 
| }else if( op!=TK_INSERT && sqlite3StrICmp("old",zTab)==0 ){ | 
| pExpr->iTable = 0; | 
| pTab = pParse->pTriggerTab; | 
| +      }else{ | 
| +        pTab = 0; | 
| } | 
|  | 
| if( pTab ){ | 
| int iCol; | 
| pSchema = pTab->pSchema; | 
| cntTab++; | 
| -        for(iCol=0; iCol<pTab->nCol; iCol++){ | 
| -          Column *pCol = &pTab->aCol[iCol]; | 
| +        for(iCol=0, pCol=pTab->aCol; iCol<pTab->nCol; iCol++, pCol++){ | 
| if( sqlite3StrICmp(pCol->zName, zCol)==0 ){ | 
| if( iCol==pTab->iPKey ){ | 
| iCol = -1; | 
| @@ -252,8 +357,10 @@ static int lookupName( | 
| break; | 
| } | 
| } | 
| -        if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) ){ | 
| -          iCol = -1;        /* IMP: R-44911-55124 */ | 
| +        if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) && HasRowid(pTab) ){ | 
| +          /* IMP: R-51414-32910 */ | 
| +          /* IMP: R-44911-55124 */ | 
| +          iCol = -1; | 
| } | 
| if( iCol<pTab->nCol ){ | 
| cnt++; | 
| @@ -279,7 +386,8 @@ static int lookupName( | 
| /* | 
| ** Perhaps the name is a reference to the ROWID | 
| */ | 
| -    if( cnt==0 && cntTab==1 && sqlite3IsRowid(zCol) ){ | 
| +    if( cnt==0 && cntTab==1 && pMatch && sqlite3IsRowid(zCol) | 
| +     && HasRowid(pMatch->pTab) ){ | 
| cnt = 1; | 
| pExpr->iColumn = -1;     /* IMP: R-44911-55124 */ | 
| pExpr->affinity = SQLITE_AFF_INTEGER; | 
| @@ -296,8 +404,17 @@ static int lookupName( | 
| ** forms the result set entry ("a+b" in the example) and return immediately. | 
| ** Note that the expression in the result set should have already been | 
| ** resolved by the time the WHERE clause is resolved. | 
| +    ** | 
| +    ** The ability to use an output result-set column in the WHERE, GROUP BY, | 
| +    ** or HAVING clauses, or as part of a larger expression in the ORDRE BY | 
| +    ** clause is not standard SQL.  This is a (goofy) SQLite extension, that | 
| +    ** is supported for backwards compatibility only.  TO DO: Issue a warning | 
| +    ** on sqlite3_log() whenever the capability is used. | 
| */ | 
| -    if( cnt==0 && (pEList = pNC->pEList)!=0 && zTab==0 ){ | 
| +    if( (pEList = pNC->pEList)!=0 | 
| +     && zTab==0 | 
| +     && cnt==0 | 
| +    ){ | 
| for(j=0; j<pEList->nExpr; j++){ | 
| char *zAs = pEList->a[j].zName; | 
| if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){ | 
| @@ -306,11 +423,11 @@ static int lookupName( | 
| assert( pExpr->x.pList==0 ); | 
| assert( pExpr->x.pSelect==0 ); | 
| pOrig = pEList->a[j].pExpr; | 
| -          if( !pNC->allowAgg && ExprHasProperty(pOrig, EP_Agg) ){ | 
| +          if( (pNC->ncFlags&NC_AllowAgg)==0 && ExprHasProperty(pOrig, EP_Agg) ){ | 
| sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs); | 
| return WRC_Abort; | 
| } | 
| -          resolveAlias(pParse, pEList, j, pExpr, ""); | 
| +          resolveAlias(pParse, pEList, j, pExpr, "", nSubquery); | 
| cnt = 1; | 
| pMatch = 0; | 
| assert( zTab==0 && zDb==0 ); | 
| @@ -324,6 +441,7 @@ static int lookupName( | 
| */ | 
| if( cnt==0 ){ | 
| pNC = pNC->pNext; | 
| +      nSubquery++; | 
| } | 
| } | 
|  | 
| @@ -387,7 +505,9 @@ static int lookupName( | 
| lookupname_end: | 
| if( cnt==1 ){ | 
| assert( pNC!=0 ); | 
| -    sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList); | 
| +    if( pExpr->op!=TK_AS ){ | 
| +      sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList); | 
| +    } | 
| /* Increment the nRef value on all name contexts from TopNC up to | 
| ** the point where the name matched. */ | 
| for(;;){ | 
| @@ -426,6 +546,52 @@ Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSrc, int iCol){ | 
| } | 
|  | 
| /* | 
| +** Report an error that an expression is not valid for a partial index WHERE | 
| +** clause. | 
| +*/ | 
| +static void notValidPartIdxWhere( | 
| +  Parse *pParse,       /* Leave error message here */ | 
| +  NameContext *pNC,    /* The name context */ | 
| +  const char *zMsg     /* Type of error */ | 
| +){ | 
| +  if( (pNC->ncFlags & NC_PartIdx)!=0 ){ | 
| +    sqlite3ErrorMsg(pParse, "%s prohibited in partial index WHERE clauses", | 
| +                    zMsg); | 
| +  } | 
| +} | 
| + | 
| +#ifndef SQLITE_OMIT_CHECK | 
| +/* | 
| +** Report an error that an expression is not valid for a CHECK constraint. | 
| +*/ | 
| +static void notValidCheckConstraint( | 
| +  Parse *pParse,       /* Leave error message here */ | 
| +  NameContext *pNC,    /* The name context */ | 
| +  const char *zMsg     /* Type of error */ | 
| +){ | 
| +  if( (pNC->ncFlags & NC_IsCheck)!=0 ){ | 
| +    sqlite3ErrorMsg(pParse,"%s prohibited in CHECK constraints", zMsg); | 
| +  } | 
| +} | 
| +#else | 
| +# define notValidCheckConstraint(P,N,M) | 
| +#endif | 
| + | 
| +/* | 
| +** Expression p should encode a floating point value between 1.0 and 0.0. | 
| +** Return 1024 times this value.  Or return -1 if p is not a floating point | 
| +** value between 1.0 and 0.0. | 
| +*/ | 
| +static int exprProbability(Expr *p){ | 
| +  double r = -1.0; | 
| +  if( p->op!=TK_FLOAT ) return -1; | 
| +  sqlite3AtoF(p->u.zToken, &r, sqlite3Strlen30(p->u.zToken), SQLITE_UTF8); | 
| +  assert( r>=0.0 ); | 
| +  if( r>1.0 ) return -1; | 
| +  return (int)(r*1000.0); | 
| +} | 
| + | 
| +/* | 
| ** This routine is callback for sqlite3WalkExpr(). | 
| ** | 
| ** Resolve symbolic names into TK_COLUMN operators for the current | 
| @@ -445,7 +611,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ | 
| pParse = pNC->pParse; | 
| assert( pParse==pWalker->pParse ); | 
|  | 
| -  if( ExprHasAnyProperty(pExpr, EP_Resolved) ) return WRC_Prune; | 
| +  if( ExprHasProperty(pExpr, EP_Resolved) ) return WRC_Prune; | 
| ExprSetProperty(pExpr, EP_Resolved); | 
| #ifndef NDEBUG | 
| if( pNC->pSrcList && pNC->pSrcList->nAlloc>0 ){ | 
| @@ -509,7 +675,6 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ | 
|  | 
| /* Resolve function names | 
| */ | 
| -    case TK_CONST_FUNC: | 
| case TK_FUNCTION: { | 
| ExprList *pList = pExpr->x.pList;    /* The argument list */ | 
| int n = pList ? pList->nExpr : 0;    /* Number of arguments */ | 
| @@ -522,13 +687,13 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ | 
| FuncDef *pDef;              /* Information about the function */ | 
| u8 enc = ENC(pParse->db);   /* The database encoding */ | 
|  | 
| -      testcase( pExpr->op==TK_CONST_FUNC ); | 
| assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); | 
| +      notValidPartIdxWhere(pParse, pNC, "functions"); | 
| zId = pExpr->u.zToken; | 
| nId = sqlite3Strlen30(zId); | 
| pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0); | 
| if( pDef==0 ){ | 
| -        pDef = sqlite3FindFunction(pParse->db, zId, nId, -1, enc, 0); | 
| +        pDef = sqlite3FindFunction(pParse->db, zId, nId, -2, enc, 0); | 
| if( pDef==0 ){ | 
| no_such_func = 1; | 
| }else{ | 
| @@ -536,9 +701,29 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ | 
| } | 
| }else{ | 
| is_agg = pDef->xFunc==0; | 
| -      } | 
| +        if( pDef->funcFlags & SQLITE_FUNC_UNLIKELY ){ | 
| +          ExprSetProperty(pExpr, EP_Unlikely|EP_Skip); | 
| +          if( n==2 ){ | 
| +            pExpr->iTable = exprProbability(pList->a[1].pExpr); | 
| +            if( pExpr->iTable<0 ){ | 
| +              sqlite3ErrorMsg(pParse, "second argument to likelihood() must be a " | 
| +                                      "constant between 0.0 and 1.0"); | 
| +              pNC->nErr++; | 
| +            } | 
| +          }else{ | 
| +            /* EVIDENCE-OF: R-61304-29449 The unlikely(X) function is equivalent to | 
| +            ** likelihood(X, 0.0625). | 
| +            ** EVIDENCE-OF: R-01283-11636 The unlikely(X) function is short-hand for | 
| +            ** likelihood(X,0.0625). | 
| +            ** EVIDENCE-OF: R-36850-34127 The likely(X) function is short-hand for | 
| +            ** likelihood(X,0.9375). | 
| +            ** EVIDENCE-OF: R-53436-40973 The likely(X) function is equivalent to | 
| +            ** likelihood(X,0.9375). */ | 
| +            /* TUNING: unlikely() probability is 0.0625.  likely() is 0.9375 */ | 
| +            pExpr->iTable = pDef->zName[0]=='u' ? 62 : 938; | 
| +          } | 
| +        } | 
| #ifndef SQLITE_OMIT_AUTHORIZATION | 
| -      if( pDef ){ | 
| auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0, pDef->zName, 0); | 
| if( auth!=SQLITE_OK ){ | 
| if( auth==SQLITE_DENY ){ | 
| @@ -549,13 +734,14 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ | 
| pExpr->op = TK_NULL; | 
| return WRC_Prune; | 
| } | 
| -      } | 
| #endif | 
| -      if( is_agg && !pNC->allowAgg ){ | 
| +        if( pDef->funcFlags & SQLITE_FUNC_CONSTANT ) ExprSetProperty(pExpr,EP_Constant); | 
| +      } | 
| +      if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){ | 
| sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId); | 
| pNC->nErr++; | 
| is_agg = 0; | 
| -      }else if( no_such_func ){ | 
| +      }else if( no_such_func && pParse->db->init.busy==0 ){ | 
| sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId); | 
| pNC->nErr++; | 
| }else if( wrong_num_args ){ | 
| @@ -563,13 +749,25 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ | 
| nId, zId); | 
| pNC->nErr++; | 
| } | 
| +      if( is_agg ) pNC->ncFlags &= ~NC_AllowAgg; | 
| +      sqlite3WalkExprList(pWalker, pList); | 
| if( is_agg ){ | 
| +        NameContext *pNC2 = pNC; | 
| pExpr->op = TK_AGG_FUNCTION; | 
| -        pNC->hasAgg = 1; | 
| +        pExpr->op2 = 0; | 
| +        while( pNC2 && !sqlite3FunctionUsesThisSrc(pExpr, pNC2->pSrcList) ){ | 
| +          pExpr->op2++; | 
| +          pNC2 = pNC2->pNext; | 
| +        } | 
| +        assert( pDef!=0 ); | 
| +        if( pNC2 ){ | 
| +          assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg ); | 
| +          testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 ); | 
| +          pNC2->ncFlags |= NC_HasAgg | (pDef->funcFlags & SQLITE_FUNC_MINMAX); | 
| + | 
| +        } | 
| +        pNC->ncFlags |= NC_AllowAgg; | 
| } | 
| -      if( is_agg ) pNC->allowAgg = 0; | 
| -      sqlite3WalkExprList(pWalker, pList); | 
| -      if( is_agg ) pNC->allowAgg = 1; | 
| /* FIX ME:  Compute pExpr->affinity based on the expected return | 
| ** type of the function | 
| */ | 
| @@ -583,11 +781,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ | 
| testcase( pExpr->op==TK_IN ); | 
| if( ExprHasProperty(pExpr, EP_xIsSelect) ){ | 
| int nRef = pNC->nRef; | 
| -#ifndef SQLITE_OMIT_CHECK | 
| -        if( pNC->isCheck ){ | 
| -          sqlite3ErrorMsg(pParse,"subqueries prohibited in CHECK constraints"); | 
| -        } | 
| -#endif | 
| +        notValidCheckConstraint(pParse, pNC, "subqueries"); | 
| +        notValidPartIdxWhere(pParse, pNC, "subqueries"); | 
| sqlite3WalkSelect(pWalker, pExpr->x.pSelect); | 
| assert( pNC->nRef>=nRef ); | 
| if( nRef!=pNC->nRef ){ | 
| @@ -596,14 +791,11 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ | 
| } | 
| break; | 
| } | 
| -#ifndef SQLITE_OMIT_CHECK | 
| case TK_VARIABLE: { | 
| -      if( pNC->isCheck ){ | 
| -        sqlite3ErrorMsg(pParse,"parameters prohibited in CHECK constraints"); | 
| -      } | 
| +      notValidCheckConstraint(pParse, pNC, "parameters"); | 
| +      notValidPartIdxWhere(pParse, pNC, "parameters"); | 
| break; | 
| } | 
| -#endif | 
| } | 
| return (pParse->nErr || pParse->db->mallocFailed) ? WRC_Abort : WRC_Continue; | 
| } | 
| @@ -680,7 +872,7 @@ static int resolveOrderByTermToExprList( | 
| nc.pParse = pParse; | 
| nc.pSrcList = pSelect->pSrc; | 
| nc.pEList = pEList; | 
| -  nc.allowAgg = 1; | 
| +  nc.ncFlags = NC_AllowAgg; | 
| nc.nErr = 0; | 
| db = pParse->db; | 
| savedSuppErr = db->suppressErr; | 
| @@ -694,7 +886,7 @@ static int resolveOrderByTermToExprList( | 
| ** result-set entry. | 
| */ | 
| for(i=0; i<pEList->nExpr; i++){ | 
| -    if( sqlite3ExprCompare(pEList->a[i].pExpr, pE)<2 ){ | 
| +    if( sqlite3ExprCompare(pEList->a[i].pExpr, pE, -1)<2 ){ | 
| return i+1; | 
| } | 
| } | 
| @@ -768,7 +960,7 @@ static int resolveCompoundOrderBy( | 
| int iCol = -1; | 
| Expr *pE, *pDup; | 
| if( pItem->done ) continue; | 
| -      pE = pItem->pExpr; | 
| +      pE = sqlite3ExprSkipCollate(pItem->pExpr); | 
| if( sqlite3ExprIsInteger(pE, &iCol) ){ | 
| if( iCol<=0 || iCol>pEList->nExpr ){ | 
| resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr); | 
| @@ -786,15 +978,21 @@ static int resolveCompoundOrderBy( | 
| } | 
| } | 
| if( iCol>0 ){ | 
| -        CollSeq *pColl = pE->pColl; | 
| -        int flags = pE->flags & EP_ExpCollate; | 
| +        /* Convert the ORDER BY term into an integer column number iCol, | 
| +        ** taking care to preserve the COLLATE clause if it exists */ | 
| +        Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0); | 
| +        if( pNew==0 ) return 1; | 
| +        pNew->flags |= EP_IntValue; | 
| +        pNew->u.iValue = iCol; | 
| +        if( pItem->pExpr==pE ){ | 
| +          pItem->pExpr = pNew; | 
| +        }else{ | 
| +          assert( pItem->pExpr->op==TK_COLLATE ); | 
| +          assert( pItem->pExpr->pLeft==pE ); | 
| +          pItem->pExpr->pLeft = pNew; | 
| +        } | 
| sqlite3ExprDelete(db, pE); | 
| -        pItem->pExpr = pE = sqlite3Expr(db, TK_INTEGER, 0); | 
| -        if( pE==0 ) return 1; | 
| -        pE->pColl = pColl; | 
| -        pE->flags |= EP_IntValue | flags; | 
| -        pE->u.iValue = iCol; | 
| -        pItem->iCol = (u16)iCol; | 
| +        pItem->u.x.iOrderByCol = (u16)iCol; | 
| pItem->done = 1; | 
| }else{ | 
| moreToDo = 1; | 
| @@ -815,8 +1013,8 @@ static int resolveCompoundOrderBy( | 
| /* | 
| ** Check every term in the ORDER BY or GROUP BY clause pOrderBy of | 
| ** the SELECT statement pSelect.  If any term is reference to a | 
| -** result set expression (as determined by the ExprList.a.iCol field) | 
| -** then convert that term into a copy of the corresponding result set | 
| +** result set expression (as determined by the ExprList.a.u.x.iOrderByCol | 
| +** field) then convert that term into a copy of the corresponding result set | 
| ** column. | 
| ** | 
| ** If any errors are detected, add an error message to pParse and | 
| @@ -843,12 +1041,12 @@ int sqlite3ResolveOrderGroupBy( | 
| pEList = pSelect->pEList; | 
| assert( pEList!=0 );  /* sqlite3SelectNew() guarantees this */ | 
| for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){ | 
| -    if( pItem->iCol ){ | 
| -      if( pItem->iCol>pEList->nExpr ){ | 
| +    if( pItem->u.x.iOrderByCol ){ | 
| +      if( pItem->u.x.iOrderByCol>pEList->nExpr ){ | 
| resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr); | 
| return 1; | 
| } | 
| -      resolveAlias(pParse, pEList, pItem->iCol-1, pItem->pExpr, zType); | 
| +      resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr, zType,0); | 
| } | 
| } | 
| return 0; | 
| @@ -863,7 +1061,7 @@ int sqlite3ResolveOrderGroupBy( | 
| ** If the order-by term is an integer I between 1 and N (where N is the | 
| ** number of columns in the result set of the SELECT) then the expression | 
| ** in the resolution is a copy of the I-th result-set expression.  If | 
| -** the order-by term is an identify that corresponds to the AS-name of | 
| +** the order-by term is an identifier that corresponds to the AS-name of | 
| ** a result-set expression, then the term resolves to a copy of the | 
| ** result-set expression.  Otherwise, the expression is resolved in | 
| ** the usual way - using sqlite3ResolveExprNames(). | 
| @@ -878,7 +1076,7 @@ static int resolveOrderGroupBy( | 
| ExprList *pOrderBy,   /* An ORDER BY or GROUP BY clause to resolve */ | 
| const char *zType     /* Either "ORDER" or "GROUP", as appropriate */ | 
| ){ | 
| -  int i;                         /* Loop counter */ | 
| +  int i, j;                      /* Loop counters */ | 
| int iCol;                      /* Column number */ | 
| struct ExprList_item *pItem;   /* A term of the ORDER BY clause */ | 
| Parse *pParse;                 /* Parsing context */ | 
| @@ -889,38 +1087,46 @@ static int resolveOrderGroupBy( | 
| pParse = pNC->pParse; | 
| for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){ | 
| Expr *pE = pItem->pExpr; | 
| -    iCol = resolveAsName(pParse, pSelect->pEList, pE); | 
| -    if( iCol>0 ){ | 
| -      /* If an AS-name match is found, mark this ORDER BY column as being | 
| -      ** a copy of the iCol-th result-set column.  The subsequent call to | 
| -      ** sqlite3ResolveOrderGroupBy() will convert the expression to a | 
| -      ** copy of the iCol-th result-set expression. */ | 
| -      pItem->iCol = (u16)iCol; | 
| -      continue; | 
| +    Expr *pE2 = sqlite3ExprSkipCollate(pE); | 
| +    if( zType[0]!='G' ){ | 
| +      iCol = resolveAsName(pParse, pSelect->pEList, pE2); | 
| +      if( iCol>0 ){ | 
| +        /* If an AS-name match is found, mark this ORDER BY column as being | 
| +        ** a copy of the iCol-th result-set column.  The subsequent call to | 
| +        ** sqlite3ResolveOrderGroupBy() will convert the expression to a | 
| +        ** copy of the iCol-th result-set expression. */ | 
| +        pItem->u.x.iOrderByCol = (u16)iCol; | 
| +        continue; | 
| +      } | 
| } | 
| -    if( sqlite3ExprIsInteger(pE, &iCol) ){ | 
| +    if( sqlite3ExprIsInteger(pE2, &iCol) ){ | 
| /* The ORDER BY term is an integer constant.  Again, set the column | 
| ** number so that sqlite3ResolveOrderGroupBy() will convert the | 
| ** order-by term to a copy of the result-set expression */ | 
| -      if( iCol<1 ){ | 
| +      if( iCol<1 || iCol>0xffff ){ | 
| resolveOutOfRangeError(pParse, zType, i+1, nResult); | 
| return 1; | 
| } | 
| -      pItem->iCol = (u16)iCol; | 
| +      pItem->u.x.iOrderByCol = (u16)iCol; | 
| continue; | 
| } | 
|  | 
| /* Otherwise, treat the ORDER BY term as an ordinary expression */ | 
| -    pItem->iCol = 0; | 
| +    pItem->u.x.iOrderByCol = 0; | 
| if( sqlite3ResolveExprNames(pNC, pE) ){ | 
| return 1; | 
| } | 
| +    for(j=0; j<pSelect->pEList->nExpr; j++){ | 
| +      if( sqlite3ExprCompare(pE, pSelect->pEList->a[j].pExpr, -1)==0 ){ | 
| +        pItem->u.x.iOrderByCol = j+1; | 
| +      } | 
| +    } | 
| } | 
| return sqlite3ResolveOrderGroupBy(pParse, pSelect, pOrderBy, zType); | 
| } | 
|  | 
| /* | 
| -** Resolve names in the SELECT statement p and all of its descendents. | 
| +** Resolve names in the SELECT statement p and all of its descendants. | 
| */ | 
| static int resolveSelectStep(Walker *pWalker, Select *p){ | 
| NameContext *pOuterNC;  /* Context that contains this SELECT */ | 
| @@ -974,10 +1180,37 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ | 
| return WRC_Abort; | 
| } | 
|  | 
| +    /* Recursively resolve names in all subqueries | 
| +    */ | 
| +    for(i=0; i<p->pSrc->nSrc; i++){ | 
| +      struct SrcList_item *pItem = &p->pSrc->a[i]; | 
| +      if( pItem->pSelect ){ | 
| +        NameContext *pNC;         /* Used to iterate name contexts */ | 
| +        int nRef = 0;             /* Refcount for pOuterNC and outer contexts */ | 
| +        const char *zSavedContext = pParse->zAuthContext; | 
| + | 
| +        /* Count the total number of references to pOuterNC and all of its | 
| +        ** parent contexts. After resolving references to expressions in | 
| +        ** pItem->pSelect, check if this value has changed. If so, then | 
| +        ** SELECT statement pItem->pSelect must be correlated. Set the | 
| +        ** pItem->isCorrelated flag if this is the case. */ | 
| +        for(pNC=pOuterNC; pNC; pNC=pNC->pNext) nRef += pNC->nRef; | 
| + | 
| +        if( pItem->zName ) pParse->zAuthContext = pItem->zName; | 
| +        sqlite3ResolveSelectNames(pParse, pItem->pSelect, pOuterNC); | 
| +        pParse->zAuthContext = zSavedContext; | 
| +        if( pParse->nErr || db->mallocFailed ) return WRC_Abort; | 
| + | 
| +        for(pNC=pOuterNC; pNC; pNC=pNC->pNext) nRef -= pNC->nRef; | 
| +        assert( pItem->isCorrelated==0 && nRef<=0 ); | 
| +        pItem->isCorrelated = (nRef!=0); | 
| +      } | 
| +    } | 
| + | 
| /* Set up the local name-context to pass to sqlite3ResolveExprNames() to | 
| ** resolve the result-set expression list. | 
| */ | 
| -    sNC.allowAgg = 1; | 
| +    sNC.ncFlags = NC_AllowAgg; | 
| sNC.pSrcList = p->pSrc; | 
| sNC.pNext = pOuterNC; | 
|  | 
| @@ -991,28 +1224,16 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ | 
| } | 
| } | 
|  | 
| -    /* Recursively resolve names in all subqueries | 
| -    */ | 
| -    for(i=0; i<p->pSrc->nSrc; i++){ | 
| -      struct SrcList_item *pItem = &p->pSrc->a[i]; | 
| -      if( pItem->pSelect ){ | 
| -        const char *zSavedContext = pParse->zAuthContext; | 
| -        if( pItem->zName ) pParse->zAuthContext = pItem->zName; | 
| -        sqlite3ResolveSelectNames(pParse, pItem->pSelect, pOuterNC); | 
| -        pParse->zAuthContext = zSavedContext; | 
| -        if( pParse->nErr || db->mallocFailed ) return WRC_Abort; | 
| -      } | 
| -    } | 
| - | 
| /* If there are no aggregate functions in the result-set, and no GROUP BY | 
| ** expression, do not allow aggregates in any of the other expressions. | 
| */ | 
| assert( (p->selFlags & SF_Aggregate)==0 ); | 
| pGroupBy = p->pGroupBy; | 
| -    if( pGroupBy || sNC.hasAgg ){ | 
| -      p->selFlags |= SF_Aggregate; | 
| +    if( pGroupBy || (sNC.ncFlags & NC_HasAgg)!=0 ){ | 
| +      assert( NC_MinMaxAgg==SF_MinMaxAgg ); | 
| +      p->selFlags |= SF_Aggregate | (sNC.ncFlags&NC_MinMaxAgg); | 
| }else{ | 
| -      sNC.allowAgg = 0; | 
| +      sNC.ncFlags &= ~NC_AllowAgg; | 
| } | 
|  | 
| /* If a HAVING clause is present, then there must be a GROUP BY clause. | 
| @@ -1022,7 +1243,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ | 
| return WRC_Abort; | 
| } | 
|  | 
| -    /* Add the expression list to the name-context before parsing the | 
| +    /* Add the output column list to the name-context before parsing the | 
| ** other expressions in the SELECT statement. This is so that | 
| ** expressions in the WHERE clause (etc.) can refer to expressions by | 
| ** aliases in the result set. | 
| @@ -1031,17 +1252,14 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ | 
| ** re-evaluated for each reference to it. | 
| */ | 
| sNC.pEList = p->pEList; | 
| -    if( sqlite3ResolveExprNames(&sNC, p->pWhere) || | 
| -       sqlite3ResolveExprNames(&sNC, p->pHaving) | 
| -    ){ | 
| -      return WRC_Abort; | 
| -    } | 
| +    if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort; | 
| +    if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort; | 
|  | 
| /* The ORDER BY and GROUP BY clauses may not refer to terms in | 
| ** outer queries | 
| */ | 
| sNC.pNext = 0; | 
| -    sNC.allowAgg = 1; | 
| +    sNC.ncFlags |= NC_AllowAgg; | 
|  | 
| /* Process the ORDER BY clause for singleton SELECT statements. | 
| ** The ORDER BY clause for compounds SELECT statements is handled | 
| @@ -1129,7 +1347,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ | 
| ** | 
| ** Function calls are checked to make sure that the function is | 
| ** defined and that the correct number of arguments are specified. | 
| -** If the function is an aggregate function, then the pNC->hasAgg is | 
| +** If the function is an aggregate function, then the NC_HasAgg flag is | 
| ** set and the opcode is changed from TK_FUNCTION to TK_AGG_FUNCTION. | 
| ** If an expression contains aggregate functions then the EP_Agg | 
| ** property on the expression is set. | 
| @@ -1141,7 +1359,7 @@ int sqlite3ResolveExprNames( | 
| NameContext *pNC,       /* Namespace to resolve expressions in. */ | 
| Expr *pExpr             /* The expression to be analyzed. */ | 
| ){ | 
| -  int savedHasAgg; | 
| +  u16 savedHasAgg; | 
| Walker w; | 
|  | 
| if( pExpr==0 ) return 0; | 
| @@ -1154,8 +1372,9 @@ int sqlite3ResolveExprNames( | 
| pParse->nHeight += pExpr->nHeight; | 
| } | 
| #endif | 
| -  savedHasAgg = pNC->hasAgg; | 
| -  pNC->hasAgg = 0; | 
| +  savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg); | 
| +  pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg); | 
| +  memset(&w, 0, sizeof(w)); | 
| w.xExprCallback = resolveExprStep; | 
| w.xSelectCallback = resolveSelectStep; | 
| w.pParse = pNC->pParse; | 
| @@ -1167,11 +1386,10 @@ int sqlite3ResolveExprNames( | 
| if( pNC->nErr>0 || w.pParse->nErr>0 ){ | 
| ExprSetProperty(pExpr, EP_Error); | 
| } | 
| -  if( pNC->hasAgg ){ | 
| +  if( pNC->ncFlags & NC_HasAgg ){ | 
| ExprSetProperty(pExpr, EP_Agg); | 
| -  }else if( savedHasAgg ){ | 
| -    pNC->hasAgg = 1; | 
| } | 
| +  pNC->ncFlags |= savedHasAgg; | 
| return ExprHasProperty(pExpr, EP_Error); | 
| } | 
|  | 
| @@ -1196,9 +1414,52 @@ void sqlite3ResolveSelectNames( | 
| Walker w; | 
|  | 
| assert( p!=0 ); | 
| +  memset(&w, 0, sizeof(w)); | 
| w.xExprCallback = resolveExprStep; | 
| w.xSelectCallback = resolveSelectStep; | 
| w.pParse = pParse; | 
| w.u.pNC = pOuterNC; | 
| sqlite3WalkSelect(&w, p); | 
| } | 
| + | 
| +/* | 
| +** Resolve names in expressions that can only reference a single table: | 
| +** | 
| +**    *   CHECK constraints | 
| +**    *   WHERE clauses on partial indices | 
| +** | 
| +** The Expr.iTable value for Expr.op==TK_COLUMN nodes of the expression | 
| +** is set to -1 and the Expr.iColumn value is set to the column number. | 
| +** | 
| +** Any errors cause an error message to be set in pParse. | 
| +*/ | 
| +void sqlite3ResolveSelfReference( | 
| +  Parse *pParse,      /* Parsing context */ | 
| +  Table *pTab,        /* The table being referenced */ | 
| +  int type,           /* NC_IsCheck or NC_PartIdx */ | 
| +  Expr *pExpr,        /* Expression to resolve.  May be NULL. */ | 
| +  ExprList *pList     /* Expression list to resolve.  May be NUL. */ | 
| +){ | 
| +  SrcList sSrc;                   /* Fake SrcList for pParse->pNewTable */ | 
| +  NameContext sNC;                /* Name context for pParse->pNewTable */ | 
| +  int i;                          /* Loop counter */ | 
| + | 
| +  assert( type==NC_IsCheck || type==NC_PartIdx ); | 
| +  memset(&sNC, 0, sizeof(sNC)); | 
| +  memset(&sSrc, 0, sizeof(sSrc)); | 
| +  sSrc.nSrc = 1; | 
| +  sSrc.a[0].zName = pTab->zName; | 
| +  sSrc.a[0].pTab = pTab; | 
| +  sSrc.a[0].iCursor = -1; | 
| +  sNC.pParse = pParse; | 
| +  sNC.pSrcList = &sSrc; | 
| +  sNC.ncFlags = type; | 
| +  if( sqlite3ResolveExprNames(&sNC, pExpr) ) return; | 
| +  if( pList ){ | 
| +    for(i=0; i<pList->nExpr; i++){ | 
| +      if( sqlite3ResolveExprNames(&sNC, pList->a[i].pExpr) ){ | 
| +        return; | 
| +      } | 
| +    } | 
| +  } | 
| +} | 
|  |