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

Minor cleanup of the sqlite3Select() procedure.

FossilOrigin-Name: f4c90d06bb941453d8110680c7b279e471e8f034
This commit is contained in:
drh
2015-06-06 00:18:01 +00:00
parent 4490c40b90
commit adc57f6834
3 changed files with 35 additions and 36 deletions

View File

@@ -1,5 +1,5 @@
C Split\sFROM-clause\ssubquery\sflattening\sand\scode\sgeneration\sinto\sseparate\sloops. C Minor\scleanup\sof\sthe\ssqlite3Select()\sprocedure.
D 2015-06-05T22:33:39.408 D 2015-06-06T00:18:01.663
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 994bab32a3a69e0c35bd148b65cde49879772964 F Makefile.in 994bab32a3a69e0c35bd148b65cde49879772964
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -250,7 +250,7 @@ F src/printf.c 13ce37e5574f9b0682fa86dbcf9faf76b9d82a15
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
F src/resolve.c 84c571794e3ee5806274d95158a4c0177c6c4708 F src/resolve.c 84c571794e3ee5806274d95158a4c0177c6c4708
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
F src/select.c 6a8f2c442dc69ff343411788e5146b45ddb87609 F src/select.c 630623e6536115ec360e07be3cb5e01fab9166f9
F src/shell.c 07dda7cd692911d2f22269953418d049f2e2c0ee F src/shell.c 07dda7cd692911d2f22269953418d049f2e2c0ee
F src/sqlite.h.in d165beeceb6b40af60f352a4d4e37e02d9af7df0 F src/sqlite.h.in d165beeceb6b40af60f352a4d4e37e02d9af7df0
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
@@ -1282,10 +1282,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 283bf0b64da7acc5aa5812fc659954965002d409 P be8e3fc70e4c13b28b07985df3457960f58ffddd
R 7215f59414fcbc308f2938a5f5f79857 R c9ba4b66998c994d5a4d88f3868eca18
T *branch * view-optimization
T *sym-view-optimization *
T -sym-trunk *
U drh U drh
Z b4c3a234d5928895ab25f2763d32a4ad Z f5a7ad6c64c16a42ea0d51c96b63ee57

View File

@@ -1 +1 @@
be8e3fc70e4c13b28b07985df3457960f58ffddd f4c90d06bb941453d8110680c7b279e471e8f034

View File

@@ -4814,12 +4814,11 @@ int sqlite3Select(
memset(&sSort, 0, sizeof(sSort)); memset(&sSort, 0, sizeof(sSort));
sSort.pOrderBy = p->pOrderBy; sSort.pOrderBy = p->pOrderBy;
pTabList = p->pSrc; pTabList = p->pSrc;
pEList = p->pEList;
if( pParse->nErr || db->mallocFailed ){ if( pParse->nErr || db->mallocFailed ){
goto select_end; goto select_end;
} }
assert( p->pEList!=0 );
isAgg = (p->selFlags & SF_Aggregate)!=0; isAgg = (p->selFlags & SF_Aggregate)!=0;
assert( pEList!=0 );
#if SELECTTRACE_ENABLED #if SELECTTRACE_ENABLED
if( sqlite3SelectTrace & 0x100 ){ if( sqlite3SelectTrace & 0x100 ){
SELECTTRACE(0x100,pParse,p, ("after name resolution:\n")); SELECTTRACE(0x100,pParse,p, ("after name resolution:\n"));
@@ -4828,21 +4827,16 @@ int sqlite3Select(
#endif #endif
/* Begin generating code.
*/
v = sqlite3GetVdbe(pParse);
if( v==0 ) goto select_end;
/* If writing to memory or generating a set /* If writing to memory or generating a set
** only a single column may be output. ** only a single column may be output.
*/ */
#ifndef SQLITE_OMIT_SUBQUERY #ifndef SQLITE_OMIT_SUBQUERY
if( checkForMultiColumnSelectError(pParse, pDest, pEList->nExpr) ){ if( checkForMultiColumnSelectError(pParse, pDest, p->pEList->nExpr) ){
goto select_end; goto select_end;
} }
#endif #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) #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
for(i=0; !p->pPrior && i<pTabList->nSrc; i++){ for(i=0; !p->pPrior && i<pTabList->nSrc; i++){
@@ -4867,6 +4861,10 @@ int sqlite3Select(
} }
#endif #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 #ifndef SQLITE_OMIT_COMPOUND_SELECT
/* Handle compound SELECT statements using the separate multiSelect() /* Handle compound SELECT statements using the separate multiSelect()
@@ -4890,7 +4888,6 @@ int sqlite3Select(
struct SrcList_item *pItem = &pTabList->a[i]; struct SrcList_item *pItem = &pTabList->a[i];
SelectDest dest; SelectDest dest;
Select *pSub = pItem->pSelect; Select *pSub = pItem->pSelect;
if( pSub==0 ) continue; if( pSub==0 ) continue;
/* Sometimes the code for a subquery will be generated more than /* Sometimes the code for a subquery will be generated more than
@@ -4915,6 +4912,9 @@ int sqlite3Select(
*/ */
pParse->nHeight += sqlite3SelectExprHeight(p); 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 if( (pItem->jointype & JT_OUTER)==0
&& pushDownWhereTerms(db, pSub, p->pWhere, pItem->iCursor) && pushDownWhereTerms(db, pSub, p->pWhere, pItem->iCursor)
){ ){
@@ -4925,6 +4925,9 @@ int sqlite3Select(
} }
#endif #endif
} }
/* Generate code to implement the subquery
*/
if( pTabList->nSrc==1 if( pTabList->nSrc==1
&& (p->selFlags & SF_All)==0 && (p->selFlags & SF_All)==0
&& OptimizationEnabled(db, SQLITE_SubqCoroutine) && OptimizationEnabled(db, SQLITE_SubqCoroutine)
@@ -4978,13 +4981,13 @@ int sqlite3Select(
sqlite3VdbeChangeP1(v, topAddr, retAddr); sqlite3VdbeChangeP1(v, topAddr, retAddr);
sqlite3ClearTempRegCache(pParse); sqlite3ClearTempRegCache(pParse);
} }
if( db->mallocFailed ){ if( db->mallocFailed ) goto select_end;
goto select_end;
}
pParse->nHeight -= sqlite3SelectExprHeight(p); pParse->nHeight -= sqlite3SelectExprHeight(p);
} }
pEList = p->pEList;
#endif #endif
/* Various elements of the SELECT copied into local variables for convenience */
pEList = p->pEList;
pWhere = p->pWhere; pWhere = p->pWhere;
pGroupBy = p->pGroupBy; pGroupBy = p->pGroupBy;
pHaving = p->pHaving; pHaving = p->pHaving;
@@ -5013,23 +5016,23 @@ int sqlite3Select(
** BY and DISTINCT, and an index or separate temp-table for the other. ** BY and DISTINCT, and an index or separate temp-table for the other.
*/ */
if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct 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->selFlags &= ~SF_Distinct;
p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0); pGroupBy = p->pGroupBy = sqlite3ExprListDup(db, pEList, 0);
pGroupBy = p->pGroupBy;
/* Notice that even thought SF_Distinct has been cleared from p->selFlags, /* Notice that even thought SF_Distinct has been cleared from p->selFlags,
** the sDistinct.isTnct is still set. Hence, isTnct represents the ** the sDistinct.isTnct is still set. Hence, isTnct represents the
** original setting of the SF_Distinct flag, not the current setting */ ** original setting of the SF_Distinct flag, not the current setting */
assert( sDistinct.isTnct ); assert( sDistinct.isTnct );
} }
/* If there is an ORDER BY clause, then this sorting /* If there is an ORDER BY clause, then create an ephemeral index to
** index might end up being unused if the data can be ** do the sorting. But this sorting ephemeral index might end up
** extracted in pre-sorted order. If that is the case, then the ** being unused if the data can be extracted in pre-sorted order.
** OP_OpenEphemeral instruction will be changed to an OP_Noop once ** If that is the case, then the OP_OpenEphemeral instruction will be
** we figure out that the sorting index is not needed. The addrSortIndex ** changed to an OP_Noop once we figure out that the sorting index is
** variable is used to facilitate that change. ** not needed. The sSort.addrSortIndex variable is used to facilitate
** that change.
*/ */
if( sSort.pOrderBy ){ if( sSort.pOrderBy ){
KeyInfo *pKeyInfo; KeyInfo *pKeyInfo;
@@ -5060,7 +5063,7 @@ int sqlite3Select(
sSort.sortFlags |= SORTFLAG_UseSorter; 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 ){ if( p->selFlags & SF_Distinct ){
sDistinct.tabTnct = pParse->nTab++; sDistinct.tabTnct = pParse->nTab++;
@@ -5145,11 +5148,10 @@ int sqlite3Select(
p->nSelectRow = 1; p->nSelectRow = 1;
} }
/* If there is both a GROUP BY and an ORDER BY clause and they are /* 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 ** 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 ** 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 ** database index that causes rows to be grouped together as required
** but not actually sorted. Either way, record the fact that the ** but not actually sorted. Either way, record the fact that the
** ORDER BY and GROUP BY clauses are the same by setting the orderByGrp ** ORDER BY and GROUP BY clauses are the same by setting the orderByGrp