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

@ -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.
D 2014-03-18T18:59:07.798
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-18T20:33:42.067
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -217,7 +217,7 @@ F src/printf.c e5a0005f8b3de21f85da6a709d2fbee76775bf4b
F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece
F src/resolve.c 273d5f47c4e2c05b2d3d2bffeda939551ab59e66
F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
F src/select.c 0adf172d33cc610ff5ffe26edfd2ba67c3551655
F src/select.c 41df0e4dd1d167dc8b39047c84e1b8b51516a237
F src/shell.c bab4de12b441369491812ecc93212ff4deda68fa
F src/sqlite.h.in a2ef671f92747a5a1c8a47bad5c585a8dd9eca80
F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
@ -291,8 +291,8 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd
F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45
F src/where.c 81eea5ced2a2586ccd7ebd1d5bed7d34f4a2e99c
F src/whereInt.h daa3cdf9f56c1dd12b63e4eda3182e64e3bba14f
F src/where.c 3f5de18e74b0f6da3218c2c609616a2f9e2c404a
F src/whereInt.h 2564055b440e44ebec8b47f237bbccae6719b7af
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
@ -1156,7 +1156,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
P b150902579d708b454efd5f8750e26a816f7f1a6
R 179b4f0ee34acb2c0f356485d1e56bc3
P 59d49b7fc49fa290e04a02653e7268c85836b27e
R 2b69bb33bc67b11eec1f6a4a37941d3e
U drh
Z adae3618c374e493bb2483c0db46dcf7
Z 43f4f2d39f5cfe334420891461bd8dda

@ -1 +1 @@
59d49b7fc49fa290e04a02653e7268c85836b27e
e258df236b7de70087c8227cb209080e55b9bf9c

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

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

@ -397,7 +397,7 @@ struct WhereInfo {
Bitmask revMask; /* Mask of ORDER BY terms that need reversing */
LogEst nRowOut; /* Estimated number of output rows */
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 untestedTerms; /* Not all WHERE terms resolved by outer loop */
u8 eDistinct; /* One of the WHERE_DISTINCT_* values below */