1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-12-24 14:17:58 +03:00

Additional testing of LEFT OUTER JOIN. (CVS 588)

FossilOrigin-Name: d8d04c14f18d1feba89ccea0be70530a18248c51
This commit is contained in:
drh
2002-05-25 00:18:20 +00:00
parent ad2d8307ac
commit 195e6967fb
5 changed files with 163 additions and 21 deletions

View File

@@ -1,5 +1,5 @@
C Initial\simplementation\sof\sLEFT\sOUTER\sJOIN\sincluding\sthe\sexpanded\sSQL92\sjoin\nsyntax.\sThe\sbasic\sfunctionality\sis\sthere\sbut\sthere\sis\sstill\sa\slot\sof\stesting\nto\sdo.\s(CVS\s587)
D 2002-05-24T20:31:37
C Additional\stesting\sof\sLEFT\sOUTER\sJOIN.\s(CVS\s588)
D 2002-05-25T00:18:21
F Makefile.in 6291a33b87d2a395aafd7646ee1ed562c6f2c28c
F Makefile.template 4e11752e0b5c7a043ca50af4296ec562857ba495
F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0
@@ -37,11 +37,11 @@ F src/pager.h 6fddfddd3b73aa8abc081b973886320e3c614f0e
F src/parse.y c681da701bf142967325b8791f22418e2d81552d
F src/printf.c d8032ee18b860c812eeff596c9bebfdacb7930fd
F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe
F src/select.c 8f0ec9de36a22d167402af6ff8936e142ada4a11
F src/select.c bbf00ee2b4412c7249baf0ba737ba6a93fe82e78
F src/shell.c 1d22fe870ee852cfb975fd000dbe3973713d0a15
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
F src/sqlite.h.in 0038faa6d642de06b91143ee65a131bd831d020b
F src/sqliteInt.h 5b71407c8546514168ae6984c18c5d035a2643ce
F src/sqliteInt.h 9d565908e2ca53c54d1a0ae445cba039ee018aba
F src/table.c eed2098c9b577aa17f8abe89313a9c4413f57d63
F src/tclsqlite.c 9300c9606a38bc0c75d6c0bc8a6197ab979353d1
F src/test1.c 09d95048b66ce6dcd2bae90f443589043d7d631e
@@ -71,7 +71,7 @@ F test/insert.test 58d44c19b3557f67f4aeb5110ed9ef02038c3684
F test/insert2.test eb8481878a7f52ccb4e3346f87550f5afdd77f76
F test/intpkey.test 31b5f28b2c44273e6695cf36ab2e4133aee7753c
F test/ioerr.test 57d9bffaca18b34f9e976f786eadc2591d6efc6a
F test/join.test 905f4b13f8505f6b5b25af82ef11180860e6b180
F test/join.test ea6a4097e4fcebbb16eac7ec819569e759336a74
F test/limit.test 6f98bcefc92209103bb3764c81975a6ec21d6702
F test/lock.test 3fcfd46a73119f6a18094673328a32c7b3047a8f
F test/main.test c66b564554b770ee7fdbf6a66c0cd90329bc2c85
@@ -135,7 +135,7 @@ F www/speed.tcl da8afcc1d3ccc5696cfb388a68982bc3d9f7f00f
F www/sqlite.tcl 8b5884354cb615049aed83039f8dfe1552a44279
F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
P e238643efdbe1394c7ff85e34e486f7c6082b6cc
R b59d515c126e5f1a822d5f6777b2906b
P 99bd1f5b9a1a20bfeefe15c00d96a34a5f40923e
R 289d0473700b92bde61e98c6617d8be0
U drh
Z 38ee23869a9185b6bcb4ab87628c02b5
Z f910247eaeb3d662acb5a7b6aeac9b33

View File

@@ -1 +1 @@
99bd1f5b9a1a20bfeefe15c00d96a34a5f40923e
d8d04c14f18d1feba89ccea0be70530a18248c51

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.84 2002/05/24 20:31:37 drh Exp $
** $Id: select.c,v 1.85 2002/05/25 00:18:21 drh Exp $
*/
#include "sqliteInt.h"
@@ -81,9 +81,9 @@ int sqliteJoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){
int code;
} keywords[] = {
{ "natural", 7, JT_NATURAL },
{ "left", 4, JT_LEFT },
{ "right", 5, JT_RIGHT },
{ "full", 4, JT_FULL },
{ "left", 4, JT_LEFT|JT_OUTER },
{ "right", 5, JT_RIGHT|JT_OUTER },
{ "full", 4, JT_LEFT|JT_RIGHT|JT_OUTER },
{ "outer", 5, JT_OUTER },
{ "inner", 5, JT_INNER },
{ "cross", 5, JT_INNER },
@@ -92,7 +92,7 @@ int sqliteJoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){
apAll[0] = pA;
apAll[1] = pB;
apAll[2] = pC;
for(i=0; apAll[i]; i++){
for(i=0; i<3 && apAll[i]; i++){
p = apAll[i];
for(j=0; j<sizeof(keywords)/sizeof(keywords[0]); j++){
if( p->n==keywords[j].nChar
@@ -108,8 +108,7 @@ int sqliteJoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){
}
if(
(jointype & (JT_INNER|JT_OUTER))==(JT_INNER|JT_OUTER) ||
(jointype & JT_ERROR)!=0 ||
(jointype & JT_RIGHT)==JT_RIGHT
(jointype & JT_ERROR)!=0
){
static Token dummy = { 0, 0 };
char *zSp1 = " ", *zSp2 = " ";
@@ -119,6 +118,11 @@ int sqliteJoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){
pA->z, pA->n, zSp1, 1, pB->z, pB->n, zSp2, 1, pC->z, pC->n, 0);
pParse->nErr++;
jointype = JT_INNER;
}else if( jointype & JT_RIGHT ){
sqliteSetString(&pParse->zErrMsg,
"RIGHT and FULL OUTER JOINs are not currently supported", 0);
pParse->nErr++;
jointype = JT_INNER;
}
return jointype;
}

View File

@@ -11,7 +11,7 @@
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.115 2002/05/24 20:31:37 drh Exp $
** @(#) $Id: sqliteInt.h,v 1.116 2002/05/25 00:18:21 drh Exp $
*/
#include "sqlite.h"
#include "hash.h"
@@ -461,9 +461,8 @@ struct SrcList {
*/
#define JT_INNER 0x0001 /* Any kind of inner or cross join */
#define JT_NATURAL 0x0002 /* True for a "natural" join */
#define JT_LEFT 0x0014 /* Left outer join */
#define JT_RIGHT 0x0018 /* Right outer join */
#define JT_FULL 0x001a /* Combination of left and right outer join */
#define JT_LEFT 0x0004 /* Left outer join */
#define JT_RIGHT 0x0008 /* Right outer join */
#define JT_OUTER 0x0010 /* The "OUTER" keyword is present */
#define JT_ERROR 0x0020 /* unknown or unsupported join type */

View File

@@ -12,7 +12,7 @@
#
# This file implements tests for joins, including outer joins.
#
# $Id: join.test,v 1.1 2002/05/24 20:31:38 drh Exp $
# $Id: join.test,v 1.2 2002/05/25 00:18:21 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@@ -41,6 +41,11 @@ do_test join-1.3 {
SELECT * FROM t1 NATURAL JOIN t2;
}
} {t1.a 1 t1.b 2 t1.c 3 t2.d 4 t1.a 2 t1.b 3 t1.c 4 t2.d 5}
do_test join-1.3.1 {
execsql2 {
SELECT * FROM t2 NATURAL JOIN t1;
}
} {t2.b 2 t2.c 3 t2.d 4 t1.a 1 t2.b 3 t2.c 4 t2.d 5 t1.a 2}
do_test join-1.4 {
execsql2 {
SELECT * FROM t1 INNER JOIN t2 USING(b,c);
@@ -62,10 +67,144 @@ do_test join-1.7 {
}
} {t1.a 1 t1.b 2 t1.c 3 t2.d 4 t1.a 2 t1.b 3 t1.c 4 t2.d 5}
do_test join-1.8 {
execsql {
SELECT * FROM t1 NATURAL CROSS JOIN t2;
}
} {1 2 3 4 2 3 4 5}
do_test join-1.9 {
execsql {
SELECT * FROM t1 CROSS JOIN t2 USING(b,c);
}
} {1 2 3 4 2 3 4 5}
do_test join-1.10 {
execsql {
SELECT * FROM t1 NATURAL INNER JOIN t2;
}
} {1 2 3 4 2 3 4 5}
do_test join-1.11 {
execsql {
SELECT * FROM t1 INNER JOIN t2 USING(b,c);
}
} {1 2 3 4 2 3 4 5}
do_test join-1.12 {
execsql {
SELECT * FROM t1 natural inner join t2;
}
} {1 2 3 4 2 3 4 5}
do_test join-1.13 {
execsql2 {
SELECT * FROM t1 NATURAL JOIN
(SELECT b as 'c', c as 'd', d as 'e' FROM t2) as t3
}
} {t1.a 1 t1.b 2 t1.c 3 t3.d 4 t3.e 5}
do_test join-1.14 {
execsql2 {
SELECT * FROM (SELECT b as 'c', c as 'd', d as 'e' FROM t2) as 'tx'
NATURAL JOIN t1
}
} {tx.c 3 tx.d 4 tx.e 5 t1.a 1 t1.b 2}
do_test join-1.15 {
execsql {
CREATE TABLE t3(c,d,e);
INSERT INTO t3 VALUES(2,3,4);
INSERT INTO t3 VALUES(3,4,5);
INSERT INTO t3 VALUES(4,5,6);
SELECT * FROM t3;
}
} {2 3 4 3 4 5 4 5 6}
do_test join-1.16 {
execsql {
SELECT * FROM t1 natural join t2 natural join t3;
}
} {1 2 3 4 5 2 3 4 5 6}
do_test join-1.17 {
execsql2 {
SELECT * FROM t1 natural join t2 natural join t3;
}
} {t1.a 1 t1.b 2 t1.c 3 t2.d 4 t3.e 5 t1.a 2 t1.b 3 t1.c 4 t2.d 5 t3.e 6}
do_test join-1.18 {
execsql {
CREATE TABLE t4(d,e,f);
INSERT INTO t4 VALUES(2,3,4);
INSERT INTO t4 VALUES(3,4,5);
INSERT INTO t4 VALUES(4,5,6);
SELECT * FROM t4;
}
} {2 3 4 3 4 5 4 5 6}
do_test join-1.19 {
execsql {
SELECT * FROM t1 natural join t2 natural join t4;
}
} {1 2 3 4 5 6}
do_test join-1.19 {
execsql2 {
SELECT * FROM t1 natural join t2 natural join t4;
}
} {t1.a 1 t1.b 2 t1.c 3 t2.d 4 t4.e 5 t4.f 6}
do_test join-1.20 {
execsql {
SELECT * FROM t1 natural join t2 natural join t3 WHERE t1.a=1
}
} {1 2 3 4 5}
do_test join-2.1 {
execsql {
SELECT * FROM t1 NATURAL LEFT JOIN t2;
}
} {1 2 3 4 2 3 4 5 3 4 5 {}}
do_test join-2.2 {
execsql {
SELECT * FROM t2 NATURAL LEFT OUTER JOIN t1;
}
} {1 2 3 {} 2 3 4 1 3 4 5 2}
do_test join-2.3 {
catchsql {
SELECT * FROM t1 NATURAL RIGHT OUTER JOIN t2;
}
} {1 {RIGHT and FULL OUTER JOINs are not currently supported}}
do_test join-3.1 {
catchsql {
SELECT * FROM t1 NATURAL JOIN t2 ON t1.a=t2.b;
}
} {1 {a NATURAL join may not have an ON or USING clause}}
do_test join-3.2 {
catchsql {
SELECT * FROM t1 NATURAL JOIN t2 USING(b);
}
} {1 {a NATURAL join may not have an ON or USING clause}}
do_test join-3.3 {
catchsql {
SELECT * FROM t1 JOIN t2 ON t1.a=t2.b USING(b);
}
} {1 {cannot have both ON and USING clauses in the same join}}
do_test join-3.4 {
catchsql {
SELECT * FROM t1 JOIN t2 USING(a);
}
} {1 {cannot join using column a - column not present in both tables}}
do_test join-3.5 {
catchsql {
SELECT * FROM t1 USING(a);
}
} {0 {1 2 3 2 3 4 3 4 5}}
do_test join-3.6 {
catchsql {
SELECT * FROM t1 JOIN t2 ON t3.a=t2.b;
}
} {1 {no such column: t3.a}}
do_test join-3.7 {
catchsql {
SELECT * FROM t1 INNER OUTER JOIN t2;
}
} {1 {unknown or unsupported join type: INNER OUTER}}
do_test join-3.7 {
catchsql {
SELECT * FROM t1 BOGUS JOIN t2;
}
} {1 {unknown or unsupported join type: BOGUS}}
finish_test