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/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