Search in sources :

Example 6 with RelTraitSet

use of org.apache.calcite.plan.RelTraitSet in project drill by apache.

the class JoinPruleBase method createDistBothPlan.

// Create join plan with both left and right children hash distributed. If the physical join type
// is MergeJoin, a collation must be provided for both left and right child and the plan will contain
// sort converter if necessary to provide the collation.
private void createDistBothPlan(RelOptRuleCall call, DrillJoinRel join, PhysicalJoinType physicalJoinType, RelNode left, RelNode right, RelCollation collationLeft, RelCollation collationRight, DrillDistributionTrait hashLeftPartition, DrillDistributionTrait hashRightPartition) throws InvalidRelException {
    //DrillDistributionTrait hashLeftPartition = new DrillDistributionTrait(DrillDistributionTrait.DistributionType.HASH_DISTRIBUTED, ImmutableList.copyOf(getDistributionField(join.getLeftKeys())));
    //DrillDistributionTrait hashRightPartition = new DrillDistributionTrait(DrillDistributionTrait.DistributionType.HASH_DISTRIBUTED, ImmutableList.copyOf(getDistributionField(join.getRightKeys())));
    RelTraitSet traitsLeft = null;
    RelTraitSet traitsRight = null;
    if (physicalJoinType == PhysicalJoinType.MERGE_JOIN) {
        assert collationLeft != null && collationRight != null;
        traitsLeft = left.getTraitSet().plus(Prel.DRILL_PHYSICAL).plus(collationLeft).plus(hashLeftPartition);
        traitsRight = right.getTraitSet().plus(Prel.DRILL_PHYSICAL).plus(collationRight).plus(hashRightPartition);
    } else if (physicalJoinType == PhysicalJoinType.HASH_JOIN) {
        traitsLeft = left.getTraitSet().plus(Prel.DRILL_PHYSICAL).plus(hashLeftPartition);
        traitsRight = right.getTraitSet().plus(Prel.DRILL_PHYSICAL).plus(hashRightPartition);
    }
    final RelNode convertedLeft = convert(left, traitsLeft);
    final RelNode convertedRight = convert(right, traitsRight);
    DrillJoinRelBase newJoin = null;
    if (physicalJoinType == PhysicalJoinType.HASH_JOIN) {
        newJoin = new HashJoinPrel(join.getCluster(), traitsLeft, convertedLeft, convertedRight, join.getCondition(), join.getJoinType());
    } else if (physicalJoinType == PhysicalJoinType.MERGE_JOIN) {
        newJoin = new MergeJoinPrel(join.getCluster(), traitsLeft, convertedLeft, convertedRight, join.getCondition(), join.getJoinType());
    }
    call.transformTo(newJoin);
}
Also used : DrillJoinRelBase(org.apache.drill.exec.planner.common.DrillJoinRelBase) RelNode(org.apache.calcite.rel.RelNode) RelTraitSet(org.apache.calcite.plan.RelTraitSet)

Example 7 with RelTraitSet

use of org.apache.calcite.plan.RelTraitSet in project drill by apache.

the class ProjectPrule method onMatch.

@Override
public void onMatch(RelOptRuleCall call) {
    final DrillProjectRel project = (DrillProjectRel) call.rel(0);
    final RelNode input = project.getInput();
    RelTraitSet traits = input.getTraitSet().plus(Prel.DRILL_PHYSICAL);
    RelNode convertedInput = convert(input, traits);
    // Maintain two different map for distribution trait and collation trait.
    // For now, the only difference comes from the way how cast function impacts propagating trait.
    final Map<Integer, Integer> distributionMap = getDistributionMap(project);
    final Map<Integer, Integer> collationMap = getCollationMap(project);
    boolean traitPull = new ProjectTraitPull(call, distributionMap, collationMap).go(project, convertedInput);
    if (!traitPull) {
        call.transformTo(new ProjectPrel(project.getCluster(), convertedInput.getTraitSet(), convertedInput, project.getProjects(), project.getRowType()));
    }
}
Also used : RelNode(org.apache.calcite.rel.RelNode) DrillProjectRel(org.apache.drill.exec.planner.logical.DrillProjectRel) RelTraitSet(org.apache.calcite.plan.RelTraitSet)

Example 8 with RelTraitSet

use of org.apache.calcite.plan.RelTraitSet in project drill by apache.

the class ScanPrule method onMatch.

@Override
public void onMatch(RelOptRuleCall call) {
    final DrillScanRel scan = (DrillScanRel) call.rel(0);
    GroupScan groupScan = scan.getGroupScan();
    DrillDistributionTrait partition = (groupScan.getMaxParallelizationWidth() > 1 || groupScan.getDistributionAffinity() == DistributionAffinity.HARD) ? DrillDistributionTrait.RANDOM_DISTRIBUTED : DrillDistributionTrait.SINGLETON;
    final RelTraitSet traits = scan.getTraitSet().plus(Prel.DRILL_PHYSICAL).plus(partition);
    final DrillScanPrel newScan = ScanPrel.create(scan, traits, groupScan, scan.getRowType());
    call.transformTo(newScan);
}
Also used : GroupScan(org.apache.drill.exec.physical.base.GroupScan) DrillScanRel(org.apache.drill.exec.planner.logical.DrillScanRel) RelTraitSet(org.apache.calcite.plan.RelTraitSet)

Example 9 with RelTraitSet

use of org.apache.calcite.plan.RelTraitSet in project drill by apache.

the class StreamAggPrule method onMatch.

@Override
public void onMatch(RelOptRuleCall call) {
    final DrillAggregateRel aggregate = (DrillAggregateRel) call.rel(0);
    RelNode input = aggregate.getInput();
    final RelCollation collation = getCollation(aggregate);
    RelTraitSet traits = null;
    if (aggregate.containsDistinctCall()) {
        // currently, don't use StreamingAggregate if any of the logical aggrs contains DISTINCT
        return;
    }
    try {
        if (aggregate.getGroupSet().isEmpty()) {
            DrillDistributionTrait singleDist = DrillDistributionTrait.SINGLETON;
            final RelTraitSet singleDistTrait = call.getPlanner().emptyTraitSet().plus(Prel.DRILL_PHYSICAL).plus(singleDist);
            if (create2PhasePlan(call, aggregate)) {
                traits = call.getPlanner().emptyTraitSet().plus(Prel.DRILL_PHYSICAL);
                RelNode convertedInput = convert(input, traits);
                new SubsetTransformer<DrillAggregateRel, InvalidRelException>(call) {

                    @Override
                    public RelNode convertChild(final DrillAggregateRel join, final RelNode rel) throws InvalidRelException {
                        DrillDistributionTrait toDist = rel.getTraitSet().getTrait(DrillDistributionTraitDef.INSTANCE);
                        RelTraitSet traits = newTraitSet(Prel.DRILL_PHYSICAL, toDist);
                        RelNode newInput = convert(rel, traits);
                        StreamAggPrel phase1Agg = new StreamAggPrel(aggregate.getCluster(), traits, newInput, aggregate.indicator, aggregate.getGroupSet(), aggregate.getGroupSets(), aggregate.getAggCallList(), OperatorPhase.PHASE_1of2);
                        UnionExchangePrel exch = new UnionExchangePrel(phase1Agg.getCluster(), singleDistTrait, phase1Agg);
                        return new StreamAggPrel(aggregate.getCluster(), singleDistTrait, exch, aggregate.indicator, aggregate.getGroupSet(), aggregate.getGroupSets(), phase1Agg.getPhase2AggCalls(), OperatorPhase.PHASE_2of2);
                    }
                }.go(aggregate, convertedInput);
            } else {
                createTransformRequest(call, aggregate, input, singleDistTrait);
            }
        } else {
            // hash distribute on all grouping keys
            final DrillDistributionTrait distOnAllKeys = new DrillDistributionTrait(DrillDistributionTrait.DistributionType.HASH_DISTRIBUTED, ImmutableList.copyOf(getDistributionField(aggregate, true)));
            traits = call.getPlanner().emptyTraitSet().plus(Prel.DRILL_PHYSICAL).plus(collation).plus(distOnAllKeys);
            createTransformRequest(call, aggregate, input, traits);
            // hash distribute on one grouping key
            DrillDistributionTrait distOnOneKey = new DrillDistributionTrait(DrillDistributionTrait.DistributionType.HASH_DISTRIBUTED, ImmutableList.copyOf(getDistributionField(aggregate, false)));
            traits = call.getPlanner().emptyTraitSet().plus(Prel.DRILL_PHYSICAL).plus(collation).plus(distOnOneKey);
            if (create2PhasePlan(call, aggregate)) {
                traits = call.getPlanner().emptyTraitSet().plus(Prel.DRILL_PHYSICAL);
                RelNode convertedInput = convert(input, traits);
                new SubsetTransformer<DrillAggregateRel, InvalidRelException>(call) {

                    @Override
                    public RelNode convertChild(final DrillAggregateRel aggregate, final RelNode rel) throws InvalidRelException {
                        DrillDistributionTrait toDist = rel.getTraitSet().getTrait(DrillDistributionTraitDef.INSTANCE);
                        RelTraitSet traits = newTraitSet(Prel.DRILL_PHYSICAL, collation, toDist);
                        RelNode newInput = convert(rel, traits);
                        StreamAggPrel phase1Agg = new StreamAggPrel(aggregate.getCluster(), traits, newInput, aggregate.indicator, aggregate.getGroupSet(), aggregate.getGroupSets(), aggregate.getAggCallList(), OperatorPhase.PHASE_1of2);
                        int numEndPoints = PrelUtil.getSettings(phase1Agg.getCluster()).numEndPoints();
                        HashToMergeExchangePrel exch = new HashToMergeExchangePrel(phase1Agg.getCluster(), phase1Agg.getTraitSet().plus(Prel.DRILL_PHYSICAL).plus(distOnAllKeys), phase1Agg, ImmutableList.copyOf(getDistributionField(aggregate, true)), collation, numEndPoints);
                        return new StreamAggPrel(aggregate.getCluster(), exch.getTraitSet(), exch, aggregate.indicator, aggregate.getGroupSet(), aggregate.getGroupSets(), phase1Agg.getPhase2AggCalls(), OperatorPhase.PHASE_2of2);
                    }
                }.go(aggregate, convertedInput);
            }
        }
    } catch (InvalidRelException e) {
        tracer.warning(e.toString());
    }
}
Also used : InvalidRelException(org.apache.calcite.rel.InvalidRelException) RelCollation(org.apache.calcite.rel.RelCollation) RelNode(org.apache.calcite.rel.RelNode) DrillAggregateRel(org.apache.drill.exec.planner.logical.DrillAggregateRel) RelTraitSet(org.apache.calcite.plan.RelTraitSet)

Example 10 with RelTraitSet

use of org.apache.calcite.plan.RelTraitSet in project drill by apache.

the class DefaultSqlHandler method convertToDrel.

/**
   *  Given a relNode tree for SELECT statement, convert to Drill Logical RelNode tree.
   * @param relNode
   * @return
   * @throws SqlUnsupportedException
   * @throws RelConversionException
   */
protected DrillRel convertToDrel(final RelNode relNode) throws SqlUnsupportedException, RelConversionException {
    if (context.getOptions().getOption(ExecConstants.EARLY_LIMIT0_OPT) && context.getPlannerSettings().isTypeInferenceEnabled() && FindLimit0Visitor.containsLimit0(relNode)) {
        // if the schema is known, return the schema directly
        final DrillRel shorterPlan;
        if ((shorterPlan = FindLimit0Visitor.getDirectScanRelIfFullySchemaed(relNode)) != null) {
            return shorterPlan;
        }
        if (FindHardDistributionScans.canForceSingleMode(relNode)) {
            // disable distributed mode
            context.getPlannerSettings().forceSingleMode();
        }
    }
    try {
        final RelNode convertedRelNode;
        // HEP Directory pruning .
        final RelNode pruned = transform(PlannerType.HEP_BOTTOM_UP, PlannerPhase.DIRECTORY_PRUNING, relNode);
        final RelTraitSet logicalTraits = pruned.getTraitSet().plus(DrillRel.DRILL_LOGICAL);
        if (!context.getPlannerSettings().isHepOptEnabled()) {
            // hep is disabled, use volcano
            convertedRelNode = transform(PlannerType.VOLCANO, PlannerPhase.LOGICAL_PRUNE_AND_JOIN, pruned, logicalTraits);
        } else {
            final RelNode intermediateNode2;
            if (context.getPlannerSettings().isHepPartitionPruningEnabled()) {
                // hep is enabled and hep pruning is enabled.
                final RelNode intermediateNode = transform(PlannerType.VOLCANO, PlannerPhase.LOGICAL, pruned, logicalTraits);
                intermediateNode2 = transform(PlannerType.HEP_BOTTOM_UP, PlannerPhase.PARTITION_PRUNING, intermediateNode);
            } else {
                // Only hep is enabled
                intermediateNode2 = transform(PlannerType.VOLCANO, PlannerPhase.LOGICAL_PRUNE, pruned, logicalTraits);
            }
            // Do Join Planning.
            convertedRelNode = transform(PlannerType.HEP_BOTTOM_UP, PlannerPhase.JOIN_PLANNING, intermediateNode2);
        }
        // Convert SUM to $SUM0
        final RelNode convertedRelNodeWithSum0 = transform(PlannerType.HEP_BOTTOM_UP, PlannerPhase.SUM_CONVERSION, convertedRelNode);
        final DrillRel drillRel = (DrillRel) convertedRelNodeWithSum0;
        if (drillRel instanceof DrillStoreRel) {
            throw new UnsupportedOperationException();
        } else {
            // If the query contains a limit 0 clause, disable distributed mode since it is overkill for determining schema.
            if (FindLimit0Visitor.containsLimit0(convertedRelNodeWithSum0) && FindHardDistributionScans.canForceSingleMode(convertedRelNodeWithSum0)) {
                context.getPlannerSettings().forceSingleMode();
            }
            return drillRel;
        }
    } catch (RelOptPlanner.CannotPlanException ex) {
        logger.error(ex.getMessage());
        if (JoinUtils.checkCartesianJoin(relNode, new ArrayList<Integer>(), new ArrayList<Integer>(), new ArrayList<Boolean>())) {
            throw new UnsupportedRelOperatorException("This query cannot be planned possibly due to either a cartesian join or an inequality join");
        } else {
            throw ex;
        }
    }
}
Also used : RelNode(org.apache.calcite.rel.RelNode) UnsupportedRelOperatorException(org.apache.drill.exec.work.foreman.UnsupportedRelOperatorException) DrillStoreRel(org.apache.drill.exec.planner.logical.DrillStoreRel) ArrayList(java.util.ArrayList) DrillRel(org.apache.drill.exec.planner.logical.DrillRel) RelTraitSet(org.apache.calcite.plan.RelTraitSet) RelOptPlanner(org.apache.calcite.plan.RelOptPlanner)

Aggregations

RelTraitSet (org.apache.calcite.plan.RelTraitSet)36 RelNode (org.apache.calcite.rel.RelNode)25 InvalidRelException (org.apache.calcite.rel.InvalidRelException)8 ArrayList (java.util.ArrayList)4 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)4 RexNode (org.apache.calcite.rex.RexNode)4 RelOptCluster (org.apache.calcite.plan.RelOptCluster)3 RelOptPlanner (org.apache.calcite.plan.RelOptPlanner)3 RelCollation (org.apache.calcite.rel.RelCollation)3 Stopwatch (com.google.common.base.Stopwatch)2 ImmutableList (com.google.common.collect.ImmutableList)2 RelOptTable (org.apache.calcite.plan.RelOptTable)2 Sort (org.apache.calcite.rel.core.Sort)2 Window (org.apache.calcite.rel.core.Window)2 RelDataType (org.apache.calcite.rel.type.RelDataType)2 RexInputRef (org.apache.calcite.rex.RexInputRef)2 Table (org.apache.calcite.schema.Table)2 DrillAggregateRel (org.apache.drill.exec.planner.logical.DrillAggregateRel)2 DrillDirectScanRel (org.apache.drill.exec.planner.logical.DrillDirectScanRel)2 DrillRel (org.apache.drill.exec.planner.logical.DrillRel)2