1
0
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:
dan
2019-08-16 21:07:19 +00:00
parent 6e11892db8
commit 15750a26fa
6 changed files with 133 additions and 69 deletions

View File

@@ -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