An optimization: avoid the use of an intermediate table on UNION ALL if there
is no ORDER BY clause. (CVS 637)

FossilOrigin-Name: 8aa73ce61268a50d353d9a5c878461290195525f
diff --git a/src/main.c b/src/main.c
index 653c315..436afc8 100644
--- a/src/main.c
+++ b/src/main.c
@@ -14,7 +14,7 @@
 ** other files are for internal use by SQLite and should not be
 ** accessed by users of the library.
 **
-** $Id: main.c,v 1.82 2002/06/21 11:55:49 drh Exp $
+** $Id: main.c,v 1.83 2002/06/22 02:33:38 drh Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -843,4 +843,5 @@
     p->dataType = dataType; 
     p = p->pNext;
   }
+  return SQLITE_OK;
 }
diff --git a/src/select.c b/src/select.c
index 4cd71a2..206e7b8 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.96 2002/06/21 23:01:50 drh Exp $
+** $Id: select.c,v 1.97 2002/06/22 02:33:38 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -441,26 +441,28 @@
       break;
     }
 
+    /* Send the data to the callback function.
+    */
+    case SRT_Callback:
+    case SRT_Sorter: {
+      if( pOrderBy ){
+        sqliteVdbeAddOp(v, OP_SortMakeRec, nColumn, 0);
+        pushOntoSorter(pParse, v, pOrderBy);
+      }else{
+        assert( eDest==SRT_Callback );
+        sqliteVdbeAddOp(v, OP_Callback, nColumn, 0);
+      }
+      break;
+    }
+
     /* Discard the results.  This is used for SELECT statements inside
     ** the body of a TRIGGER.  The purpose of such selects is to call
     ** user-defined functions that have side effects.  We do not care
     ** about the actual results of the select.
     */
-    case SRT_Discard: {
-      sqliteVdbeAddOp(v, OP_Pop, nColumn, 0);
-      break;
-    }
-
-    /* Send the data to the callback function.
-    */
     default: {
-      assert( eDest==SRT_Callback );
-      if( pOrderBy ){
-        sqliteVdbeAddOp(v, OP_SortMakeRec, nColumn, 0);
-        pushOntoSorter(pParse, v, pOrderBy);
-      }else{
-        sqliteVdbeAddOp(v, OP_Callback, nColumn, 0);
-      }
+      assert( eDest==SRT_Discard );
+      sqliteVdbeAddOp(v, OP_Pop, nColumn, 0);
       break;
     }
   }
@@ -482,6 +484,7 @@
 ){
   int end = sqliteVdbeMakeLabel(v);
   int addr;
+  if( eDest==SRT_Sorter ) return;
   sqliteVdbeAddOp(v, OP_Sort, 0, 0);
   addr = sqliteVdbeAddOp(v, OP_SortNext, 0, end);
   if( p->nOffset>0 ){
@@ -518,7 +521,7 @@
       break;
     }
     default: {
-      assert( end==0 ); /* Cannot happen */
+      /* Do nothing */
       break;
     }
   }
@@ -998,11 +1001,22 @@
     eDest = SRT_Table;
   }
 
-  /* Process the UNION or INTERSECTION
+  /* Generate code for the left and right SELECT statements.
   */
   base = pParse->nTab;
   switch( p->op ){
-    case TK_ALL:
+    case TK_ALL: {
+      if( p->pOrderBy==0 ){
+        rc = sqliteSelect(pParse, pPrior, eDest, iParm, 0, 0, 0);
+        if( rc ) return rc;
+        p->pPrior = 0;
+        rc = sqliteSelect(pParse, p, eDest, iParm, 0, 0, 0);
+        p->pPrior = pPrior;
+        if( rc ) return rc;
+        break;
+      }
+      /* For UNION ALL ... ORDER BY fall through to the next case */
+    }
     case TK_EXCEPT:
     case TK_UNION: {
       int unionTab;    /* Cursor number of the temporary table holding result */
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index ef2d5ed..5abc316 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.128 2002/06/21 23:01:50 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.129 2002/06/22 02:33:39 drh Exp $
 */
 #include "sqlite.h"
 #include "hash.h"
@@ -603,6 +603,7 @@
 #define SRT_Table        7  /* Store result as data with a unique key */
 #define SRT_TempTable    8  /* Store result in a trasient table */
 #define SRT_Discard      9  /* Do not save the results anywhere */
+#define SRT_Sorter      10  /* Store results in the sorter */
 
 /*
 ** When a SELECT uses aggregate functions (like "count(*)" or "avg(f1)")