/** * 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 org.apache.hadoop.hive.ql.optimizer.calcite; import java.util.Collections; import java.util.List; import java.util.Set; import org.apache.calcite.plan.Contexts; import org.apache.calcite.plan.RelOptCluster; import org.apache.calcite.plan.RelTraitSet; import org.apache.calcite.rel.RelCollation; import org.apache.calcite.rel.RelNode; import org.apache.calcite.rel.core.AggregateCall; import org.apache.calcite.rel.core.CorrelationId; import org.apache.calcite.rel.core.JoinInfo; import org.apache.calcite.rel.core.JoinRelType; import org.apache.calcite.rel.core.RelFactories.AggregateFactory; import org.apache.calcite.rel.core.RelFactories.FilterFactory; import org.apache.calcite.rel.core.RelFactories.JoinFactory; import org.apache.calcite.rel.core.RelFactories.ProjectFactory; import org.apache.calcite.rel.core.RelFactories.SemiJoinFactory; import org.apache.calcite.rel.core.RelFactories.SetOpFactory; import org.apache.calcite.rel.core.RelFactories.SortFactory; import org.apache.calcite.rel.type.RelDataType; import org.apache.calcite.rex.RexNode; import org.apache.calcite.rex.RexUtil; import org.apache.calcite.sql.SqlKind; import org.apache.calcite.tools.RelBuilderFactory; import org.apache.calcite.util.ImmutableBitSet; import org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveAggregate; import org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveFilter; import org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveIntersect; import org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveJoin; import org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveExcept; import org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveProject; import org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveSemiJoin; import org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveSortLimit; import org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveUnion; import com.google.common.collect.ImmutableList; public class HiveRelFactories { public static final ProjectFactory HIVE_PROJECT_FACTORY = new HiveProjectFactoryImpl(); public static final FilterFactory HIVE_FILTER_FACTORY = new HiveFilterFactoryImpl(); public static final JoinFactory HIVE_JOIN_FACTORY = new HiveJoinFactoryImpl(); public static final SemiJoinFactory HIVE_SEMI_JOIN_FACTORY = new HiveSemiJoinFactoryImpl(); public static final SortFactory HIVE_SORT_FACTORY = new HiveSortFactoryImpl(); public static final AggregateFactory HIVE_AGGREGATE_FACTORY = new HiveAggregateFactoryImpl(); public static final SetOpFactory HIVE_SET_OP_FACTORY = new HiveSetOpFactoryImpl(); public static final RelBuilderFactory HIVE_BUILDER = HiveRelBuilder.proto( Contexts.of(HIVE_PROJECT_FACTORY, HIVE_FILTER_FACTORY, HIVE_JOIN_FACTORY, HIVE_SEMI_JOIN_FACTORY, HIVE_SORT_FACTORY, HIVE_AGGREGATE_FACTORY, HIVE_SET_OP_FACTORY)); private HiveRelFactories() { } /** * Implementation of {@link ProjectFactory} that returns * {@link org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveProject} * . */ private static class HiveProjectFactoryImpl implements ProjectFactory { @Override public RelNode createProject(RelNode child, List<? extends RexNode> childExprs, List<String> fieldNames) { RelOptCluster cluster = child.getCluster(); RelDataType rowType = RexUtil.createStructType(cluster.getTypeFactory(), childExprs, fieldNames); RelTraitSet trait = TraitsUtil.getDefaultTraitSet(cluster, child.getTraitSet()); RelNode project = HiveProject.create(cluster, child, childExprs, rowType, trait, Collections.<RelCollation> emptyList()); return project; } } /** * Implementation of {@link FilterFactory} that returns * {@link org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveFilter} * . */ private static class HiveFilterFactoryImpl implements FilterFactory { @Override public RelNode createFilter(RelNode child, RexNode condition) { RelOptCluster cluster = child.getCluster(); HiveFilter filter = new HiveFilter(cluster, TraitsUtil.getDefaultTraitSet(cluster), child, condition); return filter; } } private static class HiveJoinFactoryImpl implements JoinFactory { /** * Creates a join. * * @param left * Left input * @param right * Right input * @param condition * Join condition * @param joinType * Join type * @param variablesStopped * Set of names of variables which are set by the LHS and used by * the RHS and are not available to nodes above this JoinRel in the * tree * @param semiJoinDone * Whether this join has been translated to a semi-join */ @Override public RelNode createJoin(RelNode left, RelNode right, RexNode condition, JoinRelType joinType, Set<String> variablesStopped, boolean semiJoinDone) { return HiveJoin.getJoin(left.getCluster(), left, right, condition, joinType); } @Override public RelNode createJoin(RelNode left, RelNode right, RexNode condition, Set<CorrelationId> variablesSet, JoinRelType joinType, boolean semiJoinDone) { // According to calcite, it is going to be removed before Calcite-2.0 // TODO: to handle CorrelationId return HiveJoin.getJoin(left.getCluster(), left, right, condition, joinType); } } /** * Implementation of {@link SemiJoinFactory} that returns * {@link org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveSemiJoin} * . */ private static class HiveSemiJoinFactoryImpl implements SemiJoinFactory { @Override public RelNode createSemiJoin(RelNode left, RelNode right, RexNode condition) { final JoinInfo joinInfo = JoinInfo.of(left, right, condition); final RelOptCluster cluster = left.getCluster(); return HiveSemiJoin.getSemiJoin(cluster, left.getTraitSet(), left, right, condition, joinInfo.leftKeys, joinInfo.rightKeys); } } private static class HiveSortFactoryImpl implements SortFactory { @Override public RelNode createSort(RelTraitSet traits, RelNode input, RelCollation collation, RexNode offset, RexNode fetch) { return createSort(input, collation, offset, fetch); } @Override public RelNode createSort(RelNode input, RelCollation collation, RexNode offset, RexNode fetch) { return HiveSortLimit.create(input, collation, offset, fetch); } } private static class HiveAggregateFactoryImpl implements AggregateFactory { @Override public RelNode createAggregate(RelNode child, boolean indicator, ImmutableBitSet groupSet, ImmutableList<ImmutableBitSet> groupSets, List<AggregateCall> aggCalls) { return new HiveAggregate(child.getCluster(), child.getTraitSet(), child, indicator, groupSet, groupSets, aggCalls); } } private static class HiveSetOpFactoryImpl implements SetOpFactory { @Override public RelNode createSetOp(SqlKind kind, List<RelNode> inputs, boolean all) { if (kind == SqlKind.UNION) { return new HiveUnion(inputs.get(0).getCluster(), inputs.get(0).getTraitSet(), inputs); } else if (kind == SqlKind.INTERSECT) { return new HiveIntersect(inputs.get(0).getCluster(), inputs.get(0).getTraitSet(), inputs, all); } else if (kind == SqlKind.EXCEPT) { return new HiveExcept(inputs.get(0).getCluster(), inputs.get(0).getTraitSet(), inputs, all); } else { throw new IllegalStateException("Expected to get set operator of type Union, Intersect or Except(Minus). Found : " + kind); } } } }