use of org.apache.drill.exec.planner.logical.DrillLimitRel in project drill by axbaretto.
the class LimitPrule method onMatch.
@Override
public void onMatch(RelOptRuleCall call) {
final DrillLimitRel limit = (DrillLimitRel) call.rel(0);
final RelNode input = limit.getInput();
final RelTraitSet traits = input.getTraitSet().plus(Prel.DRILL_PHYSICAL).plus(DrillDistributionTrait.SINGLETON);
final RelNode convertedInput = convert(input, traits);
LimitPrel newLimit = new LimitPrel(limit.getCluster(), limit.getTraitSet().plus(Prel.DRILL_PHYSICAL).plus(DrillDistributionTrait.SINGLETON), convertedInput, limit.getOffset(), limit.getFetch());
call.transformTo(newLimit);
}
use of org.apache.drill.exec.planner.logical.DrillLimitRel in project drill by apache.
the class JoinUtils method isScalarSubquery.
/**
* Utility method to check if a subquery (represented by its root RelNode) is provably scalar. Currently
* only aggregates with no group-by are considered scalar. In the future, this method should be generalized
* to include more cases and reconciled with Calcite's notion of scalar.
* @param root The root RelNode to be examined
* @return True if the root rel or its descendant is scalar, False otherwise
*/
public static boolean isScalarSubquery(RelNode root) {
DrillAggregateRel agg = null;
RelNode currentrel = root;
while (agg == null && currentrel != null) {
if (currentrel instanceof DrillAggregateRel) {
agg = (DrillAggregateRel) currentrel;
} else if (currentrel instanceof RelSubset) {
currentrel = ((RelSubset) currentrel).getBest();
} else if (currentrel instanceof DrillLimitRel) {
// TODO: Improve this check when DRILL-5691 is fixed.
// The problem is that RelMdMaxRowCount currently cannot be used
// due to CALCITE-1048.
Integer fetchValue = ((RexLiteral) ((DrillLimitRel) currentrel).getFetch()).getValueAs(Integer.class);
return fetchValue != null && fetchValue <= 1;
} else if (currentrel.getInputs().size() == 1) {
// If the rel is not an aggregate or RelSubset, but is a single-input rel (could be Project,
// Filter, Sort etc.), check its input
currentrel = currentrel.getInput(0);
} else {
break;
}
}
if (agg != null) {
if (agg.getGroupSet().isEmpty()) {
return true;
}
// with empty call list and literal from project expression in group set.
if (agg.getAggCallList().isEmpty() && agg.getGroupSet().cardinality() == 1) {
ProjectExpressionsCollector expressionsCollector = new ProjectExpressionsCollector();
agg.accept(expressionsCollector);
List<RexNode> projectedExpressions = expressionsCollector.getProjectedExpressions();
return projectedExpressions.size() == 1 && RexUtil.isLiteral(projectedExpressions.get(agg.getGroupSet().nth(0)), true);
}
}
return false;
}
use of org.apache.drill.exec.planner.logical.DrillLimitRel in project drill by apache.
the class LimitPrule method onMatch.
@Override
public void onMatch(RelOptRuleCall call) {
final DrillLimitRel limit = (DrillLimitRel) call.rel(0);
final RelNode input = limit.getInput();
final RelTraitSet traits = input.getTraitSet().plus(Prel.DRILL_PHYSICAL).plus(DrillDistributionTrait.SINGLETON);
final RelNode convertedInput = convert(input, traits);
LimitPrel newLimit = new LimitPrel(limit.getCluster(), limit.getTraitSet().plus(Prel.DRILL_PHYSICAL).plus(DrillDistributionTrait.SINGLETON), convertedInput, limit.getOffset(), limit.getFetch());
call.transformTo(newLimit);
}
use of org.apache.drill.exec.planner.logical.DrillLimitRel in project drill by apache.
the class FindLimit0Visitor method addLimitOnTopOfLeafNodes.
public static DrillRel addLimitOnTopOfLeafNodes(final DrillRel rel) {
final Pointer<Boolean> isUnsupported = new Pointer<>(false);
// to visit unsupported functions
final RexShuttle unsupportedFunctionsVisitor = new RexShuttle() {
@Override
public RexNode visitCall(RexCall call) {
final SqlOperator operator = call.getOperator();
if (isUnsupportedScalarFunction(operator)) {
isUnsupported.value = true;
return call;
}
return super.visitCall(call);
}
};
// to visit unsupported operators
final RelShuttle unsupportedOperationsVisitor = new RelShuttleImpl() {
@Override
public RelNode visit(RelNode other) {
if (other instanceof DrillUnionRelBase) {
isUnsupported.value = true;
return other;
} else if (other instanceof DrillProjectRelBase) {
if (!isUnsupported.value) {
other.accept(unsupportedFunctionsVisitor);
}
if (isUnsupported.value) {
return other;
}
}
return super.visit(other);
}
};
rel.accept(unsupportedOperationsVisitor);
if (isUnsupported.value) {
return rel;
}
// to add LIMIT (0) on top of leaf nodes
final RelShuttle addLimitOnScanVisitor = new RelShuttleImpl() {
private RelNode addLimitAsParent(RelNode node) {
final RexBuilder builder = node.getCluster().getRexBuilder();
final RexLiteral offset = builder.makeExactLiteral(BigDecimal.ZERO);
final RexLiteral fetch = builder.makeExactLiteral(BigDecimal.ZERO);
return new DrillLimitRel(node.getCluster(), node.getTraitSet(), node, offset, fetch);
}
@Override
public RelNode visit(LogicalValues values) {
return addLimitAsParent(values);
}
@Override
public RelNode visit(TableScan scan) {
return addLimitAsParent(scan);
}
@Override
public RelNode visit(RelNode other) {
if (other.getInputs().isEmpty()) {
// leaf operator
return addLimitAsParent(other);
}
return super.visit(other);
}
};
return (DrillRel) rel.accept(addLimitOnScanVisitor);
}
Aggregations