From adc57f6834167cd55e8c4d1129cf2c32ee3cfde0 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 6 Jun 2015 00:18:01 +0000 Subject: [PATCH] Minor cleanup of the sqlite3Select() procedure. FossilOrigin-Name: f4c90d06bb941453d8110680c7b279e471e8f034 --- manifest | 15 ++++++-------- manifest.uuid | 2 +- src/select.c | 54 ++++++++++++++++++++++++++------------------------- 3 files changed, 35 insertions(+), 36 deletions(-) diff --git a/manifest b/manifest index d868635d2e..26d43362ba 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Split\sFROM-clause\ssubquery\sflattening\sand\scode\sgeneration\sinto\sseparate\sloops. -D 2015-06-05T22:33:39.408 +C Minor\scleanup\sof\sthe\ssqlite3Select()\sprocedure. +D 2015-06-06T00:18:01.663 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 994bab32a3a69e0c35bd148b65cde49879772964 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -250,7 +250,7 @@ F src/printf.c 13ce37e5574f9b0682fa86dbcf9faf76b9d82a15 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 84c571794e3ee5806274d95158a4c0177c6c4708 F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e -F src/select.c 6a8f2c442dc69ff343411788e5146b45ddb87609 +F src/select.c 630623e6536115ec360e07be3cb5e01fab9166f9 F src/shell.c 07dda7cd692911d2f22269953418d049f2e2c0ee F src/sqlite.h.in d165beeceb6b40af60f352a4d4e37e02d9af7df0 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad @@ -1282,10 +1282,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 283bf0b64da7acc5aa5812fc659954965002d409 -R 7215f59414fcbc308f2938a5f5f79857 -T *branch * view-optimization -T *sym-view-optimization * -T -sym-trunk * +P be8e3fc70e4c13b28b07985df3457960f58ffddd +R c9ba4b66998c994d5a4d88f3868eca18 U drh -Z b4c3a234d5928895ab25f2763d32a4ad +Z f5a7ad6c64c16a42ea0d51c96b63ee57 diff --git a/manifest.uuid b/manifest.uuid index 39d8550257..e0f55059d7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -be8e3fc70e4c13b28b07985df3457960f58ffddd \ No newline at end of file +f4c90d06bb941453d8110680c7b279e471e8f034 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 2341e84509..9dd34dc567 100644 --- a/src/select.c +++ b/src/select.c @@ -4814,12 +4814,11 @@ int sqlite3Select( memset(&sSort, 0, sizeof(sSort)); sSort.pOrderBy = p->pOrderBy; pTabList = p->pSrc; - pEList = p->pEList; if( pParse->nErr || db->mallocFailed ){ goto select_end; } + assert( p->pEList!=0 ); isAgg = (p->selFlags & SF_Aggregate)!=0; - assert( pEList!=0 ); #if SELECTTRACE_ENABLED if( sqlite3SelectTrace & 0x100 ){ SELECTTRACE(0x100,pParse,p, ("after name resolution:\n")); @@ -4828,21 +4827,16 @@ int sqlite3Select( #endif - /* Begin generating code. - */ - v = sqlite3GetVdbe(pParse); - if( v==0 ) goto select_end; - /* If writing to memory or generating a set ** only a single column may be output. */ #ifndef SQLITE_OMIT_SUBQUERY - if( checkForMultiColumnSelectError(pParse, pDest, pEList->nExpr) ){ + if( checkForMultiColumnSelectError(pParse, pDest, p->pEList->nExpr) ){ goto select_end; } #endif - /* Try to flatten subqueries in the FROM clause into the main query + /* Try to flatten subqueries in the FROM clause up into the main query */ #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) for(i=0; !p->pPrior && inSrc; i++){ @@ -4867,6 +4861,10 @@ int sqlite3Select( } #endif + /* Get a pointer the VDBE under construction, allocating a new VDBE if one + ** does not already exist */ + v = sqlite3GetVdbe(pParse); + if( v==0 ) goto select_end; #ifndef SQLITE_OMIT_COMPOUND_SELECT /* Handle compound SELECT statements using the separate multiSelect() @@ -4890,7 +4888,6 @@ int sqlite3Select( struct SrcList_item *pItem = &pTabList->a[i]; SelectDest dest; Select *pSub = pItem->pSelect; - if( pSub==0 ) continue; /* Sometimes the code for a subquery will be generated more than @@ -4915,6 +4912,9 @@ int sqlite3Select( */ pParse->nHeight += sqlite3SelectExprHeight(p); + /* Make copies of constant WHERE-clause terms in the outer query down + ** inside the subquery. This can help the subquery to run more efficiently. + */ if( (pItem->jointype & JT_OUTER)==0 && pushDownWhereTerms(db, pSub, p->pWhere, pItem->iCursor) ){ @@ -4925,6 +4925,9 @@ int sqlite3Select( } #endif } + + /* Generate code to implement the subquery + */ if( pTabList->nSrc==1 && (p->selFlags & SF_All)==0 && OptimizationEnabled(db, SQLITE_SubqCoroutine) @@ -4978,13 +4981,13 @@ int sqlite3Select( sqlite3VdbeChangeP1(v, topAddr, retAddr); sqlite3ClearTempRegCache(pParse); } - if( db->mallocFailed ){ - goto select_end; - } + if( db->mallocFailed ) goto select_end; pParse->nHeight -= sqlite3SelectExprHeight(p); } - pEList = p->pEList; #endif + + /* Various elements of the SELECT copied into local variables for convenience */ + pEList = p->pEList; pWhere = p->pWhere; pGroupBy = p->pGroupBy; pHaving = p->pHaving; @@ -5013,23 +5016,23 @@ int sqlite3Select( ** BY and DISTINCT, and an index or separate temp-table for the other. */ if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct - && sqlite3ExprListCompare(sSort.pOrderBy, p->pEList, -1)==0 + && sqlite3ExprListCompare(sSort.pOrderBy, pEList, -1)==0 ){ p->selFlags &= ~SF_Distinct; - p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0); - pGroupBy = p->pGroupBy; + pGroupBy = p->pGroupBy = sqlite3ExprListDup(db, pEList, 0); /* Notice that even thought SF_Distinct has been cleared from p->selFlags, ** the sDistinct.isTnct is still set. Hence, isTnct represents the ** original setting of the SF_Distinct flag, not the current setting */ assert( sDistinct.isTnct ); } - /* 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 - ** OP_OpenEphemeral instruction will be changed to an OP_Noop once - ** we figure out that the sorting index is not needed. The addrSortIndex - ** variable is used to facilitate that change. + /* If there is an ORDER BY clause, then create an ephemeral index to + ** do the sorting. But this sorting ephemeral index might end up + ** being unused if the data can be extracted in pre-sorted order. + ** If that is the case, then the OP_OpenEphemeral instruction will be + ** changed to an OP_Noop once we figure out that the sorting index is + ** not needed. The sSort.addrSortIndex variable is used to facilitate + ** that change. */ if( sSort.pOrderBy ){ KeyInfo *pKeyInfo; @@ -5060,7 +5063,7 @@ int sqlite3Select( sSort.sortFlags |= SORTFLAG_UseSorter; } - /* Open a virtual index to use for the distinct set. + /* Open an ephemeral index to use for the distinct set. */ if( p->selFlags & SF_Distinct ){ sDistinct.tabTnct = pParse->nTab++; @@ -5145,11 +5148,10 @@ int sqlite3Select( p->nSelectRow = 1; } - /* If there is both a GROUP BY and an ORDER BY clause and they are ** identical, then it may be possible to disable the ORDER BY clause ** on the grounds that the GROUP BY will cause elements to come out - ** in the correct order. It also may not - the GROUP BY may use a + ** in the correct order. It also may not - the GROUP BY might use a ** database index that causes rows to be grouped together as required ** but not actually sorted. Either way, record the fact that the ** ORDER BY and GROUP BY clauses are the same by setting the orderByGrp -- 2.47.2