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());
}
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);
}
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;
}
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);
}
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);
}
}
Aggregations