mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
An optimization: avoid the use of an intermediate table on UNION ALL if there
is no ORDER BY clause. (CVS 637) FossilOrigin-Name: 8aa73ce61268a50d353d9a5c878461290195525f
This commit is contained in:
18
manifest
18
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)
|
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-21T23:01:50
|
D 2002-06-22T02:33:38
|
||||||
F Makefile.in 6291a33b87d2a395aafd7646ee1ed562c6f2c28c
|
F Makefile.in 6291a33b87d2a395aafd7646ee1ed562c6f2c28c
|
||||||
F Makefile.template 4e11752e0b5c7a043ca50af4296ec562857ba495
|
F Makefile.template 4e11752e0b5c7a043ca50af4296ec562857ba495
|
||||||
F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0
|
F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0
|
||||||
@ -28,7 +28,7 @@ F src/func.c 5eae8227a8b0d276a64d51a3880a6e86f238fedf
|
|||||||
F src/hash.c 6a6236b89c8c060c65dabd300a1c8ce7c10edb72
|
F src/hash.c 6a6236b89c8c060c65dabd300a1c8ce7c10edb72
|
||||||
F src/hash.h cd0433998bc1a3759d244e1637fe5a3c13b53bf8
|
F src/hash.h cd0433998bc1a3759d244e1637fe5a3c13b53bf8
|
||||||
F src/insert.c 4bb40ed9dbaba4516fc2abbcff3f08d5687b073c
|
F src/insert.c 4bb40ed9dbaba4516fc2abbcff3f08d5687b073c
|
||||||
F src/main.c 53995702ae744bedd206c1818b1aa0309a04f1fc
|
F src/main.c 0e922ecfe4ce58c3e5c49f111d86003607d2114b
|
||||||
F src/md5.c 0ae1f3e2cac92d06fc6246d1b4b8f61a2fe66d3b
|
F src/md5.c 0ae1f3e2cac92d06fc6246d1b4b8f61a2fe66d3b
|
||||||
F src/os.c 9cc40c5384baba4a85e160e67807645ca98ba3cc
|
F src/os.c 9cc40c5384baba4a85e160e67807645ca98ba3cc
|
||||||
F src/os.h 4a361fccfbc4e7609b3e1557f604f94c1e96ad10
|
F src/os.h 4a361fccfbc4e7609b3e1557f604f94c1e96ad10
|
||||||
@ -37,11 +37,11 @@ F src/pager.h 6fddfddd3b73aa8abc081b973886320e3c614f0e
|
|||||||
F src/parse.y 2285d8967d7334d52a2188089e5a881d73ba56f6
|
F src/parse.y 2285d8967d7334d52a2188089e5a881d73ba56f6
|
||||||
F src/printf.c 236ed7a79386feed4456fa728fff8be793f1547c
|
F src/printf.c 236ed7a79386feed4456fa728fff8be793f1547c
|
||||||
F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe
|
F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe
|
||||||
F src/select.c 346da88a44aef311e932e95239dc0288fdcb10dd
|
F src/select.c d71b59805fe8dd8eb9dd87b50860c07820ec7918
|
||||||
F src/shell.c 1d22fe870ee852cfb975fd000dbe3973713d0a15
|
F src/shell.c 1d22fe870ee852cfb975fd000dbe3973713d0a15
|
||||||
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
|
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
|
||||||
F src/sqlite.h.in 7c8882e352cb70818cfaf9bdb5b1b3bee81ef144
|
F src/sqlite.h.in 7c8882e352cb70818cfaf9bdb5b1b3bee81ef144
|
||||||
F src/sqliteInt.h f283e5628174d7124c39968442e7adb5b95ea82c
|
F src/sqliteInt.h 2f7b1f4d5062a17dfd75caa5639360c76881d5b2
|
||||||
F src/table.c eed2098c9b577aa17f8abe89313a9c4413f57d63
|
F src/table.c eed2098c9b577aa17f8abe89313a9c4413f57d63
|
||||||
F src/tclsqlite.c 9300c9606a38bc0c75d6c0bc8a6197ab979353d1
|
F src/tclsqlite.c 9300c9606a38bc0c75d6c0bc8a6197ab979353d1
|
||||||
F src/test1.c 5cc4f0bbf38237e04e1b2077e285b41bfb4c4cbf
|
F src/test1.c 5cc4f0bbf38237e04e1b2077e285b41bfb4c4cbf
|
||||||
@ -90,7 +90,7 @@ F test/rowid.test 4c55943300cddf73dd0f88d40a268cab14c83274
|
|||||||
F test/select1.test 0d708cec567104653ec9aa49fecf3444a2e7d150
|
F test/select1.test 0d708cec567104653ec9aa49fecf3444a2e7d150
|
||||||
F test/select2.test aceea74fd895b9d007512f72499db589735bd8e4
|
F test/select2.test aceea74fd895b9d007512f72499db589735bd8e4
|
||||||
F test/select3.test 9469c332250a75a0ef1771fb5da62dc04ec77f18
|
F test/select3.test 9469c332250a75a0ef1771fb5da62dc04ec77f18
|
||||||
F test/select4.test 13618c1107c2b51f5ae8417f00c50f899a68056f
|
F test/select4.test 10ba54f24ef6ca7958a7045b001079378db2370c
|
||||||
F test/select5.test c2a6c4a003316ee42cbbd689eebef8fdce0db2ac
|
F test/select5.test c2a6c4a003316ee42cbbd689eebef8fdce0db2ac
|
||||||
F test/select6.test efb8d0c07a440441db87db2c4ade6904e1407e85
|
F test/select6.test efb8d0c07a440441db87db2c4ade6904e1407e85
|
||||||
F test/sort.test 3b996ce7ca385f9cd559944ac0f4027a23aa546b
|
F test/sort.test 3b996ce7ca385f9cd559944ac0f4027a23aa546b
|
||||||
@ -137,7 +137,7 @@ F www/speed.tcl da8afcc1d3ccc5696cfb388a68982bc3d9f7f00f
|
|||||||
F www/sqlite.tcl 8b5884354cb615049aed83039f8dfe1552a44279
|
F www/sqlite.tcl 8b5884354cb615049aed83039f8dfe1552a44279
|
||||||
F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
|
F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
|
||||||
F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
|
F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
|
||||||
P 7936b0325024c81ed8d4bab192d7350d045ec999
|
P 9d5523107937e3700c76666fb058694babdd672c
|
||||||
R d15c924c28dce20794c50e0013aa8eb2
|
R 8009c7f3df0b06e96c68ea3fa98dc912
|
||||||
U drh
|
U drh
|
||||||
Z 7d39bfd0dd2f959041e3d2a9c3cd818e
|
Z 29b6ba248298ad91adb3978ba4b0728d
|
||||||
|
@ -1 +1 @@
|
|||||||
9d5523107937e3700c76666fb058694babdd672c
|
8aa73ce61268a50d353d9a5c878461290195525f
|
@ -14,7 +14,7 @@
|
|||||||
** other files are for internal use by SQLite and should not be
|
** other files are for internal use by SQLite and should not be
|
||||||
** accessed by users of the library.
|
** 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 "sqliteInt.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
@ -843,4 +843,5 @@ int sqlite_function_type(sqlite *db, const char *zName, int dataType){
|
|||||||
p->dataType = dataType;
|
p->dataType = dataType;
|
||||||
p = p->pNext;
|
p = p->pNext;
|
||||||
}
|
}
|
||||||
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
50
src/select.c
50
src/select.c
@ -12,7 +12,7 @@
|
|||||||
** This file contains C code routines that are called by the parser
|
** This file contains C code routines that are called by the parser
|
||||||
** to handle SELECT statements in SQLite.
|
** 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"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@ -441,26 +441,28 @@ static int selectInnerLoop(
|
|||||||
break;
|
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
|
/* Discard the results. This is used for SELECT statements inside
|
||||||
** the body of a TRIGGER. The purpose of such selects is to call
|
** the body of a TRIGGER. The purpose of such selects is to call
|
||||||
** user-defined functions that have side effects. We do not care
|
** user-defined functions that have side effects. We do not care
|
||||||
** about the actual results of the select.
|
** 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: {
|
default: {
|
||||||
assert( eDest==SRT_Callback );
|
assert( eDest==SRT_Discard );
|
||||||
if( pOrderBy ){
|
sqliteVdbeAddOp(v, OP_Pop, nColumn, 0);
|
||||||
sqliteVdbeAddOp(v, OP_SortMakeRec, nColumn, 0);
|
|
||||||
pushOntoSorter(pParse, v, pOrderBy);
|
|
||||||
}else{
|
|
||||||
sqliteVdbeAddOp(v, OP_Callback, nColumn, 0);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -482,6 +484,7 @@ static void generateSortTail(
|
|||||||
){
|
){
|
||||||
int end = sqliteVdbeMakeLabel(v);
|
int end = sqliteVdbeMakeLabel(v);
|
||||||
int addr;
|
int addr;
|
||||||
|
if( eDest==SRT_Sorter ) return;
|
||||||
sqliteVdbeAddOp(v, OP_Sort, 0, 0);
|
sqliteVdbeAddOp(v, OP_Sort, 0, 0);
|
||||||
addr = sqliteVdbeAddOp(v, OP_SortNext, 0, end);
|
addr = sqliteVdbeAddOp(v, OP_SortNext, 0, end);
|
||||||
if( p->nOffset>0 ){
|
if( p->nOffset>0 ){
|
||||||
@ -518,7 +521,7 @@ static void generateSortTail(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
assert( end==0 ); /* Cannot happen */
|
/* Do nothing */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -998,11 +1001,22 @@ static int multiSelect(Parse *pParse, Select *p, int eDest, int iParm){
|
|||||||
eDest = SRT_Table;
|
eDest = SRT_Table;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process the UNION or INTERSECTION
|
/* Generate code for the left and right SELECT statements.
|
||||||
*/
|
*/
|
||||||
base = pParse->nTab;
|
base = pParse->nTab;
|
||||||
switch( p->op ){
|
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_EXCEPT:
|
||||||
case TK_UNION: {
|
case TK_UNION: {
|
||||||
int unionTab; /* Cursor number of the temporary table holding result */
|
int unionTab; /* Cursor number of the temporary table holding result */
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** Internal interface definitions for SQLite.
|
** 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 "sqlite.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
@ -603,6 +603,7 @@ struct Select {
|
|||||||
#define SRT_Table 7 /* Store result as data with a unique key */
|
#define SRT_Table 7 /* Store result as data with a unique key */
|
||||||
#define SRT_TempTable 8 /* Store result in a trasient table */
|
#define SRT_TempTable 8 /* Store result in a trasient table */
|
||||||
#define SRT_Discard 9 /* Do not save the results anywhere */
|
#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)")
|
** When a SELECT uses aggregate functions (like "count(*)" or "avg(f1)")
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
# focus of this file is testing UNION, INTERSECT and EXCEPT operators
|
# focus of this file is testing UNION, INTERSECT and EXCEPT operators
|
||||||
# in SELECT statements.
|
# 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]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@ -73,6 +73,23 @@ do_test select4-1.1e {
|
|||||||
}
|
}
|
||||||
} {8 7 6 5 5 4 3 2 1 0}
|
} {8 7 6 5 5 4 3 2 1 0}
|
||||||
execsql {DROP TABLE t2}
|
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 {
|
do_test select4-1.2 {
|
||||||
execsql {
|
execsql {
|
||||||
SELECT log FROM t1 WHERE n IN
|
SELECT log FROM t1 WHERE n IN
|
||||||
|
Reference in New Issue
Block a user