]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
An optimization: avoid the use of an intermediate table on UNION ALL if there
authordrh <drh@noemail.net>
Sat, 22 Jun 2002 02:33:38 +0000 (02:33 +0000)
committerdrh <drh@noemail.net>
Sat, 22 Jun 2002 02:33:38 +0000 (02:33 +0000)
is no ORDER BY clause. (CVS 637)

FossilOrigin-Name: 8aa73ce61268a50d353d9a5c878461290195525f

manifest
manifest.uuid
src/main.c
src/select.c
src/sqliteInt.h
test/select4.test

index c920d64faa7bfe9576d7e801b7173fb2a713c620..6517b285f1eb8aee2b9193485592f997c97c3c3e 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sfor\sbugs\s#77\sand\s#80:\sRework\sthe\sLIMIT\smechanism\sto\sbe\sreentrant\sand\sto\nclean\sup\sthe\sVDBE\sstack\sproperly.\s(CVS\s636)
-D 2002-06-21T23:01:50
+C An\soptimization:\savoid\sthe\suse\sof\san\sintermediate\stable\son\sUNION\sALL\sif\sthere\nis\sno\sORDER\sBY\sclause.\s(CVS\s637)
+D 2002-06-22T02:33:38
 F Makefile.in 6291a33b87d2a395aafd7646ee1ed562c6f2c28c
 F Makefile.template 4e11752e0b5c7a043ca50af4296ec562857ba495
 F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0
@@ -28,7 +28,7 @@ F src/func.c 5eae8227a8b0d276a64d51a3880a6e86f238fedf
 F src/hash.c 6a6236b89c8c060c65dabd300a1c8ce7c10edb72
 F src/hash.h cd0433998bc1a3759d244e1637fe5a3c13b53bf8
 F src/insert.c 4bb40ed9dbaba4516fc2abbcff3f08d5687b073c
-F src/main.c 53995702ae744bedd206c1818b1aa0309a04f1fc
+F src/main.c 0e922ecfe4ce58c3e5c49f111d86003607d2114b
 F src/md5.c 0ae1f3e2cac92d06fc6246d1b4b8f61a2fe66d3b
 F src/os.c 9cc40c5384baba4a85e160e67807645ca98ba3cc
 F src/os.h 4a361fccfbc4e7609b3e1557f604f94c1e96ad10
@@ -37,11 +37,11 @@ F src/pager.h 6fddfddd3b73aa8abc081b973886320e3c614f0e
 F src/parse.y 2285d8967d7334d52a2188089e5a881d73ba56f6
 F src/printf.c 236ed7a79386feed4456fa728fff8be793f1547c
 F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe
-F src/select.c 346da88a44aef311e932e95239dc0288fdcb10dd
+F src/select.c d71b59805fe8dd8eb9dd87b50860c07820ec7918
 F src/shell.c 1d22fe870ee852cfb975fd000dbe3973713d0a15
 F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
 F src/sqlite.h.in 7c8882e352cb70818cfaf9bdb5b1b3bee81ef144
-F src/sqliteInt.h f283e5628174d7124c39968442e7adb5b95ea82c
+F src/sqliteInt.h 2f7b1f4d5062a17dfd75caa5639360c76881d5b2
 F src/table.c eed2098c9b577aa17f8abe89313a9c4413f57d63
 F src/tclsqlite.c 9300c9606a38bc0c75d6c0bc8a6197ab979353d1
 F src/test1.c 5cc4f0bbf38237e04e1b2077e285b41bfb4c4cbf
@@ -90,7 +90,7 @@ F test/rowid.test 4c55943300cddf73dd0f88d40a268cab14c83274
 F test/select1.test 0d708cec567104653ec9aa49fecf3444a2e7d150
 F test/select2.test aceea74fd895b9d007512f72499db589735bd8e4
 F test/select3.test 9469c332250a75a0ef1771fb5da62dc04ec77f18
-F test/select4.test 13618c1107c2b51f5ae8417f00c50f899a68056f
+F test/select4.test 10ba54f24ef6ca7958a7045b001079378db2370c
 F test/select5.test c2a6c4a003316ee42cbbd689eebef8fdce0db2ac
 F test/select6.test efb8d0c07a440441db87db2c4ade6904e1407e85
 F test/sort.test 3b996ce7ca385f9cd559944ac0f4027a23aa546b
@@ -137,7 +137,7 @@ F www/speed.tcl da8afcc1d3ccc5696cfb388a68982bc3d9f7f00f
 F www/sqlite.tcl 8b5884354cb615049aed83039f8dfe1552a44279
 F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
-P 7936b0325024c81ed8d4bab192d7350d045ec999
-R d15c924c28dce20794c50e0013aa8eb2
+P 9d5523107937e3700c76666fb058694babdd672c
+R 8009c7f3df0b06e96c68ea3fa98dc912
 U drh
-Z 7d39bfd0dd2f959041e3d2a9c3cd818e
+Z 29b6ba248298ad91adb3978ba4b0728d
index da81f1e59d7f6286f79ed76ad3443080649e2487..24233c1e4bf0ea6fc726cb911812880eb514787b 100644 (file)
@@ -1 +1 @@
-9d5523107937e3700c76666fb058694babdd672c
\ No newline at end of file
+8aa73ce61268a50d353d9a5c878461290195525f
\ No newline at end of file
index 653c315e99163a598461a2c2aa37795a307c8e64..436afc848ea216f30db7c6caa2801a2860abfc10 100644 (file)
@@ -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 @@ int sqlite_function_type(sqlite *db, const char *zName, int dataType){
     p->dataType = dataType; 
     p = p->pNext;
   }
+  return SQLITE_OK;
 }
index 4cd71a2a1182b34e65854aed301b0d0907693853..206e7b89147f9846961b618719c7b2b9453154e7 100644 (file)
@@ -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,28 +441,30 @@ static int selectInnerLoop(
       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 );
+    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.
+    */
+    default: {
+      assert( eDest==SRT_Discard );
+      sqliteVdbeAddOp(v, OP_Pop, nColumn, 0);
+      break;
+    }
   }
   return 0;
 }
@@ -482,6 +484,7 @@ static void generateSortTail(
 ){
   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 @@ static void generateSortTail(
       break;
     }
     default: {
-      assert( end==0 ); /* Cannot happen */
+      /* Do nothing */
       break;
     }
   }
@@ -998,11 +1001,22 @@ static int multiSelect(Parse *pParse, Select *p, int eDest, int iParm){
     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 */
index ef2d5ed44a4f2a46f049e1feba09687fca55d8d1..5abc3161011c6582c0f25bddbb284ed729608ac4 100644 (file)
@@ -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 @@ struct Select {
 #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)")
index 2f3d2ef336e30b5d4673bea717ca7c6418ddca4a..ac36d6d4b0a11bbd53cab4bb76558d642df11e4a 100644 (file)
@@ -12,7 +12,7 @@
 # focus of this file is testing UNION, INTERSECT and EXCEPT operators
 # in SELECT statements.
 #
-# $Id: select4.test,v 1.11 2002/06/20 03:38:26 drh Exp $
+# $Id: select4.test,v 1.12 2002/06/22 02:33:39 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -73,6 +73,23 @@ do_test select4-1.1e {
   }
 } {8 7 6 5 5 4 3 2 1 0}
 execsql {DROP TABLE t2}
+do_test select4-1.1f {
+  execsql {
+    SELECT DISTINCT log FROM t1
+    UNION ALL
+    SELECT n FROM t1 WHERE log=2
+  }
+} {0 1 2 3 4 5 3 4}
+do_test select4-1.1g {
+  execsql {
+    CREATE TABLE t2 AS 
+      SELECT DISTINCT log FROM t1
+      UNION ALL
+      SELECT n FROM t1 WHERE log=2;
+    SELECT * FROM t2;
+  }
+} {0 1 2 3 4 5 3 4}
+execsql {DROP TABLE t2}
 do_test select4-1.2 {
   execsql {
     SELECT log FROM t1 WHERE n IN