Test and documentation updates for sub-queries. (CVS 373)

FossilOrigin-Name: 607c0c49b2098771020514198cb1076de8245a62
This commit is contained in:
drh 2002-02-18 03:21:45 +00:00
parent 22f70c32f0
commit d820cb1b75
5 changed files with 104 additions and 38 deletions

View File

@ -1,5 +1,5 @@
C Add\ssupport\sfor\ssubqueries\sin\sthe\sFROM\sclause\sof\sa\sSELECT.\s\sStill\sneed\nto\sadd\stests\sfor\sthis\sfeature.\s(CVS\s372)
D 2002-02-18T01:17:00
C Test\sand\sdocumentation\supdates\sfor\ssub-queries.\s(CVS\s373)
D 2002-02-18T03:21:46
F Makefile.in 9fa4277413bf1d9cf91365f07d4108d7d87ed2af
F Makefile.template 3372d45f8853afdb70bd30cc6fb50a3cd9069834
F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0
@ -36,7 +36,7 @@ F src/pager.h b28f004e2f5541dc60cc32db01bf80cf4d056283
F src/parse.y f7a6d8122b2d65ae8ded78721d0995f47ad277e1
F src/printf.c 300a90554345751f26e1fc0c0333b90a66110a1d
F src/random.c f6b36bec5ebd3edb3440224bf5bf811fe4ac9a1b
F src/select.c 48c14a44da6bc04a6e19f2c5da15b5ea984ede13
F src/select.c d2bbaf4cba97b4c40503d0dc47e8b729e7088e0b
F src/shell.c c102dfe388c7618a668c944ff157c49cb48f28e3
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
F src/sqlite.h.in f57074c84a2c112a5093ba7a9d9636aa9cacc87c
@ -84,6 +84,7 @@ F test/select2.test ed2c1882857106b85478f54f67000e14966be4c4
F test/select3.test 9469c332250a75a0ef1771fb5da62dc04ec77f18
F test/select4.test 29a2ffb187f3d8b6ca42a0a6b619e9cabe12e228
F test/select5.test c2a6c4a003316ee42cbbd689eebef8fdce0db2ac
F test/select6.test 510377ac09e3b5de9a164eea7732395c6813f0ca
F test/sort.test 3b996ce7ca385f9cd559944ac0f4027a23aa546b
F test/subselect.test 335d3dad8d585726c447dfee8d9c4f7383c76b78
F test/table.test 3ef4254d62ece31a3872ab11cdaec846f6fa8fd1
@ -115,14 +116,14 @@ F www/dynload.tcl 02eb8273aa78cfa9070dd4501dca937fb22b466c
F www/faq.tcl 32cbc134879871604070d4cc3a32e73fb22a35f9
F www/formatchng.tcl 2d9a35c787823b48d72a5c64bb5414a43e26d5ad
F www/index.tcl fba075f31a9cbbf13e6adec080e4943db54dbc05
F www/lang.tcl 58077cb0c383fb312c04bf2ab6a80d7b1c525987
F www/lang.tcl 4865287af7bb8649d8d985772a13e2f6ec639a3e
F www/mingw.tcl f1c7c0a7f53387dd9bb4f8c7e8571b7561510ebc
F www/opcode.tcl bdec8ef9f100dbd87bbef8976c54b88e43fd8ccc
F www/speed.tcl 83457b2bf6bb430900bd48ca3dd98264d9a916a5
F www/sqlite.tcl 8b5884354cb615049aed83039f8dfe1552a44279
F www/tclsqlite.tcl 829b393d1ab187fd7a5e978631b3429318885c49
F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
P 2336b1eadaedf2556a1988acc7bdf133135154dc
R b61f3cbe24d03942a9f4eed0442e350a
P 89ffa9ff132858b62a91df1fb7fe49b2d58c01e7
R 7ab01fed9c641afece9998e0036b69da
U drh
Z 5a9cc96ed308ce034a9e31eeae708204
Z c93e572aa74a691d85a071d29df82a3d

View File

@ -1 +1 @@
89ffa9ff132858b62a91df1fb7fe49b2d58c01e7
607c0c49b2098771020514198cb1076de8245a62

View 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.60 2002/02/18 01:17:00 drh Exp $
** $Id: select.c,v 1.61 2002/02/18 03:21:46 drh Exp $
*/
#include "sqliteInt.h"
@ -330,6 +330,10 @@ Table *sqliteResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){
pTab->aCol[i].zName = sqliteStrDup(pEList->a[i].zName);
}else if( (p=pEList->a[i].pExpr)->span.z && p->span.z[0] ){
sqliteSetNString(&pTab->aCol[i].zName, p->span.z, p->span.n, 0);
}else if( p->op==TK_DOT && p->pRight && p->pRight->token.z &&
p->pRight->token.z[0] ){
sqliteSetNString(&pTab->aCol[i].zName,
p->pRight->token.z, p->pRight->token.n, 0);
}else{
char zBuf[30];
sprintf(zBuf, "column%d", i+1);
@ -781,7 +785,6 @@ int sqliteSelect(
** errors before this routine starts.
*/
if( pParse->nErr>0 ) goto select_end;
sqliteAggregateInfoReset(pParse);
/* Look up every table in the table list and create an appropriate
** columnlist in pEList if there isn't one already. (The parser leaves
@ -908,8 +911,28 @@ int sqliteSelect(
}
}
/* Begin generating code.
*/
v = sqliteGetVdbe(pParse);
if( v==0 ) goto select_end;
/* Generate code for all sub-queries in the FROM clause
*/
for(i=0; i<pTabList->nId; i++){
int oldNTab;
Table *pTab = pTabList->a[i].pTab;
if( !pTab->isTransient ) continue;
assert( pTabList->a[i].pSelect!=0 );
oldNTab = pParse->nTab;
pParse->nTab += i+1;
sqliteVdbeAddOp(v, OP_OpenTemp, oldNTab+i, 0);
sqliteSelect(pParse, pTabList->a[i].pSelect, SRT_Table, oldNTab+i);
pParse->nTab = oldNTab;
}
/* Do an analysis of aggregate expressions.
*/
sqliteAggregateInfoReset(pParse);
if( isAgg ){
assert( pParse->nAgg==0 && pParse->iAggCount<0 );
for(i=0; i<pEList->nExpr; i++){
@ -936,25 +959,6 @@ int sqliteSelect(
}
}
/* Begin generating code.
*/
v = sqliteGetVdbe(pParse);
if( v==0 ) goto select_end;
/* Generate code for all sub-queries in the FROM clause
*/
for(i=0; i<pTabList->nId; i++){
int oldNTab;
Table *pTab = pTabList->a[i].pTab;
if( !pTab->isTransient ) continue;
assert( pTabList->a[i].pSelect!=0 );
oldNTab = pParse->nTab;
pParse->nTab += i+1;
sqliteVdbeAddOp(v, OP_OpenTemp, oldNTab+i, 0);
sqliteSelect(pParse, pTabList->a[i].pSelect, SRT_Table, oldNTab+i);
pParse->nTab = oldNTab;
}
/* Set the limiter
*/
if( p->nLimit<=0 ){

56
test/select6.test Normal file
View File

@ -0,0 +1,56 @@
# 2001 September 15
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library. The
# focus of this file is testing SELECT statements that contain
# subqueries in their FROM clause.
#
# $Id: select6.test,v 1.1 2002/02/18 03:21:47 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# Build some test data
#
set fd [open data1.txt w]
for {set i 1} {$i<32} {incr i} {
for {set j 0} {pow(2,$j)<$i} {incr j} {}
puts $fd "[expr {32-$i}]\t[expr {10-$j}]"
}
close $fd
execsql {
CREATE TABLE t1(x int, y int);
COPY t1 FROM 'data1.txt'
}
file delete data1.txt
do_test select6-1.0 {
execsql {SELECT DISTINCT y FROM t1 ORDER BY y}
} {5 6 7 8 9 10}
do_test select6-1.1 {
execsql2 {SELECT * FROM (SELECT x, y FROM t1 ORDER BY x LIMIT 1)}
} {x 31 y 10}
do_test select6-1.2 {
execsql {SELECT count(*) FROM (SELECT y FROM t1)}
} {31}
do_test select6-1.3 {
execsql {SELECT count(*) FROM (SELECT DISTINCT y FROM t1)}
} {6}
do_test select6-1.4 {
execsql {SELECT count(*) FROM (SELECT DISTINCT * FROM (SELECT y FROM t1))}
} {6}
do_test select6-1.5 {
execsql {SELECT count(*) FROM (SELECT * FROM (SELECT DISTINCT y FROM t1))}
} {6}
finish_test

View File

@ -1,7 +1,7 @@
#
# Run this Tcl script to generate the sqlite.html file.
#
set rcsid {$Id: lang.tcl,v 1.22 2002/02/03 19:06:04 drh Exp $}
set rcsid {$Id: lang.tcl,v 1.23 2002/02/18 03:21:47 drh Exp $}
puts {<html>
<head>
@ -782,7 +782,7 @@ information.</p>
Section SELECT select
Syntax {sql-statement} {
SELECT <result> FROM <table-list>
SELECT <result> FROM <table-list>
[WHERE <expression>]
[GROUP BY <expr-list>]
[HAVING <expression>]
@ -790,11 +790,14 @@ SELECT <result> FROM <table-list>
[ORDER BY <sort-expr-list>]
[LIMIT <integer> [OFFSET <integer>]]
} {result} {
STAR | <result-column> [, <result-column>]*
<result-column> [, <result-column>]*
} {result-column} {
<expression> [ [AS] <string> ]
STAR | <expression> [ [AS] <string> ]
} {table-list} {
<table-name> [, <table-name>]*
<table> [, <table>]*
} {table} {
<table-name> [AS <alias>] |
( <select> ) [AS <alias>]
} {sort-expr-list} {
<expr> [<sort-order>] [, <expr> [<sort-order>]]*
} {sort-order} {
@ -809,13 +812,15 @@ result of a SELECT is zero or more rows of data where each row
has a fixed number of columns. The number of columns in the
result is specified by the expression list in between the
SELECT and FROM keywords. Any arbitrary expression can be used
as a result. If the result specification is just}
puts "[Operator *] then all columns of all tables are used as the result."
puts {</p>
as a result. If a result expression is }
puts "[Operator *] then all columns of all tables are substituted"
puts {for that one expression.</p>
<p>The query is executed again one or more tables specified after
the FROM keyword. If more than one table is specified, then the
query is against the join of the various tables.</p>
query is against the (inner) join of the various tables. A sub-query
in parentheses may be substituted for any table name in the FROM clause.
</p>
<p>The WHERE clause can be used to limit the number of rows over
which the query operates. In the current implementation,