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

Reply via email to