aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2016-03-15 17:52:12 +0000
committerdrh <drh@noemail.net>2016-03-15 17:52:12 +0000
commit0ff47e9e1b74e270648cac1ea72f9bcf4e35031d (patch)
tree72ff372a009adf8e5cd81f51de4eddc6f0f2bc1e /src
parent82f525406af6e0ca6887a82c8bb561fac610fa59 (diff)
downloadsqlite-0ff47e9e1b74e270648cac1ea72f9bcf4e35031d.tar.gz
sqlite-0ff47e9e1b74e270648cac1ea72f9bcf4e35031d.zip
Implement FROM-clause subqueries as co-routines whenever they are guaranteed
to be the outer-most loop of the join. FossilOrigin-Name: c7bae50bdccb5bcf3bc22e8ac5bb6725ef13db39
Diffstat (limited to 'src')
-rw-r--r--src/select.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/src/select.c b/src/select.c
index c9bc389b2..a62581efc 100644
--- a/src/select.c
+++ b/src/select.c
@@ -4970,10 +4970,24 @@ int sqlite3Select(
}
/* Generate code to implement the subquery
+ **
+ ** The subquery is implemented as a co-routine if all of these are true:
+ ** (1) The subquery is guaranteed to be the outer loop (so that it
+ ** does not need to be computed more than once)
+ ** (2) The ALL keyword after SELECT is omitted. (Applications are
+ ** allowed to say "SELECT ALL" instead of just "SELECT" to disable
+ ** the use of co-routines.)
+ ** (3) Co-routines are not disabled using sqlite3_test_control()
+ ** with SQLITE_TESTCTRL_OPTIMIZATIONS.
+ **
+ ** TODO: Are there other reasons beside (1) to use a co-routine
+ ** implementation?
*/
- if( pTabList->nSrc==1
- && (p->selFlags & SF_All)==0
- && OptimizationEnabled(db, SQLITE_SubqCoroutine)
+ if( i==0
+ && (pTabList->nSrc==1
+ || (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0) /* (1) */
+ && (p->selFlags & SF_All)==0 /* (2) */
+ && OptimizationEnabled(db, SQLITE_SubqCoroutine) /* (3) */
){
/* Implement a co-routine that will return a single row of the result
** set on each invocation.