Minor optimizations for sub-selects in EXISTS(...) expressions: Discard any DISTINCT or ORDER BY clauses and do not calculate any column values. (CVS 4658)

FossilOrigin-Name: fbd17a8976cc9b4dd7c7c903d8beade9a7ef095f
diff --git a/manifest b/manifest
index 2ddab03..e4108d9 100644
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Combine\sthe\seDest\sand\siParm\sarguments\sto\ssqlite3Select()\sinto\sa\ssingle\stype\s-\s"SelectDest".\s(CVS\s4657)
-D 2008-01-02T16:27:10
+C Minor\soptimizations\sfor\ssub-selects\sin\sEXISTS(...)\sexpressions:\sDiscard\sany\sDISTINCT\sor\sORDER\sBY\sclauses\sand\sdo\snot\scalculate\sany\scolumn\svalues.\s(CVS\s4658)
+D 2008-01-02T17:11:14
 F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
 F Makefile.in 30789bf70614bad659351660d76b8e533f3340e9
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -131,12 +131,12 @@
 F src/prepare.c 7aeba7851773fbe3950a26b35d3389bef0eb1c62
 F src/printf.c eb27822ba2eec669161409ca31279a24c26ac910
 F src/random.c 4a22746501bf36b0a088c66e38dde5daba6a35da
-F src/select.c 6a3790a03f10b2dfce9011d93e817b2cff7746d4
+F src/select.c cc4064f931c32139f97b43572180a99eff08e759
 F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
 F src/shell.c 77895a54c2082157e169c857a2e244525ec25af7
 F src/sqlite.h.in 2a7e3776534bbe6ff2cdc058f3abebe91e7e429f
 F src/sqlite3ext.h a93f59cdee3638dc0c9c086f80df743a4e68c3cb
-F src/sqliteInt.h ff7a5de4ac31a974eab8cc5286fef01d4ed2e148
+F src/sqliteInt.h dc0f9180d4aa50fce261d7ae7387952e02752165
 F src/sqliteLimit.h ee4430f88f69bf63527967bb35ca52af7b0ccb1e
 F src/table.c 1aeb9eab57b4235db86fe15a35dec76fb445a9c4
 F src/tclsqlite.c 9923abeffc9b3d7dad58e92b319661521f60debf
@@ -603,7 +603,7 @@
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
 F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
-P 4c7f35da7751c61a9b61b1d95adddcc37fff3266
-R cf4761a43ed1fe7db5bce1f482fb074b
+P 86dcdfe6d7d629618ccb3c3ff0ca09f2da2d06c7
+R 982c17244c2079cbd0e5e4196c9007ad
 U danielk1977
-Z 493527b5521ff75db65bcee76afc559a
+Z 3000de620d66b1fa18c8d40dc95b7145
diff --git a/manifest.uuid b/manifest.uuid
index 28f9cf8..9a124b5 100644
--- a/manifest.uuid
+++ b/manifest.uuid
@@ -1 +1 @@
-86dcdfe6d7d629618ccb3c3ff0ca09f2da2d06c7
\ No newline at end of file
+fbd17a8976cc9b4dd7c7c903d8beade9a7ef095f
\ No newline at end of file
diff --git a/src/select.c b/src/select.c
index 34b7d31..a854e3e 100644
--- a/src/select.c
+++ b/src/select.c
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle SELECT statements in SQLite.
 **
-** $Id: select.c,v 1.376 2008/01/02 16:27:10 danielk1977 Exp $
+** $Id: select.c,v 1.377 2008/01/02 17:11:14 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 
@@ -548,7 +548,10 @@
     for(i=0; i<nColumn; i++){
       sqlite3VdbeOp3Int(v, OP_Column, srcTab, i, iMem+i+1);
     }
-  }else{
+  }else if( eDest!=SRT_Exists ){
+    /* If the destination is an EXISTS(...) expression, the actual
+    ** values returned by the SELECT are not required.
+    */
     for(i=0; i<n; i++){
       sqlite3ExprIntoReg(pParse, pEList->a[i].pExpr, iMem+i+1);
     }
@@ -3143,6 +3146,13 @@
   pOrderBy = p->pOrderBy;
   if( IgnorableOrderby(pDest) ){
     p->pOrderBy = 0;
+
+    /* In these cases the DISTINCT operator makes no difference to the
+    ** results, so remove it if it were specified.
+    */
+    assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union || 
+           pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard);
+    p->isDistinct = 0;
   }
   if( sqlite3SelectResolve(pParse, p, 0) ){
     goto select_end;
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 89b337b..c25f80e 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.629 2008/01/02 16:27:10 danielk1977 Exp $
+** @(#) $Id: sqliteInt.h,v 1.630 2008/01/02 17:11:14 danielk1977 Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
@@ -1330,18 +1330,18 @@
 */
 #define SRT_Union        1  /* Store result as keys in an index */
 #define SRT_Except       2  /* Remove result from a UNION index */
-#define SRT_Discard      3  /* Do not save the results anywhere */
+#define SRT_Exists       3  /* Store 1 if the result is not empty */
+#define SRT_Discard      4  /* Do not save the results anywhere */
 
 /* The ORDER BY clause is ignored for all of the above */
 #define IgnorableOrderby(X) ((X->eDest)<=SRT_Discard)
 
-#define SRT_Callback     4  /* Invoke a callback with each row of result */
-#define SRT_Mem          5  /* Store result in a memory cell */
-#define SRT_Set          6  /* Store non-null results as keys in an index */
-#define SRT_Table        7  /* Store result as data with an automatic rowid */
-#define SRT_EphemTab     8  /* Create transient tab and store like SRT_Table */
-#define SRT_Subroutine   9  /* Call a subroutine to handle results */
-#define SRT_Exists      10  /* Store 1 if the result is not empty */
+#define SRT_Callback     5  /* Invoke a callback with each row of result */
+#define SRT_Mem          6  /* Store result in a memory cell */
+#define SRT_Set          7  /* Store non-null results as keys in an index */
+#define SRT_Table        8  /* Store result as data with an automatic rowid */
+#define SRT_EphemTab     9  /* Create transient tab and store like SRT_Table */
+#define SRT_Subroutine  10  /* Call a subroutine to handle results */
 
 /*
 ** A structure used to customize the behaviour of sqlite3Select(). See