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)")