mirror of
https://github.com/sqlite/sqlite.git
synced 2026-01-06 08:01:16 +03:00
Organize the various flag bits of the ExprList_item object into a substructure
so that the whole lot can be copied all at once. Faster and smaller code. FossilOrigin-Name: 5341d4bbe9a943f9cdbbdea829e18f108e98972ebb706396c50fc62fcc6a6328
This commit is contained in:
@@ -880,7 +880,7 @@ static int renameUnmapSelectCb(Walker *pWalker, Select *p){
|
||||
if( ALWAYS(p->pEList) ){
|
||||
ExprList *pList = p->pEList;
|
||||
for(i=0; i<pList->nExpr; i++){
|
||||
if( pList->a[i].zEName && pList->a[i].eEName==ENAME_NAME ){
|
||||
if( pList->a[i].zEName && pList->a[i].fg.eEName==ENAME_NAME ){
|
||||
sqlite3RenameTokenRemap(pParse, 0, (void*)pList->a[i].zEName);
|
||||
}
|
||||
}
|
||||
@@ -929,7 +929,7 @@ void sqlite3RenameExprlistUnmap(Parse *pParse, ExprList *pEList){
|
||||
sWalker.xExprCallback = renameUnmapExprCb;
|
||||
sqlite3WalkExprList(&sWalker, pEList);
|
||||
for(i=0; i<pEList->nExpr; i++){
|
||||
if( ALWAYS(pEList->a[i].eEName==ENAME_NAME) ){
|
||||
if( ALWAYS(pEList->a[i].fg.eEName==ENAME_NAME) ){
|
||||
sqlite3RenameTokenRemap(pParse, 0, (void*)pEList->a[i].zEName);
|
||||
}
|
||||
}
|
||||
@@ -1087,7 +1087,7 @@ static void renameColumnElistNames(
|
||||
int i;
|
||||
for(i=0; i<pEList->nExpr; i++){
|
||||
const char *zName = pEList->a[i].zEName;
|
||||
if( ALWAYS(pEList->a[i].eEName==ENAME_NAME)
|
||||
if( ALWAYS(pEList->a[i].fg.eEName==ENAME_NAME)
|
||||
&& ALWAYS(zName!=0)
|
||||
&& 0==sqlite3_stricmp(zName, zOld)
|
||||
){
|
||||
|
||||
10
src/build.c
10
src/build.c
@@ -1890,7 +1890,7 @@ void sqlite3AddPrimaryKey(
|
||||
pTab->keyConf = (u8)onError;
|
||||
assert( autoInc==0 || autoInc==1 );
|
||||
pTab->tabFlags |= autoInc*TF_Autoincrement;
|
||||
if( pList ) pParse->iPkSortOrder = pList->a[0].sortFlags;
|
||||
if( pList ) pParse->iPkSortOrder = pList->a[0].fg.sortFlags;
|
||||
(void)sqlite3HasExplicitNulls(pParse, pList);
|
||||
}else if( autoInc ){
|
||||
#ifndef SQLITE_OMIT_AUTOINCREMENT
|
||||
@@ -2384,7 +2384,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
|
||||
if( IN_RENAME_OBJECT ){
|
||||
sqlite3RenameTokenRemap(pParse, pList->a[0].pExpr, &pTab->iPKey);
|
||||
}
|
||||
pList->a[0].sortFlags = pParse->iPkSortOrder;
|
||||
pList->a[0].fg.sortFlags = pParse->iPkSortOrder;
|
||||
assert( pParse->pNewTable==pTab );
|
||||
pTab->iPKey = -1;
|
||||
sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0,
|
||||
@@ -3872,8 +3872,8 @@ int sqlite3HasExplicitNulls(Parse *pParse, ExprList *pList){
|
||||
if( pList ){
|
||||
int i;
|
||||
for(i=0; i<pList->nExpr; i++){
|
||||
if( pList->a[i].bNulls ){
|
||||
u8 sf = pList->a[i].sortFlags;
|
||||
if( pList->a[i].fg.bNulls ){
|
||||
u8 sf = pList->a[i].fg.sortFlags;
|
||||
sqlite3ErrorMsg(pParse, "unsupported use of NULLS %s",
|
||||
(sf==0 || sf==3) ? "FIRST" : "LAST"
|
||||
);
|
||||
@@ -4226,7 +4226,7 @@ void sqlite3CreateIndex(
|
||||
goto exit_create_index;
|
||||
}
|
||||
pIndex->azColl[i] = zColl;
|
||||
requestedSortOrder = pListItem->sortFlags & sortOrderMask;
|
||||
requestedSortOrder = pListItem->fg.sortFlags & sortOrderMask;
|
||||
pIndex->aSortOrder[i] = (u8)requestedSortOrder;
|
||||
}
|
||||
|
||||
|
||||
32
src/expr.c
32
src/expr.c
@@ -1628,14 +1628,8 @@ ExprList *sqlite3ExprListDup(sqlite3 *db, const ExprList *p, int flags){
|
||||
}
|
||||
}
|
||||
pItem->zEName = sqlite3DbStrDup(db, pOldItem->zEName);
|
||||
pItem->sortFlags = pOldItem->sortFlags;
|
||||
pItem->eEName = pOldItem->eEName;
|
||||
pItem->done = 0;
|
||||
pItem->bNulls = pOldItem->bNulls;
|
||||
pItem->bUsed = pOldItem->bUsed;
|
||||
pItem->bUsingTerm = pOldItem->bUsingTerm;
|
||||
pItem->bSorterRef = pOldItem->bSorterRef;
|
||||
pItem->bNoExpand = pOldItem->bNoExpand;
|
||||
pItem->fg = pOldItem->fg;
|
||||
pItem->fg.done = 0;
|
||||
pItem->u = pOldItem->u;
|
||||
}
|
||||
return pNew;
|
||||
@@ -1935,16 +1929,16 @@ void sqlite3ExprListSetSortOrder(ExprList *p, int iSortOrder, int eNulls){
|
||||
);
|
||||
|
||||
pItem = &p->a[p->nExpr-1];
|
||||
assert( pItem->bNulls==0 );
|
||||
assert( pItem->fg.bNulls==0 );
|
||||
if( iSortOrder==SQLITE_SO_UNDEFINED ){
|
||||
iSortOrder = SQLITE_SO_ASC;
|
||||
}
|
||||
pItem->sortFlags = (u8)iSortOrder;
|
||||
pItem->fg.sortFlags = (u8)iSortOrder;
|
||||
|
||||
if( eNulls!=SQLITE_SO_UNDEFINED ){
|
||||
pItem->bNulls = 1;
|
||||
pItem->fg.bNulls = 1;
|
||||
if( iSortOrder!=eNulls ){
|
||||
pItem->sortFlags |= KEYINFO_ORDER_BIGNULL;
|
||||
pItem->fg.sortFlags |= KEYINFO_ORDER_BIGNULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1970,7 +1964,7 @@ void sqlite3ExprListSetName(
|
||||
assert( pList->nExpr>0 );
|
||||
pItem = &pList->a[pList->nExpr-1];
|
||||
assert( pItem->zEName==0 );
|
||||
assert( pItem->eEName==ENAME_NAME );
|
||||
assert( pItem->fg.eEName==ENAME_NAME );
|
||||
pItem->zEName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n);
|
||||
if( dequote ){
|
||||
/* If dequote==0, then pName->z does not point to part of a DDL
|
||||
@@ -2005,7 +1999,7 @@ void sqlite3ExprListSetSpan(
|
||||
assert( pList->nExpr>0 );
|
||||
if( pItem->zEName==0 ){
|
||||
pItem->zEName = sqlite3DbSpanDup(db, zStart, zEnd);
|
||||
pItem->eEName = ENAME_SPAN;
|
||||
pItem->fg.eEName = ENAME_SPAN;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4831,7 +4825,9 @@ int sqlite3ExprCodeRunJustOnce(
|
||||
struct ExprList_item *pItem;
|
||||
int i;
|
||||
for(pItem=p->a, i=p->nExpr; i>0; pItem++, i--){
|
||||
if( pItem->reusable && sqlite3ExprCompare(0,pItem->pExpr,pExpr,-1)==0 ){
|
||||
if( pItem->fg.reusable
|
||||
&& sqlite3ExprCompare(0,pItem->pExpr,pExpr,-1)==0
|
||||
){
|
||||
return pItem->u.iConstExprReg;
|
||||
}
|
||||
}
|
||||
@@ -4854,7 +4850,7 @@ int sqlite3ExprCodeRunJustOnce(
|
||||
p = sqlite3ExprListAppend(pParse, p, pExpr);
|
||||
if( p ){
|
||||
struct ExprList_item *pItem = &p->a[p->nExpr-1];
|
||||
pItem->reusable = regDest<0;
|
||||
pItem->fg.reusable = regDest<0;
|
||||
if( regDest<0 ) regDest = ++pParse->nMem;
|
||||
pItem->u.iConstExprReg = regDest;
|
||||
}
|
||||
@@ -4988,7 +4984,7 @@ int sqlite3ExprCodeExprList(
|
||||
for(pItem=pList->a, i=0; i<n; i++, pItem++){
|
||||
Expr *pExpr = pItem->pExpr;
|
||||
#ifdef SQLITE_ENABLE_SORTER_REFERENCES
|
||||
if( pItem->bSorterRef ){
|
||||
if( pItem->fg.bSorterRef ){
|
||||
i--;
|
||||
n--;
|
||||
}else
|
||||
@@ -5613,7 +5609,7 @@ int sqlite3ExprListCompare(const ExprList *pA, const ExprList *pB, int iTab){
|
||||
int res;
|
||||
Expr *pExprA = pA->a[i].pExpr;
|
||||
Expr *pExprB = pB->a[i].pExpr;
|
||||
if( pA->a[i].sortFlags!=pB->a[i].sortFlags ) return 1;
|
||||
if( pA->a[i].fg.sortFlags!=pB->a[i].fg.sortFlags ) return 1;
|
||||
if( (res = sqlite3ExprCompare(0, pExprA, pExprB, iTab)) ) return res;
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -130,7 +130,7 @@ int sqlite3MatchEName(
|
||||
){
|
||||
int n;
|
||||
const char *zSpan;
|
||||
if( pItem->eEName!=ENAME_TAB ) return 0;
|
||||
if( pItem->fg.eEName!=ENAME_TAB ) return 0;
|
||||
zSpan = pItem->zEName;
|
||||
for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){}
|
||||
if( zDb && (sqlite3StrNICmp(zSpan, zDb, n)!=0 || zDb[n]!=0) ){
|
||||
@@ -359,9 +359,9 @@ static int lookupName(
|
||||
cntTab = 2;
|
||||
pMatch = pItem;
|
||||
pExpr->iColumn = j;
|
||||
pEList->a[j].bUsed = 1;
|
||||
pEList->a[j].fg.bUsed = 1;
|
||||
hit = 1;
|
||||
if( pEList->a[j].bUsingTerm ) break;
|
||||
if( pEList->a[j].fg.bUsingTerm ) break;
|
||||
}
|
||||
if( hit || zTab==0 ) continue;
|
||||
}
|
||||
@@ -584,7 +584,7 @@ static int lookupName(
|
||||
assert( pEList!=0 );
|
||||
for(j=0; j<pEList->nExpr; j++){
|
||||
char *zAs = pEList->a[j].zEName;
|
||||
if( pEList->a[j].eEName==ENAME_NAME
|
||||
if( pEList->a[j].fg.eEName==ENAME_NAME
|
||||
&& sqlite3_stricmp(zAs, zCol)==0
|
||||
){
|
||||
Expr *pOrig;
|
||||
@@ -1337,7 +1337,7 @@ static int resolveAsName(
|
||||
assert( !ExprHasProperty(pE, EP_IntValue) );
|
||||
zCol = pE->u.zToken;
|
||||
for(i=0; i<pEList->nExpr; i++){
|
||||
if( pEList->a[i].eEName==ENAME_NAME
|
||||
if( pEList->a[i].fg.eEName==ENAME_NAME
|
||||
&& sqlite3_stricmp(pEList->a[i].zEName, zCol)==0
|
||||
){
|
||||
return i+1;
|
||||
@@ -1458,7 +1458,7 @@ static int resolveCompoundOrderBy(
|
||||
return 1;
|
||||
}
|
||||
for(i=0; i<pOrderBy->nExpr; i++){
|
||||
pOrderBy->a[i].done = 0;
|
||||
pOrderBy->a[i].fg.done = 0;
|
||||
}
|
||||
pSelect->pNext = 0;
|
||||
while( pSelect->pPrior ){
|
||||
@@ -1473,7 +1473,7 @@ static int resolveCompoundOrderBy(
|
||||
for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
|
||||
int iCol = -1;
|
||||
Expr *pE, *pDup;
|
||||
if( pItem->done ) continue;
|
||||
if( pItem->fg.done ) continue;
|
||||
pE = sqlite3ExprSkipCollateAndLikely(pItem->pExpr);
|
||||
if( NEVER(pE==0) ) continue;
|
||||
if( sqlite3ExprIsInteger(pE, &iCol) ){
|
||||
@@ -1526,7 +1526,7 @@ static int resolveCompoundOrderBy(
|
||||
sqlite3ExprDelete(db, pE);
|
||||
pItem->u.x.iOrderByCol = (u16)iCol;
|
||||
}
|
||||
pItem->done = 1;
|
||||
pItem->fg.done = 1;
|
||||
}else{
|
||||
moreToDo = 1;
|
||||
}
|
||||
@@ -1534,7 +1534,7 @@ static int resolveCompoundOrderBy(
|
||||
pSelect = pSelect->pNext;
|
||||
}
|
||||
for(i=0; i<pOrderBy->nExpr; i++){
|
||||
if( pOrderBy->a[i].done==0 ){
|
||||
if( pOrderBy->a[i].fg.done==0 ){
|
||||
sqlite3ErrorMsg(pParse, "%r ORDER BY term does not match any "
|
||||
"column in the result set", i+1);
|
||||
return 1;
|
||||
|
||||
49
src/select.c
49
src/select.c
@@ -331,7 +331,7 @@ void sqlite3SrcItemColumnUsed(SrcItem *pItem, int iCol){
|
||||
pResults = pItem->pSelect->pEList;
|
||||
assert( pResults!=0 );
|
||||
assert( iCol>=0 && iCol<pResults->nExpr );
|
||||
pResults->a[iCol].bUsed = 1;
|
||||
pResults->a[iCol].fg.bUsed = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -999,7 +999,7 @@ static void fixDistinctOpenEph(
|
||||
** retrieved directly from table t1. If the values are very large, this
|
||||
** can be more efficient than storing them directly in the sorter records.
|
||||
**
|
||||
** The ExprList_item.bSorterRef flag is set for each expression in pEList
|
||||
** The ExprList_item.fg.fg.bSorterRef flag is set for each expression in pEList
|
||||
** for which the sorter-reference optimization should be enabled.
|
||||
** Additionally, the pSort->aDefer[] array is populated with entries
|
||||
** for all cursors required to evaluate all selected expressions. Finally.
|
||||
@@ -1059,7 +1059,7 @@ static void selectExprDefer(
|
||||
nDefer++;
|
||||
}
|
||||
}
|
||||
pItem->bSorterRef = 1;
|
||||
pItem->fg.bSorterRef = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1190,7 +1190,7 @@ static void selectInnerLoop(
|
||||
for(i=0; i<pEList->nExpr; i++){
|
||||
if( pEList->a[i].u.x.iOrderByCol>0
|
||||
#ifdef SQLITE_ENABLE_SORTER_REFERENCES
|
||||
|| pEList->a[i].bSorterRef
|
||||
|| pEList->a[i].fg.bSorterRef
|
||||
#endif
|
||||
){
|
||||
nResultCol--;
|
||||
@@ -1552,7 +1552,7 @@ KeyInfo *sqlite3KeyInfoFromExprList(
|
||||
assert( sqlite3KeyInfoIsWriteable(pInfo) );
|
||||
for(i=iStart, pItem=pList->a+iStart; i<nExpr; i++, pItem++){
|
||||
pInfo->aColl[i-iStart] = sqlite3ExprNNCollSeq(pParse, pItem->pExpr);
|
||||
pInfo->aSortFlags[i-iStart] = pItem->sortFlags;
|
||||
pInfo->aSortFlags[i-iStart] = pItem->fg.sortFlags;
|
||||
}
|
||||
}
|
||||
return pInfo;
|
||||
@@ -1691,7 +1691,7 @@ static void generateSortTail(
|
||||
}
|
||||
for(i=0, iCol=nKey+bSeq-1; i<nColumn; i++){
|
||||
#ifdef SQLITE_ENABLE_SORTER_REFERENCES
|
||||
if( aOutEx[i].bSorterRef ) continue;
|
||||
if( aOutEx[i].fg.bSorterRef ) continue;
|
||||
#endif
|
||||
if( aOutEx[i].u.x.iOrderByCol==0 ) iCol++;
|
||||
}
|
||||
@@ -1728,7 +1728,7 @@ static void generateSortTail(
|
||||
#endif
|
||||
for(i=nColumn-1; i>=0; i--){
|
||||
#ifdef SQLITE_ENABLE_SORTER_REFERENCES
|
||||
if( aOutEx[i].bSorterRef ){
|
||||
if( aOutEx[i].fg.bSorterRef ){
|
||||
sqlite3ExprCode(pParse, aOutEx[i].pExpr, regRow+i);
|
||||
}else
|
||||
#endif
|
||||
@@ -2094,7 +2094,7 @@ void sqlite3GenerateColumnNames(
|
||||
assert( p->op!=TK_AGG_COLUMN ); /* Agg processing has not run yet */
|
||||
assert( p->op!=TK_COLUMN
|
||||
|| (ExprUseYTab(p) && p->y.pTab!=0) ); /* Covering idx not yet coded */
|
||||
if( pEList->a[i].zEName && pEList->a[i].eEName==ENAME_NAME ){
|
||||
if( pEList->a[i].zEName && pEList->a[i].fg.eEName==ENAME_NAME ){
|
||||
/* An AS clause always takes first priority */
|
||||
char *zName = pEList->a[i].zEName;
|
||||
sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT);
|
||||
@@ -2183,7 +2183,7 @@ int sqlite3ColumnsFromExprList(
|
||||
struct ExprList_item *pCollide;
|
||||
/* Get an appropriate name for the column
|
||||
*/
|
||||
if( (zName = pX->zEName)!=0 && pX->eEName==ENAME_NAME ){
|
||||
if( (zName = pX->zEName)!=0 && pX->fg.eEName==ENAME_NAME ){
|
||||
/* If the column contains an "AS <name>" phrase, use <name> as the name */
|
||||
}else{
|
||||
Expr *pColExpr = sqlite3ExprSkipCollateAndLikely(pX->pExpr);
|
||||
@@ -2218,7 +2218,7 @@ int sqlite3ColumnsFromExprList(
|
||||
*/
|
||||
cnt = 0;
|
||||
while( zName && (pCollide = sqlite3HashFind(&ht, zName))!=0 ){
|
||||
if( pCollide->bUsingTerm ){
|
||||
if( pCollide->fg.bUsingTerm ){
|
||||
pCol->colFlags |= COLFLAG_NOEXPAND;
|
||||
}
|
||||
nName = sqlite3Strlen30(zName);
|
||||
@@ -2231,7 +2231,7 @@ int sqlite3ColumnsFromExprList(
|
||||
}
|
||||
pCol->zCnName = zName;
|
||||
pCol->hName = sqlite3StrIHash(zName);
|
||||
if( pX->bNoExpand ){
|
||||
if( pX->fg.bNoExpand ){
|
||||
pCol->colFlags |= COLFLAG_NOEXPAND;
|
||||
}
|
||||
sqlite3ColumnPropertiesFromName(0, pCol);
|
||||
@@ -2492,7 +2492,7 @@ static KeyInfo *multiSelectOrderByKeyInfo(Parse *pParse, Select *p, int nExtra){
|
||||
}
|
||||
assert( sqlite3KeyInfoIsWriteable(pRet) );
|
||||
pRet->aColl[i] = pColl;
|
||||
pRet->aSortFlags[i] = pOrderBy->a[i].sortFlags;
|
||||
pRet->aSortFlags[i] = pOrderBy->a[i].fg.sortFlags;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5098,7 +5098,7 @@ static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){
|
||||
}
|
||||
*ppMinMax = pOrderBy = sqlite3ExprListDup(db, pEList, 0);
|
||||
assert( pOrderBy!=0 || db->mallocFailed );
|
||||
if( pOrderBy ) pOrderBy->a[0].sortFlags = sortFlags;
|
||||
if( pOrderBy ) pOrderBy->a[0].fg.sortFlags = sortFlags;
|
||||
return eRet;
|
||||
}
|
||||
|
||||
@@ -5805,7 +5805,7 @@ static int selectExpander(Walker *pWalker, Select *p){
|
||||
pNew = sqlite3ExprListAppend(pParse, pNew, a[k].pExpr);
|
||||
if( pNew ){
|
||||
pNew->a[pNew->nExpr-1].zEName = a[k].zEName;
|
||||
pNew->a[pNew->nExpr-1].eEName = a[k].eEName;
|
||||
pNew->a[pNew->nExpr-1].fg.eEName = a[k].fg.eEName;
|
||||
a[k].zEName = 0;
|
||||
}
|
||||
a[k].pExpr = 0;
|
||||
@@ -5859,8 +5859,8 @@ static int selectExpander(Walker *pWalker, Select *p){
|
||||
struct ExprList_item *pX = &pNew->a[pNew->nExpr-1];
|
||||
assert( pX->zEName==0 );
|
||||
pX->zEName = sqlite3MPrintf(db,"..%s", zUName);
|
||||
pX->eEName = ENAME_TAB;
|
||||
pX->bUsingTerm = 1;
|
||||
pX->fg.eEName = ENAME_TAB;
|
||||
pX->fg.bUsingTerm = 1;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
@@ -5943,20 +5943,20 @@ static int selectExpander(Walker *pWalker, Select *p){
|
||||
zSchemaName, zTabName, zName);
|
||||
testcase( pX->zEName==0 );
|
||||
}
|
||||
pX->eEName = ENAME_TAB;
|
||||
pX->fg.eEName = ENAME_TAB;
|
||||
if( (pFrom->fg.isUsing
|
||||
&& sqlite3IdListIndex(pFrom->u3.pUsing, zName)>=0)
|
||||
|| (pUsing && sqlite3IdListIndex(pUsing, zName)>=0)
|
||||
|| (pTab->aCol[j].colFlags & COLFLAG_NOEXPAND)!=0
|
||||
){
|
||||
pX->bNoExpand = 1;
|
||||
pX->fg.bNoExpand = 1;
|
||||
}
|
||||
}else if( longNames ){
|
||||
pX->zEName = sqlite3MPrintf(db, "%s.%s", zTabName, zName);
|
||||
pX->eEName = ENAME_NAME;
|
||||
pX->fg.eEName = ENAME_NAME;
|
||||
}else{
|
||||
pX->zEName = sqlite3DbStrDup(db, zName);
|
||||
pX->eEName = ENAME_NAME;
|
||||
pX->fg.eEName = ENAME_NAME;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7084,13 +7084,13 @@ int sqlite3Select(
|
||||
if( p->selFlags & SF_NestedFrom ){
|
||||
/* Delete or NULL-out result columns that will never be used */
|
||||
int ii;
|
||||
for(ii=pEList->nExpr-1; ii>0 && pEList->a[ii].bUsed==0; ii--){
|
||||
for(ii=pEList->nExpr-1; ii>0 && pEList->a[ii].fg.bUsed==0; ii--){
|
||||
sqlite3ExprDelete(db, pEList->a[ii].pExpr);
|
||||
sqlite3DbFree(db, pEList->a[ii].zEName);
|
||||
pEList->nExpr--;
|
||||
}
|
||||
for(ii=0; ii<pEList->nExpr; ii++){
|
||||
if( pEList->a[ii].bUsed==0 ) pEList->a[ii].pExpr->op = TK_NULL;
|
||||
if( pEList->a[ii].fg.bUsed==0 ) pEList->a[ii].pExpr->op = TK_NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7242,8 +7242,9 @@ int sqlite3Select(
|
||||
** ORDER BY to maximize the chances of rows being delivered in an
|
||||
** order that makes the ORDER BY redundant. */
|
||||
for(ii=0; ii<pGroupBy->nExpr; ii++){
|
||||
u8 sortFlags = sSort.pOrderBy->a[ii].sortFlags & KEYINFO_ORDER_DESC;
|
||||
pGroupBy->a[ii].sortFlags = sortFlags;
|
||||
u8 sortFlags;
|
||||
sortFlags = sSort.pOrderBy->a[ii].fg.sortFlags & KEYINFO_ORDER_DESC;
|
||||
pGroupBy->a[ii].fg.sortFlags = sortFlags;
|
||||
}
|
||||
if( sqlite3ExprListCompare(pGroupBy, sSort.pOrderBy, -1)==0 ){
|
||||
orderByGrp = 1;
|
||||
|
||||
@@ -3001,16 +3001,18 @@ struct ExprList {
|
||||
struct ExprList_item { /* For each expression in the list */
|
||||
Expr *pExpr; /* The parse tree for this expression */
|
||||
char *zEName; /* Token associated with this expression */
|
||||
u8 sortFlags; /* Mask of KEYINFO_ORDER_* flags */
|
||||
unsigned eEName :2; /* Meaning of zEName */
|
||||
unsigned done :1; /* A flag to indicate when processing is finished */
|
||||
unsigned reusable :1; /* Constant expression is reusable */
|
||||
unsigned bSorterRef :1; /* Defer evaluation until after sorting */
|
||||
unsigned bNulls :1; /* True if explicit "NULLS FIRST/LAST" */
|
||||
unsigned bUsed :1; /* This column used in a SF_NestedFrom subquery */
|
||||
unsigned bUsingTerm:1; /* Term from the USING clause of a NestedFrom */
|
||||
unsigned bNoExpand: 1; /* Term is an auxiliary in NestedFrom and should
|
||||
** not be expanded by "*" in parent queries */
|
||||
struct {
|
||||
u8 sortFlags; /* Mask of KEYINFO_ORDER_* flags */
|
||||
unsigned eEName :2; /* Meaning of zEName */
|
||||
unsigned done :1; /* Indicates when processing is finished */
|
||||
unsigned reusable :1; /* Constant expression is reusable */
|
||||
unsigned bSorterRef :1; /* Defer evaluation until after sorting */
|
||||
unsigned bNulls :1; /* True if explicit "NULLS FIRST/LAST" */
|
||||
unsigned bUsed :1; /* This column used in a SF_NestedFrom subquery */
|
||||
unsigned bUsingTerm:1; /* Term from the USING clause of a NestedFrom */
|
||||
unsigned bNoExpand: 1; /* Term is an auxiliary in NestedFrom and should
|
||||
** not be expanded by "*" in parent queries */
|
||||
} fg;
|
||||
union {
|
||||
struct { /* Used by any ExprList other than Parse.pConsExpr */
|
||||
u16 iOrderByCol; /* For ORDER BY, column number in result set */
|
||||
|
||||
@@ -875,15 +875,15 @@ void sqlite3TreeViewBareExprList(
|
||||
moreToFollow = 0;
|
||||
sqlite3TreeViewLine(pView, 0);
|
||||
if( zName ){
|
||||
switch( pList->a[i].eEName ){
|
||||
switch( pList->a[i].fg.eEName ){
|
||||
default:
|
||||
fprintf(stdout, "AS %s ", zName);
|
||||
break;
|
||||
case ENAME_TAB:
|
||||
fprintf(stdout, "TABLE-ALIAS-NAME(\"%s\") ", zName);
|
||||
if( pList->a[i].bUsed ) fprintf(stdout, "(used) ");
|
||||
if( pList->a[i].bUsingTerm ) fprintf(stdout, "(USING-term) ");
|
||||
if( pList->a[i].bNoExpand ) fprintf(stdout, "(NoExpand) ");
|
||||
if( pList->a[i].fg.bUsed ) fprintf(stdout, "(used) ");
|
||||
if( pList->a[i].fg.bUsingTerm ) fprintf(stdout, "(USING-term) ");
|
||||
if( pList->a[i].fg.bNoExpand ) fprintf(stdout, "(NoExpand) ");
|
||||
break;
|
||||
case ENAME_SPAN:
|
||||
fprintf(stdout, "SPAN(\"%s\") ", zName);
|
||||
|
||||
@@ -905,7 +905,7 @@ static ExprList *sqlite3ExpandReturning(
|
||||
if( !db->mallocFailed ){
|
||||
struct ExprList_item *pItem = &pNew->a[pNew->nExpr-1];
|
||||
pItem->zEName = sqlite3DbStrDup(db, pTab->aCol[jj].zCnName);
|
||||
pItem->eEName = ENAME_NAME;
|
||||
pItem->fg.eEName = ENAME_NAME;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
@@ -914,7 +914,7 @@ static ExprList *sqlite3ExpandReturning(
|
||||
if( !db->mallocFailed && ALWAYS(pList->a[i].zEName!=0) ){
|
||||
struct ExprList_item *pItem = &pNew->a[pNew->nExpr-1];
|
||||
pItem->zEName = sqlite3DbStrDup(db, pList->a[i].zEName);
|
||||
pItem->eEName = pList->a[i].eEName;
|
||||
pItem->fg.eEName = pList->a[i].fg.eEName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
12
src/where.c
12
src/where.c
@@ -1206,7 +1206,7 @@ static sqlite3_index_info *allocateIndexInfo(
|
||||
}
|
||||
|
||||
/* Virtual tables are unable to deal with NULLS FIRST */
|
||||
if( pOrderBy->a[i].sortFlags & KEYINFO_ORDER_BIGNULL ) break;
|
||||
if( pOrderBy->a[i].fg.sortFlags & KEYINFO_ORDER_BIGNULL ) break;
|
||||
|
||||
/* First case - a direct column references without a COLLATE operator */
|
||||
if( pExpr->op==TK_COLUMN && pExpr->iTable==pSrc->iCursor ){
|
||||
@@ -1318,7 +1318,7 @@ static sqlite3_index_info *allocateIndexInfo(
|
||||
|| (pExpr->op==TK_COLLATE && pExpr->pLeft->op==TK_COLUMN
|
||||
&& pExpr->iColumn==pExpr->pLeft->iColumn) );
|
||||
pIdxOrderBy[j].iColumn = pExpr->iColumn;
|
||||
pIdxOrderBy[j].desc = pOrderBy->a[i].sortFlags & KEYINFO_ORDER_DESC;
|
||||
pIdxOrderBy[j].desc = pOrderBy->a[i].fg.sortFlags & KEYINFO_ORDER_DESC;
|
||||
j++;
|
||||
}
|
||||
pIdxInfo->nOrderBy = j;
|
||||
@@ -4457,16 +4457,18 @@ static i8 wherePathSatisfiesOrderBy(
|
||||
/* Make sure the sort order is compatible in an ORDER BY clause.
|
||||
** Sort order is irrelevant for a GROUP BY clause. */
|
||||
if( revSet ){
|
||||
if( (rev ^ revIdx)!=(pOrderBy->a[i].sortFlags&KEYINFO_ORDER_DESC) ){
|
||||
if( (rev ^ revIdx)
|
||||
!= (pOrderBy->a[i].fg.sortFlags&KEYINFO_ORDER_DESC)
|
||||
){
|
||||
isMatch = 0;
|
||||
}
|
||||
}else{
|
||||
rev = revIdx ^ (pOrderBy->a[i].sortFlags & KEYINFO_ORDER_DESC);
|
||||
rev = revIdx ^ (pOrderBy->a[i].fg.sortFlags & KEYINFO_ORDER_DESC);
|
||||
if( rev ) *pRevMask |= MASKBIT(iLoop);
|
||||
revSet = 1;
|
||||
}
|
||||
}
|
||||
if( isMatch && (pOrderBy->a[i].sortFlags & KEYINFO_ORDER_BIGNULL) ){
|
||||
if( isMatch && (pOrderBy->a[i].fg.sortFlags & KEYINFO_ORDER_BIGNULL) ){
|
||||
if( j==pLoop->u.btree.nEq ){
|
||||
pLoop->wsFlags |= WHERE_BIGNULL_SORT;
|
||||
}else{
|
||||
|
||||
@@ -1616,7 +1616,7 @@ void sqlite3WhereAddLimit(WhereClause *pWC, Select *p){
|
||||
Expr *pExpr = pOrderBy->a[ii].pExpr;
|
||||
if( pExpr->op!=TK_COLUMN ) return;
|
||||
if( pExpr->iTable!=iCsr ) return;
|
||||
if( pOrderBy->a[ii].sortFlags & KEYINFO_ORDER_BIGNULL ) return;
|
||||
if( pOrderBy->a[ii].fg.sortFlags & KEYINFO_ORDER_BIGNULL ) return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -916,7 +916,7 @@ static ExprList *exprListAppendList(
|
||||
}
|
||||
}
|
||||
pList = sqlite3ExprListAppend(pParse, pList, pDup);
|
||||
if( pList ) pList->a[nInit+i].sortFlags = pAppend->a[i].sortFlags;
|
||||
if( pList ) pList->a[nInit+i].fg.sortFlags = pAppend->a[i].fg.sortFlags;
|
||||
}
|
||||
}
|
||||
return pList;
|
||||
@@ -2117,7 +2117,7 @@ static void windowCodeRangeTest(
|
||||
|
||||
assert( op==OP_Ge || op==OP_Gt || op==OP_Le );
|
||||
assert( pOrderBy && pOrderBy->nExpr==1 );
|
||||
if( pOrderBy->a[0].sortFlags & KEYINFO_ORDER_DESC ){
|
||||
if( pOrderBy->a[0].fg.sortFlags & KEYINFO_ORDER_DESC ){
|
||||
switch( op ){
|
||||
case OP_Ge: op = OP_Le; break;
|
||||
case OP_Gt: op = OP_Lt; break;
|
||||
@@ -2150,7 +2150,7 @@ static void windowCodeRangeTest(
|
||||
** Additionally, if either reg1 or reg2 are NULL but the jump to lbl is
|
||||
** not taken, control jumps over the comparison operator coded below this
|
||||
** block. */
|
||||
if( pOrderBy->a[0].sortFlags & KEYINFO_ORDER_BIGNULL ){
|
||||
if( pOrderBy->a[0].fg.sortFlags & KEYINFO_ORDER_BIGNULL ){
|
||||
/* This block runs if reg1 contains a NULL. */
|
||||
int addr = sqlite3VdbeAddOp1(v, OP_NotNull, reg1); VdbeCoverage(v);
|
||||
switch( op ){
|
||||
|
||||
Reference in New Issue
Block a user