Search in sources :

Example 81 with RexBuilder

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexBuilder in project drill by apache.

the class FinalColumnReorderer method addTrivialOrderedProjectPrel.

private Prel addTrivialOrderedProjectPrel(Prel prel) {
    RelDataType t = prel.getRowType();
    RexBuilder b = prel.getCluster().getRexBuilder();
    List<RexNode> projections = Lists.newArrayList();
    int projectCount = t.getFieldList().size();
    // no point in reordering if we only have one column
    if (projectCount < 2) {
        return prel;
    }
    for (int i = 0; i < projectCount; i++) {
        projections.add(b.makeInputRef(prel, i));
    }
    return new ProjectPrel(prel.getCluster(), prel.getTraitSet(), prel, projections, prel.getRowType());
}
Also used : ProjectPrel(org.apache.drill.exec.planner.physical.ProjectPrel) RexBuilder(org.apache.calcite.rex.RexBuilder) RelDataType(org.apache.calcite.rel.type.RelDataType) RexNode(org.apache.calcite.rex.RexNode)

Example 82 with RexBuilder

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexBuilder in project drill by apache.

the class DrillRelMdDistinctRowCount method getDistinctRowCountInternal.

private Double getDistinctRowCountInternal(DrillJoinRelBase joinRel, RelMetadataQuery mq, ImmutableBitSet groupKey, RexNode predicate) {
    if (DrillRelOptUtil.guessRows(joinRel)) {
        return super.getDistinctRowCount(joinRel, mq, groupKey, predicate);
    }
    // Assume NDV is unaffected by the join when groupKey comes from one side of the join
    // Alleviates NDV over-estimates
    ImmutableBitSet.Builder leftMask = ImmutableBitSet.builder();
    ImmutableBitSet.Builder rightMask = ImmutableBitSet.builder();
    JoinRelType joinType = joinRel.getJoinType();
    RelNode left = joinRel.getInputs().get(0);
    RelNode right = joinRel.getInputs().get(1);
    RelMdUtil.setLeftRightBitmaps(groupKey, leftMask, rightMask, left.getRowType().getFieldCount());
    RexNode leftPred = null;
    RexNode rightPred = null;
    // Identify predicates which can be pushed onto the left and right sides of the join
    if (predicate != null) {
        List<RexNode> leftFilters = new ArrayList<>();
        List<RexNode> rightFilters = new ArrayList<>();
        List<RexNode> joinFilters = new ArrayList();
        List<RexNode> predList = RelOptUtil.conjunctions(predicate);
        RelOptUtil.classifyFilters(joinRel, predList, joinType, joinType == JoinRelType.INNER, !joinType.generatesNullsOnLeft(), !joinType.generatesNullsOnRight(), joinFilters, leftFilters, rightFilters);
        RexBuilder rexBuilder = joinRel.getCluster().getRexBuilder();
        leftPred = RexUtil.composeConjunction(rexBuilder, leftFilters, true);
        rightPred = RexUtil.composeConjunction(rexBuilder, rightFilters, true);
    }
    double distRowCount = 1;
    int gbyCols = 0;
    PlannerSettings plannerSettings = PrelUtil.getPlannerSettings(joinRel.getCluster().getPlanner());
    /*
     * The NDV for a multi-column GBY key past a join is determined as follows:
     * GBY(s1, s2, s3) = CNDV(s1)*CNDV(s2)*CNDV(s3)
     * where CNDV is determined as follows:
     * A) If sX is present as a join column (sX = tX) CNDV(sX) = MIN(NDV(sX), NDV(tX)) where X =1, 2, 3, etc
     * B) Otherwise, based on independence assumption CNDV(sX) = NDV(sX)
     */
    Set<ImmutableBitSet> joinFiltersSet = new HashSet<>();
    for (RexNode filter : RelOptUtil.conjunctions(joinRel.getCondition())) {
        final RelOptUtil.InputFinder inputFinder = RelOptUtil.InputFinder.analyze(filter);
        joinFiltersSet.add(inputFinder.inputBitSet.build());
    }
    for (int idx = 0; idx < groupKey.length(); idx++) {
        if (groupKey.get(idx)) {
            // GBY key is present in some filter - now try options A) and B) as described above
            double ndvSGby = Double.MAX_VALUE;
            Double ndv;
            boolean presentInFilter = false;
            ImmutableBitSet sGby = getSingleGbyKey(groupKey, idx);
            if (sGby != null) {
                // If we see any NULL ndv i.e. cant process ..we bail out!
                for (ImmutableBitSet jFilter : joinFiltersSet) {
                    if (jFilter.contains(sGby)) {
                        presentInFilter = true;
                        // Found join condition containing this GBY key. Pick min NDV across all columns in this join
                        for (int fidx : jFilter) {
                            if (fidx < left.getRowType().getFieldCount()) {
                                ndv = mq.getDistinctRowCount(left, ImmutableBitSet.of(fidx), leftPred);
                                if (ndv == null) {
                                    return super.getDistinctRowCount(joinRel, mq, groupKey, predicate);
                                }
                                ndvSGby = Math.min(ndvSGby, ndv);
                            } else {
                                ndv = mq.getDistinctRowCount(right, ImmutableBitSet.of(fidx - left.getRowType().getFieldCount()), rightPred);
                                if (ndv == null) {
                                    return super.getDistinctRowCount(joinRel, mq, groupKey, predicate);
                                }
                                ndvSGby = Math.min(ndvSGby, ndv);
                            }
                        }
                        break;
                    }
                }
                // Did not find it in any join condition(s)
                if (!presentInFilter) {
                    for (int sidx : sGby) {
                        if (sidx < left.getRowType().getFieldCount()) {
                            ndv = mq.getDistinctRowCount(left, ImmutableBitSet.of(sidx), leftPred);
                            if (ndv == null) {
                                return super.getDistinctRowCount(joinRel, mq, groupKey, predicate);
                            }
                            ndvSGby = ndv;
                        } else {
                            ndv = mq.getDistinctRowCount(right, ImmutableBitSet.of(sidx - left.getRowType().getFieldCount()), rightPred);
                            if (ndv == null) {
                                return super.getDistinctRowCount(joinRel, mq, groupKey, predicate);
                            }
                            ndvSGby = ndv;
                        }
                    }
                }
                ++gbyCols;
                // Multiply NDV(s) of different GBY cols to determine the overall NDV
                distRowCount *= ndvSGby;
            }
        }
    }
    if (gbyCols > 1) {
        // Scale with multi-col NDV factor if more than one GBY cols were found
        distRowCount *= plannerSettings.getStatisticsMultiColNdvAdjustmentFactor();
    }
    double joinRowCount = mq.getRowCount(joinRel);
    // Cap NDV to join row count
    distRowCount = Math.min(distRowCount, joinRowCount);
    return RelMdUtil.numDistinctVals(distRowCount, joinRowCount);
}
Also used : ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) PlannerSettings(org.apache.drill.exec.planner.physical.PlannerSettings) RelOptUtil(org.apache.calcite.plan.RelOptUtil) DrillRelOptUtil(org.apache.drill.exec.planner.common.DrillRelOptUtil) ArrayList(java.util.ArrayList) JoinRelType(org.apache.calcite.rel.core.JoinRelType) RelNode(org.apache.calcite.rel.RelNode) RexBuilder(org.apache.calcite.rex.RexBuilder) RexNode(org.apache.calcite.rex.RexNode) HashSet(java.util.HashSet)

Example 83 with RexBuilder

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexBuilder in project drill by apache.

the class DrillRelMdSelectivity method getJoinSelectivity.

private Double getJoinSelectivity(DrillJoinRelBase rel, RelMetadataQuery mq, RexNode predicate) {
    double sel = 1.0;
    // determine which filters apply to the left vs right
    RexNode leftPred, rightPred;
    JoinRelType joinType = rel.getJoinType();
    final RexBuilder rexBuilder = rel.getCluster().getRexBuilder();
    int[] adjustments = new int[rel.getRowType().getFieldCount()];
    if (DrillRelOptUtil.guessRows(rel)) {
        return super.getSelectivity(rel, mq, predicate);
    }
    if (predicate != null) {
        RexNode pred;
        List<RexNode> leftFilters = new ArrayList<>();
        List<RexNode> rightFilters = new ArrayList<>();
        List<RexNode> joinFilters = new ArrayList<>();
        List<RexNode> predList = RelOptUtil.conjunctions(predicate);
        RelOptUtil.classifyFilters(rel, predList, joinType, joinType == JoinRelType.INNER, !joinType.generatesNullsOnLeft(), !joinType.generatesNullsOnRight(), joinFilters, leftFilters, rightFilters);
        leftPred = RexUtil.composeConjunction(rexBuilder, leftFilters, true);
        rightPred = RexUtil.composeConjunction(rexBuilder, rightFilters, true);
        for (RelNode child : rel.getInputs()) {
            RexNode modifiedPred = null;
            if (child == rel.getLeft()) {
                pred = leftPred;
            } else {
                pred = rightPred;
            }
            if (pred != null) {
                // convert the predicate to reference the types of the children
                modifiedPred = pred.accept(new RelOptUtil.RexInputConverter(rexBuilder, null, child.getRowType().getFieldList(), adjustments));
            }
            sel *= mq.getSelectivity(child, modifiedPred);
        }
        sel *= RelMdUtil.guessSelectivity(RexUtil.composeConjunction(rexBuilder, joinFilters, true));
    }
    return sel;
}
Also used : JoinRelType(org.apache.calcite.rel.core.JoinRelType) RelNode(org.apache.calcite.rel.RelNode) ArrayList(java.util.ArrayList) RexBuilder(org.apache.calcite.rex.RexBuilder) RexNode(org.apache.calcite.rex.RexNode)

Example 84 with RexBuilder

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexBuilder in project drill by apache.

the class DrillRelMdSelectivity method getScanSelectivity.

private Double getScanSelectivity(RelNode rel, RelMetadataQuery mq, RexNode predicate) {
    double ROWCOUNT_UNKNOWN = -1.0;
    GroupScan scan = null;
    PlannerSettings settings = PrelUtil.getPlannerSettings(rel.getCluster().getPlanner());
    final RexBuilder rexBuilder = rel.getCluster().getRexBuilder();
    if (rel instanceof DrillScanRel) {
        scan = ((DrillScanRel) rel).getGroupScan();
    } else if (rel instanceof ScanPrel) {
        scan = ((ScanPrel) rel).getGroupScan();
    }
    if (scan != null) {
        if (settings.isStatisticsEnabled() && scan instanceof DbGroupScan) {
            double filterRows = ((DbGroupScan) scan).getRowCount(predicate, rel);
            double totalRows = ((DbGroupScan) scan).getRowCount(null, rel);
            if (filterRows != ROWCOUNT_UNKNOWN && totalRows != ROWCOUNT_UNKNOWN && totalRows > 0) {
                return Math.min(1.0, filterRows / totalRows);
            }
        }
    }
    // Do not mess with statistics used for DBGroupScans.
    if (rel instanceof TableScan) {
        if (DrillRelOptUtil.guessRows(rel)) {
            return super.getSelectivity(rel, mq, predicate);
        }
        DrillTable table = Utilities.getDrillTable(rel.getTable());
        try {
            TableMetadata tableMetadata;
            if (table != null && (tableMetadata = table.getGroupScan().getTableMetadata()) != null && TableStatisticsKind.HAS_DESCRIPTIVE_STATISTICS.getValue(tableMetadata)) {
                List<SchemaPath> fieldNames;
                if (rel instanceof DrillScanRelBase) {
                    fieldNames = ((DrillScanRelBase) rel).getGroupScan().getColumns();
                } else {
                    fieldNames = rel.getRowType().getFieldNames().stream().map(SchemaPath::getSimplePath).collect(Collectors.toList());
                }
                return getScanSelectivityInternal(tableMetadata, predicate, fieldNames, rexBuilder);
            }
        } catch (IOException e) {
            super.getSelectivity(rel, mq, predicate);
        }
    }
    return super.getSelectivity(rel, mq, predicate);
}
Also used : TableMetadata(org.apache.drill.metastore.metadata.TableMetadata) TableScan(org.apache.calcite.rel.core.TableScan) DrillScanRel(org.apache.drill.exec.planner.logical.DrillScanRel) ScanPrel(org.apache.drill.exec.planner.physical.ScanPrel) DrillTable(org.apache.drill.exec.planner.logical.DrillTable) PlannerSettings(org.apache.drill.exec.planner.physical.PlannerSettings) IOException(java.io.IOException) DbGroupScan(org.apache.drill.exec.physical.base.DbGroupScan) GroupScan(org.apache.drill.exec.physical.base.GroupScan) SchemaPath(org.apache.drill.common.expression.SchemaPath) DbGroupScan(org.apache.drill.exec.physical.base.DbGroupScan) DrillScanRelBase(org.apache.drill.exec.planner.common.DrillScanRelBase) RexBuilder(org.apache.calcite.rex.RexBuilder)

Example 85 with RexBuilder

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexBuilder in project drill by apache.

the class DrillReduceAggregatesRule method reduceAgg.

private RexNode reduceAgg(Aggregate oldAggRel, AggregateCall oldCall, List<AggregateCall> newCalls, Map<AggregateCall, RexNode> aggCallMapping, List<RexNode> inputExprs) {
    final SqlAggFunction sqlAggFunction = DrillCalciteWrapperUtility.extractSqlOperatorFromWrapper(oldCall.getAggregation());
    if (sqlAggFunction instanceof SqlSumAggFunction) {
        // case COUNT(x) when 0 then null else SUM0(x) end
        return reduceSum(oldAggRel, oldCall, newCalls, aggCallMapping);
    }
    if (sqlAggFunction instanceof SqlAvgAggFunction) {
        // causes the loss of the scale
        if (oldCall.getType().getSqlTypeName() == SqlTypeName.DECIMAL) {
            return oldAggRel.getCluster().getRexBuilder().addAggCall(oldCall, oldAggRel.getGroupCount(), newCalls, aggCallMapping, ImmutableList.of(getFieldType(oldAggRel.getInput(), oldCall.getArgList().get(0))));
        }
        final SqlKind subtype = sqlAggFunction.getKind();
        switch(subtype) {
            case AVG:
                // replace original AVG(x) with SUM(x) / COUNT(x)
                return reduceAvg(oldAggRel, oldCall, newCalls, aggCallMapping);
            case STDDEV_POP:
                // / COUNT(x))
                return reduceStddev(oldAggRel, oldCall, true, true, newCalls, aggCallMapping, inputExprs);
            case STDDEV_SAMP:
                // / CASE COUNT(x) WHEN 1 THEN NULL ELSE COUNT(x) - 1 END)
                return reduceStddev(oldAggRel, oldCall, false, true, newCalls, aggCallMapping, inputExprs);
            case VAR_POP:
                // / COUNT(x)
                return reduceStddev(oldAggRel, oldCall, true, false, newCalls, aggCallMapping, inputExprs);
            case VAR_SAMP:
                // / CASE COUNT(x) WHEN 1 THEN NULL ELSE COUNT(x) - 1 END
                return reduceStddev(oldAggRel, oldCall, false, false, newCalls, aggCallMapping, inputExprs);
            default:
                throw Util.unexpected(subtype);
        }
    } else {
        // anything else:  preserve original call
        RexBuilder rexBuilder = oldAggRel.getCluster().getRexBuilder();
        final int nGroups = oldAggRel.getGroupCount();
        List<RelDataType> oldArgTypes = new ArrayList<>();
        List<Integer> ordinals = oldCall.getArgList();
        assert ordinals.size() <= inputExprs.size();
        for (int ordinal : ordinals) {
            oldArgTypes.add(inputExprs.get(ordinal).getType());
        }
        // different RelDataTypes
        if (aggCallMapping.containsKey(oldCall) && !aggCallMapping.get(oldCall).getType().equals(oldCall.getType())) {
            int index = newCalls.size() + nGroups;
            newCalls.add(oldCall);
            return rexBuilder.makeInputRef(oldCall.getType(), index);
        }
        return rexBuilder.addAggCall(oldCall, nGroups, newCalls, aggCallMapping, oldArgTypes);
    }
}
Also used : SqlAvgAggFunction(org.apache.calcite.sql.fun.SqlAvgAggFunction) SqlSumAggFunction(org.apache.calcite.sql.fun.SqlSumAggFunction) ArrayList(java.util.ArrayList) RexBuilder(org.apache.calcite.rex.RexBuilder) RelDataType(org.apache.calcite.rel.type.RelDataType) SqlAggFunction(org.apache.calcite.sql.SqlAggFunction) SqlKind(org.apache.calcite.sql.SqlKind)

Aggregations

RexBuilder (org.apache.calcite.rex.RexBuilder)314 RexNode (org.apache.calcite.rex.RexNode)248 ArrayList (java.util.ArrayList)151 RelNode (org.apache.calcite.rel.RelNode)121 RelDataType (org.apache.calcite.rel.type.RelDataType)121 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)77 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)59 RexInputRef (org.apache.calcite.rex.RexInputRef)49 RelBuilder (org.apache.calcite.tools.RelBuilder)49 AggregateCall (org.apache.calcite.rel.core.AggregateCall)48 List (java.util.List)41 RelDataTypeFactory (org.apache.calcite.rel.type.RelDataTypeFactory)41 RelOptCluster (org.apache.calcite.plan.RelOptCluster)36 HashMap (java.util.HashMap)33 RelOptPredicateList (org.apache.calcite.plan.RelOptPredicateList)24 Project (org.apache.calcite.rel.core.Project)24 RexCall (org.apache.calcite.rex.RexCall)24 BigDecimal (java.math.BigDecimal)23 Collectors (java.util.stream.Collectors)23 RelMetadataQuery (org.apache.calcite.rel.metadata.RelMetadataQuery)22