Thanks a lot Gian. I couldn't grasp your reply then, but after some tracing
through the Druid adapter, I understood what you said about overriding
*deriveRowType,* returning a valid *rowType* and the sketchy *setProjection*
method. What's still bothering me is why does DruidQuery avoid having
inputs and stores them in (*List<RelNode> rels*) instead. I think I'll
start another thread for that.

Julian, no it has nothing to do with nullability difference between
columns. Would you please clarify more about that ?

Thanks,
Gelbana

On Fri, Mar 9, 2018 at 12:32 AM, Julian Hyde <jh...@apache.org> wrote:

> Is it the case that the only difference is nullability of certain columns?
>
> > On Mar 8, 2018, at 10:36 AM, Gian Merlino <g...@imply.io> wrote:
> >
> > Hi Gelbana,
> >
> > My understanding is that the planner rules are not meant to change row
> > types or query behavior. They are just meant to transform into something
> > that is equivalent, but hopefully better in some way (lower cost, proper
> > calling convention, etc).
> >
> > What you can do is have your SQLiQuery's deriveRowType method return
> > something different if you have pushed a projection into it. If the
> > SQLiQuery is going to do the projection, then it should return a row type
> > that matches the projection.
> >
> > Also having "setProjection" method looks sketchy to me. Presumably that
> > should change the digest of the SQLiQuery, but I am not sure if anything
> is
> > allowed to do that except replaceInput?
> >
> > Gian
> >
> > On Thu, Mar 8, 2018 at 9:27 AM, Muhammad Gelbana <m.gelb...@gmail.com>
> > wrote:
> >
> >> I'm trying to push down projection to a bindable node but I'm facing the
> >> following error.
> >>
> >> java.lang.AssertionError: Type mismatch:
> >> rowtype of new rel:
> >> RecordType(INTEGER NOT NULL EXPR$0) NOT NULL
> >> rowtype of set:
> >> RecordType(VARCHAR CHARACTER SET "ISO-8859-1" COLLATE
> >> "ISO-8859-1$en_US$primary" NOT NULL COUNTRY_ISO_CODE, VARCHAR CHARACTER
> SET
> >> "ISO-8859-1" COLLATE "ISO-8859-1$en_US$primary" NOT NULL COUNTRY_NAME,
> >> VARCHAR CHARACTER SET "ISO-8859-1" COLLATE "ISO-8859-1$en_US$primary"
> NOT
> >> NULL COUNTRY_SUBREGION, VARCHAR CHARACTER SET "ISO-8859-1" COLLATE
> >> "ISO-8859-1$en_US$primary" NOT NULL COUNTRY_REGION, VARCHAR CHARACTER
> SET
> >> "ISO-8859-1" COLLATE "ISO-8859-1$en_US$primary" NOT NULL COUNTRY_TOTAL,
> >> VARCHAR CHARACTER SET "ISO-8859-1" COLLATE "ISO-8859-1$en_US$primary"
> NOT
> >> NULL COUNTRY_NAME_HIST, VARCHAR CHARACTER SET "ISO-8859-1" COLLATE
> >> "ISO-8859-1$en_US$primary" NOT NULL DEFAULT_KW, VARCHAR CHARACTER SET
> >> "ISO-8859-1" COLLATE "ISO-8859-1$en_US$primary" NOT NULL
> CURRENT_TIMESTAMP,
> >> VARCHAR CHARACTER SET "ISO-8859-1" COLLATE "ISO-8859-1$en_US$primary"
> NOT
> >> NULL ANALYSE) NOT NULL
> >>    at org.apache.calcite.util.Litmus$1.fail(Litmus.java:31)
> >>    at org.apache.calcite.plan.RelOptUtil.equal(RelOptUtil.java:1864)
> >>    at org.apache.calcite.plan.volcano.RelSubset.add(RelSubset.java:271)
> >>    at org.apache.calcite.plan.volcano.RelSet.add(RelSet.java:148)
> >>    at
> >> org.apache.calcite.plan.volcano.VolcanoPlanner.
> addRelToSet(VolcanoPlanner.
> >> java:1644)
> >>    at
> >> org.apache.calcite.plan.volcano.VolcanoPlanner.
> reregister(VolcanoPlanner.
> >> java:1319)
> >>    at org.apache.calcite.plan.volcano.RelSet.mergeWith(RelSet.java:331)
> >>    at
> >> org.apache.calcite.plan.volcano.VolcanoPlanner.merge(
> >> VolcanoPlanner.java:1410)
> >>    at
> >> org.apache.calcite.plan.volcano.VolcanoPlanner.ensureRegistered(
> >> VolcanoPlanner.java:878)
> >>    at
> >> org.apache.calcite.plan.volcano.VolcanoPlanner.ensureRegistered(
> >> VolcanoPlanner.java:1766)
> >>    at
> >> org.apache.calcite.plan.volcano.VolcanoRuleCall.
> >> transformTo(VolcanoRuleCall.java:135)
> >>    at
> >> org.apache.calcite.plan.RelOptRuleCall.transformTo(
> >> RelOptRuleCall.java:234)
> >>    at
> >> com.sqlinterface.data.provider.calcite.internal.
> >> SQLiProjectionRule.onMatch(SQLiProjectionRule.java:24)
> >>    at
> >> org.apache.calcite.plan.volcano.VolcanoRuleCall.
> >> onMatch(VolcanoRuleCall.java:212)
> >>    at
> >> org.apache.calcite.plan.volcano.VolcanoPlanner.
> findBestExp(VolcanoPlanner.
> >> java:650)
> >>    at org.apache.calcite.tools.Programs$5.run(Programs.java:326)
> >>    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)
> >>    at
> >> org.apache.calcite.avatica.AvaticaStatement.executeQuery(
> >> AvaticaStatement.java:218)
> >>    at
> >> com.sqlinterface.data.provider.calcite.internal.
> >> Test_SQLi.test(Test_SQLi.java:32)
> >>    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)
> >>
> >> Here is the rule I'm using
> >>
> >> public class SQLiProjectionRule extends RelOptRule {
> >>    public SQLiProjectionRule() {
> >>        super(operand(LogicalProject.class, operand(SQLiQuery.class,
> >> any())), "SQLiProjectionRule");
> >>    }
> >>    @Override
> >>    public Convention getOutConvention() {
> >>        return BindableConvention.INSTANCE;
> >>    }
> >>    @Override
> >>    public void onMatch(RelOptRuleCall call) {
> >>        SQLiQuery query = call.rel(1);
> >>        query.setProjection(call.rel(0)); //Now the SQLiQuery node knows
> >> about the projected columns
> >>        call.transformTo(query); // Replace LogicalAggregate with
> >> SQLiQuery..but it fails as mentioned.
> >>    }
> >> }
> >>
> >> What I'm trying to do is to replace the *LogicalProject* node with my
> >> *SQLiQuery* node that includes the table scanning information and
> projected
> >> columns information too after the rule is fired.
> >>
> >> Is this an invalid approach ? What is the correct way to achieve my goal
> >> please ?
> >>
> >> Thanks,
> >> Gelbana
> >>
>
>

Reply via email to