[
https://issues.apache.org/jira/browse/CALCITE-2223?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16754345#comment-16754345
]
Vladimir Sitnikov commented on CALCITE-2223:
--------------------------------------------
A bit of a problem is {{RelBuilderFactory}} provides no clue on the convention
of the generated of the generated relations.
I'm afraid below suggestions seem to break backward compatibility, however it
looks like current implementation is not that very well defined.
For instance, consider
{code:java} public FilterSetOpTransposeRule(RelBuilderFactory
relBuilderFactory) {
super(operand(Filter.class, operand(SetOp.class, ...)
{code}
It takes arbitrary Filter and arbitrary SetOp and converts them to none knows
which relation via RelBuilderFactory.
The principle of least astonishment says that the rule should not match for
JdbcFilter(EnumerableTableScan...) in case RelBuilderFactory comes from Drill :)
I think the rule should have "Convention" argument, so it can confine the
proper relations.
Then we could use {{Filter.class}} and {{SetOp.class}} in rule definition and
still get sane results (e.g. JdbcFilter(JdbcScan..) or
DrillFilter(DrillScan..) )
It think it would be OK.
The downside is we (and consumers) would have to add that argument all over the
place.
An alternative approach would be to add
{code:java}
public interface RelBuilderFactory {
org.apache.calcite.plan.Convention getConvention();{code}
Then we won't have to add Convention argument to all the rules, however
getConvention might sound a bit odd for RelBuilderFactory. <-- I like this
approach better.
On top of that we might want to confine rules to a single convention by
default. I guess cross-convention rules are much less desired and expected in
practice, so we could make sure the default
{{org.apache.calcite.plan.RelOptRule#operand}}) ensures all the children have
the same convention. In other words {{operand(Filter.class, any())}} would
ensure that Filter and its child have the same convention.
> ProjectMergeRule is infinitely matched when is applied after
> ProjectReduceExpressionsRule
> -----------------------------------------------------------------------------------------
>
> Key: CALCITE-2223
> URL: https://issues.apache.org/jira/browse/CALCITE-2223
> Project: Calcite
> Issue Type: Bug
> Reporter: Volodymyr Vysotskyi
> Assignee: Julian Hyde
> Priority: Critical
> Attachments:
> TestLimitWithExchanges_testPushLimitPastUnionExchange.png, heap_overview.png,
> provenance_contents.png
>
>
> For queries like this:
> {code:sql}
> select t1.f from (select cast(f as int) f, f from (select cast(f as int) f
> from (values('1')) t(f))) as t1
> {code}
> OOM is thrown when {{ProjectMergeRule}} is applied before applying
> {{ProjectReduceExpressionsRule}} in VolcanoPlanner.
> A simple test to reproduce this issue (in {{RelOptRulesTest}}):
> {code:java}
> @Test public void testOomProjectMergeRule() {
> RelBuilder relBuilder =
> RelBuilder.create(RelBuilderTest.config().build());
> RelNode relNode = relBuilder
> .values(new String[]{"f"}, "1")
> .project(
> relBuilder.alias(
> relBuilder.cast(relBuilder.field(0), SqlTypeName.INTEGER),
> "f"))
> .project(
> relBuilder.alias(
> relBuilder.cast(relBuilder.field(0), SqlTypeName.INTEGER),
> "f0"),
> relBuilder.alias(relBuilder.field(0), "f"))
> .project(
> relBuilder.alias(relBuilder.field(0), "f"))
> .build();
> RelOptPlanner planner = relNode.getCluster().getPlanner();
> RuleSet ruleSet =
> RuleSets.ofList(
> ReduceExpressionsRule.PROJECT_INSTANCE,
> new ProjectMergeRuleWithLongerName(),
> EnumerableRules.ENUMERABLE_PROJECT_RULE,
> EnumerableRules.ENUMERABLE_VALUES_RULE);
> Program program = Programs.of(ruleSet);
> RelTraitSet toTraits =
> relNode.getCluster().traitSet()
> .replace(0, EnumerableConvention.INSTANCE);
> RelNode output = program.run(planner, relNode, toTraits,
> ImmutableList.<RelOptMaterialization>of(),
> ImmutableList.<RelOptLattice>of());
> // check for output
> }
> /**
> * ProjectMergeRule inheritor which has
> * class name greater than ProjectReduceExpressionsRule class name
> (String.compareTo()).
> *
> * It is needed for RuleQueue.popMatch() method
> * to apply this rule before ProjectReduceExpressionsRule.
> */
> private static class ProjectMergeRuleWithLongerName extends
> ProjectMergeRule {
> public ProjectMergeRuleWithLongerName() {
> super(true, RelFactories.LOGICAL_BUILDER);
> }
> }
> {code}
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)