Package org.eigenbase.test

Source Code of org.eigenbase.test.MockRelOptPlanner

/*
// Licensed to Julian Hyde under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// Julian Hyde 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 org.eigenbase.test;

import java.util.*;

import org.eigenbase.rel.*;
import org.eigenbase.relopt.*;
import org.eigenbase.rex.RexExecutorImpl;
import org.eigenbase.util.Pair;

import net.hydromatic.optiq.Schemas;

/**
* MockRelOptPlanner is a mock implementation of the {@link RelOptPlanner}
* interface.
*/
public class MockRelOptPlanner extends AbstractRelOptPlanner {
  //~ Instance fields --------------------------------------------------------

  private RelNode root;

  private RelOptRule rule;

  private RelNode transformationResult;

  private long metadataTimestamp = 0L;

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

  /** Creates MockRelOptPlanner. */
  public MockRelOptPlanner() {
    super(RelOptCostImpl.FACTORY);
    setExecutor(new RexExecutorImpl(Schemas.createDataContext(null)));
  }

  // implement RelOptPlanner
  public void setRoot(RelNode rel) {
    this.root = rel;
  }

  // implement RelOptPlanner
  public RelNode getRoot() {
    return root;
  }

  public void addMaterialization(RelOptMaterialization materialization) {
    // ignore - this planner does not support materializations
  }

  @Override public void clear() {
    super.clear();
    this.rule = null;
  }

  public boolean addRule(RelOptRule rule) {
    assert this.rule == null
        : "MockRelOptPlanner only supports a single rule";
    this.rule = rule;

    return false;
  }

  public boolean removeRule(RelOptRule rule) {
    return false;
  }

  // implement RelOptPlanner
  public RelNode changeTraits(RelNode rel, RelTraitSet toTraits) {
    return rel;
  }

  // implement RelOptPlanner
  public RelNode findBestExp() {
    if (rule != null) {
      matchRecursive(root, null, -1);
    }
    return root;
  }

  /**
   * Recursively matches a rule.
   *
   * @param rel             Relational expression
   * @param parent          Parent relational expression
   * @param ordinalInParent Ordinal of relational expression among its
   *                        siblings
   * @return whether match occurred
   */
  private boolean matchRecursive(
      RelNode rel,
      RelNode parent,
      int ordinalInParent) {
    List<RelNode> bindings = new ArrayList<RelNode>();
    if (match(
        rule.getOperand(),
        rel,
        bindings)) {
      MockRuleCall call =
          new MockRuleCall(
              this,
              rule.getOperand(),
              bindings.toArray(new RelNode[bindings.size()]));
      if (rule.matches(call)) {
        rule.onMatch(call);
      }
    }

    if (transformationResult != null) {
      if (parent == null) {
        root = transformationResult;
      } else {
        parent.replaceInput(ordinalInParent, transformationResult);
      }
      return true;
    }

    List<? extends RelNode> children = rel.getInputs();
    for (int i = 0; i < children.size(); ++i) {
      if (matchRecursive(children.get(i), rel, i)) {
        return true;
      }
    }
    return false;
  }

  /**
   * Matches a relational expression to a rule.
   *
   * @param operand  Root operand of rule
   * @param rel      Relational expression
   * @param bindings Bindings, populated on successful match
   * @return whether relational expression matched rule
   */
  private boolean match(
      RelOptRuleOperand operand,
      RelNode rel,
      List<RelNode> bindings) {
    if (!operand.matches(rel)) {
      return false;
    }
    bindings.add(rel);
    switch (operand.childPolicy) {
    case ANY:
      return true;
    }
    List<RelOptRuleOperand> childOperands = operand.getChildOperands();
    List<? extends RelNode> childRels = rel.getInputs();
    if (childOperands.size() != childRels.size()) {
      return false;
    }
    for (Pair<RelOptRuleOperand, ? extends RelNode> pair
        : Pair.zip(childOperands, childRels)) {
      if (!match(pair.left, pair.right, bindings)) {
        return false;
      }
    }
    return true;
  }

  // implement RelOptPlanner
  public RelNode register(
      RelNode rel,
      RelNode equivRel) {
    return rel;
  }

  // implement RelOptPlanner
  public RelNode ensureRegistered(RelNode rel, RelNode equivRel) {
    return rel;
  }

  // implement RelOptPlanner
  public boolean isRegistered(RelNode rel) {
    return true;
  }

  @Override
  public long getRelMetadataTimestamp(RelNode rel) {
    return metadataTimestamp;
  }

  /** Allow tests to tweak the timestamp. */
  public void setRelMetadataTimestamp(long metadataTimestamp) {
    this.metadataTimestamp = metadataTimestamp;
  }

  //~ Inner Classes ----------------------------------------------------------

  private class MockRuleCall extends RelOptRuleCall {
    /**
     * Creates a MockRuleCall.
     *
     * @param planner Planner
     * @param operand Operand
     * @param rels    List of matched relational expressions
     */
    MockRuleCall(
        RelOptPlanner planner,
        RelOptRuleOperand operand,
        RelNode[] rels) {
      super(
          planner,
          operand,
          rels,
          Collections.<RelNode, List<RelNode>>emptyMap());
    }

    // implement RelOptRuleCall
    public void transformTo(RelNode rel, Map<RelNode, RelNode> equiv) {
      transformationResult = rel;
    }
  }
}

// End MockRelOptPlanner.java
TOP

Related Classes of org.eigenbase.test.MockRelOptPlanner

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.