Index: src/build.c ================================================================== --- src/build.c +++ src/build.c @@ -3160,14 +3160,15 @@ */ int sqlite3HasExplicitNulls(Parse *pParse, ExprList *pList){ if( pList ){ int i; for(i=0; inExpr; i++){ - if( pList->a[i].bNulls ){ - u8 sf = pList->a[i].sortFlags; + u8 sf = pList->a[i].sortFlags; + if( sf & (SQLITE_SO_BIGNULL|SQLITE_SO_SMALLNULL) ){ sqlite3ErrorMsg(pParse, "unsupported use of NULLS %s", - (sf==0 || sf==3) ? "FIRST" : "LAST" + (sf & SQLITE_SO_BIGNULL)==(sf & SQLITE_SO_DESC) ? + "FIRST" : "LAST" ); return 1; } } } @@ -3390,11 +3391,11 @@ sqlite3TokenInit(&prevCol, pCol->zName); pList = sqlite3ExprListAppend(pParse, 0, sqlite3ExprAlloc(db, TK_ID, &prevCol, 0)); if( pList==0 ) goto exit_create_index; assert( pList->nExpr==1 ); - sqlite3ExprListSetSortOrder(pList, sortOrder, SQLITE_SO_UNDEFINED); + sqlite3ExprListSetSortOrder(pList, sortOrder); }else{ sqlite3ExprListCheckLength(pParse, pList, "index"); if( pParse->nErr ) goto exit_create_index; } Index: src/expr.c ================================================================== --- src/expr.c +++ src/expr.c @@ -1411,11 +1411,10 @@ } pItem->zName = sqlite3DbStrDup(db, pOldItem->zName); pItem->zSpan = sqlite3DbStrDup(db, pOldItem->zSpan); pItem->sortFlags = pOldItem->sortFlags; pItem->done = 0; - pItem->bNulls = pOldItem->bNulls; pItem->bSpanIsTab = pOldItem->bSpanIsTab; pItem->bSorterRef = pOldItem->bSorterRef; pItem->u = pOldItem->u; } return pNew; @@ -1663,38 +1662,19 @@ } /* ** Set the sort order for the last element on the given ExprList. */ -void sqlite3ExprListSetSortOrder(ExprList *p, int iSortOrder, int eNulls){ +void sqlite3ExprListSetSortOrder(ExprList *p, int iSortOrder){ struct ExprList_item *pItem; if( p==0 ) return; assert( p->nExpr>0 ); - - assert( SQLITE_SO_UNDEFINED<0 && SQLITE_SO_ASC==0 && SQLITE_SO_DESC>0 ); - assert( iSortOrder==SQLITE_SO_UNDEFINED - || iSortOrder==SQLITE_SO_ASC - || iSortOrder==SQLITE_SO_DESC - ); - assert( eNulls==SQLITE_SO_UNDEFINED - || eNulls==SQLITE_SO_ASC - || eNulls==SQLITE_SO_DESC - ); + assert( SQLITE_SO_DESC==KEYINFO_ORDER_DESC ); + assert( SQLITE_SO_BIGNULL==KEYINFO_ORDER_BIGNULL ); pItem = &p->a[p->nExpr-1]; - assert( pItem->bNulls==0 ); - if( iSortOrder==SQLITE_SO_UNDEFINED ){ - iSortOrder = SQLITE_SO_ASC; - } pItem->sortFlags = (u8)iSortOrder; - - if( eNulls!=SQLITE_SO_UNDEFINED ){ - pItem->bNulls = 1; - if( iSortOrder!=eNulls ){ - pItem->sortFlags |= KEYINFO_ORDER_BIGNULL; - } - } } /* ** Set the ExprList.a[].zName element of the most recently added item ** on the expression list. Index: src/parse.y ================================================================== --- src/parse.y +++ src/parse.y @@ -780,29 +780,30 @@ %type sortlist {ExprList*} %destructor sortlist {sqlite3ExprListDelete(pParse->db, $$);} orderby_opt(A) ::= . {A = 0;} orderby_opt(A) ::= ORDER BY sortlist(X). {A = X;} -sortlist(A) ::= sortlist(A) COMMA expr(Y) sortorder(Z) nulls(X). { +sortlist(A) ::= sortlist(A) COMMA expr(Y) sortorder(Z). { A = sqlite3ExprListAppend(pParse,A,Y); - sqlite3ExprListSetSortOrder(A,Z,X); + sqlite3ExprListSetSortOrder(A,Z); } -sortlist(A) ::= expr(Y) sortorder(Z) nulls(X). { +sortlist(A) ::= expr(Y) sortorder(Z). { A = sqlite3ExprListAppend(pParse,0,Y); /*A-overwrites-Y*/ - sqlite3ExprListSetSortOrder(A,Z,X); + sqlite3ExprListSetSortOrder(A,Z); } %type sortorder {int} -sortorder(A) ::= ASC. {A = SQLITE_SO_ASC;} -sortorder(A) ::= DESC. {A = SQLITE_SO_DESC;} -sortorder(A) ::= . {A = SQLITE_SO_UNDEFINED;} - -%type nulls {int} -nulls(A) ::= NULLS FIRST. {A = SQLITE_SO_ASC;} -nulls(A) ::= NULLS LAST. {A = SQLITE_SO_DESC;} -nulls(A) ::= . {A = SQLITE_SO_UNDEFINED;} +sortorder(A) ::= ASC. {A = SQLITE_SO_XASC;} +sortorder(A) ::= ASC NULLS FIRST. {A = SQLITE_SO_XASC|SQLITE_SO_SMALLNULL;} +sortorder(A) ::= ASC NULLS LAST. {A = SQLITE_SO_XASC|SQLITE_SO_BIGNULL;} +sortorder(A) ::= DESC. {A = SQLITE_SO_DESC;} +sortorder(A) ::= DESC NULLS FIRST. {A = SQLITE_SO_DESC|SQLITE_SO_BIGNULL;} +sortorder(A) ::= DESC NULLS LAST. {A = SQLITE_SO_DESC|SQLITE_SO_SMALLNULL;} +sortorder(A) ::= . {A = SQLITE_SO_ASC;} +sortorder(A) ::= NULLS FIRST. {A = SQLITE_SO_XASC|SQLITE_SO_SMALLNULL;} +sortorder(A) ::= NULLS LAST. {A = SQLITE_SO_XASC|SQLITE_SO_BIGNULL;} %type groupby_opt {ExprList*} %destructor groupby_opt {sqlite3ExprListDelete(pParse->db, $$);} groupby_opt(A) ::= . {A = 0;} groupby_opt(A) ::= GROUP BY nexprlist(X). {A = X;} @@ -1345,11 +1346,11 @@ Token *pIdToken, int hasCollate, int sortOrder ){ ExprList *p = sqlite3ExprListAppend(pParse, pPrior, 0); - if( (hasCollate || sortOrder!=SQLITE_SO_UNDEFINED) + if( (hasCollate || sortOrder!=SQLITE_SO_ASC) && pParse->db->init.busy==0 ){ sqlite3ErrorMsg(pParse, "syntax error after column name \"%.*s\"", pIdToken->n, pIdToken->z); } Index: src/sqliteInt.h ================================================================== --- src/sqliteInt.h +++ src/sqliteInt.h @@ -1845,13 +1845,15 @@ }; /* ** A sort order can be either ASC or DESC. */ -#define SQLITE_SO_ASC 0 /* Sort in ascending order */ -#define SQLITE_SO_DESC 1 /* Sort in ascending order */ -#define SQLITE_SO_UNDEFINED -1 /* No sort order specified */ +#define SQLITE_SO_ASC 0 /* Sort in ascending order by default */ +#define SQLITE_SO_DESC 1 /* Sort in descending order */ +#define SQLITE_SO_BIGNULL 2 /* NULLs larger than all other values */ +#define SQLITE_SO_SMALLNULL 4 /* NULLs smaller, explicitly stated */ +#define SQLITE_SO_XASC 8 /* Actually holds the ASC keyword */ /* ** Column affinity types. ** ** These used to have mnemonic name like 'i' for SQLITE_AFF_INTEGER and @@ -2608,11 +2610,10 @@ u8 sortFlags; /* Mask of KEYINFO_ORDER_* flags */ unsigned done :1; /* A flag to indicate when processing is finished */ unsigned bSpanIsTab :1; /* zSpan holds DB.TABLE.COLUMN */ unsigned reusable :1; /* Constant expression is reusable */ unsigned bSorterRef :1; /* Defer evaluation until after sorting */ - unsigned bNulls: 1; /* True if explicit "NULLS FIRST/LAST" */ union { struct { u16 iOrderByCol; /* For ORDER BY, column number in result set */ u16 iAlias; /* Index into Parse.aAlias[] for zName */ } x; @@ -3889,11 +3890,11 @@ void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32); void sqlite3ExprDelete(sqlite3*, Expr*); void sqlite3ExprUnmapAndDelete(Parse*, Expr*); ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*); ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*); -void sqlite3ExprListSetSortOrder(ExprList*,int,int); +void sqlite3ExprListSetSortOrder(ExprList*,int); void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int); void sqlite3ExprListSetSpan(Parse*,ExprList*,const char*,const char*); void sqlite3ExprListDelete(sqlite3*, ExprList*); u32 sqlite3ExprListFlags(const ExprList*); int sqlite3IndexHasDuplicateRootPage(Index*);