1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-11 01:42:22 +03:00

Make the partial-ORDER-BY information in the query planner available to the

SELECT code generator.  Still doesn't make a difference in the generated code.

FossilOrigin-Name: e258df236b7de70087c8227cb209080e55b9bf9c
This commit is contained in:
drh
2014-03-18 20:33:42 +00:00
parent d2de861cbe
commit ddba0c227e
5 changed files with 34 additions and 28 deletions

View File

@@ -1,5 +1,5 @@
C Adjust\sthe\squery\splanner\sto\skeep\strack\sof\sthe\snumber\sof\sORDER\sBY\sterms\nsatisfied.\s\sStill\sdoesn't\sdo\sanything\swith\sthis\sinformation.\s\sSome\stests\nfail\safter\sthis\scheck-in,\sbut\sall\sfailures\sare\sbelieved\sto\sbe\sbenign.\s\sThe\nfailures\swill\sbe\saddressed\sat\sa\slater\sstage. C Make\sthe\spartial-ORDER-BY\sinformation\sin\sthe\squery\splanner\savailable\sto\sthe\nSELECT\scode\sgenerator.\s\sStill\sdoesn't\smake\sa\sdifference\sin\sthe\sgenerated\scode.
D 2014-03-18T18:59:07.798 D 2014-03-18T20:33:42.067
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -217,7 +217,7 @@ F src/printf.c e5a0005f8b3de21f85da6a709d2fbee76775bf4b
F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece
F src/resolve.c 273d5f47c4e2c05b2d3d2bffeda939551ab59e66 F src/resolve.c 273d5f47c4e2c05b2d3d2bffeda939551ab59e66
F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
F src/select.c 0adf172d33cc610ff5ffe26edfd2ba67c3551655 F src/select.c 41df0e4dd1d167dc8b39047c84e1b8b51516a237
F src/shell.c bab4de12b441369491812ecc93212ff4deda68fa F src/shell.c bab4de12b441369491812ecc93212ff4deda68fa
F src/sqlite.h.in a2ef671f92747a5a1c8a47bad5c585a8dd9eca80 F src/sqlite.h.in a2ef671f92747a5a1c8a47bad5c585a8dd9eca80
F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
@@ -291,8 +291,8 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd
F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8 F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45
F src/where.c 81eea5ced2a2586ccd7ebd1d5bed7d34f4a2e99c F src/where.c 3f5de18e74b0f6da3218c2c609616a2f9e2c404a
F src/whereInt.h daa3cdf9f56c1dd12b63e4eda3182e64e3bba14f F src/whereInt.h 2564055b440e44ebec8b47f237bbccae6719b7af
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6 F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
@@ -1156,7 +1156,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
P b150902579d708b454efd5f8750e26a816f7f1a6 P 59d49b7fc49fa290e04a02653e7268c85836b27e
R 179b4f0ee34acb2c0f356485d1e56bc3 R 2b69bb33bc67b11eec1f6a4a37941d3e
U drh U drh
Z adae3618c374e493bb2483c0db46dcf7 Z 43f4f2d39f5cfe334420891461bd8dda

View File

@@ -1 +1 @@
59d49b7fc49fa290e04a02653e7268c85836b27e e258df236b7de70087c8227cb209080e55b9bf9c

View File

@@ -562,6 +562,7 @@ static void selectInnerLoop(
ExprList *pEList, /* List of values being extracted */ ExprList *pEList, /* List of values being extracted */
int srcTab, /* Pull data from this table */ int srcTab, /* Pull data from this table */
ExprList *pOrderBy, /* If not NULL, sort results using this key */ ExprList *pOrderBy, /* If not NULL, sort results using this key */
int nOBSat, /* Terms of ORDER BY already satisfied */
DistinctCtx *pDistinct, /* If not NULL, info on how to process DISTINCT */ DistinctCtx *pDistinct, /* If not NULL, info on how to process DISTINCT */
SelectDest *pDest, /* How to dispose of the results */ SelectDest *pDest, /* How to dispose of the results */
int iContinue, /* Jump here to continue with next row */ int iContinue, /* Jump here to continue with next row */
@@ -1054,10 +1055,10 @@ static void explainComposite(
static void generateSortTail( static void generateSortTail(
Parse *pParse, /* Parsing context */ Parse *pParse, /* Parsing context */
Select *p, /* The SELECT statement */ Select *p, /* The SELECT statement */
Vdbe *v, /* Generate code into this VDBE */
int nColumn, /* Number of columns of data */ int nColumn, /* Number of columns of data */
SelectDest *pDest /* Write the sorted results here */ SelectDest *pDest /* Write the sorted results here */
){ ){
Vdbe *v = pParse->pVdbe; /* The prepared statement */
int addrBreak = sqlite3VdbeMakeLabel(v); /* Jump here to exit loop */ int addrBreak = sqlite3VdbeMakeLabel(v); /* Jump here to exit loop */
int addrContinue = sqlite3VdbeMakeLabel(v); /* Jump here for next cycle */ int addrContinue = sqlite3VdbeMakeLabel(v); /* Jump here for next cycle */
int addr; int addr;
@@ -1918,7 +1919,7 @@ static void generateWithRecursiveQuery(
addrCont = sqlite3VdbeMakeLabel(v); addrCont = sqlite3VdbeMakeLabel(v);
codeOffset(v, regOffset, addrCont); codeOffset(v, regOffset, addrCont);
selectInnerLoop(pParse, p, p->pEList, iCurrent, selectInnerLoop(pParse, p, p->pEList, iCurrent,
0, 0, pDest, addrCont, addrBreak); 0, 0, 0, pDest, addrCont, addrBreak);
if( regLimit ){ if( regLimit ){
sqlite3VdbeAddOp3(v, OP_IfZero, regLimit, addrBreak, -1); sqlite3VdbeAddOp3(v, OP_IfZero, regLimit, addrBreak, -1);
VdbeCoverage(v); VdbeCoverage(v);
@@ -2192,7 +2193,7 @@ static int multiSelect(
sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); VdbeCoverage(v);
iStart = sqlite3VdbeCurrentAddr(v); iStart = sqlite3VdbeCurrentAddr(v);
selectInnerLoop(pParse, p, p->pEList, unionTab, selectInnerLoop(pParse, p, p->pEList, unionTab,
0, 0, &dest, iCont, iBreak); 0, 0, 0, &dest, iCont, iBreak);
sqlite3VdbeResolveLabel(v, iCont); sqlite3VdbeResolveLabel(v, iCont);
sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart); VdbeCoverage(v);
sqlite3VdbeResolveLabel(v, iBreak); sqlite3VdbeResolveLabel(v, iBreak);
@@ -2270,7 +2271,7 @@ static int multiSelect(
sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0); VdbeCoverage(v); sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0); VdbeCoverage(v);
sqlite3ReleaseTempReg(pParse, r1); sqlite3ReleaseTempReg(pParse, r1);
selectInnerLoop(pParse, p, p->pEList, tab1, selectInnerLoop(pParse, p, p->pEList, tab1,
0, 0, &dest, iCont, iBreak); 0, 0, 0, &dest, iCont, iBreak);
sqlite3VdbeResolveLabel(v, iCont); sqlite3VdbeResolveLabel(v, iCont);
sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart); VdbeCoverage(v);
sqlite3VdbeResolveLabel(v, iBreak); sqlite3VdbeResolveLabel(v, iBreak);
@@ -4730,6 +4731,7 @@ int sqlite3Select(
if( !isAgg && pGroupBy==0 ){ if( !isAgg && pGroupBy==0 ){
/* No aggregate functions and no GROUP BY clause */ /* No aggregate functions and no GROUP BY clause */
u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0); u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0);
int nOBSat;
/* Begin the database scan. */ /* Begin the database scan. */
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pOrderBy, p->pEList, pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pOrderBy, p->pEList,
@@ -4741,7 +4743,8 @@ int sqlite3Select(
if( sDistinct.isTnct && sqlite3WhereIsDistinct(pWInfo) ){ if( sDistinct.isTnct && sqlite3WhereIsDistinct(pWInfo) ){
sDistinct.eTnctType = sqlite3WhereIsDistinct(pWInfo); sDistinct.eTnctType = sqlite3WhereIsDistinct(pWInfo);
} }
if( pOrderBy && sqlite3WhereIsOrdered(pWInfo) ) pOrderBy = 0; nOBSat = sqlite3WhereIsOrdered(pWInfo);
if( pOrderBy && nOBSat==pOrderBy->nExpr ){ pOrderBy = 0; nOBSat = 0; }
/* If sorting index that was created by a prior OP_OpenEphemeral /* If sorting index that was created by a prior OP_OpenEphemeral
** instruction ended up not being needed, then change the OP_OpenEphemeral ** instruction ended up not being needed, then change the OP_OpenEphemeral
@@ -4753,7 +4756,7 @@ int sqlite3Select(
} }
/* Use the standard inner loop. */ /* Use the standard inner loop. */
selectInnerLoop(pParse, p, pEList, -1, pOrderBy, &sDistinct, pDest, selectInnerLoop(pParse, p, pEList, -1, pOrderBy, nOBSat, &sDistinct, pDest,
sqlite3WhereContinueLabel(pWInfo), sqlite3WhereContinueLabel(pWInfo),
sqlite3WhereBreakLabel(pWInfo)); sqlite3WhereBreakLabel(pWInfo));
@@ -4875,7 +4878,7 @@ int sqlite3Select(
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0, pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0,
WHERE_GROUPBY, 0); WHERE_GROUPBY, 0);
if( pWInfo==0 ) goto select_end; if( pWInfo==0 ) goto select_end;
if( sqlite3WhereIsOrdered(pWInfo) ){ if( sqlite3WhereIsOrdered(pWInfo)==pGroupBy->nExpr ){
/* The optimizer is able to deliver rows in group by order so /* The optimizer is able to deliver rows in group by order so
** we do not have to sort. The OP_OpenEphemeral table will be ** we do not have to sort. The OP_OpenEphemeral table will be
** cancelled later because we still need to use the pKeyInfo ** cancelled later because we still need to use the pKeyInfo
@@ -5026,7 +5029,7 @@ int sqlite3Select(
sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
finalizeAggFunctions(pParse, &sAggInfo); finalizeAggFunctions(pParse, &sAggInfo);
sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL); sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL);
selectInnerLoop(pParse, p, p->pEList, -1, pOrderBy, selectInnerLoop(pParse, p, p->pEList, -1, pOrderBy, 0,
&sDistinct, pDest, &sDistinct, pDest,
addrOutputRow+1, addrSetAbort); addrOutputRow+1, addrSetAbort);
sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
@@ -5158,7 +5161,7 @@ int sqlite3Select(
} }
updateAccumulator(pParse, &sAggInfo); updateAccumulator(pParse, &sAggInfo);
assert( pMinMax==0 || pMinMax->nExpr==1 ); assert( pMinMax==0 || pMinMax->nExpr==1 );
if( sqlite3WhereIsOrdered(pWInfo) ){ if( sqlite3WhereIsOrdered(pWInfo)>0 ){
sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3WhereBreakLabel(pWInfo)); sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3WhereBreakLabel(pWInfo));
VdbeComment((v, "%s() by index", VdbeComment((v, "%s() by index",
(flag==WHERE_ORDERBY_MIN?"min":"max"))); (flag==WHERE_ORDERBY_MIN?"min":"max")));
@@ -5169,7 +5172,7 @@ int sqlite3Select(
pOrderBy = 0; pOrderBy = 0;
sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL); sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL);
selectInnerLoop(pParse, p, p->pEList, -1, 0, 0, selectInnerLoop(pParse, p, p->pEList, -1, 0, 0, 0,
pDest, addrEnd, addrEnd); pDest, addrEnd, addrEnd);
sqlite3ExprListDelete(db, pDel); sqlite3ExprListDelete(db, pDel);
} }
@@ -5186,7 +5189,7 @@ int sqlite3Select(
*/ */
if( pOrderBy ){ if( pOrderBy ){
explainTempTable(pParse, "ORDER BY"); explainTempTable(pParse, "ORDER BY");
generateSortTail(pParse, p, v, pEList->nExpr, pDest); generateSortTail(pParse, p, pEList->nExpr, pDest);
} }
/* Jump here to skip this query /* Jump here to skip this query

View File

@@ -39,7 +39,7 @@ int sqlite3WhereIsDistinct(WhereInfo *pWInfo){
** Return FALSE if the output needs to be sorted. ** Return FALSE if the output needs to be sorted.
*/ */
int sqlite3WhereIsOrdered(WhereInfo *pWInfo){ int sqlite3WhereIsOrdered(WhereInfo *pWInfo){
return pWInfo->bOBSat!=0; return pWInfo->nOBSat;
} }
/* /*
@@ -3036,8 +3036,11 @@ static Bitmask codeOneLoopStart(
** the first one after the nEq equality constraints in the index, ** the first one after the nEq equality constraints in the index,
** this requires some special handling. ** this requires some special handling.
*/ */
assert( pWInfo->pOrderBy==0
|| pWInfo->pOrderBy->nExpr==1
|| (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0 );
if( (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)!=0 if( (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)!=0
&& (pWInfo->bOBSat!=0) && pWInfo->nOBSat>0
&& (pIdx->nKeyCol>nEq) && (pIdx->nKeyCol>nEq)
){ ){
assert( pLoop->u.btree.nSkip==0 ); assert( pLoop->u.btree.nSkip==0 );
@@ -5199,7 +5202,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
if( pWInfo->wctrlFlags & WHERE_DISTINCTBY ){ if( pWInfo->wctrlFlags & WHERE_DISTINCTBY ){
pWInfo->eDistinct = WHERE_DISTINCT_ORDERED; pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
}else{ }else{
pWInfo->bOBSat = 1; pWInfo->nOBSat = pFrom->isOrdered;
pWInfo->revMask = pFrom->revLoop; pWInfo->revMask = pFrom->revLoop;
} }
} }
@@ -5284,7 +5287,7 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){
pLoop->maskSelf = getMask(&pWInfo->sMaskSet, iCur); pLoop->maskSelf = getMask(&pWInfo->sMaskSet, iCur);
pWInfo->a[0].iTabCur = iCur; pWInfo->a[0].iTabCur = iCur;
pWInfo->nRowOut = 1; pWInfo->nRowOut = 1;
if( pWInfo->pOrderBy ) pWInfo->bOBSat = 1; if( pWInfo->pOrderBy ) pWInfo->nOBSat = pWInfo->pOrderBy->nExpr;
if( pWInfo->wctrlFlags & WHERE_WANT_DISTINCT ){ if( pWInfo->wctrlFlags & WHERE_WANT_DISTINCT ){
pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
} }
@@ -5492,7 +5495,7 @@ WhereInfo *sqlite3WhereBegin(
/* Special case: No FROM clause /* Special case: No FROM clause
*/ */
if( nTabList==0 ){ if( nTabList==0 ){
if( pOrderBy ) pWInfo->bOBSat = 1; if( pOrderBy ) pWInfo->nOBSat = pOrderBy->nExpr;
if( wctrlFlags & WHERE_WANT_DISTINCT ){ if( wctrlFlags & WHERE_WANT_DISTINCT ){
pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
} }
@@ -5603,8 +5606,8 @@ WhereInfo *sqlite3WhereBegin(
if( sqlite3WhereTrace ){ if( sqlite3WhereTrace ){
int ii; int ii;
sqlite3DebugPrintf("---- Solution nRow=%d", pWInfo->nRowOut); sqlite3DebugPrintf("---- Solution nRow=%d", pWInfo->nRowOut);
if( pWInfo->bOBSat ){ if( pWInfo->nOBSat>0 ){
sqlite3DebugPrintf(" ORDERBY=0x%llx", pWInfo->revMask); sqlite3DebugPrintf(" ORDERBY=%d,0x%llx", pWInfo->nOBSat, pWInfo->revMask);
} }
switch( pWInfo->eDistinct ){ switch( pWInfo->eDistinct ){
case WHERE_DISTINCT_UNIQUE: { case WHERE_DISTINCT_UNIQUE: {

View File

@@ -397,7 +397,7 @@ struct WhereInfo {
Bitmask revMask; /* Mask of ORDER BY terms that need reversing */ Bitmask revMask; /* Mask of ORDER BY terms that need reversing */
LogEst nRowOut; /* Estimated number of output rows */ LogEst nRowOut; /* Estimated number of output rows */
u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */ u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */
u8 bOBSat; /* ORDER BY satisfied by indices */ i8 nOBSat; /* Number of ORDER BY terms satisfied by indices */
u8 okOnePass; /* Ok to use one-pass algorithm for UPDATE/DELETE */ u8 okOnePass; /* Ok to use one-pass algorithm for UPDATE/DELETE */
u8 untestedTerms; /* Not all WHERE terms resolved by outer loop */ u8 untestedTerms; /* Not all WHERE terms resolved by outer loop */
u8 eDistinct; /* One of the WHERE_DISTINCT_* values below */ u8 eDistinct; /* One of the WHERE_DISTINCT_* values below */