use of org.apache.calcite.plan.hep.HepRelVertex in project hive by apache.
the class HiveSemiJoinRule method onMatch.
@Override
public void onMatch(RelOptRuleCall call) {
LOG.debug("Matched HiveSemiJoinRule");
final Project project = call.rel(0);
final Join join = call.rel(1);
final RelNode left = call.rel(2);
final Aggregate aggregate = call.rel(3);
final RelOptCluster cluster = join.getCluster();
final RexBuilder rexBuilder = cluster.getRexBuilder();
final ImmutableBitSet bits = RelOptUtil.InputFinder.bits(project.getProjects(), null);
final ImmutableBitSet rightBits = ImmutableBitSet.range(left.getRowType().getFieldCount(), join.getRowType().getFieldCount());
if (bits.intersects(rightBits)) {
return;
}
final JoinInfo joinInfo = join.analyzeCondition();
if (!joinInfo.rightSet().equals(ImmutableBitSet.range(aggregate.getGroupCount()))) {
// By the way, neither a super-set nor a sub-set would work.
return;
}
if (join.getJoinType() == JoinRelType.LEFT) {
// since for LEFT join we are only interested in rows from LEFT we can get rid of right side
call.transformTo(call.builder().push(left).project(project.getProjects(), project.getRowType().getFieldNames()).build());
return;
}
if (join.getJoinType() != JoinRelType.INNER) {
return;
}
if (!joinInfo.isEqui()) {
return;
}
LOG.debug("All conditions matched for HiveSemiJoinRule. Going to apply transformation.");
final List<Integer> newRightKeyBuilder = Lists.newArrayList();
final List<Integer> aggregateKeys = aggregate.getGroupSet().asList();
for (int key : joinInfo.rightKeys) {
newRightKeyBuilder.add(aggregateKeys.get(key));
}
final ImmutableIntList newRightKeys = ImmutableIntList.copyOf(newRightKeyBuilder);
final RelNode newRight = aggregate.getInput();
final RexNode newCondition = RelOptUtil.createEquiJoinCondition(left, joinInfo.leftKeys, newRight, newRightKeys, rexBuilder);
RelNode semi = null;
// is not expected further down the pipeline. see jira for more details
if (aggregate.getInput() instanceof HepRelVertex && ((HepRelVertex) aggregate.getInput()).getCurrentRel() instanceof Join) {
Join rightJoin = (Join) (((HepRelVertex) aggregate.getInput()).getCurrentRel());
List<RexNode> projects = new ArrayList<>();
for (int i = 0; i < rightJoin.getRowType().getFieldCount(); i++) {
projects.add(rexBuilder.makeInputRef(rightJoin, i));
}
RelNode topProject = call.builder().push(rightJoin).project(projects, rightJoin.getRowType().getFieldNames(), true).build();
semi = call.builder().push(left).push(topProject).semiJoin(newCondition).build();
} else {
semi = call.builder().push(left).push(aggregate.getInput()).semiJoin(newCondition).build();
}
call.transformTo(call.builder().push(semi).project(project.getProjects(), project.getRowType().getFieldNames()).build());
}
use of org.apache.calcite.plan.hep.HepRelVertex in project hive by apache.
the class HiveSortLimitPullUpConstantsRule method onMatch.
@Override
public void onMatch(RelOptRuleCall call) {
final RelNode parent = call.rel(0);
final Sort sort = call.rel(1);
final int count = sort.getInput().getRowType().getFieldCount();
if (count == 1) {
// Project operator.
return;
}
final RexBuilder rexBuilder = sort.getCluster().getRexBuilder();
final RelMetadataQuery mq = call.getMetadataQuery();
final RelOptPredicateList predicates = mq.getPulledUpPredicates(sort.getInput());
if (predicates == null) {
return;
}
Map<RexNode, RexNode> conditionsExtracted = HiveReduceExpressionsRule.predicateConstants(RexNode.class, rexBuilder, predicates);
Map<RexNode, RexNode> constants = new HashMap<>();
for (int i = 0; i < count; i++) {
RexNode expr = rexBuilder.makeInputRef(sort.getInput(), i);
if (conditionsExtracted.containsKey(expr)) {
constants.put(expr, conditionsExtracted.get(expr));
}
}
// None of the expressions are constant. Nothing to do.
if (constants.isEmpty()) {
return;
}
if (count == constants.size()) {
// At least a single item in project is required.
constants.remove(constants.keySet().iterator().next());
}
// Create expressions for Project operators before and after the Sort
List<RelDataTypeField> fields = sort.getInput().getRowType().getFieldList();
List<Pair<RexNode, String>> newChildExprs = new ArrayList<>();
List<RexNode> topChildExprs = new ArrayList<>();
List<String> topChildExprsFields = new ArrayList<>();
for (int i = 0; i < count; i++) {
RexNode expr = rexBuilder.makeInputRef(sort.getInput(), i);
RelDataTypeField field = fields.get(i);
if (constants.containsKey(expr)) {
topChildExprs.add(constants.get(expr));
topChildExprsFields.add(field.getName());
} else {
newChildExprs.add(Pair.<RexNode, String>of(expr, field.getName()));
topChildExprs.add(expr);
topChildExprsFields.add(field.getName());
}
}
// Update field collations
final Mappings.TargetMapping mapping = RelOptUtil.permutation(Pair.left(newChildExprs), sort.getInput().getRowType()).inverse();
List<RelFieldCollation> fieldCollations = new ArrayList<>();
for (RelFieldCollation fc : sort.getCollation().getFieldCollations()) {
final int target = mapping.getTargetOpt(fc.getFieldIndex());
if (target < 0) {
// It is a constant, we can ignore it
continue;
}
fieldCollations.add(fc.copy(target));
}
// Update top Project positions
topChildExprs = ImmutableList.copyOf(RexUtil.apply(mapping, topChildExprs));
// Create new Project-Sort-Project sequence
final RelBuilder relBuilder = call.builder();
relBuilder.push(sort.getInput());
relBuilder.project(Pair.left(newChildExprs), Pair.right(newChildExprs));
final ImmutableList<RexNode> sortFields = relBuilder.fields(RelCollations.of(fieldCollations));
relBuilder.sortLimit(sort.offset == null ? -1 : RexLiteral.intValue(sort.offset), sort.fetch == null ? -1 : RexLiteral.intValue(sort.fetch), sortFields);
// Create top Project fixing nullability of fields
relBuilder.project(topChildExprs, topChildExprsFields);
relBuilder.convert(sort.getRowType(), false);
List<RelNode> inputs = new ArrayList<>();
for (RelNode child : parent.getInputs()) {
if (!((HepRelVertex) child).getCurrentRel().equals(sort)) {
inputs.add(child);
} else {
inputs.add(relBuilder.build());
}
}
call.transformTo(parent.copy(parent.getTraitSet(), inputs));
}
use of org.apache.calcite.plan.hep.HepRelVertex in project calcite by apache.
the class RelDecorrelator method stripHep.
private static RelNode stripHep(RelNode rel) {
if (rel instanceof HepRelVertex) {
HepRelVertex hepRelVertex = (HepRelVertex) rel;
rel = hepRelVertex.getCurrentRel();
}
return rel;
}
use of org.apache.calcite.plan.hep.HepRelVertex in project drill by apache.
the class DrillPushRowKeyJoinToScanRule method isRowKeyColumn.
/* Finds whether the given column reference is for the rowkey col(also known as primary-key col).
* We need to recurse down the operators looking at their references down to the scan
* to figure out whether the reference is a rowkey col. Projections can rearrange the
* incoming columns. We also need to handle HepRelVertex/RelSubset while handling the rels.
*/
private static boolean isRowKeyColumn(int index, RelNode rel) {
RelNode curRel = rel;
int curIndex = index;
while (curRel != null && !(curRel instanceof DrillScanRel)) {
logger.debug("IsRowKeyColumn: Rel={}, RowTypePos={}, RowType={}", curRel.toString(), curIndex, curRel.getRowType().toString());
if (curRel instanceof HepRelVertex) {
curRel = ((HepRelVertex) curRel).getCurrentRel();
} else if (curRel instanceof RelSubset) {
if (((RelSubset) curRel).getBest() != null) {
curRel = ((RelSubset) curRel).getBest();
} else {
curRel = ((RelSubset) curRel).getOriginal();
}
} else {
RelNode child = null;
// before recursing down that child rel.
for (RelNode input : curRel.getInputs()) {
if (input.getRowType().getFieldList().size() <= curIndex) {
curIndex -= input.getRowType().getFieldList().size();
} else {
child = input;
break;
}
}
curRel = child;
}
// Otherwise, the column index is the `RexInputRef` index.
if (curRel != null && curRel instanceof DrillProjectRel) {
List<RexNode> childExprs = curRel.getChildExps();
if (childExprs != null && childExprs.size() > 0) {
if (childExprs.get(curIndex) instanceof RexInputRef) {
curIndex = ((RexInputRef) childExprs.get(curIndex)).getIndex();
} else {
// Currently do not support expressions on rowkey col. So if an expr is present,
// return false
logger.debug("IsRowKeyColumn: ABORT: Primary-key EXPR$={}", childExprs.get(curIndex).toString());
return false;
}
}
}
}
logger.debug("IsRowKeyColumn:Primary-key Col={} ", curRel != null ? curRel.getRowType().getFieldNames().get(curIndex) : "??");
// Get the primary-key col name from the scan and match with the column being referenced.
if (curRel != null && curRel instanceof DrillScanRel) {
if (((DrillScanRel) curRel).getGroupScan() instanceof DbGroupScan) {
DbGroupScan dbGroupScan = (DbGroupScan) ((DrillScanRel) curRel).getGroupScan();
String rowKeyName = dbGroupScan.getRowKeyName();
DbGroupScan restrictedGroupScan = dbGroupScan.getRestrictedScan(((DrillScanRel) curRel).getColumns());
// Also verify this scan supports restricted groupscans(random seeks)
if (restrictedGroupScan != null && curRel.getRowType().getFieldNames().get(curIndex).equalsIgnoreCase(rowKeyName)) {
logger.debug("IsRowKeyColumn: FOUND: Rel={}, RowTypePos={}, RowType={}", curRel.toString(), curIndex, curRel.getRowType().toString());
return true;
}
}
}
logger.debug("IsRowKeyColumn: NOT FOUND");
return false;
}
use of org.apache.calcite.plan.hep.HepRelVertex in project flink by apache.
the class PythonCorrelateSplitRule method matches.
@Override
public boolean matches(RelOptRuleCall call) {
FlinkLogicalCorrelate correlate = call.rel(0);
RelNode right = ((HepRelVertex) correlate.getRight()).getCurrentRel();
FlinkLogicalTableFunctionScan tableFunctionScan;
if (right instanceof FlinkLogicalTableFunctionScan) {
tableFunctionScan = (FlinkLogicalTableFunctionScan) right;
} else if (right instanceof FlinkLogicalCalc) {
tableFunctionScan = StreamPhysicalCorrelateRule.getTableScan((FlinkLogicalCalc) right);
} else {
return false;
}
RexNode rexNode = tableFunctionScan.getCall();
if (rexNode instanceof RexCall) {
return PythonUtil.isPythonCall(rexNode, null) && PythonUtil.containsNonPythonCall(rexNode) || PythonUtil.isNonPythonCall(rexNode) && PythonUtil.containsPythonCall(rexNode, null) || (PythonUtil.isPythonCall(rexNode, null) && RexUtil.containsFieldAccess(rexNode));
}
return false;
}
Aggregations