I'm trying to push down projections while querying a DB but I'm facing the below exception. I've written the following code based on my understanding of the Druid adapter as it seems to be analogous to what I need to achieve.
*Projection pushdown rule* > import static com.google.common.collect.ImmutableList.of; > import static java.util.Arrays.asList; > import static org.apache.calcite.util.Util.last; > > public class SQLiProjectionRule extends RelOptRule { > > public SQLiProjectionRule() { > super(operand(LogicalProject.class, operand(SQLiQuery.class, > any())), "ProjectionRule"); > } > > @Override > public Convention getOutConvention() { > return BindableConvention.INSTANCE; > } > > @Override > public void onMatch(RelOptRuleCall call) { > SQLiQuery query = call.rel(1); > > LogicalProject project = call.rel(0); > RelNode newProject = project.copy(project.getTraitSet(), > of(last(query.getInputs()))); > > SQLiQuery newNode = (SQLiQuery) > query.copy(project.getTraitSet().replace(getOutConvention()), > asList(newProject)); > > call.transformTo(newNode); > } > } > *SQLiQuery portions* > > @Override > protected RelDataType deriveRowType() { > List<RelDataTypeField> topMostRelFieldList = > Util.last(inputs).getRowType().getFieldList(); > return > getCluster().getTypeFactory().createStructType(Util.right(topMostRelFieldList), > Util.left(topMostRelFieldList)); > } > > @Override > public RelNode copy(RelTraitSet traitSet, List<RelNode> extraInputs) { > List<RelNode> copiedInputs = new ArrayList<>(); > if (this.inputs != null) copiedInputs.addAll(this.inputs); > if (extraInputs != null) copiedInputs.addAll(extraInputs); > return new SQLiQuery(getTable(), this.sqliTable, this.rowType, > getCluster(), traitSet, copiedInputs); > } > *Stacktrace* > java.sql.SQLException: Error while executing SQL "SELECT COUNTRY_NAME FROM > SALES.COUNTRIES": Index: 0, Size: 0 > 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.AvaticaStatement.executeInternal(AvaticaStatement.java:156) > at > org.apache.calcite.avatica.AvaticaStatement.executeQuery(AvaticaStatement.java:218) > at > com.sqlinterface.data.provider.calcite.internal.Test_SQLi.test(Test_SQLi.java:34) > 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.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.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) > at > org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) > at org.junit.runners.ParentRunner.run(ParentRunner.java:363) > at > org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) > at > org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) > at > org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) > at > org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678) > at > org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) > at > org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) > *Caused by: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0* > at java.util.ArrayList.rangeCheck(ArrayList.java:657) > at java.util.ArrayList.get(ArrayList.java:433) > at > org.apache.calcite.rel.externalize.RelWriterImpl.checkInputsPresentInExplain(RelWriterImpl.java:167) > at > org.apache.calcite.rel.externalize.RelWriterImpl.done(RelWriterImpl.java:152) > at > org.apache.calcite.rel.AbstractRelNode.explain(AbstractRelNode.java:314) > at > org.apache.calcite.rel.AbstractRelNode.computeDigest(AbstractRelNode.java:422) > at > org.apache.calcite.rel.AbstractRelNode.recomputeDigest(AbstractRelNode.java:358) > at > org.apache.calcite.plan.hep.HepPlanner.updateVertex(HepPlanner.java:842) > at > org.apache.calcite.plan.hep.HepPlanner.addRelToGraph(HepPlanner.java:782) > at > org.apache.calcite.plan.hep.HepPlanner.addRelToGraph(HepPlanner.java:758) > at org.apache.calcite.plan.hep.HepPlanner.setRoot(HepPlanner.java:150) > at org.apache.calcite.tools.Programs$2.run(Programs.java:212) > at > org.apache.calcite.tools.Programs$SequenceProgram.run(Programs.java:387) > at org.apache.calcite.prepare.Prepare.optimize(Prepare.java:188) > at org.apache.calcite.prepare.Prepare.prepareSql(Prepare.java:319) > at org.apache.calcite.prepare.Prepare.prepareSql(Prepare.java:230) > at > org.apache.calcite.prepare.CalcitePrepareImpl.prepare2_(CalcitePrepareImpl.java:781) > at > org.apache.calcite.prepare.CalcitePrepareImpl.prepare_(CalcitePrepareImpl.java:640) > at > org.apache.calcite.prepare.CalcitePrepareImpl.prepareSql(CalcitePrepareImpl.java:610) > at > org.apache.calcite.jdbc.CalciteConnectionImpl.parseQuery(CalciteConnectionImpl.java:221) > at > org.apache.calcite.jdbc.CalciteMetaImpl.prepareAndExecute(CalciteMetaImpl.java:603) > at > org.apache.calcite.avatica.AvaticaConnection.prepareAndExecuteInternal(AvaticaConnection.java:638) > at > org.apache.calcite.avatica.AvaticaStatement.executeInternal(AvaticaStatement.java:149) > ... 27 more > The exception occurs in this method because *values.size() == 0* > private boolean checkInputsPresentInExplain(RelNode node) { > int i = 0; > if (values.size() > 0 && values.get(0).left.equals("subset")) { > ++i; > } > for (RelNode input : node.getInputs()) { > assert values.get(i).right == input; *// Exception thrown here* > ++i; > } > return true; > } > Please tell me if I need to provide more information. Thanks, Gelbana