@Override public boolean matches(RelOptRuleCall call) { final Filter filterRel = call.rel(0); // The condition fetched here can reference a udf that is not deterministic, but defined // as part of the select list when a view is in play. But the condition after the pushdown // will resolve to using the udf from select list. The check here for deterministic filters // should be based on the resolved expression. Refer to test case cbo_ppd_non_deterministic.q. RexNode condition = RelOptUtil.pushPastProject(filterRel.getCondition(), call.rel(1)); if (this.onlyDeterministic && !HiveCalciteUtil.isDeterministic(condition)) { return false; } return super.matches(call); }
@Override public void onMatch(RelOptRuleCall call) { final ScanPrel scan = (ScanPrel) call.rel(2); final ProjectPrel project = (ProjectPrel) call.rel(1); final FilterPrel filter = (FilterPrel) call.rel(0); HBaseGroupScan groupScan = (HBaseGroupScan)scan.getGroupScan(); 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; } // convert the filter to one that references the child of the project final RexNode condition = RelOptUtil.pushPastProject(filter.getCondition(), project); doPushFilterToScan(call, filter, project, scan, groupScan, condition); }
RexNode newCondition = RelOptUtil.pushPastProject(ce, origproject); if (HiveCalciteUtil.isDeterministicFuncWithSingleInputRef(newCondition, commonPartitionKeys)) {
theProject = newSelectProject; } else { final List<RexNode> newProjectRexNodes = RelOptUtil.pushPastProject( newSelectProject.getProjects(), selectProject
RexNode newCondition = RelOptUtil.pushPastProject(ce, origproject); if (HiveCalciteUtil.isDeterministicFuncWithSingleInputRef(newCondition, commonPartitionKeys)) {
private static RelNode getNewProject(RexNode filterCondToPushBelowProj, RexNode unPushedFilCondAboveProj, Project oldProj, RelDataTypeFactory typeFactory, RelBuilder relBuilder) { // convert the filter to one that references the child of the project RexNode newPushedCondition = RelOptUtil.pushPastProject(filterCondToPushBelowProj, oldProj); // Remove cast of BOOLEAN NOT NULL to BOOLEAN or vice versa. Filter accepts // nullable and not-nullable conditions, but a CAST might get in the way of // other rewrites. if (RexUtil.isNullabilityCast(typeFactory, newPushedCondition)) { newPushedCondition = ((RexCall) newPushedCondition).getOperands().get(0); } RelNode newPushedFilterRel = relBuilder.push(oldProj.getInput()).filter(newPushedCondition).build(); RelNode newProjRel = relBuilder.push(newPushedFilterRel) .project(oldProj.getProjects(), oldProj.getRowType().getFieldNames()).build(); if (unPushedFilCondAboveProj != null) { // Remove cast of BOOLEAN NOT NULL to BOOLEAN or vice versa. Filter accepts // nullable and not-nullable conditions, but a CAST might get in the way of // other rewrites. if (RexUtil.isNullabilityCast(typeFactory, newPushedCondition)) { unPushedFilCondAboveProj = ((RexCall) unPushedFilCondAboveProj).getOperands().get(0); } newProjRel = relBuilder.push(newProjRel).filter(unPushedFilCondAboveProj).build(); } return newProjRel; }
@Override public void onMatch(RelOptRuleCall call) { final FilterPrel filter = call.rel(0); final ProjectPrel project = call.rel(1); final ScanPrel scan = call.rel(2); // convert the filter to one that references the child of the project final RexNode condition = RelOptUtil.pushPastProject(filter.getCondition(), project); if (scan.getGroupScan() instanceof BinaryTableGroupScan) { BinaryTableGroupScan groupScan = (BinaryTableGroupScan)scan.getGroupScan(); doPushFilterIntoBinaryGroupScan(call, filter, project, scan, groupScan, condition); } else { assert(scan.getGroupScan() instanceof JsonTableGroupScan); JsonTableGroupScan groupScan = (JsonTableGroupScan)scan.getGroupScan(); doPushFilterIntoJsonGroupScan(call, filter, project, scan, groupScan, condition); } }
private static RelNode getNewProject(RexNode filterCondToPushBelowProj, RexNode unPushedFilCondAboveProj, Project oldProj, RelDataTypeFactory typeFactory, RelBuilder relBuilder) { // convert the filter to one that references the child of the project RexNode newPushedCondition = RelOptUtil.pushPastProject(filterCondToPushBelowProj, oldProj); // Remove cast of BOOLEAN NOT NULL to BOOLEAN or vice versa. Filter accepts // nullable and not-nullable conditions, but a CAST might get in the way of // other rewrites. if (RexUtil.isNullabilityCast(typeFactory, newPushedCondition)) { newPushedCondition = ((RexCall) newPushedCondition).getOperands().get(0); } RelNode newPushedFilterRel = relBuilder.push(oldProj.getInput()).filter(newPushedCondition).build(); RelNode newProjRel = relBuilder.push(newPushedFilterRel) .project(oldProj.getProjects(), oldProj.getRowType().getFieldNames()).build(); if (unPushedFilCondAboveProj != null) { // Remove cast of BOOLEAN NOT NULL to BOOLEAN or vice versa. Filter accepts // nullable and not-nullable conditions, but a CAST might get in the way of // other rewrites. if (RexUtil.isNullabilityCast(typeFactory, newPushedCondition)) { unPushedFilCondAboveProj = ((RexCall) unPushedFilCondAboveProj).getOperands().get(0); } newProjRel = relBuilder.push(newProjRel).filter(unPushedFilCondAboveProj).build(); } return newProjRel; }
RexNode newCondition = RelOptUtil.pushPastProject(filter.getCondition(), project);
RexNode newCondition = RelOptUtil.pushPastProject(filter.getCondition(), project);
@Override public void processProject(ElasticsearchProject project) { projectExprs = RelOptUtil.pushPastProject(projectExprs, project); // projectDataType should not be set here, since we want to keep the top project's row type. }
@Deprecated // to be removed before 2.0 public static RexNode pushFilterPastProject(RexNode filter, final Project projRel) { return pushPastProject(filter, projRel); }
@Deprecated // to be removed before 2.0 public static RexNode pushFilterPastProject(RexNode filter, final Project projRel) { return pushPastProject(filter, projRel); }
@Override public void processProject(ElasticsearchProject project) { filterExprs = pushPastProject(filterExprs, project); if (projectExprs == null) { projectExprs = project.getProjects(); projectDataType = project.getRowType(); } else { projectExprs = RelOptUtil.pushPastProject(projectExprs, project); // projectDataType should not be set here, since we want to keep the top project's row type. } }
@Override public void onMatch(RelOptRuleCall call) { ProjectForFlattenRel projectForFlattenRel = call.rel(0); ProjectRel project = call.rel(1); List<RexNode> newItemsExprs = RelOptUtil.pushPastProject(projectForFlattenRel.getItemExprs(), project); List<RexNode> newProjExprs = RelOptUtil.pushPastProject(projectForFlattenRel.getProjExprs(), project); ProjectForFlattenRel newProjectForFlattenRel = new ProjectForFlattenRel( projectForFlattenRel.getCluster(), projectForFlattenRel.getTraitSet(), project.getInput(), projectForFlattenRel.getRowType(), newProjExprs, newItemsExprs); call.transformTo(newProjectForFlattenRel); } }
@Override public void onMatch(RelOptRuleCall call) { ProjectForFlattenRel top = call.rel(0); ProjectForFlattenRel bottom = call.rel(1); ProjectRel temporary = new ProjectRel(bottom.getCluster(), bottom.getTraitSet(), bottom.getInput(), bottom.getProjExprs(), bottom.getRowType()); List<RexNode> newProjExprs = RelOptUtil.pushPastProject(top.getProjExprs(), temporary); List<RexNode> newItemExprs = new ArrayList<>(top.getItemExprs().size() + bottom.getItemExprs().size()); newItemExprs.addAll(RelOptUtil.pushPastProject(top.getItemExprs(), temporary)); newItemExprs.addAll(bottom.getItemExprs()); ProjectForFlattenRel newProjectForFlatten = new ProjectForFlattenRel( top.getCluster(), top.getTraitSet(), bottom.getInput(), top.getRowType(), newProjExprs, newItemExprs); call.transformTo(newProjectForFlatten); } }
@Override public void onMatch(RelOptRuleCall call) { final FilterPrel filter = call.rel(0); final ProjectPrel project = call.rel(1); final HBaseScanPrel scan = call.rel(2); /* * 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 Calcite 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. */ if(scan.isFilterPushed()) { return; } // convert the filter to one that references the child of the project final RexNode condition = RelOptUtil.pushPastProject(filter.getCondition(), project); doPushFilterToScan(call, filter, project, scan, condition); }
@Override public void onMatch(RelOptRuleCall call) { final ScanPrel scan = (ScanPrel) call.rel(2); final ProjectPrel project = (ProjectPrel) call.rel(1); final FilterPrel filter = (FilterPrel) call.rel(0); HBaseGroupScan groupScan = (HBaseGroupScan)scan.getGroupScan(); 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; } // convert the filter to one that references the child of the project final RexNode condition = RelOptUtil.pushPastProject(filter.getCondition(), project); doPushFilterToScan(call, filter, project, scan, groupScan, condition); }
@Override public void onMatch(RelOptRuleCall call) { final FilterPrel filter = call.rel(0); final ProjectPrel project = call.rel(1); final ScanPrel scan = call.rel(2); // convert the filter to one that references the child of the project final RexNode condition = RelOptUtil.pushPastProject(filter.getCondition(), project); if (scan.getGroupScan() instanceof BinaryTableGroupScan) { BinaryTableGroupScan groupScan = (BinaryTableGroupScan)scan.getGroupScan(); doPushFilterIntoBinaryGroupScan(call, filter, project, scan, groupScan, condition); } else { assert(scan.getGroupScan() instanceof JsonTableGroupScan); JsonTableGroupScan groupScan = (JsonTableGroupScan)scan.getGroupScan(); doPushFilterIntoJsonGroupScan(call, filter, project, scan, groupScan, condition); } }
/** * The purpose of the replace() method is to allow the caller to replace a 'top' and 'bottom' project with * a single merged project with the assumption that caller knows exactly the semantics/correctness of merging * the two projects. This is not applying the full fledged DrillMergeProjectRule. * @param topProject * @param bottomProject * @return new project after replacement */ public static Project replace(Project topProject, Project bottomProject) { final List<RexNode> newProjects = RelOptUtil.pushPastProject(topProject.getProjects(), bottomProject); // replace the two projects with a combined projection if (topProject instanceof DrillProjectRel) { RelNode newProjectRel = DrillRelFactories.DRILL_LOGICAL_PROJECT_FACTORY.createProject( bottomProject.getInput(), newProjects, topProject.getRowType().getFieldNames()); return (Project) newProjectRel; } else { RelNode newProjectRel = PrelFactories.PROJECT_FACTORY.createProject( bottomProject.getInput(), newProjects, topProject.getRowType().getFieldNames()); return (Project) newProjectRel; } }