diff options
author | danielk1977 <danielk1977@noemail.net> | 2007-11-12 15:29:18 +0000 |
---|---|---|
committer | danielk1977 <danielk1977@noemail.net> | 2007-11-12 15:29:18 +0000 |
commit | 3c4809a2017488fb4ccd9e10f6efcd1570e16893 (patch) | |
tree | bfa53732227de928d186a2fabb0d22f8eac76589 /src | |
parent | 390025053e0b4660e83db4b206bd97d594179bf0 (diff) | |
download | sqlite-3c4809a2017488fb4ccd9e10f6efcd1570e16893.tar.gz sqlite-3c4809a2017488fb4ccd9e10f6efcd1570e16893.zip |
Where possible, transform the DISTINCT qualifier to a GROUP BY clause. GROUP BY clauses may be optimized by indices, DISTINCT qualifiers cannot. (CVS 4538)
FossilOrigin-Name: e56331234791cf3d830a30e4cfa66682bdf2eed1
Diffstat (limited to 'src')
-rw-r--r-- | src/select.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/src/select.c b/src/select.c index fbe1b066d..7298251c2 100644 --- a/src/select.c +++ b/src/select.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** -** $Id: select.c,v 1.359 2007/08/31 17:42:48 danielk1977 Exp $ +** $Id: select.c,v 1.360 2007/11/12 15:29:19 danielk1977 Exp $ */ #include "sqliteInt.h" @@ -3067,6 +3067,15 @@ int sqlite3Select( } #endif + /* If possible, rewrite the query to use GROUP BY instead of + */ + if( p->isDistinct && !p->isAgg && !p->pGroupBy ){ + p->pGroupBy = sqlite3ExprListDup(db, p->pEList); + pGroupBy = p->pGroupBy; + p->isDistinct = 0; + isDistinct = 0; + } + /* If there is an ORDER BY clause, then this sorting ** index might end up being unused if the data can be ** extracted in pre-sorted order. If that is the case, then the @@ -3102,6 +3111,7 @@ int sqlite3Select( */ if( isDistinct ){ KeyInfo *pKeyInfo; + assert( isAgg || pGroupBy ); distinct = pParse->nTab++; pKeyInfo = keyInfoFromExprList(pParse, p->pEList); sqlite3VdbeOp3(v, OP_OpenEphemeral, distinct, 0, @@ -3129,7 +3139,8 @@ int sqlite3Select( /* Use the standard inner loop */ - if( selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, distinct, eDest, + assert(!isDistinct); + if( selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, -1, eDest, iParm, pWInfo->iContinue, pWInfo->iBreak, aff) ){ goto select_end; } @@ -3191,7 +3202,7 @@ int sqlite3Select( if( db->mallocFailed ) goto select_end; /* Processing for aggregates with GROUP BY is very different and - ** much more complex tha aggregates without a GROUP BY. + ** much more complex than aggregates without a GROUP BY. */ if( pGroupBy ){ KeyInfo *pKeyInfo; /* Keying information for the group by clause */ |