]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Slight simplification to the query optimizer logic associated with IN (SELECT).
authordrh <drh@noemail.net>
Wed, 9 Mar 2016 15:34:51 +0000 (15:34 +0000)
committerdrh <drh@noemail.net>
Wed, 9 Mar 2016 15:34:51 +0000 (15:34 +0000)
FossilOrigin-Name: 2c55c3c2950cafdc256ab540f60dc4609b9c354b

manifest
manifest.uuid
src/expr.c

index 75c68eb813c586fbec65d517baa1eb9c3f02b1b9..5189ebea8e56e8e4e21bfce6be5bac40662119fc 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\sanother\stest\scase\sfor\sbug\s[5e3c8867].
-D 2016-03-09T15:14:54.990
+C Slight\ssimplification\sto\sthe\squery\soptimizer\slogic\sassociated\swith\sIN\s(SELECT).
+D 2016-03-09T15:34:51.959
 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66
@@ -303,7 +303,7 @@ F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198
 F src/date.c 0b73e681c11fca867fec554750c07fe0d4e417c1
 F src/dbstat.c c845548d4346e606e2f2b7d2e714ace2b8a7dd1b
 F src/delete.c 48802aa3ee6339f576d074336d3ae1b5f40e240f
-F src/expr.c 4ce9e66a297ec08d234817c3d9f7fa8c3bf4d851
+F src/expr.c c329d581e5d631153456369684d7d4bcd94c907d
 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
 F src/fkey.c 5cb42d9a59e2a590776fd3fc8ff6f61d40df3c6e
 F src/func.c 552d300265aed09eea21f68ac742a440550c0062
@@ -1455,7 +1455,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 1ed6b06ea3c432f920fb2b66b6042be906c5d21c
-R 95d0f94d6b7106c7ee892a8bac9f59f5
-U dan
-Z b79fcffb60dd8a57430224ebf643a8ab
+P d91e57e49f23414ec9211b775eb11cd6230a4f96
+R c1ca42221fb7dbc6b010dbeefd096918
+U drh
+Z 8017c7a46c10555b3cc0af7ce0a6b14d
index 519f37196f61468ecc1c2b871a2f656d712e1bd5..41eb62d74803a344f72bdc07aa983c1341934482 100644 (file)
@@ -1 +1 @@
-d91e57e49f23414ec9211b775eb11cd6230a4f96
\ No newline at end of file
+2c55c3c2950cafdc256ab540f60dc4609b9c354b
\ No newline at end of file
index 22ca21de01a724b1d373a3c6f49cdb19b0e125f4..3672d02df1022d6f544c912f9e0c285d85091e6e 100644 (file)
@@ -1568,24 +1568,22 @@ int sqlite3IsRowid(const char *z){
 }
 
 /*
-** Return true if we are able to the IN operator optimization on a
-** query of the form
-**
-**       x IN (SELECT ...)
-**
-** Where the SELECT... clause is as specified by the parameter to this
-** routine.
-**
-** The Select object passed in has already been preprocessed and no
-** errors have been found.
+** pX is the RHS of an IN operator.  If pX is a SELECT statement 
+** that can be simplified to a direct table access, then return
+** a pointer to the SELECT statement.  If pX is not a SELECT statement,
+** or if the SELECT statement needs to be manifested into a transient
+** table, then return NULL.
 */
 #ifndef SQLITE_OMIT_SUBQUERY
-static int isCandidateForInOpt(Select *p){
+static Select *isCandidateForInOpt(Expr *pX){
+  Select *p;
   SrcList *pSrc;
   ExprList *pEList;
+  Expr *pRes;
   Table *pTab;
-  Expr *pRes;                            /* Result expression */
-  if( p==0 ) return 0;                   /* right-hand side of IN is SELECT */
+  if( !ExprHasProperty(pX, EP_xIsSelect) ) return 0;  /* Not a subquery */
+  if( ExprHasProperty(pX, EP_VarSelect)  ) return 0;  /* Correlated subq */
+  p = pX->x.pSelect;
   if( p->pPrior ) return 0;              /* Not a compound SELECT */
   if( p->selFlags & (SF_Distinct|SF_Aggregate) ){
     testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct );
@@ -1601,15 +1599,15 @@ static int isCandidateForInOpt(Select *p){
   if( pSrc->nSrc!=1 ) return 0;          /* Single term in FROM clause */
   if( pSrc->a[0].pSelect ) return 0;     /* FROM is not a subquery or view */
   pTab = pSrc->a[0].pTab;
-  if( NEVER(pTab==0) ) return 0;
+  assert( pTab!=0 );
   assert( pTab->pSelect==0 );            /* FROM clause is not a view */
   if( IsVirtual(pTab) ) return 0;        /* FROM clause not a virtual table */
   pEList = p->pEList;
   if( pEList->nExpr!=1 ) return 0;       /* One column in the result set */
   pRes = pEList->a[0].pExpr;
   if( pRes->op!=TK_COLUMN ) return 0;    /* Result is a column */
-  if( pRes->iTable!=pSrc->a[0].iCursor ) return 0;  /* Not a correlated subq */
-  return 1;
+  assert( pRes->iTable==pSrc->a[0].iCursor );  /* Not a correlated subquery */
+  return p;
 }
 #endif /* SQLITE_OMIT_SUBQUERY */
 
@@ -1741,15 +1739,13 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, u32 inFlags, int *prRhsHasNull){
   ** satisfy the query.  This is preferable to generating a new 
   ** ephemeral table.
   */
-  p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0);
-  if( pParse->nErr==0 && isCandidateForInOpt(p) ){
+  if( pParse->nErr==0 && (p = isCandidateForInOpt(pX))!=0 ){
     sqlite3 *db = pParse->db;              /* Database connection */
     Table *pTab;                           /* Table <table>. */
     Expr *pExpr;                           /* Expression <column> */
     i16 iCol;                              /* Index of column <column> */
     i16 iDb;                               /* Database idx for pTab */
 
-    assert( p );                        /* Because of isCandidateForInOpt(p) */
     assert( p->pEList!=0 );             /* Because of isCandidateForInOpt(p) */
     assert( p->pEList->a[0].pExpr!=0 ); /* Because of isCandidateForInOpt(p) */
     assert( p->pSrc!=0 );               /* Because of isCandidateForInOpt(p) */