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

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


The following commit(s) were added to refs/heads/master by this push:
     new 0e15ae6  [CALCITE-2722] Unparsing may have run into StackOverflowError 
in case of large number of AND/OR operands (Haisheng Yuan)
0e15ae6 is described below

commit 0e15ae669102ceffec49a6f99ac12106226a9ba9
Author: Haisheng Yuan <[email protected]>
AuthorDate: Mon Feb 4 10:48:30 2019 -0600

    [CALCITE-2722] Unparsing may have run into StackOverflowError in case of 
large number of AND/OR operands (Haisheng Yuan)
    
    Create left-deep tree in iterative way instead of recursion to avoid
    potential stack overflow in case of large number of OR expressions.
    
    Add testcase (Zoltan Haindrich)
    
    Close apache/calcite#1048
---
 .../org/apache/calcite/rel/rel2sql/SqlImplementor.java | 11 ++++-------
 .../calcite/rel/rel2sql/RelToSqlConverterTest.java     | 18 ++++++++++++++++++
 2 files changed, 22 insertions(+), 7 deletions(-)

diff --git 
a/core/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java 
b/core/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java
index 0937667..8b51530 100644
--- a/core/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java
+++ b/core/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java
@@ -70,7 +70,6 @@ import org.apache.calcite.sql.validate.SqlValidatorUtil;
 import org.apache.calcite.util.DateString;
 import org.apache.calcite.util.TimeString;
 import org.apache.calcite.util.TimestampString;
-import org.apache.calcite.util.Util;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
@@ -748,13 +747,11 @@ public abstract class SqlImplementor {
     }
 
     private SqlNode createLeftCall(SqlOperator op, List<SqlNode> nodeList) {
-      if (nodeList.size() == 2) {
-        return op.createCall(new SqlNodeList(nodeList, POS));
+      SqlNode node = op.createCall(new SqlNodeList(nodeList.subList(0, 2), 
POS));
+      for (int i = 2; i < nodeList.size(); i++) {
+        node = op.createCall(new SqlNodeList(ImmutableList.of(node, 
nodeList.get(i)), POS));
       }
-      final List<SqlNode> butLast = Util.skipLast(nodeList);
-      final SqlNode last = nodeList.get(nodeList.size() - 1);
-      final SqlNode call = createLeftCall(op, butLast);
-      return op.createCall(new SqlNodeList(ImmutableList.of(call, last), POS));
+      return node;
     }
 
     private List<SqlNode> toSql(RexProgram program, List<RexNode> operandList) 
{
diff --git 
a/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java 
b/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java
index 4a9e20b..aa5a676 100644
--- 
a/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java
+++ 
b/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java
@@ -61,6 +61,8 @@ import org.junit.Test;
 
 import java.util.List;
 import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
 
 import static org.apache.calcite.test.Matchers.isLinux;
 
@@ -334,6 +336,22 @@ public class RelToSqlConverterTest {
   }
 
   /** Test case for
+   * <a 
href="https://issues.apache.org/jira/browse/CALCITE-2722";>[CALCITE-2722]
+   * SqlImplementor createLeftCall method throws StackOverflowError</a>. */
+  @Test public void testStack() {
+    final RelBuilder builder = relBuilder();
+    final RelNode root = builder
+        .scan("EMP")
+        .filter(
+            builder.or(
+                IntStream.range(1, 10000)
+                    .mapToObj(i -> builder.equals(builder.field("EMPNO"), 
builder.literal(i)))
+                    .collect(Collectors.toList())))
+        .build();
+    assertThat(toSql(root), notNullValue());
+  }
+
+  /** Test case for
    * <a 
href="https://issues.apache.org/jira/browse/CALCITE-1946";>[CALCITE-1946]
    * JDBC adapter should generate sub-SELECT if dialect does not support nested
    * aggregate functions</a>. */

Reply via email to