Index: src/expr.c ================================================================== --- src/expr.c +++ src/expr.c @@ -1281,11 +1281,12 @@ int i; u32 m = 0; if( pList ){ for(i=0; inExpr; i++){ Expr *pExpr = pList->a[i].pExpr; - if( ALWAYS(pExpr) ) m |= pExpr->flags; + assert( pExpr!=0 ); + m |= pExpr->flags; } } return m; } Index: src/parse.y ================================================================== --- src/parse.y +++ src/parse.y @@ -548,17 +548,17 @@ A = sqlite3ExprListAppend(pParse, A, X.pExpr); if( Y.n>0 ) sqlite3ExprListSetName(pParse, A, &Y, 1); sqlite3ExprListSetSpan(pParse,A,&X); } selcollist(A) ::= sclp(A) STAR. { - Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0); - A = sqlite3ExprListAppend(pParse, A, p); + A = sqlite3WildcardResultSet(pParse,A); } selcollist(A) ::= sclp(A) nm(X) DOT STAR(Y). { Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0, &Y); Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, &X); Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0); + if( pDot ) ExprSetProperty(pDot, EP_Wildcard); A = sqlite3ExprListAppend(pParse,A, pDot); } // An option "AS " phrase that can follow one of the expressions that // define the result set, or one of the tables in the FROM clause. Index: src/select.c ================================================================== --- src/select.c +++ src/select.c @@ -90,10 +90,20 @@ pDest->affSdst = 0; pDest->iSdst = 0; pDest->nSdst = 0; } +/* +** Return an expression list that represents the wildcard result set +** of a SELECT. +*/ +ExprList *sqlite3WildcardResultSet(Parse *pParse, ExprList *pPrior){ + Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0); + if( p ) ExprSetProperty(p, EP_Wildcard); + return sqlite3ExprListAppend(pParse, pPrior, p); +} + /* ** Allocate a new Select structure and return a pointer to that ** structure. */ @@ -115,13 +125,11 @@ pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) ); if( pNew==0 ){ assert( db->mallocFailed ); pNew = &standin; } - if( pEList==0 ){ - pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ASTERISK,0)); - } + if( pEList==0 ) pEList = sqlite3WildcardResultSet(pParse,0); pNew->pEList = pEList; pNew->op = TK_SELECT; pNew->selFlags = selFlags; pNew->iLimit = 0; pNew->iOffset = 0; @@ -3950,11 +3958,11 @@ memset(&dummy, 0, sizeof(dummy)); pNewSrc = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&dummy,pNew,0,0); if( pNewSrc==0 ) return WRC_Abort; *pNew = *p; p->pSrc = pNewSrc; - p->pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ASTERISK, 0)); + p->pEList = sqlite3WildcardResultSet(pParse,0); p->op = TK_SELECT; p->pWhere = 0; pNew->pGroupBy = 0; pNew->pHaving = 0; pNew->pOrderBy = 0; @@ -4308,22 +4316,12 @@ ** of all columns in TABLE. The parser inserted a special expression ** with the TK_ASTERISK operator for each "*" that it found in the column ** list. The following code just has to locate the TK_ASTERISK ** expressions and expand each one to the list of all columns in ** all tables. - ** - ** The first loop just checks to see if there are any "*" operators - ** that need expanding. */ - for(k=0; knExpr; k++){ - pE = pEList->a[k].pExpr; - if( pE->op==TK_ASTERISK ) break; - assert( pE->op!=TK_DOT || pE->pRight!=0 ); - assert( pE->op!=TK_DOT || (pE->pLeft!=0 && pE->pLeft->op==TK_ID) ); - if( pE->op==TK_DOT && pE->pRight->op==TK_ASTERISK ) break; - } - if( knExpr ){ + if( sqlite3ExprListFlags(pEList) & EP_Wildcard ){ /* ** If we get here it means the result set contains one or more "*" ** operators that need to be expanded. Loop through each expression ** in the result set and expand them one by one. */ @@ -4335,13 +4333,11 @@ for(k=0; knExpr; k++){ pE = a[k].pExpr; pRight = pE->pRight; assert( pE->op!=TK_DOT || pRight!=0 ); - if( pE->op!=TK_ASTERISK - && (pE->op!=TK_DOT || pRight->op!=TK_ASTERISK) - ){ + if( !ExprHasProperty(pE, EP_Wildcard) ){ /* This particular expression does not need to be expanded. */ pNew = sqlite3ExprListAppend(pParse, pNew, a[k].pExpr); if( pNew ){ pNew->a[pNew->nExpr-1].zName = a[k].zName; Index: src/sqliteInt.h ================================================================== --- src/sqliteInt.h +++ src/sqliteInt.h @@ -2255,10 +2255,11 @@ #define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */ #define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */ #define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */ #define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */ #define EP_Alias 0x400000 /* Is an alias for a result set column */ +#define EP_Wildcard 0x800000 /* The "*" or "TABLE.*" of a SELECT result */ /* ** Combinations of two or more EP_* flags */ #define EP_Propagate (EP_Collate|EP_Subquery) /* Propagate these bits up tree */ @@ -3525,10 +3526,11 @@ void sqlite3SrcListDelete(sqlite3*, SrcList*); Index *sqlite3AllocateIndexObject(sqlite3*,i16,int,char**); Index *sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*, Expr*, int, int); void sqlite3DropIndex(Parse*, SrcList*, int); +ExprList *sqlite3WildcardResultSet(Parse*,ExprList*); int sqlite3Select(Parse*, Select*, SelectDest*); Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*, Expr*,ExprList*,u32,Expr*,Expr*); void sqlite3SelectDelete(sqlite3*, Select*); Table *sqlite3SrcListLookup(Parse*, SrcList*);