From: drh Date: Thu, 19 May 2016 22:40:04 +0000 (+0000) Subject: Appears to work now. Needs test cases, more comments, and code optimization. X-Git-Tag: version-3.14.0~157^2~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d711e522292566c8ef055da3af8f095dabea6781;p=thirdparty%2Fsqlite.git Appears to work now. Needs test cases, more comments, and code optimization. FossilOrigin-Name: 990fe50c9182f74c9b54a12602c4c30d891273e6 --- diff --git a/manifest b/manifest index d01cdd7db8..39cec630ce 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sa\squery\swith\sboth\sORDER\sBY\sand\sLIMIT,\sif\sthe\sinner\sloop\ssatisfies\sthe\s\nORDER\sBY\sthen\stry\sto\scut\sshort\seach\sinvocation\sof\sthe\sinner\sloop\sonce\sthe\nLIMIT\shas\sbeen\ssatisfied.\s\sThis\scheck-in\sis\sa\spartial\simplementation\sonly. -D 2016-05-19T22:13:37.318 +C Appears\sto\swork\snow.\s\sNeeds\stest\scases,\smore\scomments,\sand\scode\soptimization. +D 2016-05-19T22:40:04.862 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -383,7 +383,7 @@ F src/shell.c 14ff7f660530a52b117d110ba3390b7b2eb719b6 F src/sqlite.h.in 9984129d86243424b765fcb3f147c697bd20bb54 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 -F src/sqliteInt.h 863cf0d421611ccfa30541ee5ffe761c896ffa5b +F src/sqliteInt.h 09621b4b7dba808b24262c2480ea75b045001853 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -458,7 +458,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 4db22ed7e77bcf672b1a685d6ddeffba8d5be302 F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 -F src/where.c a7454e62ca13f1ff54892339022f8cb0a8bb3728 +F src/where.c 0e54a03d11d4e99ad25528f42ff4c9a6fa7a23da F src/whereInt.h 6e18240be400bef8e4dbafea605251707c5dbf49 F src/wherecode.c e3f18fcda2d7f8218a09dc33cf495dca0efa6e3e F src/whereexpr.c eacc0e60d029a082b4fc0cc42ea98544add1319e @@ -1489,10 +1489,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 58b516e8c0b00a41bc0364eab267bc2ecb9efeff -R 766495aa6109f75a3c3b0e829e8d3b47 -T *branch * orderby-limit -T *sym-orderby-limit * -T -sym-trunk * +P 852d1eda6ecca1171f6ed800b06f5b4854672002 +R 664cd7ecddde2637b78c890f65cd5e15 U drh -Z 1f191cc43f073ab10b6b672b5a12f950 +Z a9319f97e8df1737542ca3813ad100bc diff --git a/manifest.uuid b/manifest.uuid index ec9b410bfa..2ec1166f5a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -852d1eda6ecca1171f6ed800b06f5b4854672002 \ No newline at end of file +990fe50c9182f74c9b54a12602c4c30d891273e6 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 7adfd3779b..b15d788093 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2540,7 +2540,7 @@ struct SrcList { #define WHERE_WANT_DISTINCT 0x0100 /* All output needs to be distinct */ #define WHERE_SORTBYGROUP 0x0200 /* Support sqlite3WhereIsSorted() */ #define WHERE_SEEK_TABLE 0x0400 /* Do not defer seeks on main table */ - /* 0x0800 not currently used */ +#define WHERE_ORDERBY_LIMIT 0x0800 /* ORDERBY+LIMIT on the inner loop */ /* 0x1000 not currently used */ /* 0x2000 not currently used */ #define WHERE_USE_LIMIT 0x4000 /* Use the LIMIT in cost estimates */ diff --git a/src/where.c b/src/where.c index 521d2e19ec..cb008b7df4 100644 --- a/src/where.c +++ b/src/where.c @@ -3262,7 +3262,7 @@ static i8 wherePathSatisfiesOrderBy( WhereInfo *pWInfo, /* The WHERE clause */ ExprList *pOrderBy, /* ORDER BY or GROUP BY or DISTINCT clause to check */ WherePath *pPath, /* The WherePath to check */ - u16 wctrlFlags, /* Might contain WHERE_GROUPBY or WHERE_DISTINCTBY */ + u16 wctrlFlags, /* WHERE_GROUPBY or _DISTINCTBY or _ORDERBY_LIMIT */ u16 nLoop, /* Number of entries in pPath->aLoop[] */ WhereLoop *pLast, /* Add this WhereLoop to the end of pPath->aLoop[] */ Bitmask *pRevMask /* OUT: Mask of WhereLoops to run in reverse order */ @@ -3273,6 +3273,7 @@ static i8 wherePathSatisfiesOrderBy( u8 isOrderDistinct; /* All prior WhereLoops are order-distinct */ u8 distinctColumns; /* True if the loop has UNIQUE NOT NULL columns */ u8 isMatch; /* iColumn matches a term of the ORDER BY clause */ + u16 eqOpMask; /* Allowed equality operators */ u16 nKeyCol; /* Number of key columns in pIndex */ u16 nColumn; /* Total number of ordered columns in the index */ u16 nOrderBy; /* Number terms in the ORDER BY clause */ @@ -3323,9 +3324,16 @@ static i8 wherePathSatisfiesOrderBy( obDone = MASKBIT(nOrderBy)-1; orderDistinctMask = 0; ready = 0; + eqOpMask = WO_EQ | WO_IS | WO_ISNULL; + if( wctrlFlags & WHERE_ORDERBY_LIMIT ) eqOpMask |= WO_IN; for(iLoop=0; isOrderDistinct && obSat0 ) ready |= pLoop->maskSelf; - pLoop = iLoopaLoop[iLoop] : pLast; + if( iLoopaLoop[iLoop]; + if( wctrlFlags & WHERE_ORDERBY_LIMIT ) continue; + }else{ + pLoop = pLast; + } if( pLoop->wsFlags & WHERE_VIRTUALTABLE ){ if( pLoop->u.vtab.isOrdered ) obSat = obDone; break; @@ -3343,7 +3351,7 @@ static i8 wherePathSatisfiesOrderBy( if( pOBExpr->op!=TK_COLUMN ) continue; if( pOBExpr->iTable!=iCur ) continue; pTerm = sqlite3WhereFindTerm(&pWInfo->sWC, iCur, pOBExpr->iColumn, - ~ready, WO_EQ|WO_ISNULL|WO_IS, 0); + ~ready, eqOpMask, 0); if( pTerm==0 ) continue; if( (pTerm->eOperator&(WO_EQ|WO_IS))!=0 && pOBExpr->iColumn>=0 ){ const char *z1, *z2; @@ -3383,10 +3391,12 @@ static i8 wherePathSatisfiesOrderBy( for(j=0; ju.btree.nEq && pLoop->nSkip==0 - && ((i = pLoop->aLTerm[j]->eOperator) & (WO_EQ|WO_ISNULL|WO_IS))!=0 + && ((i = pLoop->aLTerm[j]->eOperator) & eqOpMask)!=0 ){ if( i & WO_ISNULL ){ testcase( isOrderDistinct ); @@ -3913,6 +3923,15 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ pWInfo->revMask = pFrom->revLoop; if( pWInfo->nOBSat<=0 ){ pWInfo->nOBSat = 0; + if( nLoop>0 ){ + Bitmask m; + int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, pFrom, + WHERE_ORDERBY_LIMIT, nLoop-1, pFrom->aLoop[nLoop-1], &m); + if( rc==pWInfo->pOrderBy->nExpr ){ + pWInfo->bOrderedInnerLoop = 1; + pWInfo->revMask = m; + } + } } } if( (pWInfo->wctrlFlags & WHERE_SORTBYGROUP)