mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-18 10:21:03 +03:00
Add support for using indexes for some ORDER BY clauses that use non-default NULL handling. Still some problems on this branch.
FossilOrigin-Name: 81069d7196857e909c94195d67388f71bc9f832eafd9156d8c5cdddb63513b4a
This commit is contained in:
32
src/where.c
32
src/where.c
@@ -3798,7 +3798,7 @@ static i8 wherePathSatisfiesOrderBy(
|
||||
*/
|
||||
if( pIndex ){
|
||||
iColumn = pIndex->aiColumn[j];
|
||||
revIdx = pIndex->aSortOrder[j];
|
||||
revIdx = pIndex->aSortOrder[j] & KEYINFO_ORDER_DESC;
|
||||
if( iColumn==pIndex->pTable->iPKey ) iColumn = XN_ROWID;
|
||||
}else{
|
||||
iColumn = XN_ROWID;
|
||||
@@ -3836,7 +3836,6 @@ static i8 wherePathSatisfiesOrderBy(
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if( pOrderBy->a[i].sortFlags & KEYINFO_ORDER_BIGNULL ) continue;
|
||||
if( iColumn!=XN_ROWID ){
|
||||
pColl = sqlite3ExprNNCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
|
||||
if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue;
|
||||
@@ -3850,24 +3849,29 @@ static i8 wherePathSatisfiesOrderBy(
|
||||
if( isMatch && (wctrlFlags & WHERE_GROUPBY)==0 ){
|
||||
/* Make sure the sort order is compatible in an ORDER BY clause.
|
||||
** Sort order is irrelevant for a GROUP BY clause. */
|
||||
assert( (pOrderBy->a[i].sortFlags & KEYINFO_ORDER_BIGNULL)==0 );
|
||||
if( revSet ){
|
||||
if( (rev ^ revIdx)!=pOrderBy->a[i].sortFlags ) isMatch = 0;
|
||||
if( (rev ^ revIdx)!=(pOrderBy->a[i].sortFlags&KEYINFO_ORDER_DESC) ){
|
||||
isMatch = 0;
|
||||
}
|
||||
}else{
|
||||
rev = revIdx ^ pOrderBy->a[i].sortFlags;
|
||||
rev = revIdx ^ (pOrderBy->a[i].sortFlags & KEYINFO_ORDER_DESC);
|
||||
if( rev ) *pRevMask |= MASKBIT(iLoop);
|
||||
revSet = 1;
|
||||
}
|
||||
}
|
||||
if( isMatch && (pOrderBy->a[i].sortFlags & KEYINFO_ORDER_BIGNULL) ){
|
||||
if( j==pLoop->u.btree.nEq ){
|
||||
pLoop->wsFlags |= WHERE_BIGNULL_SORT;
|
||||
}else{
|
||||
isMatch = 0;
|
||||
}
|
||||
}
|
||||
if( isMatch ){
|
||||
if( iColumn==XN_ROWID ){
|
||||
testcase( distinctColumns==0 );
|
||||
distinctColumns = 1;
|
||||
}
|
||||
obSat |= MASKBIT(i);
|
||||
if( (wctrlFlags & WHERE_ORDERBY_MIN) && j==pLoop->u.btree.nEq ){
|
||||
pLoop->wsFlags |= WHERE_MIN_ORDERED;
|
||||
}
|
||||
}else{
|
||||
/* No match found */
|
||||
if( j==0 || j<nKeyCol ){
|
||||
@@ -5061,6 +5065,7 @@ WhereInfo *sqlite3WhereBegin(
|
||||
sqlite3VdbeSetP4KeyInfo(pParse, pIx);
|
||||
if( (pLoop->wsFlags & WHERE_CONSTRAINT)!=0
|
||||
&& (pLoop->wsFlags & (WHERE_COLUMN_RANGE|WHERE_SKIPSCAN))==0
|
||||
&& (pLoop->wsFlags & WHERE_BIGNULL_SORT)==0
|
||||
&& (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0
|
||||
&& pWInfo->eDistinct!=WHERE_DISTINCT_ORDERED
|
||||
){
|
||||
@@ -5202,6 +5207,17 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
|
||||
VdbeCoverageIf(v, pLevel->op==OP_Next);
|
||||
VdbeCoverageIf(v, pLevel->op==OP_Prev);
|
||||
VdbeCoverageIf(v, pLevel->op==OP_VNext);
|
||||
if( pLevel->regBignull ){
|
||||
sqlite3VdbeResolveLabel(v, pLevel->addrBignull);
|
||||
addr = sqlite3VdbeAddOp1(v, OP_If, pLevel->regBignull);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->regBignull);
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->p2-1);
|
||||
sqlite3VdbeChangeP5(v, pLevel->p5);
|
||||
VdbeCoverage(v);
|
||||
VdbeCoverageIf(v, pLevel->op==OP_Next);
|
||||
VdbeCoverageIf(v, pLevel->op==OP_Prev);
|
||||
sqlite3VdbeJumpHere(v, addr);
|
||||
}
|
||||
#ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT
|
||||
if( addrSeek ) sqlite3VdbeJumpHere(v, addrSeek);
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user