[
https://issues.apache.org/jira/browse/CALCITE-2792?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16946209#comment-16946209
]
Julian Hyde commented on CALCITE-2792:
--------------------------------------
The balanced tree is a clever idea but it seems to be masking the problem.
The real solution is to not create huge expressions. So, a fix to CALCITE-2696
would be good.
Also, I think it would be useful to create a "$HARD_IN" function that has the
same arguments as IN but is not expanded to OR. It can pass through the
planning process unchanged. Users wouldn't reference it in their SQL, but
SqlToRelConverter could introduce it based on a parameter setting. Because it
has a large argument list it would be "flat" and not susceptible to
StackOverflowError. People could add some conservative optimizations.
> Stackoverflow while evaluating filter with large number of OR conditions
> ------------------------------------------------------------------------
>
> Key: CALCITE-2792
> URL: https://issues.apache.org/jira/browse/CALCITE-2792
> Project: Calcite
> Issue Type: Bug
> Components: core
> Affects Versions: 1.18.0
> Reporter: Dirk Mahler
> Priority: Major
> Labels: pull-request-available
> Attachments: calcite-stackoverflow.zip
>
> Time Spent: 0.5h
> Remaining Estimate: 0h
>
> As a workaround for CALCITE-2696 we're currently using OR conditions for
> filtering values, e.g. instead of
> {noformat}
> ... WHERE value2 IN (1,2,3)
> {noformat}
> {noformat}
> ... WHERE value2=1 OR value2=2 OR value2=3
> {noformat}
> We're now hitting a StackOverflowError because the number of values in the
> filter grows quite large (i.e. 1000-3000) and obviously the evaluation
> recursive:
> {noformat}
> java.lang.StackOverflowError
> at java.util.AbstractCollection.toArray(AbstractCollection.java:176)
> at
> org.apache.calcite.sql.util.SqlShuttle$CallCopyingArgHandler.<init>(SqlShuttle.java:111)
> at
> org.apache.calcite.sql.validate.SqlValidatorImpl$Expander.visitScoped(SqlValidatorImpl.java:5699)
> at
> org.apache.calcite.sql.validate.SqlScopedShuttle.visit(SqlScopedShuttle.java:50)
> at
> org.apache.calcite.sql.validate.SqlScopedShuttle.visit(SqlScopedShuttle.java:33)
> at org.apache.calcite.sql.SqlCall.accept(SqlCall.java:138)
> at
> org.apache.calcite.sql.util.SqlShuttle$CallCopyingArgHandler.visitChild(SqlShuttle.java:134)
> at
> org.apache.calcite.sql.util.SqlShuttle$CallCopyingArgHandler.visitChild(SqlShuttle.java:101)
> at org.apache.calcite.sql.SqlOperator.acceptCall(SqlOperator.java:865)
> at
> org.apache.calcite.sql.validate.SqlValidatorImpl$Expander.visitScoped(SqlValidatorImpl.java:5701)
> at
> org.apache.calcite.sql.validate.SqlScopedShuttle.visit(SqlScopedShuttle.java:50)
> at
> org.apache.calcite.sql.validate.SqlScopedShuttle.visit(SqlScopedShuttle.java:33)
> at org.apache.calcite.sql.SqlCall.accept(SqlCall.java:138)
> at
> org.apache.calcite.sql.util.SqlShuttle$CallCopyingArgHandler.visitChild(SqlShuttle.java:134)
> at
> org.apache.calcite.sql.util.SqlShuttle$CallCopyingArgHandler.visitChild(SqlShuttle.java:101)
> at org.apache.calcite.sql.SqlOperator.acceptCall(SqlOperator.java:865)
> at
> org.apache.calcite.sql.validate.SqlValidatorImpl$Expander.visitScoped(SqlValidatorImpl.java:5701)
> at
> org.apache.calcite.sql.validate.SqlScopedShuttle.visit(SqlScopedShuttle.java:50)
> at
> org.apache.calcite.sql.validate.SqlScopedShuttle.visit(SqlScopedShuttle.java:33)
> at org.apache.calcite.sql.SqlCall.accept(SqlCall.java:138)
> ...
> {noformat}
> We tried to increase the stack size of the virtual machine (-Xss8000k) but
> this leads to a problem with Janino:
> {noformat}
> java.sql.SQLException: exception while executing query: Compiling "Buzz":
> Code of method
> "execute(Lorg/apache/calcite/interpreter/Context;[Ljava/lang/Object;)V" of
> class "Buzz" grows beyond 64 KB
> at org.apache.calcite.avatica.Helper.createException(Helper.java:56)
> at org.apache.calcite.avatica.Helper.createException(Helper.java:41)
> at
> org.apache.calcite.avatica.AvaticaConnection.executeQueryInternal(AvaticaConnection.java:577)
> at
> org.apache.calcite.avatica.AvaticaPreparedStatement.executeQuery(AvaticaPreparedStatement.java:137)
> at
> org.apache.calcite.issue.StackOverflowTest.stackOverflow(StackOverflowTest.java:45)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
> at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> at java.lang.reflect.Method.invoke(Method.java:498)
> at
> org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
> at
> org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
> at
> org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
> at
> org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
> at
> org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
> at
> org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
> at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
> at
> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
> at
> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
> at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
> at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
> at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
> at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
> at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
> at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
> at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
> at
> com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
> at
> com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
> at
> com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
> at
> com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
> Caused by: org.codehaus.janino.InternalCompilerException: Compiling "Buzz":
> Code of method
> "execute(Lorg/apache/calcite/interpreter/Context;[Ljava/lang/Object;)V" of
> class "Buzz" grows beyond 64 KB
> at org.codehaus.janino.UnitCompiler.compileUnit(UnitCompiler.java:382)
> at org.codehaus.janino.SimpleCompiler.cook(SimpleCompiler.java:237)
> at
> org.codehaus.janino.SimpleCompiler.compileToClassLoader(SimpleCompiler.java:465)
> at
> org.codehaus.janino.ClassBodyEvaluator.compileToClass(ClassBodyEvaluator.java:313)
> at
> org.codehaus.janino.ClassBodyEvaluator.cook(ClassBodyEvaluator.java:235)
> at org.codehaus.janino.SimpleCompiler.cook(SimpleCompiler.java:207)
> at org.codehaus.commons.compiler.Cookable.cook(Cookable.java:50)
> at
> org.codehaus.janino.ClassBodyEvaluator.createInstance(ClassBodyEvaluator.java:347)
> at
> org.apache.calcite.interpreter.JaninoRexCompiler.getScalar(JaninoRexCompiler.java:176)
> at
> org.apache.calcite.interpreter.JaninoRexCompiler.baz(JaninoRexCompiler.java:153)
> at
> org.apache.calcite.interpreter.JaninoRexCompiler.compile(JaninoRexCompiler.java:111)
> at
> org.apache.calcite.interpreter.Interpreter$CompilerImpl.compile(Interpreter.java:487)
> at
> org.apache.calcite.interpreter.Nodes$CoreCompiler.compile(Nodes.java:42)
> at
> org.apache.calcite.interpreter.TableScanNode.createEnumerable(TableScanNode.java:266)
> at
> org.apache.calcite.interpreter.TableScanNode.createProjectableFilterable(TableScanNode.java:233)
> at
> org.apache.calcite.interpreter.TableScanNode.create(TableScanNode.java:81)
> at
> org.apache.calcite.interpreter.Nodes$CoreCompiler.visit(Nodes.java:69)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
> at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> at java.lang.reflect.Method.invoke(Method.java:498)
> at
> org.apache.calcite.util.ReflectUtil.invokeVisitorInternal(ReflectUtil.java:257)
> at
> org.apache.calcite.util.ReflectUtil.invokeVisitor(ReflectUtil.java:214)
> at
> org.apache.calcite.util.ReflectUtil$1.invokeVisitor(ReflectUtil.java:464)
> at
> org.apache.calcite.interpreter.Interpreter$CompilerImpl.visit(Interpreter.java:451)
> at
> org.apache.calcite.interpreter.Nodes$CoreCompiler.visit(Nodes.java:42)
> at
> org.apache.calcite.interpreter.Interpreter$CompilerImpl.visitRoot(Interpreter.java:405)
> at
> org.apache.calcite.interpreter.Interpreter.<init>(Interpreter.java:88)
> at Baz.bind(Unknown Source)
> at
> org.apache.calcite.jdbc.CalcitePrepare$CalciteSignature.enumerable(CalcitePrepare.java:355)
> at
> org.apache.calcite.jdbc.CalciteConnectionImpl.enumerable(CalciteConnectionImpl.java:309)
> at
> org.apache.calcite.jdbc.CalciteMetaImpl._createIterable(CalciteMetaImpl.java:506)
> at
> org.apache.calcite.jdbc.CalciteMetaImpl.createIterable(CalciteMetaImpl.java:497)
> at
> org.apache.calcite.avatica.AvaticaResultSet.execute(AvaticaResultSet.java:182)
> at
> org.apache.calcite.jdbc.CalciteResultSet.execute(CalciteResultSet.java:64)
> at
> org.apache.calcite.jdbc.CalciteResultSet.execute(CalciteResultSet.java:43)
> at
> org.apache.calcite.avatica.AvaticaConnection.executeQueryInternal(AvaticaConnection.java:573)
> ... 26 more
> Caused by: org.codehaus.janino.InternalCompilerException: Code of method
> "execute(Lorg/apache/calcite/interpreter/Context;[Ljava/lang/Object;)V" of
> class "Buzz" grows beyond 64 KB
> at org.codehaus.janino.CodeContext.makeSpace(CodeContext.java:1048)
> at org.codehaus.janino.CodeContext.write(CodeContext.java:925)
> at org.codehaus.janino.UnitCompiler.writeByte(UnitCompiler.java:12275)
> at org.codehaus.janino.UnitCompiler.load(UnitCompiler.java:11936)
> at org.codehaus.janino.UnitCompiler.load(UnitCompiler.java:11926)
> at org.codehaus.janino.UnitCompiler.compileGet2(UnitCompiler.java:4465)
> at org.codehaus.janino.UnitCompiler.access$8000(UnitCompiler.java:215)
> at
> org.codehaus.janino.UnitCompiler$16$1.visitLocalVariableAccess(UnitCompiler.java:4408)
> at
> org.codehaus.janino.UnitCompiler$16$1.visitLocalVariableAccess(UnitCompiler.java:4400)
> at org.codehaus.janino.Java$LocalVariableAccess.accept(Java.java:4274)
> at
> org.codehaus.janino.UnitCompiler$16.visitLvalue(UnitCompiler.java:4400)
> at
> org.codehaus.janino.UnitCompiler$16.visitLvalue(UnitCompiler.java:4396)
> at org.codehaus.janino.Java$Lvalue.accept(Java.java:4148)
> at org.codehaus.janino.UnitCompiler.compileGet(UnitCompiler.java:4396)
> at org.codehaus.janino.UnitCompiler.compileGet2(UnitCompiler.java:4461)
> at org.codehaus.janino.UnitCompiler.access$7500(UnitCompiler.java:215)
> at
> org.codehaus.janino.UnitCompiler$16$1.visitAmbiguousName(UnitCompiler.java:4403)
> at
> org.codehaus.janino.UnitCompiler$16$1.visitAmbiguousName(UnitCompiler.java:4400)
> at org.codehaus.janino.Java$AmbiguousName.accept(Java.java:4224)
> at
> org.codehaus.janino.UnitCompiler$16.visitLvalue(UnitCompiler.java:4400)
> at
> org.codehaus.janino.UnitCompiler$16.visitLvalue(UnitCompiler.java:4396)
> at org.codehaus.janino.Java$Lvalue.accept(Java.java:4148)
> at org.codehaus.janino.UnitCompiler.compileGet(UnitCompiler.java:4396)
> at
> org.codehaus.janino.UnitCompiler.compileGetValue(UnitCompiler.java:5662)
> at
> org.codehaus.janino.UnitCompiler.compileBoolean2(UnitCompiler.java:4120)
> at org.codehaus.janino.UnitCompiler.access$6600(UnitCompiler.java:215)
> at
> org.codehaus.janino.UnitCompiler$14.visitBinaryOperation(UnitCompiler.java:3957)
> at
> org.codehaus.janino.UnitCompiler$14.visitBinaryOperation(UnitCompiler.java:3935)
> at org.codehaus.janino.Java$BinaryOperation.accept(Java.java:4864)
> at
> org.codehaus.janino.UnitCompiler.compileBoolean(UnitCompiler.java:3935)
> at
> org.codehaus.janino.UnitCompiler.compileBoolean2(UnitCompiler.java:4078)
> at org.codehaus.janino.UnitCompiler.access$6600(UnitCompiler.java:215)
> at
> org.codehaus.janino.UnitCompiler$14.visitBinaryOperation(UnitCompiler.java:3957)
> at
> org.codehaus.janino.UnitCompiler$14.visitBinaryOperation(UnitCompiler.java:3935)
> at org.codehaus.janino.Java$BinaryOperation.accept(Java.java:4864)
> {noformat}
--
This message was sent by Atlassian Jira
(v8.3.4#803005)