-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
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
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
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
-99bd1f5b9a1a20bfeefe15c00d96a34a5f40923e
\ No newline at end of file
+d8d04c14f18d1feba89ccea0be70530a18248c51
\ No newline at end of file
** 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"
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 },
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
}
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 = " ";
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;
}
*************************************************************************
** 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"
*/
#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 */
#
# 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
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);
}
} {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