[
https://issues.apache.org/jira/browse/CALCITE-3094?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17140508#comment-17140508
]
Thomas Rebele commented on CALCITE-3094:
----------------------------------------
I would not apply a transformation to the generated code, but generate
different code in the first place. During code generation the length of the
left and right array are known, so it would be easy to generate the according
System.arraycopy(...) calls. I see three points in favor of my proposal:
* It is easy to implement (though I haven't found the method that generates
the method for concatenating arrays yet).
* It fixes the cause of the exception for this particular query. Maybe we can
find other fixes when other generated methods hit the 64kB limit.
* It is more performant for inputs with many fields. I did a JMH benchmark.
For |left| = |right| >= 500 fields it shows a speedup of >20x with
System.arraycopy(...). For 100 to 50 fields the speedup is still 3-4x. The
break even point is somewhere between 10 and 50 fields.
*Benchmark results:* (source code for benchmark [^CTE-3094.zip])
With 500ms per iteration (should be redone with a higher time limit to get more
reliable results):
{code:java}
Benchmark (fields) Mode Cnt Score Error Units
MyBenchmark.arraycopy 1 thrpt 25 36125106.608 ± 1697823.670 ops/s
MyBenchmark.arraycopy 5 thrpt 25 35451604.912 ± 329986.258 ops/s
MyBenchmark.arraycopy 10 thrpt 25 35102765.686 ± 428249.309 ops/s
MyBenchmark.arraycopy 50 thrpt 25 24356938.619 ± 260712.335 ops/s
MyBenchmark.arraycopy 100 thrpt 25 13577289.534 ± 51174.663 ops/s
MyBenchmark.newArray 1 thrpt 25 102568455.693 ± 1548429.031 ops/s
MyBenchmark.newArray 5 thrpt 25 66322353.185 ± 3822598.128 ops/s
MyBenchmark.newArray 10 thrpt 25 37661074.279 ± 268101.214 ops/s
MyBenchmark.newArray 50 thrpt 25 7955575.721 ± 81694.888 ops/s
MyBenchmark.newArray 100 thrpt 25 2964480.660 ± 123294.506 ops/s
{code}
With 10s per iteration (default settings):
{code:java}
Benchmark (fields) Mode Cnt Score Error Units
MyBenchmark.arraycopy 3001 thrpt 25 535075.323 ± 984.691 ops/s
MyBenchmark.newArray 3001 thrpt 25 23586.443 ± 189.309 ops/s
Benchmark (fields) Mode Cnt Score Error Units
MyBenchmark.arraycopy 500 thrpt 25 2834626.364 ± 11407.411 ops/s
MyBenchmark.arraycopy 1000 thrpt 25 1650213.571 ± 2468.686 ops/s
MyBenchmark.newArray 500 thrpt 25 138037.870 ± 791.348 ops/s
MyBenchmark.newArray 1000 thrpt 25 70199.080 ± 404.447 ops/s
{code}
> Code of method grows beyond 64 KB
> ---------------------------------
>
> Key: CALCITE-3094
> URL: https://issues.apache.org/jira/browse/CALCITE-3094
> Project: Calcite
> Issue Type: Bug
> Components: core, jdbc-adapter
> Affects Versions: 1.19.0
> Reporter: Pablo
> Priority: Critical
> Attachments: CTE-3094.zip
>
>
> I am running simple queries like these:
> {{SELECT * FROM t0 INNER JOIN t1 ON t0.`f000000` = t1.`f000003`"}}
>
> They are running ok, but, when t1 and t0 have about 3290 fields, I get this
> error.
> Is there anything I can do? I can't do joins with this amount of fields?
>
> Thank you in advance
>
> {noformat}
> Caused by: java.lang.RuntimeException: Error while compiling generated Java
> code:
> public org.apache.calcite.linq4j.Enumerable bind(final
> org.apache.calcite.DataContext root) {
> final org.apache.calcite.rel.RelNode v2stashed =
> (org.apache.calcite.rel.RelNode) root.get("v2stashed");
> final org.apache.calcite.rel.RelNode v1stashed =
> (org.apache.calcite.rel.RelNode) root.get("v1stashed");
> final org.apache.calcite.interpreter.Interpreter interpreter = new
> org.apache.calcite.interpreter.Interpreter(
> root,
> v1stashed);
> final org.apache.calcite.interpreter.Interpreter interpreter0 = new
> org.apache.calcite.interpreter.Interpreter(
> root,
> v2stashed);
> return interpreter.join(interpreter0, new
> org.apache.calcite.linq4j.function.Function1() {
> public Byte apply(Object[] v1) {
> return (Byte) v1[0];
> }
> public Object apply(Object v1) {
> return apply(
> (Object[]) v1);
> }
> }
> , new org.apache.calcite.linq4j.function.Function1() {
> public Byte apply(Object[] v1) {
> return (Byte) v1[3];
> }
> public Object apply(Object v1) {
> return apply(
> (Object[]) v1);
> }
> }
> , new org.apache.calcite.linq4j.function.Function2() {
> public Object[] apply(Object[] left, Object[] right) {
> return new Object[] {
> left[0],
> left[1],
> left[2],
> [...elided ...]
> left[3298],
> left[3299],
> right[0],
> right[1],
> [...elided...]]
> right[3295],
> right[3296],
> right[3297],
> right[3298],
> right[3299]};
> }
> public Object[] apply(Object left, Object right) {
> return apply(
> (Object[]) left,
> (Object[]) right);
> }
> }
> , null, false, false);
> }
> public Class getElementType() {
> return java.lang.Object[].class;
> }
> at org.apache.calcite.avatica.Helper.wrap(Helper.java:37)
> at
> org.apache.calcite.adapter.enumerable.EnumerableInterpretable.toBindable(EnumerableInterpretable.java:128)
> at
> org.apache.calcite.prepare.CalcitePrepareImpl$CalcitePreparingStmt.implement(CalcitePrepareImpl.java:1233)
> at org.apache.calcite.prepare.Prepare.prepareSql(Prepare.java:332)
> at org.apache.calcite.prepare.Prepare.prepareSql(Prepare.java:231)
> at
> org.apache.calcite.prepare.CalcitePrepareImpl.prepare2_(CalcitePrepareImpl.java:767)
> at
> org.apache.calcite.prepare.CalcitePrepareImpl.prepare_(CalcitePrepareImpl.java:631)
> at
> org.apache.calcite.prepare.CalcitePrepareImpl.prepareSql(CalcitePrepareImpl.java:601)
> at
> org.apache.calcite.jdbc.CalciteConnectionImpl.parseQuery(CalciteConnectionImpl.java:229)
> at
> org.apache.calcite.jdbc.CalciteConnectionImpl.prepareStatement_(CalciteConnectionImpl.java:211)
> ... 80 more
> Caused by: org.codehaus.janino.InternalCompilerException: Compiling "Baz":
> Code of method
> "apply([Ljava/lang/Object;[Ljava/lang/Object;)[Ljava/lang/Object;" of class
> "Baz$3" 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.adapter.enumerable.EnumerableInterpretable.getBindable(EnumerableInterpretable.java:162)
> at
> org.apache.calcite.adapter.enumerable.EnumerableInterpretable.toBindable(EnumerableInterpretable.java:125)
> ... 88 more
> Caused by: org.codehaus.janino.InternalCompilerException: Code of method
> "apply([Ljava/lang/Object;[Ljava/lang/Object;)[Ljava/lang/Object;" of class
> "Baz$3" 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.writeOpcode(UnitCompiler.java:12291)
> at org.codehaus.janino.UnitCompiler.pushConstant(UnitCompiler.java:10746)
> at org.codehaus.janino.UnitCompiler.compileGetValue(UnitCompiler.java:5616)
> at org.codehaus.janino.UnitCompiler.compileGet2(UnitCompiler.java:5592)
> at org.codehaus.janino.UnitCompiler.access$9700(UnitCompiler.java:215)
> at
> org.codehaus.janino.UnitCompiler$16.visitNewInitializedArray(UnitCompiler.java:4434)
> at
> org.codehaus.janino.UnitCompiler$16.visitNewInitializedArray(UnitCompiler.java:4396)
> at org.codehaus.janino.Java$NewInitializedArray.accept(Java.java:5373)
> at org.codehaus.janino.UnitCompiler.compileGet(UnitCompiler.java:4396)
> at org.codehaus.janino.UnitCompiler.compileGetValue(UnitCompiler.java:5662)
> at org.codehaus.janino.UnitCompiler.compile2(UnitCompiler.java:2649)
> at org.codehaus.janino.UnitCompiler.access$2800(UnitCompiler.java:215)
> at
> org.codehaus.janino.UnitCompiler$6.visitReturnStatement(UnitCompiler.java:1504)
> at
> org.codehaus.janino.UnitCompiler$6.visitReturnStatement(UnitCompiler.java:1487)
> at org.codehaus.janino.Java$ReturnStatement.accept(Java.java:3563)
> at org.codehaus.janino.UnitCompiler.compile(UnitCompiler.java:1487)
> at org.codehaus.janino.UnitCompiler.compileStatements(UnitCompiler.java:1567)
> at org.codehaus.janino.UnitCompiler.compile(UnitCompiler.java:3388)
> at
> org.codehaus.janino.UnitCompiler.compileDeclaredMethods(UnitCompiler.java:1357)
> at
> org.codehaus.janino.UnitCompiler.compileDeclaredMethods(UnitCompiler.java:1330)
> at org.codehaus.janino.UnitCompiler.compile2(UnitCompiler.java:822)
> at org.codehaus.janino.UnitCompiler.compile2(UnitCompiler.java:981)
> at org.codehaus.janino.UnitCompiler.compile2(UnitCompiler.java:951)
> at org.codehaus.janino.UnitCompiler.access$200(UnitCompiler.java:215)
> at
> org.codehaus.janino.UnitCompiler$2.visitAnonymousClassDeclaration(UnitCompiler.java:409)
> at
> org.codehaus.janino.UnitCompiler$2.visitAnonymousClassDeclaration(UnitCompiler.java:406)
> at org.codehaus.janino.Java$AnonymousClassDeclaration.accept(Java.java:1149)
> at org.codehaus.janino.UnitCompiler.compile(UnitCompiler.java:406)
> at org.codehaus.janino.UnitCompiler.compileGet2(UnitCompiler.java:5509)
> at org.codehaus.janino.UnitCompiler.access$9500(UnitCompiler.java:215)
> at
> org.codehaus.janino.UnitCompiler$16.visitNewAnonymousClassInstance(UnitCompiler.java:4432)
> at
> org.codehaus.janino.UnitCompiler$16.visitNewAnonymousClassInstance(UnitCompiler.java:4396)
> at org.codehaus.janino.Java$NewAnonymousClassInstance.accept(Java.java:5238)
> at org.codehaus.janino.UnitCompiler.compileGet(UnitCompiler.java:4396)
> at org.codehaus.janino.UnitCompiler.compileGetValue(UnitCompiler.java:5662)
> at org.codehaus.janino.UnitCompiler.compileGet2(UnitCompiler.java:5182)
> at org.codehaus.janino.UnitCompiler.access$9100(UnitCompiler.java:215)
> at
> org.codehaus.janino.UnitCompiler$16.visitMethodInvocation(UnitCompiler.java:4423)
> at
> org.codehaus.janino.UnitCompiler$16.visitMethodInvocation(UnitCompiler.java:4396)
> at org.codehaus.janino.Java$MethodInvocation.accept(Java.java:5073)
> at org.codehaus.janino.UnitCompiler.compileGet(UnitCompiler.java:4396)
> at org.codehaus.janino.UnitCompiler.compileGetValue(UnitCompiler.java:5662)
> at org.codehaus.janino.UnitCompiler.compile2(UnitCompiler.java:2649)
> at org.codehaus.janino.UnitCompiler.access$2800(UnitCompiler.java:215)
> at
> org.codehaus.janino.UnitCompiler$6.visitReturnStatement(UnitCompiler.java:1504)
> at
> org.codehaus.janino.UnitCompiler$6.visitReturnStatement(UnitCompiler.java:1487)
> at org.codehaus.janino.Java$ReturnStatement.accept(Java.java:3563)
> at org.codehaus.janino.UnitCompiler.compile(UnitCompiler.java:1487)
> at org.codehaus.janino.UnitCompiler.compileStatements(UnitCompiler.java:1567)
> at org.codehaus.janino.UnitCompiler.compile(UnitCompiler.java:3388)
> at
> org.codehaus.janino.UnitCompiler.compileDeclaredMethods(UnitCompiler.java:1357)
> at
> org.codehaus.janino.UnitCompiler.compileDeclaredMethods(UnitCompiler.java:1330)
> at org.codehaus.janino.UnitCompiler.compile2(UnitCompiler.java:822)
> at org.codehaus.janino.UnitCompiler.compile2(UnitCompiler.java:432)
> at org.codehaus.janino.UnitCompiler.access$400(UnitCompiler.java:215)
> at
> org.codehaus.janino.UnitCompiler$2.visitPackageMemberClassDeclaration(UnitCompiler.java:411)
> at
> org.codehaus.janino.UnitCompiler$2.visitPackageMemberClassDeclaration(UnitCompiler.java:406)
> at
> org.codehaus.janino.Java$PackageMemberClassDeclaration.accept(Java.java:1414)
> at org.codehaus.janino.UnitCompiler.compile(UnitCompiler.java:406)
> at org.codehaus.janino.UnitCompiler.compileUnit(UnitCompiler.java:378)
> ... 97 more
> {noformat}
>
>
--
This message was sent by Atlassian Jira
(v8.3.4#803005)