org.apache.calcite.rel.convert.ConverterRule Java Examples

The following examples show how to use org.apache.calcite.rel.convert.ConverterRule. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: VolcanoPlanner.java    From Bats with Apache License 2.0 6 votes vote down vote up
public boolean removeRule(RelOptRule rule) {
  if (!ruleSet.remove(rule)) {
    // Rule was not present.
    return false;
  }

  // Remove description.
  unmapRuleDescription(rule);

  // Remove operands.
  classOperands.values().removeIf(entry -> entry.getRule().equals(rule));

  // Remove trait mappings. (In particular, entries from conversion
  // graph.)
  if (rule instanceof ConverterRule) {
    ConverterRule converterRule = (ConverterRule) rule;
    final RelTrait ruleTrait = converterRule.getInTrait();
    final RelTraitDef ruleTraitDef = ruleTrait.getTraitDef();
    if (traitDefs.contains(ruleTraitDef)) {
      ruleTraitDef.deregisterConverterRule(this, converterRule);
    }
  }
  return true;
}
 
Example #2
Source File: ConventionTraitDef.java    From Bats with Apache License 2.0 6 votes vote down vote up
public void registerConverterRule(
    RelOptPlanner planner,
    ConverterRule converterRule) {
  if (converterRule.isGuaranteed()) {
    ConversionData conversionData = getConversionData(planner);

    final Convention inConvention =
        (Convention) converterRule.getInTrait();
    final Convention outConvention =
        (Convention) converterRule.getOutTrait();
    conversionData.conversionGraph.addVertex(inConvention);
    conversionData.conversionGraph.addVertex(outConvention);
    conversionData.conversionGraph.addEdge(inConvention, outConvention);

    conversionData.mapArcToConverterRule.put(
        Pair.of(inConvention, outConvention), converterRule);
  }
}
 
Example #3
Source File: ConventionTraitDef.java    From Bats with Apache License 2.0 6 votes vote down vote up
/**
 * Tries to convert a relational expression to the target convention of an
 * arc.
 */
private RelNode changeConvention(
    RelNode rel,
    Convention source,
    Convention target,
    final Multimap<Pair<Convention, Convention>, ConverterRule>
        mapArcToConverterRule) {
  assert source == rel.getConvention();

  // Try to apply each converter rule for this arc's source/target calling
  // conventions.
  final Pair<Convention, Convention> key = Pair.of(source, target);
  for (ConverterRule rule : mapArcToConverterRule.get(key)) {
    assert rule.getInTrait() == source;
    assert rule.getOutTrait() == target;
    RelNode converted = rule.convert(rel);
    if (converted != null) {
      return converted;
    }
  }
  return null;
}
 
Example #4
Source File: HepPlanner.java    From Bats with Apache License 2.0 6 votes vote down vote up
private boolean doesConverterApply(
    ConverterRule converterRule,
    HepRelVertex vertex) {
  RelTrait outTrait = converterRule.getOutTrait();
  List<HepRelVertex> parents = Graphs.predecessorListOf(graph, vertex);
  for (HepRelVertex parent : parents) {
    RelNode parentRel = parent.getCurrentRel();
    if (parentRel instanceof Converter) {
      // We don't support converter chains.
      continue;
    }
    if (parentRel.getTraitSet().contains(outTrait)) {
      // This parent wants the traits produced by the converter.
      return true;
    }
  }
  return (vertex == root)
      && (requestedRootTraits != null)
      && requestedRootTraits.contains(outTrait);
}
 
Example #5
Source File: HepPlanner.java    From calcite with Apache License 2.0 6 votes vote down vote up
private boolean doesConverterApply(
    ConverterRule converterRule,
    HepRelVertex vertex) {
  RelTrait outTrait = converterRule.getOutTrait();
  List<HepRelVertex> parents = Graphs.predecessorListOf(graph, vertex);
  for (HepRelVertex parent : parents) {
    RelNode parentRel = parent.getCurrentRel();
    if (parentRel instanceof Converter) {
      // We don't support converter chains.
      continue;
    }
    if (parentRel.getTraitSet().contains(outTrait)) {
      // This parent wants the traits produced by the converter.
      return true;
    }
  }
  return (vertex == root)
      && (requestedRootTraits != null)
      && requestedRootTraits.contains(outTrait);
}
 
Example #6
Source File: ConventionTraitDef.java    From calcite with Apache License 2.0 6 votes vote down vote up
/**
 * Tries to convert a relational expression to the target convention of an
 * arc.
 */
private RelNode changeConvention(
    RelNode rel,
    Convention source,
    Convention target,
    final Multimap<Pair<Convention, Convention>, ConverterRule>
        mapArcToConverterRule) {
  assert source == rel.getConvention();

  // Try to apply each converter rule for this arc's source/target calling
  // conventions.
  final Pair<Convention, Convention> key = Pair.of(source, target);
  for (ConverterRule rule : mapArcToConverterRule.get(key)) {
    assert rule.getInTrait() == source;
    assert rule.getOutTrait() == target;
    RelNode converted = rule.convert(rel);
    if (converted != null) {
      return converted;
    }
  }
  return null;
}
 
Example #7
Source File: ConventionTraitDef.java    From calcite with Apache License 2.0 6 votes vote down vote up
public void registerConverterRule(
    RelOptPlanner planner,
    ConverterRule converterRule) {
  if (converterRule.isGuaranteed()) {
    ConversionData conversionData = getConversionData(planner);

    final Convention inConvention =
        (Convention) converterRule.getInTrait();
    final Convention outConvention =
        (Convention) converterRule.getOutTrait();
    conversionData.conversionGraph.addVertex(inConvention);
    conversionData.conversionGraph.addVertex(outConvention);
    conversionData.conversionGraph.addEdge(inConvention, outConvention);

    conversionData.mapArcToConverterRule.put(
        Pair.of(inConvention, outConvention), converterRule);
  }
}
 
Example #8
Source File: VolcanoPlanner.java    From calcite with Apache License 2.0 6 votes vote down vote up
public boolean removeRule(RelOptRule rule) {
  // Remove description.
  if (!super.removeRule(rule)) {
    // Rule was not present.
    return false;
  }

  // Remove operands.
  classOperands.values().removeIf(entry -> entry.getRule().equals(rule));

  // Remove trait mappings. (In particular, entries from conversion
  // graph.)
  if (rule instanceof ConverterRule) {
    ConverterRule converterRule = (ConverterRule) rule;
    final RelTrait ruleTrait = converterRule.getInTrait();
    final RelTraitDef ruleTraitDef = ruleTrait.getTraitDef();
    if (traitDefs.contains(ruleTraitDef)) {
      ruleTraitDef.deregisterConverterRule(this, converterRule);
    }
  }
  return true;
}
 
Example #9
Source File: VolcanoPlannerTraitTest.java    From calcite with Apache License 2.0 5 votes vote down vote up
public void registerConverterRule(
    RelOptPlanner planner,
    ConverterRule converterRule) {
  if (!converterRule.isGuaranteed()) {
    return;
  }

  RelTrait fromTrait = converterRule.getInTrait();
  RelTrait toTrait = converterRule.getOutTrait();

  conversionMap.put(fromTrait, Pair.of(toTrait, converterRule));
}
 
Example #10
Source File: VolcanoPlannerTraitTest.java    From calcite with Apache License 2.0 5 votes vote down vote up
public boolean canConvert(
    RelOptPlanner planner,
    AltTrait fromTrait,
    AltTrait toTrait) {
  if (conversionMap.containsKey(fromTrait)) {
    for (Pair<RelTrait, ConverterRule> traitAndRule
        : conversionMap.get(fromTrait)) {
      if (traitAndRule.left == toTrait) {
        return true;
      }
    }
  }

  return false;
}
 
Example #11
Source File: VolcanoPlannerTraitTest.java    From calcite with Apache License 2.0 5 votes vote down vote up
public RelNode convert(
    RelOptPlanner planner,
    RelNode rel,
    AltTrait toTrait,
    boolean allowInfiniteCostConverters) {
  RelTrait fromTrait = rel.getTraitSet().getTrait(this);

  if (conversionMap.containsKey(fromTrait)) {
    final RelMetadataQuery mq = rel.getCluster().getMetadataQuery();
    for (Pair<RelTrait, ConverterRule> traitAndRule
        : conversionMap.get(fromTrait)) {
      RelTrait trait = traitAndRule.left;
      ConverterRule rule = traitAndRule.right;

      if (trait == toTrait) {
        RelNode converted = rule.convert(rel);
        if ((converted != null)
            && (!planner.getCost(converted, mq).isInfinite()
            || allowInfiniteCostConverters)) {
          return converted;
        }
      }
    }
  }

  return null;
}
 
Example #12
Source File: RelOptRule.java    From calcite with Apache License 2.0 5 votes vote down vote up
public boolean matches(RelNode rel) {
  // Don't apply converters to converters that operate
  // on the same RelTraitDef -- otherwise we get
  // an n^2 effect.
  if (rel instanceof Converter) {
    if (((ConverterRule) getRule()).getTraitDef()
        == ((Converter) rel).getTraitDef()) {
      return false;
    }
  }
  return super.matches(rel);
}
 
Example #13
Source File: VolcanoPlanner.java    From calcite with Apache License 2.0 5 votes vote down vote up
public boolean addRule(RelOptRule rule) {
  if (locked) {
    return false;
  }

  if (!super.addRule(rule)) {
    return false;
  }

  // Each of this rule's operands is an 'entry point' for a rule call.
  // Register each operand against all concrete sub-classes that could match
  // it.
  for (RelOptRuleOperand operand : rule.getOperands()) {
    for (Class<? extends RelNode> subClass
        : subClasses(operand.getMatchedClass())) {
      if (PhysicalNode.class.isAssignableFrom(subClass)
          && rule instanceof TransformationRule) {
        continue;
      }
      classOperands.put(subClass, operand);
    }
  }

  // If this is a converter rule, check that it operates on one of the
  // kinds of trait we are interested in, and if so, register the rule
  // with the trait.
  if (rule instanceof ConverterRule) {
    ConverterRule converterRule = (ConverterRule) rule;

    final RelTrait ruleTrait = converterRule.getInTrait();
    final RelTraitDef ruleTraitDef = ruleTrait.getTraitDef();
    if (traitDefs.contains(ruleTraitDef)) {
      ruleTraitDef.registerConverterRule(this, converterRule);
    }
  }

  return true;
}
 
Example #14
Source File: HintStrategyTable.java    From calcite with Apache License 2.0 5 votes vote down vote up
/** Returns whether the {@code hintable} has hints that imply
 * the given {@code hintable} can make conversion successfully. */
private static boolean isDesiredConversionPossible(
    Set<ConverterRule> converterRules,
    Hintable hintable) {
  // If no converter rules are specified, we assume the conversion is possible.
  return converterRules.size() == 0
      || converterRules.stream()
          .anyMatch(converterRule -> converterRule.convert((RelNode) hintable) != null);
}
 
Example #15
Source File: HintStrategy.java    From calcite with Apache License 2.0 5 votes vote down vote up
private HintStrategy(
    HintPredicate predicate,
    HintOptionChecker hintOptionChecker,
    ImmutableSet<RelOptRule> excludedRules,
    ImmutableSet<ConverterRule> converterRules) {
  this.predicate = predicate;
  this.hintOptionChecker = hintOptionChecker;
  this.excludedRules = excludedRules;
  this.converterRules = converterRules;
}
 
Example #16
Source File: RelOptRule.java    From Bats with Apache License 2.0 5 votes vote down vote up
public boolean matches(RelNode rel) {
  // Don't apply converters to converters that operate
  // on the same RelTraitDef -- otherwise we get
  // an n^2 effect.
  if (rel instanceof Converter) {
    if (((ConverterRule) getRule()).getTraitDef()
        == ((Converter) rel).getTraitDef()) {
      return false;
    }
  }
  return super.matches(rel);
}
 
Example #17
Source File: HepPlanner.java    From calcite with Apache License 2.0 4 votes vote down vote up
private HepRelVertex applyRule(
    RelOptRule rule,
    HepRelVertex vertex,
    boolean forceConversions) {
  if (!graph.vertexSet().contains(vertex)) {
    return null;
  }
  RelTrait parentTrait = null;
  List<RelNode> parents = null;
  if (rule instanceof ConverterRule) {
    // Guaranteed converter rules require special casing to make sure
    // they only fire where actually needed, otherwise they tend to
    // fire to infinity and beyond.
    ConverterRule converterRule = (ConverterRule) rule;
    if (converterRule.isGuaranteed() || !forceConversions) {
      if (!doesConverterApply(converterRule, vertex)) {
        return null;
      }
      parentTrait = converterRule.getOutTrait();
    }
  } else if (rule instanceof CommonRelSubExprRule) {
    // Only fire CommonRelSubExprRules if the vertex is a common
    // subexpression.
    List<HepRelVertex> parentVertices = getVertexParents(vertex);
    if (parentVertices.size() < 2) {
      return null;
    }
    parents = new ArrayList<>();
    for (HepRelVertex pVertex : parentVertices) {
      parents.add(pVertex.getCurrentRel());
    }
  }

  final List<RelNode> bindings = new ArrayList<>();
  final Map<RelNode, List<RelNode>> nodeChildren = new HashMap<>();
  boolean match =
      matchOperands(
          rule.getOperand(),
          vertex.getCurrentRel(),
          bindings,
          nodeChildren);

  if (!match) {
    return null;
  }

  HepRuleCall call =
      new HepRuleCall(
          this,
          rule.getOperand(),
          bindings.toArray(new RelNode[0]),
          nodeChildren,
          parents);

  // Allow the rule to apply its own side-conditions.
  if (!rule.matches(call)) {
    return null;
  }

  fireRule(call);

  if (!call.getResults().isEmpty()) {
    return applyTransformationResults(
        vertex,
        call,
        parentTrait);
  }

  return null;
}
 
Example #18
Source File: VolcanoPlannerTest.java    From calcite with Apache License 2.0 4 votes vote down vote up
private void removeTrivialProject(boolean useRule) {
  VolcanoPlanner planner = new VolcanoPlanner();

  planner.addRelTraitDef(ConventionTraitDef.INSTANCE);

  if (useRule) {
    planner.addRule(ProjectRemoveRule.INSTANCE);
  }

  planner.addRule(new PhysLeafRule());
  planner.addRule(new GoodSingleRule());
  planner.addRule(new PhysProjectRule());

  planner.addRule(
      new ConverterRule(
          RelNode.class,
          PHYS_CALLING_CONVENTION,
          EnumerableConvention.INSTANCE,
          "PhysToIteratorRule") {
        public RelNode convert(RelNode rel) {
          return new PhysToIteratorConverter(
              rel.getCluster(),
              rel);
        }
      });

  RelOptCluster cluster = newCluster(planner);
  PhysLeafRel leafRel =
      new PhysLeafRel(
          cluster,
          "a");
  final RelBuilder relBuilder =
      RelFactories.LOGICAL_BUILDER.create(leafRel.getCluster(), null);
  RelNode projectRel =
      relBuilder.push(leafRel)
          .project(relBuilder.alias(relBuilder.field(0), "this"))
          .build();
  NoneSingleRel singleRel =
      new NoneSingleRel(
          cluster,
          projectRel);
  RelNode convertedRel =
      planner.changeTraits(
          singleRel,
          cluster.traitSetOf(EnumerableConvention.INSTANCE));
  planner.setRoot(convertedRel);
  RelNode result = planner.chooseDelegate().findBestExp();
  assertTrue(result instanceof PhysToIteratorConverter);
}
 
Example #19
Source File: HepPlanner.java    From Bats with Apache License 2.0 4 votes vote down vote up
private HepRelVertex applyRule(
    RelOptRule rule,
    HepRelVertex vertex,
    boolean forceConversions) {
  if (!belongsToDag(vertex)) {
    return null;
  }
  RelTrait parentTrait = null;
  List<RelNode> parents = null;
  if (rule instanceof ConverterRule) {
    // Guaranteed converter rules require special casing to make sure
    // they only fire where actually needed, otherwise they tend to
    // fire to infinity and beyond.
    ConverterRule converterRule = (ConverterRule) rule;
    if (converterRule.isGuaranteed() || !forceConversions) {
      if (!doesConverterApply(converterRule, vertex)) {
        return null;
      }
      parentTrait = converterRule.getOutTrait();
    }
  } else if (rule instanceof CommonRelSubExprRule) {
    // Only fire CommonRelSubExprRules if the vertex is a common
    // subexpression.
    List<HepRelVertex> parentVertices = getVertexParents(vertex);
    if (parentVertices.size() < 2) {
      return null;
    }
    parents = new ArrayList<>();
    for (HepRelVertex pVertex : parentVertices) {
      parents.add(pVertex.getCurrentRel());
    }
  }

  final List<RelNode> bindings = new ArrayList<>();
  final Map<RelNode, List<RelNode>> nodeChildren = new HashMap<>();
  boolean match =
      matchOperands(
          rule.getOperand(),
          vertex.getCurrentRel(),
          bindings,
          nodeChildren);

  if (!match) {
    return null;
  }

  HepRuleCall call =
      new HepRuleCall(
          this,
          rule.getOperand(),
          bindings.toArray(new RelNode[0]),
          nodeChildren,
          parents);

  // Allow the rule to apply its own side-conditions.
  if (!rule.matches(call)) {
    return null;
  }

  fireRule(call);

  if (!call.getResults().isEmpty()) {
    return applyTransformationResults(
        vertex,
        call,
        parentTrait);
  }

  return null;
}
 
Example #20
Source File: RelTraitDef.java    From calcite with Apache License 2.0 2 votes vote down vote up
/**
 * Provides notification of the registration of a particular
 * {@link ConverterRule} with a {@link RelOptPlanner}. The default
 * implementation does nothing.
 *
 * @param planner       the planner registering the rule
 * @param converterRule the registered converter rule
 */
public void registerConverterRule(
    RelOptPlanner planner,
    ConverterRule converterRule) {
}
 
Example #21
Source File: RelTraitDef.java    From calcite with Apache License 2.0 2 votes vote down vote up
/**
 * Provides notification that a particular {@link ConverterRule} has been
 * de-registered from a {@link RelOptPlanner}. The default implementation
 * does nothing.
 *
 * @param planner       the planner registering the rule
 * @param converterRule the registered converter rule
 */
public void deregisterConverterRule(
    RelOptPlanner planner,
    ConverterRule converterRule) {
}
 
Example #22
Source File: HintStrategy.java    From calcite with Apache License 2.0 2 votes vote down vote up
/**
 * Registers an array of desired converter rules during the
 * {@link org.apache.calcite.plan.RelOptPlanner} planning.
 *
 * <p>The desired converter rules work together with the excluded rules.
 * We have no validation here but they expect to have the same
 * function(semantic equivalent).
 *
 * <p>A rule fire cancels if:
 *
 * <ol>
 *   <li>The registered {@link #excludedRules} contains the rule</li>
 *   <li>And the desired converter rules conversion is not possible
 *   for the rule matched root node</li>
 * </ol>
 *
 * <p>If no converter rules are specified, we assume the conversion is possible.
 *
 * @param rules desired converter rules
 */
public Builder converterRules(ConverterRule... rules) {
  this.converterRules = ImmutableSet.copyOf(rules);
  return this;
}
 
Example #23
Source File: RelTraitDef.java    From Bats with Apache License 2.0 2 votes vote down vote up
/**
 * Provides notification that a particular {@link ConverterRule} has been
 * de-registered from a {@link RelOptPlanner}. The default implementation
 * does nothing.
 *
 * @param planner       the planner registering the rule
 * @param converterRule the registered converter rule
 */
public void deregisterConverterRule(
    RelOptPlanner planner,
    ConverterRule converterRule) {
}
 
Example #24
Source File: RelTraitDef.java    From Bats with Apache License 2.0 2 votes vote down vote up
/**
 * Provides notification of the registration of a particular
 * {@link ConverterRule} with a {@link RelOptPlanner}. The default
 * implementation does nothing.
 *
 * @param planner       the planner registering the rule
 * @param converterRule the registered converter rule
 */
public void registerConverterRule(
    RelOptPlanner planner,
    ConverterRule converterRule) {
}