]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Additional testing of LEFT OUTER JOIN. (CVS 588)
authordrh <drh@noemail.net>
Sat, 25 May 2002 00:18:20 +0000 (00:18 +0000)
committerdrh <drh@noemail.net>
Sat, 25 May 2002 00:18:20 +0000 (00:18 +0000)
FossilOrigin-Name: d8d04c14f18d1feba89ccea0be70530a18248c51

manifest
manifest.uuid
src/select.c
src/sqliteInt.h
test/join.test

index 3845b14f97fee327da0ad6b80cde715a482f78c6..3a7b09999ac299f6fb4c70d5a94e880fd2148787 100644 (file)
--- a/manifest
+++ b/manifest
@@ -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
index b7468024c651387bb7b5a8f0a204a203f4825060..65d176ce964aa984dbbe9be63221bbb705dfe070 100644 (file)
@@ -1 +1 @@
-99bd1f5b9a1a20bfeefe15c00d96a34a5f40923e
\ No newline at end of file
+d8d04c14f18d1feba89ccea0be70530a18248c51
\ No newline at end of file
index f6b719984f89f27233df494acff54a377ec7d476..e4117f9d67954e2806d7ce31c1667fc270c069ee 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.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;
 }
index d323174e7ee784a4dff2b13025f5d04ddc61e802..77cfe6282079d80577887e8e883d1f5fb6a58c80 100644 (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 */
 
index 6aa70ea804c7e70e6218a4b33652371ed4c7b1ed..c7fb82b11a89aca21c3869a1816e05d70fbba19b 100644 (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