use of org.apache.drill.exec.planner.physical.ScanPrel in project drill by apache.
the class MongoPushDownFilterForScan method onMatch.
@Override
public void onMatch(RelOptRuleCall call) {
final ScanPrel scan = (ScanPrel) call.rel(1);
final FilterPrel filter = (FilterPrel) call.rel(0);
final RexNode condition = filter.getCondition();
MongoGroupScan groupScan = (MongoGroupScan) scan.getGroupScan();
if (groupScan.isFilterPushedDown()) {
return;
}
LogicalExpression conditionExp = DrillOptiq.toDrill(new DrillParseContext(PrelUtil.getPlannerSettings(call.getPlanner())), scan, condition);
MongoFilterBuilder mongoFilterBuilder = new MongoFilterBuilder(groupScan, conditionExp);
MongoScanSpec newScanSpec = mongoFilterBuilder.parseTree();
if (newScanSpec == null) {
// no filter pushdown so nothing to apply.
return;
}
MongoGroupScan newGroupsScan = null;
try {
newGroupsScan = new MongoGroupScan(groupScan.getUserName(), groupScan.getStoragePlugin(), newScanSpec, groupScan.getColumns());
} catch (IOException e) {
logger.error(e.getMessage(), e);
throw new DrillRuntimeException(e.getMessage(), e);
}
newGroupsScan.setFilterPushedDown(true);
final ScanPrel newScanPrel = ScanPrel.create(scan, filter.getTraitSet(), newGroupsScan, scan.getRowType());
if (mongoFilterBuilder.isAllExpressionsConverted()) {
/*
* Since we could convert the entire filter condition expression into an
* Mongo filter, we can eliminate the filter operator altogether.
*/
call.transformTo(newScanPrel);
} else {
call.transformTo(filter.copy(filter.getTraitSet(), ImmutableList.of((RelNode) newScanPrel)));
}
}
use of org.apache.drill.exec.planner.physical.ScanPrel in project drill by apache.
the class ParquetPushDownFilter method getFilterOnProject.
public static RelOptRule getFilterOnProject(OptimizerRulesContext optimizerRulesContext) {
return new ParquetPushDownFilter(RelOptHelper.some(FilterPrel.class, RelOptHelper.some(ProjectPrel.class, RelOptHelper.any(ScanPrel.class))), "ParquetPushDownFilter:Filter_On_Project", optimizerRulesContext) {
@Override
public boolean matches(RelOptRuleCall call) {
final ScanPrel scan = call.rel(2);
if (scan.getGroupScan() instanceof ParquetGroupScan) {
return super.matches(call);
}
return false;
}
@Override
public void onMatch(RelOptRuleCall call) {
final FilterPrel filterRel = call.rel(0);
final ProjectPrel projectRel = call.rel(1);
final ScanPrel scanRel = call.rel(2);
doOnMatch(call, filterRel, projectRel, scanRel);
}
};
}
use of org.apache.drill.exec.planner.physical.ScanPrel in project drill by apache.
the class MapRDBPushFilterIntoScan method doPushFilterIntoBinaryGroupScan.
protected void doPushFilterIntoBinaryGroupScan(final RelOptRuleCall call, final FilterPrel filter, final ProjectPrel project, final ScanPrel scan, final BinaryTableGroupScan groupScan, final RexNode condition) {
if (groupScan.isFilterPushedDown()) {
/*
* The rule can get triggered again due to the transformed "scan => filter" sequence
* created by the earlier execution of this rule when we could not do a complete
* conversion of Optiq Filter's condition to HBase Filter. In such cases, we rely upon
* this flag to not do a re-processing of the rule on the already transformed call.
*/
return;
}
final LogicalExpression conditionExp = DrillOptiq.toDrill(new DrillParseContext(PrelUtil.getPlannerSettings(call.getPlanner())), scan, condition);
final MapRDBFilterBuilder maprdbFilterBuilder = new MapRDBFilterBuilder(groupScan, conditionExp);
final HBaseScanSpec newScanSpec = maprdbFilterBuilder.parseTree();
if (newScanSpec == null) {
//no filter pushdown ==> No transformation.
return;
}
// Pass tableStats from old groupScan so we do not go and fetch stats (an expensive operation) again from MapR DB client.
final BinaryTableGroupScan newGroupsScan = new BinaryTableGroupScan(groupScan.getUserName(), groupScan.getStoragePlugin(), groupScan.getFormatPlugin(), newScanSpec, groupScan.getColumns(), groupScan.getTableStats());
newGroupsScan.setFilterPushedDown(true);
final ScanPrel newScanPrel = ScanPrel.create(scan, filter.getTraitSet(), newGroupsScan, scan.getRowType());
// Depending on whether is a project in the middle, assign either scan or copy of project to childRel.
final RelNode childRel = project == null ? newScanPrel : project.copy(project.getTraitSet(), ImmutableList.of((RelNode) newScanPrel));
;
if (maprdbFilterBuilder.isAllExpressionsConverted()) {
/*
* Since we could convert the entire filter condition expression into an HBase filter,
* we can eliminate the filter operator altogether.
*/
call.transformTo(childRel);
} else {
call.transformTo(filter.copy(filter.getTraitSet(), ImmutableList.of(childRel)));
}
}
use of org.apache.drill.exec.planner.physical.ScanPrel in project drill by apache.
the class MapRDBPushFilterIntoScan method doPushFilterIntoJsonGroupScan.
protected void doPushFilterIntoJsonGroupScan(RelOptRuleCall call, FilterPrel filter, final ProjectPrel project, ScanPrel scan, JsonTableGroupScan groupScan, RexNode condition) {
if (// Do not pushdown filter if it is disabled in plugin configuration
groupScan.isDisablePushdown() || groupScan.isFilterPushedDown()) {
/*
* The rule can get triggered again due to the transformed "scan => filter" sequence
* created by the earlier execution of this rule when we could not do a complete
* conversion of Optiq Filter's condition to HBase Filter. In such cases, we rely upon
* this flag to not do a re-processing of the rule on the already transformed call.
*/
return;
}
LogicalExpression conditionExp = null;
try {
conditionExp = DrillOptiq.toDrill(new DrillParseContext(PrelUtil.getPlannerSettings(call.getPlanner())), scan, condition);
} catch (ClassCastException e) {
// For such cases, we return without pushdown
return;
}
final JsonConditionBuilder jsonConditionBuilder = new JsonConditionBuilder(groupScan, conditionExp);
final JsonScanSpec newScanSpec = jsonConditionBuilder.parseTree();
if (newScanSpec == null) {
//no filter pushdown ==> No transformation.
return;
}
// clone the groupScan with the newScanSpec.
final JsonTableGroupScan newGroupsScan = groupScan.clone(newScanSpec);
newGroupsScan.setFilterPushedDown(true);
final ScanPrel newScanPrel = ScanPrel.create(scan, filter.getTraitSet(), newGroupsScan, scan.getRowType());
// Depending on whether is a project in the middle, assign either scan or copy of project to childRel.
final RelNode childRel = project == null ? newScanPrel : project.copy(project.getTraitSet(), ImmutableList.of((RelNode) newScanPrel));
;
if (jsonConditionBuilder.isAllExpressionsConverted()) {
/*
* Since we could convert the entire filter condition expression into an HBase filter,
* we can eliminate the filter operator altogether.
*/
call.transformTo(childRel);
} else {
call.transformTo(filter.copy(filter.getTraitSet(), ImmutableList.of(childRel)));
}
}
use of org.apache.drill.exec.planner.physical.ScanPrel in project drill by apache.
the class ParquetPushDownFilter method doOnMatch.
protected void doOnMatch(RelOptRuleCall call, FilterPrel filter, ProjectPrel project, ScanPrel scan) {
ParquetGroupScan groupScan = (ParquetGroupScan) scan.getGroupScan();
if (groupScan.getFilter() != null && !groupScan.getFilter().equals(ValueExpressions.BooleanExpression.TRUE)) {
return;
}
RexNode condition = null;
if (project == null) {
condition = filter.getCondition();
} else {
// get the filter as if it were below the projection.
condition = RelOptUtil.pushFilterPastProject(filter.getCondition(), project);
}
if (condition == null || condition.equals(ValueExpressions.BooleanExpression.TRUE)) {
return;
}
// get a conjunctions of the filter condition. For each conjunction, if it refers to ITEM or FLATTEN expression
// then we could not pushed down. Otherwise, it's qualified to be pushed down.
final List<RexNode> predList = RelOptUtil.conjunctions(condition);
final List<RexNode> qualifiedPredList = Lists.newArrayList();
for (final RexNode pred : predList) {
if (DrillRelOptUtil.findItemOrFlatten(pred, ImmutableList.<RexNode>of()) == null) {
qualifiedPredList.add(pred);
}
}
final RexNode qualifedPred = RexUtil.composeConjunction(filter.getCluster().getRexBuilder(), qualifiedPredList, true);
if (qualifedPred == null) {
return;
}
LogicalExpression conditionExp = DrillOptiq.toDrill(new DrillParseContext(PrelUtil.getPlannerSettings(call.getPlanner())), scan, qualifedPred);
Stopwatch timer = Stopwatch.createStarted();
final GroupScan newGroupScan = groupScan.applyFilter(conditionExp, optimizerContext, optimizerContext.getFunctionRegistry(), optimizerContext.getPlannerSettings().getOptions());
logger.info("Took {} ms to apply filter on parquet row groups. ", timer.elapsed(TimeUnit.MILLISECONDS));
if (newGroupScan == null) {
return;
}
final ScanPrel newScanRel = ScanPrel.create(scan, scan.getTraitSet(), newGroupScan, scan.getRowType());
RelNode inputRel = newScanRel;
if (project != null) {
inputRel = project.copy(project.getTraitSet(), ImmutableList.of(inputRel));
}
final RelNode newFilter = filter.copy(filter.getTraitSet(), ImmutableList.<RelNode>of(inputRel));
call.transformTo(newFilter);
}
Aggregations