You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by am...@apache.org on 2021/11/24 10:10:33 UTC

[ignite] branch master updated: IGNITE-14354 Disabled optimisation in case of constants in subquery. (#9585)

This is an automated email from the ASF dual-hosted git repository.

amashenkov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/master by this push:
     new 625d110  IGNITE-14354 Disabled optimisation in case of constants in subquery. (#9585)
625d110 is described below

commit 625d110cbe9edac47a25a44c0e14cb32b79b0ab2
Author: Vladimir Ermakov <85...@users.noreply.github.com>
AuthorDate: Wed Nov 24 13:10:10 2021 +0300

    IGNITE-14354 Disabled optimisation in case of constants in subquery. (#9585)
---
 .../query/h2/GridSubqueryJoinOptimizer.java        |  10 ++-
 .../h2/GridSubqueryJoinOptimizerSelfTest.java      | 100 ++++++++++++++++++++-
 2 files changed, 107 insertions(+), 3 deletions(-)

diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/GridSubqueryJoinOptimizer.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/GridSubqueryJoinOptimizer.java
index fa3fd72..51c6da6 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/GridSubqueryJoinOptimizer.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/GridSubqueryJoinOptimizer.java
@@ -32,6 +32,7 @@ import org.apache.ignite.internal.processors.query.h2.sql.GridSqlAlias;
 import org.apache.ignite.internal.processors.query.h2.sql.GridSqlArray;
 import org.apache.ignite.internal.processors.query.h2.sql.GridSqlAst;
 import org.apache.ignite.internal.processors.query.h2.sql.GridSqlColumn;
+import org.apache.ignite.internal.processors.query.h2.sql.GridSqlConst;
 import org.apache.ignite.internal.processors.query.h2.sql.GridSqlElement;
 import org.apache.ignite.internal.processors.query.h2.sql.GridSqlFunction;
 import org.apache.ignite.internal.processors.query.h2.sql.GridSqlJoin;
@@ -516,7 +517,14 @@ public class GridSubqueryJoinOptimizer {
             return false;
 
         GridSqlAst subCol = GridSqlAlias.unwrap(subS.columns(false).get(0));
-
+        
+        // If a constant is selected in a subquery, we cannot put it in parent query without
+        // consequences for the correctness of the result.
+        // For example, select (select 1 from x where id = 1) becomes select 1 left join x...,
+        // and the where condition becomes meaningless.
+        
+        if (subCol instanceof GridSqlConst)
+            return false;
         if (targetEl != null)
             targetEl.child(childInd, subCol);
         else
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridSubqueryJoinOptimizerSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridSubqueryJoinOptimizerSelfTest.java
index 5c4dd54..dc4a381 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridSubqueryJoinOptimizerSelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridSubqueryJoinOptimizerSelfTest.java
@@ -390,6 +390,102 @@ public class GridSubqueryJoinOptimizerSelfTest extends GridCommonAbstractTest {
 
         check(resSql, 1);
     }
+    
+    /**
+     * Select result of boolean operation with constant in subquery. For this case optimization is disabled.
+     */
+    @Test
+    public void testExistsClause6() {
+        String outerSqlTemplate = "SELECT (EXISTS  (%s) )";
+        String subSql1 = "SELECT 1 FROM emp WHERE id = 1";
+        String subSql2 = "SELECT 1";
+    
+        check(String.format(outerSqlTemplate, subSql1), 2);
+        check(String.format(outerSqlTemplate, subSql2), 2);
+    }
+    
+    /**
+     * This case is similar to EXISTS case. Optimization is disabled.
+     */
+    @Test
+    public void testInCause() {
+        String outerSqlTemplate = "SELECT e.id, 1 IN (%s) from emp e";
+        String subSql = "SELECT 1 FROM emp WHERE id = 1";
+        
+        String resSql = String.format(outerSqlTemplate, subSql);
+        
+        check(resSql, 2);
+    }
+    
+    /**
+     * This case is similar to EXISTS case. Optimization is disabled.
+     */
+    @Test
+    public void testNotInClause() {
+        String outerSqlTemplate = "SELECT 1 NOT IN (%s)";
+        String subSql = "SELECT 1 FROM emp WHERE id = 1";
+        
+        String resSql = String.format(outerSqlTemplate, subSql);
+        
+        check(resSql, 2);
+    }
+    
+    /**
+     * Test boolean expression with AND operation. Optimization is disabled.
+     */
+    @Test
+    public void testAndClause() {
+        String outerSqlTemplate = "SELECT TRUE AND (%s)";
+        String subSql = "SELECT TRUE FROM emp WHERE id = 1";
+        
+        String resSql = String.format(outerSqlTemplate, subSql);
+        
+        check(resSql, 2);
+    }
+    
+    /**
+     * Test subquery with constant. Optimization is disabled.
+     */
+    @Test
+    public void testConstantSubQuery() {
+        String outerSqlTemplate = "SELECT (%s)";
+        String subSql = "SELECT 1 FROM emp WHERE id = 1";
+        
+        String resSql = String.format(outerSqlTemplate, subSql);
+        
+        check(resSql, 2);
+    }
+    
+    /**
+     * Test different operations with subquery. Optimization is disabled.
+     */
+    @Test
+    public void testOperationWithSubQuery() {
+        String outerSqlTemplate1 = "SELECT 1 = (%s)";
+        String outerSqlTemplate2 = "SELECT 1 || (%s)";
+        String outerSqlTemplate3 = "SELECT 1 + (%s)";
+        String outerSqlTemplate4 = "SELECT (%s) IS NULL";
+    
+        String subSql = "SELECT 1 FROM emp WHERE id = 1";
+        
+        check(String.format(outerSqlTemplate1, subSql), 2);
+        check(String.format(outerSqlTemplate2, subSql), 2);
+        check(String.format(outerSqlTemplate3, subSql), 2);
+        check(String.format(outerSqlTemplate4, subSql), 2);
+    }
+    
+    /**
+     * Case with IN condition.
+     */
+    @Test
+    public void testWhereInClause() {
+        String outerSqlTemplate = "select id, name from emp e where 1 IN (%s) order by 1";
+        String subSql = "select 1 from emp where id = e.id";
+        
+        String resSql = String.format(outerSqlTemplate, subSql);
+
+        check(resSql, 1);
+    }
 
     /**
      * Simple case, but inner table has coumpound PK.
@@ -400,7 +496,7 @@ public class GridSubqueryJoinOptimizerSelfTest extends GridCommonAbstractTest {
         String subSql = "select 1 from dep2 where id = e.id and id2 = 12";
 
         String resSql = String.format(outerSqlTemplate, subSql);
-
+        
         check(resSql, 1);
     }
 
@@ -509,7 +605,7 @@ public class GridSubqueryJoinOptimizerSelfTest extends GridCommonAbstractTest {
 
         check(resSql, 1);
     }
-
+    
     /**
      * Simple case, but inner table has coumpound PK.
      */