All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hazelcast.org.apache.calcite.plan.hep.HepProgramBuilder Maven / Gradle / Ivy

There is a newer version: 5.5.0
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.hazelcast.org.apache.calcite.plan.hep;

import com.hazelcast.org.apache.calcite.plan.CommonRelSubExprRule;
import com.hazelcast.org.apache.calcite.plan.RelOptPlanner;
import com.hazelcast.org.apache.calcite.plan.RelOptRule;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import static com.hazelcast.com.google.common.base.Preconditions.checkArgument;

/**
 * HepProgramBuilder creates instances of {@link HepProgram}.
 */
public class HepProgramBuilder {
  //~ Instance fields --------------------------------------------------------

  private final List instructions = new ArrayList<>();

  /** If a group is under construction, ordinal of the first instruction in the
   * group; otherwise -1. */
  private int group = -1;

  //~ Constructors -----------------------------------------------------------

  /**
   * Creates a new HepProgramBuilder with an initially empty program. The
   * program under construction has an initial match order of
   * {@link HepMatchOrder#DEPTH_FIRST}, and an initial match limit of
   * {@link HepProgram#MATCH_UNTIL_FIXPOINT}.
   */
  public HepProgramBuilder() {
  }

  //~ Methods ----------------------------------------------------------------

  private void clear() {
    instructions.clear();
    group = -1;
  }

  /**
   * Adds an instruction to attempt to match any rules of a given class. The
   * order in which the rules within a class will be attempted is arbitrary,
   * so if more control is needed, use addRuleInstance instead.
   *
   * 

Note that when this method is used, it is also necessary to add the * actual rule objects of interest to the planner via * {@link RelOptPlanner#addRule}. If the planner does not have any * rules of the given class, this instruction is a nop. * *

TODO: support classification via rule annotations. * * @param ruleClass class of rules to fire, e.g. ConverterRule.class */ public HepProgramBuilder addRuleClass( Class ruleClass) { return addInstruction(new HepInstruction.RuleClass(ruleClass)); } /** * Adds an instruction to attempt to match any rules in a given collection. * The order in which the rules within a collection will be attempted is * arbitrary, so if more control is needed, use addRuleInstance instead. The * collection can be "live" in the sense that not all rule instances need to * have been added to it at the time this method is called. The collection * contents are reevaluated for each execution of the program. * *

Note that when this method is used, it is NOT necessary to add the * rules to the planner via {@link RelOptPlanner#addRule}; the instances * supplied here will be used. However, adding the rules to the planner * redundantly is good form since other planners may require it. * * @param rules collection of rules to fire */ public HepProgramBuilder addRuleCollection(Collection rules) { return addInstruction(new HepInstruction.RuleCollection(rules)); } /** * Adds an instruction to attempt to match a specific rule object. * *

Note that when this method is used, it is NOT necessary to add the * rule to the planner via {@link RelOptPlanner#addRule}; the instance * supplied here will be used. However, adding the rule to the planner * redundantly is good form since other planners may require it. * * @param rule rule to fire */ public HepProgramBuilder addRuleInstance(RelOptRule rule) { return addInstruction(new HepInstruction.RuleInstance(rule)); } /** * Adds an instruction to attempt to match a specific rule identified by its * unique description. * *

Note that when this method is used, it is necessary to also add the * rule object of interest to the planner via {@link RelOptPlanner#addRule}. * This allows for some decoupling between optimizers and plugins: the * optimizer only knows about rule descriptions, while the plugins supply * the actual instances. If the planner does not have a rule matching the * description, this instruction is a nop. * * @param ruleDescription description of rule to fire */ public HepProgramBuilder addRuleByDescription(String ruleDescription) { return addInstruction( new HepInstruction.RuleLookup(ruleDescription)); } /** * Adds an instruction to begin a group of rules. All subsequent rules added * (until the next endRuleGroup) will be collected into the group rather * than firing individually. After addGroupBegin has been called, only * addRuleXXX methods may be called until the next addGroupEnd. */ public HepProgramBuilder addGroupBegin() { checkArgument(group < 0); group = instructions.size(); return addInstruction(new HepInstruction.Placeholder()); } /** * Adds an instruction to end a group of rules, firing the group * collectively. The order in which the rules within a group will be * attempted is arbitrary. Match order and limit applies to the group as a * whole. */ public HepProgramBuilder addGroupEnd() { checkArgument(group >= 0); final HepInstruction.EndGroup endGroup = new HepInstruction.EndGroup(); instructions.set(group, new HepInstruction.BeginGroup(endGroup)); group = -1; return addInstruction(endGroup); } /** * Adds an instruction to attempt to match instances of * {@link com.hazelcast.org.apache.calcite.rel.convert.ConverterRule}, * but only where a conversion is actually required. * * @param guaranteed if true, use only guaranteed converters; if false, use * only non-guaranteed converters */ public HepProgramBuilder addConverters(boolean guaranteed) { checkArgument(group < 0); return addInstruction(new HepInstruction.ConverterRules(guaranteed)); } /** * Adds an instruction to attempt to match instances of * {@link CommonRelSubExprRule}, but only in cases where vertices have more * than one parent. */ public HepProgramBuilder addCommonRelSubExprInstruction() { checkArgument(group < 0); return addInstruction(new HepInstruction.CommonRelSubExprRules()); } /** * Adds an instruction to change the order of pattern matching for * subsequent instructions. The new order will take effect for the rest of * the program (not counting subprograms) or until another match order * instruction is encountered. * * @param order new match direction to set */ public HepProgramBuilder addMatchOrder(HepMatchOrder order) { checkArgument(group < 0); return addInstruction(new HepInstruction.MatchOrder(order)); } /** * Adds an instruction to limit the number of pattern matches for subsequent * instructions. The limit will take effect for the rest of the program (not * counting subprograms) or until another limit instruction is encountered. * * @param limit limit to set; use {@link HepProgram#MATCH_UNTIL_FIXPOINT} to * remove limit */ public HepProgramBuilder addMatchLimit(int limit) { checkArgument(group < 0); return addInstruction(new HepInstruction.MatchLimit(limit)); } /** * Adds an instruction to execute a subprogram. Note that this is different * from adding the instructions from the subprogram individually. When added * as a subprogram, the sequence will execute repeatedly until a fixpoint is * reached, whereas when the instructions are added individually, the * sequence will only execute once (with a separate fixpoint for each * instruction). * *

The subprogram has its own state for match order and limit * (initialized to the defaults every time the subprogram is executed) and * any changes it makes to those settings do not affect the parent program. * * @param program subProgram to execute */ public HepProgramBuilder addSubprogram(HepProgram program) { checkArgument(group < 0); return addInstruction(new HepInstruction.SubProgram(program)); } private HepProgramBuilder addInstruction(HepInstruction instruction) { instructions.add(instruction); return this; } /** * Returns the constructed program, clearing the state of this program * builder as a side-effect. * * @return immutable program */ public HepProgram build() { checkArgument(group < 0); HepProgram program = new HepProgram(instructions); clear(); return program; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy