aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2011-02-11 03:56:11 +0000
committerdrh <drh@noemail.net>2011-02-11 03:56:11 +0000
commitac6de304e570cca2e4a8bfa093fd6ea410da48c7 (patch)
tree8ec8b48ec5a9b81e65e8fd388d909033f9cb5a2b /src
parent59b6188bb040492924de7f3d0eba91de23e5cac5 (diff)
downloadsqlite-ac6de304e570cca2e4a8bfa093fd6ea410da48c7.tar.gz
sqlite-ac6de304e570cca2e4a8bfa093fd6ea410da48c7.zip
Allow an index paired with a NOT NULL constraint to be used for sorting
under the condition that the index be treated as a non-unique index. FossilOrigin-Name: d78949fc93077e1aa7f05cf9f7e947727939cc96
Diffstat (limited to 'src')
-rw-r--r--src/where.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/src/where.c b/src/where.c
index 7710225bb..c6f0cbe3f 100644
--- a/src/where.c
+++ b/src/where.c
@@ -1419,6 +1419,7 @@ static int isSortingIndex(
int base, /* Cursor number for the table to be sorted */
ExprList *pOrderBy, /* The ORDER BY clause */
int nEqCol, /* Number of index columns with == constraints */
+ int wsFlags, /* Index usages flags */
int *pbRev /* Set to 1 if ORDER BY is DESC */
){
int i, j; /* Loop counters */
@@ -1524,11 +1525,14 @@ static int isSortingIndex(
return 1;
}
if( pIdx->onError!=OE_None && i==pIdx->nColumn
+ && (wsFlags & WHERE_COLUMN_NULL)==0
&& !referencesOtherTables(pOrderBy, pMaskSet, j, base) ){
/* All terms of this index match some prefix of the ORDER BY clause
** and the index is UNIQUE and no terms on the tail of the ORDER BY
** clause reference other tables in a join. If this is all true then
- ** the order by clause is superfluous. */
+ ** the order by clause is superfluous. Not that if the matching
+ ** condition is IS NULL then the result is not necessarily unique
+ ** even on a UNIQUE index, so disallow those cases. */
return 1;
}
return 0;
@@ -2881,8 +2885,9 @@ static void bestBtreeIndex(
** in wsFlags. Otherwise, if there is an ORDER BY clause but the index
** will scan rows in a different order, set the bSort variable. */
if( pOrderBy ){
- if( (wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_NULL))==0
- && isSortingIndex(pParse,pWC->pMaskSet,pProbe,iCur,pOrderBy,nEq,&rev)
+ if( (wsFlags & WHERE_COLUMN_IN)==0
+ && isSortingIndex(pParse, pWC->pMaskSet, pProbe, iCur, pOrderBy,
+ nEq, wsFlags, &rev)
){
wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE|WHERE_ORDERBY;
wsFlags |= (rev ? WHERE_REVERSE : 0);