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>. */