-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
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
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
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"));
#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 && i<pTabList->nSrc; i++){
}
#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()
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
*/
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)
){
}
#endif
}
+
+ /* Generate code to implement the subquery
+ */
if( pTabList->nSrc==1
&& (p->selFlags & SF_All)==0
&& OptimizationEnabled(db, SQLITE_SubqCoroutine)
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;
** 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;
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++;
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