ec7966
From 7d47517d579601bb6e59e33bf0896f0ed36aa0aa Mon Sep 17 00:00:00 2001
ec7966
From: Ondrej Dubaj <odubaj@redhat.com>
ec7966
Date: Mon, 20 Jan 2020 09:34:41 +0100
ec7966
Subject: [PATCH] Continue to back away from the LEFT JOIN optimization of
ec7966
 check-in
ec7966
ec7966
by disallowing query flattening if the outer query is DISTINCT.  Without this fix,
ec7966
if an index scan is run on the table within the view on the right-hand side of the
ec7966
LEFT JOIN, stale result registers might be accessed yielding incorrect results,
ec7966
and/or an OP_IfNullRow opcode might be invoked on the un-opened table, resulting
ec7966
in a NULL-pointer dereference.  This problem was found by the Yongheng and Rui fuzzer.
ec7966
---
ec7966
 src/select.c   |  8 ++++++--
ec7966
 test/join.test | 13 +++++++++++++
ec7966
 2 files changed, 19 insertions(+), 2 deletions(-)
ec7966
ec7966
diff --git a/src/select.c b/src/select.c
ec7966
index c60ff27..0205a08 100644
ec7966
--- a/src/select.c
ec7966
+++ b/src/select.c
ec7966
@@ -3569,6 +3569,7 @@ static void substSelect(
ec7966
 **        (3b) the FROM clause of the subquery may not contain a virtual
ec7966
 **             table and
ec7966
 **        (3c) the outer query may not be an aggregate.
ec7966
+**        (3d) the outer query may not be DISTINCT.
ec7966
 **
ec7966
 **   (4)  The subquery can not be DISTINCT.
ec7966
 **
ec7966
@@ -3765,8 +3766,11 @@ static int flattenSubquery(
ec7966
   */
ec7966
   if( (pSubitem->fg.jointype & JT_OUTER)!=0 ){
ec7966
     isLeftJoin = 1;
ec7966
-    if( pSubSrc->nSrc>1 || isAgg || IsVirtual(pSubSrc->a[0].pTab) ){
ec7966
-      /*  (3a)             (3c)     (3b) */
ec7966
+    if( pSubSrc->nSrc>1                   /* (3a) */
ec7966
+     || isAgg                             /* (3b) */
ec7966
+     || IsVirtual(pSubSrc->a[0].pTab)     /* (3c) */
ec7966
+     || (p->selFlags & SF_Distinct)!=0    /* (3d) */
ec7966
+    ){
ec7966
       return 0;
ec7966
     }
ec7966
   }
ec7966
diff --git a/test/join.test b/test/join.test
ec7966
index 8c6f463..8c6a53d 100644
ec7966
--- a/test/join.test
ec7966
+++ b/test/join.test
ec7966
@@ -844,4 +844,17 @@ do_execsql_test join-15.110 {
ec7966
    ORDER BY a1, a2, a3, a4, a5;
ec7966
 } {1 {} {} {} {} 1 11 {} {} {} 1 12 {} {} {} 1 12 121 {} {} 1 13 {} {} {}}
ec7966
 
ec7966
+# 2019-12-18 problem with a LEFT JOIN where the RHS is a view.
ec7966
+# Detected by Yongheng and Rui.
ec7966
+# Follows from the optimization attempt of check-in 41c27bc0ff1d3135
ec7966
+# on 2017-04-18
ec7966
+#
ec7966
+reset_db
ec7966
+do_execsql_test join-22.10 {
ec7966
+  CREATE TABLE t0(a, b);
ec7966
+  CREATE INDEX t0a ON t0(a);
ec7966
+  INSERT INTO t0 VALUES(10,10),(10,11),(10,12);
ec7966
+  SELECT DISTINCT c FROM t0 LEFT JOIN (SELECT a+1 AS c FROM t0) ORDER BY c ;
ec7966
+} {11}
ec7966
+
ec7966
 finish_test
ec7966
-- 
ec7966
2.19.1
ec7966