Package cascading.lingual.optiq

Source Code of cascading.lingual.optiq.CascadingJoinRel

/*
* Copyright (c) 2007-2014 Concurrent, Inc. All Rights Reserved.
*
* Project and contact information: http://www.cascading.org/
*
* This file is part of the Cascading project.
*
* Licensed 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 cascading.lingual.optiq;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import cascading.lingual.optiq.meta.Branch;
import cascading.pipe.CoGroup;
import cascading.pipe.Pipe;
import cascading.pipe.joiner.InnerJoin;
import cascading.pipe.joiner.Joiner;
import cascading.pipe.joiner.LeftJoin;
import cascading.pipe.joiner.OuterJoin;
import cascading.pipe.joiner.RightJoin;
import cascading.tuple.Fields;
import cascading.util.NullNotEquivalentComparator;
import org.eigenbase.rel.JoinRelBase;
import org.eigenbase.rel.JoinRelType;
import org.eigenbase.rel.RelNode;
import org.eigenbase.relopt.RelOptCluster;
import org.eigenbase.relopt.RelOptCost;
import org.eigenbase.relopt.RelOptPlanWriter;
import org.eigenbase.relopt.RelOptPlanner;
import org.eigenbase.relopt.RelOptUtil;
import org.eigenbase.relopt.RelTraitSet;
import org.eigenbase.rex.RexNode;

import static cascading.lingual.optiq.RelUtil.createTypedFieldsSelectorFor;

/** Join implemented in Cascading. */
class CascadingJoinRel extends JoinRelBase implements CascadingRelNode
  {
  /** Whether a hash join. 0 = not, 1 = hash join builds on the left, 2 = hash join builds on the right. */
  private final int hash;
  private final List<Integer> leftKeys = new ArrayList<Integer>();
  private final List<Integer> rightKeys = new ArrayList<Integer>();

  public CascadingJoinRel( RelOptCluster cluster, RelTraitSet traits, RelNode left, RelNode right, RexNode condition, JoinRelType joinType, Set<String> variablesStopped, int hash )
    {
    super( cluster, traits, left, right, condition, joinType, variablesStopped );
    this.hash = hash;

    RexNode remaining = RelOptUtil.splitJoinCondition( left, right, condition, leftKeys, rightKeys );

    // Rule should have checked "isEqui" before firing. Something went wrong.
    if( !remaining.isAlwaysTrue() )
      throw new AssertionError( "not equi-join condition: " + remaining );
    }

  @Override
  public RelOptCost computeSelfCost( RelOptPlanner planner )
    {
    final RelOptCost cost = super.computeSelfCost( planner );

    if( leftKeys.size() == 0 ) // cartesian product. make artificially expensive.
      return cost.multiplyBy( 10d );

    return cost.multiplyBy( .1 );
    }

  @Override
  public RelOptPlanWriter explainTerms( RelOptPlanWriter pw )
    {
    return super.explainTerms( pw )
      .item( "hash", hash );
    }

  @Override
  public JoinRelBase copy( RelTraitSet traitSet, RexNode conditionExpr, RelNode left, RelNode right )
    {
    return new CascadingJoinRel( getCluster(), traitSet, left, right, conditionExpr, this.joinType, this.variablesStopped, this.hash );
    }

  public Branch visitChild( Stack stack )
    {
    Branch lhsBranch = ( (CascadingRelNode) left ).visitChild( stack );
    Branch rhsBranch = ( (CascadingRelNode) right ).visitChild( stack );

    Pipe leftPipe = new Pipe( "lhs", lhsBranch.current );
    leftPipe = stack.addDebug( this, leftPipe, "lhs" );

    Pipe rightPipe = new Pipe( "rhs", rhsBranch.current );
    rightPipe = stack.addDebug( this, rightPipe, "rhs" );

    Fields lhsGroup = createTypedFieldsSelectorFor( getCluster(), leftKeys, left.getRowType(), true );
    Fields rhsGroup = createTypedFieldsSelectorFor( getCluster(), rightKeys, right.getRowType(), true );

    NullNotEquivalentComparator comparator = new NullNotEquivalentComparator();
    for( int i = 0; i < lhsGroup.size(); i++ )
      lhsGroup.setComparator( i, comparator );

    Joiner joiner = getJoiner();

    Fields declaredFields = RelUtil.createTypedFieldsFor( this, false );

    // need to parse lhs rhs fields from condition
    String name = stack.getNameFor( CoGroup.class, leftPipe, rightPipe );
    Pipe coGroup = new CoGroup( name, leftPipe, lhsGroup, rightPipe, rhsGroup, declaredFields, joiner );

    coGroup = stack.addDebug( this, coGroup );

    return new Branch( coGroup, lhsBranch, rhsBranch );
    }

  private Joiner getJoiner()
    {
    switch( getJoinType() )
      {
      case INNER:
        return new InnerJoin();
      case LEFT:
        return new LeftJoin();
      case RIGHT:
        return new RightJoin();
      case FULL:
        return new OuterJoin();
      default:
        throw new IllegalStateException( "unknown join type" );
      }
    }
  }
TOP

Related Classes of cascading.lingual.optiq.CascadingJoinRel

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.