]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
If a table is the right operand of a LEFT JOIN, then any column of that
authordrh <drh@noemail.net>
Thu, 4 Dec 2014 16:29:21 +0000 (16:29 +0000)
committerdrh <drh@noemail.net>
Thu, 4 Dec 2014 16:29:21 +0000 (16:29 +0000)
table can be NULL even if that column has a NOT NULL constraint.
Fix for ticket [6f2222d550f5b0ee7ed].

FossilOrigin-Name: 5a80957b04d68cc7e0325873a409d83c1f11b52f

manifest
manifest.uuid
src/expr.c
src/resolve.c
src/sqliteInt.h
test/join5.test

index 858d6dba723737a8c2f567f0e4c673a6ad922779..1c92ad7af4418ea82a49c7c6aad1cadcbd3c8570 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Version\s3.8.7.2.
-D 2014-11-18T20:57:56.794
+C If\sa\stable\sis\sthe\sright\soperand\sof\sa\sLEFT\sJOIN,\sthen\sany\scolumn\sof\sthat\ntable\scan\sbe\sNULL\seven\sif\sthat\scolumn\shas\sa\sNOT\sNULL\sconstraint.\nFix\sfor\sticket\s[6f2222d550f5b0ee7ed].
+D 2014-12-04T16:29:21.076
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -181,7 +181,7 @@ F src/complete.c 535183afb3c75628b78ce82612931ac7cdf26f14
 F src/ctime.c bb434068b5308a857b181c2d204a320ff0d6c638
 F src/date.c 57a7f9ba9f6b4d5268f5e411739066a611f99036
 F src/delete.c 0750b1eb4d96cd3fb2c798599a3a7c85e92f1417
-F src/expr.c 1891cb50510a31e96de8a54579e7d3aef60f0094
+F src/expr.c 6796707fe680aa511568c9f5fc0e0b2d9d3ca57b
 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
 F src/fkey.c da985ae673efef2c712caef825a5d2edb087ead7
 F src/func.c ba47c1671ab3cfdafa6e9d6ee490939ea578adee
@@ -225,14 +225,14 @@ F src/pragma.c 3f3e959390a10c0131676f0e307acce372777e0f
 F src/prepare.c 6ef0cf2f9274982988ed6b7cab1be23147e94196
 F src/printf.c d83b573624f3f6bc12b800af7fd55ce90be70659
 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece
-F src/resolve.c a3466128b52a86c466e47ac1a19e2174f7b5cf89
+F src/resolve.c 64e9f612f68d60f8f3fcd23dcee5fc62da3c4c41
 F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
 F src/select.c 428165951748151e87a15295b7357221433e311b
 F src/shell.c 18ee8bbe9502d8848072dc2eddd1ea09254ba494
 F src/sqlite.h.in 4a5e5158c189d2bcd45c7c4607c2c0eb6d25c153
 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
 F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
-F src/sqliteInt.h c97db3c4d20b34c050a801c93451ef18e4f22de1
+F src/sqliteInt.h 474a00de22bfbbb810db22689e3d1e4099d1d921
 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
 F src/status.c 961d5926e5a8fda611d385ec22c226b8635cd1cb
 F src/table.c 2e99ef7ef16187e17033d9398dc962ce22dab5cb
@@ -657,7 +657,7 @@ F test/join.test 52d4d49f86d0cf46926672878c4eaf0da399104a
 F test/join2.test f2171c265e57ee298a27e57e7051d22962f9f324
 F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0
 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916
-F test/join5.test 86675fc2919269aa923c84dd00ee4249b97990fe
+F test/join5.test 5df23eba184f159ed9705a954957e765a10c141d
 F test/join6.test cfe6503791ceb0cbb509966740286ec423cbf10b
 F test/journal1.test 69abc726c51b4a0409189f9a85191205297c0577
 F test/journal2.test ae06f566c28552c313ded3fee79a6c69e6d049b1
@@ -1205,10 +1205,8 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 945a9e687fdfee5f7103d85d131024e85d594ac3
-R 876a331fea8d7e2c7f47a110195c3ecb
-T +bgcolor * #d0c0ff
-T +sym-release *
-T +sym-version-3.8.7.2 *
+P 2ab564bf9655b7c7b97ab85cafc8a48329b27f93
+Q +6f6fcbe4736b9468a495c684d5eebc8bfe5c566a
+R a71b6beca65c1cf1c19c7bd2736bb9da
 U drh
-Z 5e45593d4fc6c698f5107e76a586ede2
+Z 8e9d9668bb846b5d8f649e9767762fc0
index c2cbf9f06593670c3f5bc7c5c66317a03efc9a46..7d8414b73017ca102032345036a730e0b1c2854c 100644 (file)
@@ -1 +1 @@
-2ab564bf9655b7c7b97ab85cafc8a48329b27f93
\ No newline at end of file
+5a80957b04d68cc7e0325873a409d83c1f11b52f
\ No newline at end of file
index 881cfd4344754a64a042f5bd406f0e33618e8e0e..4012f6c297ecc3c74f47ab039cbe129968782c11 100644 (file)
@@ -1393,7 +1393,8 @@ int sqlite3ExprCanBeNull(const Expr *p){
       return 0;
     case TK_COLUMN:
       assert( p->pTab!=0 );
-      return p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==0;
+      return ExprHasProperty(p, EP_CanBeNull) ||
+             (p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==0);
     default:
       return 1;
   }
index d6a865caefaa7ef6c35b4edc8cabf4426945e42d..068e3355680ca050fc9f8fb2ef58a14d42918e1e 100644 (file)
@@ -320,6 +320,10 @@ static int lookupName(
       if( pMatch ){
         pExpr->iTable = pMatch->iCursor;
         pExpr->pTab = pMatch->pTab;
+        assert( (pMatch->jointype & JT_RIGHT)==0 ); /* RIGHT JOIN not (yet) supported */
+        if( (pMatch->jointype & JT_LEFT)!=0 ){
+          ExprSetProperty(pExpr, EP_CanBeNull);
+        }
         pSchema = pExpr->pTab->pSchema;
       }
     } /* if( pSrcList ) */
index 40b79a79b873e44bf460fb8da376e0c40bb7b9e0..63036c56f6661f31dca21e746db5087ee41a6153 100644 (file)
@@ -2014,7 +2014,7 @@ struct Expr {
 /*
 ** The following are the meanings of bits in the Expr.flags field.
 */
-#define EP_FromJoin  0x000001 /* Originated in ON or USING clause of a join */
+#define EP_FromJoin  0x000001 /* Originates in ON/USING clause of outer join */
 #define EP_Agg       0x000002 /* Contains one or more aggregate functions */
 #define EP_Resolved  0x000004 /* IDs have been resolved to COLUMNs */
 #define EP_Error     0x000008 /* Expression contains one or more errors */
@@ -2034,6 +2034,7 @@ struct Expr {
 #define EP_NoReduce  0x020000 /* Cannot EXPRDUP_REDUCE this Expr */
 #define EP_Unlikely  0x040000 /* unlikely() or likelihood() function */
 #define EP_Constant  0x080000 /* Node is a constant */
+#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
 
 /*
 ** These macros can be used to test, set, or clear bits in the 
index 45d8a31596acaab568295adb19db845d661b98ae..b0b0df4f9ddbcc093f7c74fc4125ac31fbeb086c 100644 (file)
@@ -106,5 +106,59 @@ do_test join5-2.12 {
   execsql {SELECT * FROM xy LEFT JOIN ab ON NULL WHERE NULL}
 } {}
 
+# Ticket https://www.sqlite.org/src/tktview/6f2222d550f5b0ee7ed37601
+# Incorrect output on a LEFT JOIN.
+#
+do_execsql_test join5-3.1 {
+  DROP TABLE IF EXISTS t1;
+  DROP TABLE IF EXISTS t2;
+  DROP TABLE IF EXISTS t3;
+  CREATE TABLE x1(a);
+  INSERT INTO x1 VALUES(1);
+  CREATE TABLE x2(b NOT NULL);
+  CREATE TABLE x3(c, d);
+  INSERT INTO x3 VALUES('a', NULL);
+  INSERT INTO x3 VALUES('b', NULL);
+  INSERT INTO x3 VALUES('c', NULL);
+  SELECT * FROM x1 LEFT JOIN x2 LEFT JOIN x3 ON x3.d = x2.b;
+} {1 {} {} {}}
+do_execsql_test join5-3.2 {
+  DROP TABLE IF EXISTS t1;
+  DROP TABLE IF EXISTS t2;
+  DROP TABLE IF EXISTS t3;
+  DROP TABLE IF EXISTS t4;
+  DROP TABLE IF EXISTS t5;
+  CREATE TABLE t1(x text NOT NULL, y text);
+  CREATE TABLE t2(u text NOT NULL, x text NOT NULL);
+  CREATE TABLE t3(w text NOT NULL, v text);
+  CREATE TABLE t4(w text NOT NULL, z text NOT NULL);
+  CREATE TABLE t5(z text NOT NULL, m text);
+  INSERT INTO t1 VALUES('f6d7661f-4efe-4c90-87b5-858e61cd178b',NULL);
+  INSERT INTO t1 VALUES('f6ea82c3-2cad-45ce-ae8f-3ddca4fb2f48',NULL);
+  INSERT INTO t1 VALUES('f6f47499-ecb4-474b-9a02-35be73c235e5',NULL);
+  INSERT INTO t1 VALUES('56f47499-ecb4-474b-9a02-35be73c235e5',NULL);
+  INSERT INTO t3 VALUES('007f2033-cb20-494c-b135-a1e4eb66130c',
+                        'f6d7661f-4efe-4c90-87b5-858e61cd178b');
+  SELECT *
+    FROM t3
+         INNER JOIN t1 ON t1.x= t3.v AND t1.y IS NULL
+         LEFT JOIN t4  ON t4.w = t3.w
+         LEFT JOIN t5  ON t5.z = t4.z
+         LEFT JOIN t2  ON t2.u = t5.m
+         LEFT JOIN t1 xyz ON xyz.y = t2.x;
+} {007f2033-cb20-494c-b135-a1e4eb66130c f6d7661f-4efe-4c90-87b5-858e61cd178b f6d7661f-4efe-4c90-87b5-858e61cd178b {} {} {} {} {} {} {} {} {}}
+do_execsql_test join5-3.3 {
+  DROP TABLE IF EXISTS x1;
+  DROP TABLE IF EXISTS x2;
+  DROP TABLE IF EXISTS x3;
+  CREATE TABLE x1(a);
+  INSERT INTO x1 VALUES(1);
+  CREATE TABLE x2(b NOT NULL);
+  CREATE TABLE x3(c, d);
+  INSERT INTO x3 VALUES('a', NULL);
+  INSERT INTO x3 VALUES('b', NULL);
+  INSERT INTO x3 VALUES('c', NULL);
+  SELECT * FROM x1 LEFT JOIN x2 JOIN x3 WHERE x3.d = x2.b;
+} {}
 
 finish_test