use of org.apache.calcite.plan.volcano.RelSubset in project beam by apache.
the class BeamAggregateProjectMergeRule method getUnderlyingIO.
/**
* Following scenarios are possible:<br>
* 1) Aggregate <- Project <- IO.<br>
* 2) Aggregate <- Project <- Chain of Project/Filter <- IO.<br>
* 3) Aggregate <- Project <- Something else.<br>
* 4) Aggregate <- Project <- Chain of Project/Filter <- Something else.
*
* @param parent project that matched this rule.
* @return {@code BeamIOSourceRel} when it is present or null when some other {@code RelNode} is
* present.
*/
private BeamIOSourceRel getUnderlyingIO(Set<RelNode> visitedNodes, SingleRel parent) {
// No need to look at the same node more than once.
if (visitedNodes.contains(parent)) {
return null;
}
visitedNodes.add(parent);
List<RelNode> nodes = ((RelSubset) parent.getInput()).getRelList();
for (RelNode node : nodes) {
if (node instanceof Filter || node instanceof Project) {
// Search node inputs for an IO.
BeamIOSourceRel child = getUnderlyingIO(visitedNodes, (SingleRel) node);
if (child != null) {
return child;
}
} else if (node instanceof BeamIOSourceRel) {
return (BeamIOSourceRel) node;
}
}
return null;
}
use of org.apache.calcite.plan.volcano.RelSubset in project beam by apache.
the class BeamUnnestRule method onMatch.
@Override
public void onMatch(RelOptRuleCall call) {
LogicalCorrelate correlate = call.rel(0);
RelNode outer = call.rel(1);
RelNode uncollect = call.rel(2);
if (correlate.getCorrelationId().getId() != 0) {
// Only one level of correlation nesting is supported
return;
}
if (correlate.getRequiredColumns().cardinality() != 1) {
// can only unnest a single column
return;
}
if (correlate.getJoinType() != JoinRelType.INNER) {
return;
}
if (!(uncollect instanceof Uncollect)) {
// Drop projection
uncollect = ((SingleRel) uncollect).getInput();
if (uncollect instanceof RelSubset) {
uncollect = ((RelSubset) uncollect).getOriginal();
}
if (!(uncollect instanceof Uncollect)) {
return;
}
}
RelNode project = ((Uncollect) uncollect).getInput();
if (project instanceof RelSubset) {
project = ((RelSubset) project).getOriginal();
}
if (!(project instanceof LogicalProject)) {
return;
}
if (((LogicalProject) project).getProjects().size() != 1) {
// can only unnest a single column
return;
}
RexNode exp = ((LogicalProject) project).getProjects().get(0);
if (!(exp instanceof RexFieldAccess)) {
return;
}
RexFieldAccess fieldAccess = (RexFieldAccess) exp;
// Innermost field index comes first (e.g. struct.field1.field2 => [2, 1])
ImmutableList.Builder<Integer> fieldAccessIndices = ImmutableList.builder();
while (true) {
fieldAccessIndices.add(fieldAccess.getField().getIndex());
if (!(fieldAccess.getReferenceExpr() instanceof RexFieldAccess)) {
break;
}
fieldAccess = (RexFieldAccess) fieldAccess.getReferenceExpr();
}
call.transformTo(new BeamUnnestRel(correlate.getCluster(), correlate.getTraitSet().replace(BeamLogicalConvention.INSTANCE), convert(outer, outer.getTraitSet().replace(BeamLogicalConvention.INSTANCE)), call.rel(2).getRowType(), fieldAccessIndices.build()));
}
use of org.apache.calcite.plan.volcano.RelSubset in project calcite by apache.
the class MutableRels method toMutable.
public static MutableRel toMutable(RelNode rel) {
if (rel instanceof HepRelVertex) {
return toMutable(((HepRelVertex) rel).getCurrentRel());
}
if (rel instanceof RelSubset) {
return toMutable(Util.first(((RelSubset) rel).getBest(), ((RelSubset) rel).getOriginal()));
}
if (rel instanceof TableScan) {
return MutableScan.of((TableScan) rel);
}
if (rel instanceof Values) {
return MutableValues.of((Values) rel);
}
if (rel instanceof Project) {
final Project project = (Project) rel;
final MutableRel input = toMutable(project.getInput());
return MutableProject.of(input, project.getProjects(), project.getRowType().getFieldNames());
}
if (rel instanceof Filter) {
final Filter filter = (Filter) rel;
final MutableRel input = toMutable(filter.getInput());
return MutableFilter.of(input, filter.getCondition());
}
if (rel instanceof Aggregate) {
final Aggregate aggregate = (Aggregate) rel;
final MutableRel input = toMutable(aggregate.getInput());
return MutableAggregate.of(input, aggregate.getGroupSet(), aggregate.getGroupSets(), aggregate.getAggCallList());
}
if (rel instanceof Sort) {
final Sort sort = (Sort) rel;
final MutableRel input = toMutable(sort.getInput());
return MutableSort.of(input, sort.getCollation(), sort.offset, sort.fetch);
}
if (rel instanceof Calc) {
final Calc calc = (Calc) rel;
final MutableRel input = toMutable(calc.getInput());
return MutableCalc.of(input, calc.getProgram());
}
if (rel instanceof Exchange) {
final Exchange exchange = (Exchange) rel;
final MutableRel input = toMutable(exchange.getInput());
return MutableExchange.of(input, exchange.getDistribution());
}
if (rel instanceof Collect) {
final Collect collect = (Collect) rel;
final MutableRel input = toMutable(collect.getInput());
return MutableCollect.of(collect.getRowType(), input, collect.getFieldName());
}
if (rel instanceof Uncollect) {
final Uncollect uncollect = (Uncollect) rel;
final MutableRel input = toMutable(uncollect.getInput());
return MutableUncollect.of(uncollect.getRowType(), input, uncollect.withOrdinality);
}
if (rel instanceof Window) {
final Window window = (Window) rel;
final MutableRel input = toMutable(window.getInput());
return MutableWindow.of(window.getRowType(), input, window.groups, window.getConstants());
}
if (rel instanceof TableModify) {
final TableModify modify = (TableModify) rel;
final MutableRel input = toMutable(modify.getInput());
return MutableTableModify.of(modify.getRowType(), input, modify.getTable(), modify.getCatalogReader(), modify.getOperation(), modify.getUpdateColumnList(), modify.getSourceExpressionList(), modify.isFlattened());
}
if (rel instanceof Sample) {
final Sample sample = (Sample) rel;
final MutableRel input = toMutable(sample.getInput());
return MutableSample.of(input, sample.getSamplingParameters());
}
if (rel instanceof TableFunctionScan) {
final TableFunctionScan tableFunctionScan = (TableFunctionScan) rel;
final List<MutableRel> inputs = toMutables(tableFunctionScan.getInputs());
return MutableTableFunctionScan.of(tableFunctionScan.getCluster(), tableFunctionScan.getRowType(), inputs, tableFunctionScan.getCall(), tableFunctionScan.getElementType(), tableFunctionScan.getColumnMappings());
}
// is a sub-class of Join.
if (rel instanceof SemiJoin) {
final SemiJoin semiJoin = (SemiJoin) rel;
final MutableRel left = toMutable(semiJoin.getLeft());
final MutableRel right = toMutable(semiJoin.getRight());
return MutableSemiJoin.of(semiJoin.getRowType(), left, right, semiJoin.getCondition(), semiJoin.getLeftKeys(), semiJoin.getRightKeys());
}
if (rel instanceof Join) {
final Join join = (Join) rel;
final MutableRel left = toMutable(join.getLeft());
final MutableRel right = toMutable(join.getRight());
return MutableJoin.of(join.getRowType(), left, right, join.getCondition(), join.getJoinType(), join.getVariablesSet());
}
if (rel instanceof Correlate) {
final Correlate correlate = (Correlate) rel;
final MutableRel left = toMutable(correlate.getLeft());
final MutableRel right = toMutable(correlate.getRight());
return MutableCorrelate.of(correlate.getRowType(), left, right, correlate.getCorrelationId(), correlate.getRequiredColumns(), correlate.getJoinType());
}
if (rel instanceof Union) {
final Union union = (Union) rel;
final List<MutableRel> inputs = toMutables(union.getInputs());
return MutableUnion.of(union.getRowType(), inputs, union.all);
}
if (rel instanceof Minus) {
final Minus minus = (Minus) rel;
final List<MutableRel> inputs = toMutables(minus.getInputs());
return MutableMinus.of(minus.getRowType(), inputs, minus.all);
}
if (rel instanceof Intersect) {
final Intersect intersect = (Intersect) rel;
final List<MutableRel> inputs = toMutables(intersect.getInputs());
return MutableIntersect.of(intersect.getRowType(), inputs, intersect.all);
}
throw new RuntimeException("cannot translate " + rel + " to MutableRel");
}
use of org.apache.calcite.plan.volcano.RelSubset in project flink by apache.
the class StreamPhysicalPythonCorrelateRule method matches.
@Override
public boolean matches(RelOptRuleCall call) {
FlinkLogicalCorrelate correlate = call.rel(0);
RelNode right = ((RelSubset) correlate.getRight()).getOriginal();
if (right instanceof FlinkLogicalTableFunctionScan) {
// right node is a table function
FlinkLogicalTableFunctionScan scan = (FlinkLogicalTableFunctionScan) right;
// return true if the table function is python table function
return PythonUtil.isPythonCall(scan.getCall(), null);
} else if (right instanceof FlinkLogicalCalc) {
// a filter is pushed above the table function
return findTableFunction((FlinkLogicalCalc) right);
}
return false;
}
use of org.apache.calcite.plan.volcano.RelSubset in project flink by apache.
the class BatchPhysicalPythonCorrelateRule method matches.
@Override
public boolean matches(RelOptRuleCall call) {
FlinkLogicalCorrelate join = call.rel(0);
RelNode right = ((RelSubset) join.getRight()).getOriginal();
if (right instanceof FlinkLogicalTableFunctionScan) {
// right node is a table function
FlinkLogicalTableFunctionScan scan = (FlinkLogicalTableFunctionScan) right;
// return true if the table function is python table function
return PythonUtil.isPythonCall(scan.getCall(), null);
} else if (right instanceof FlinkLogicalCalc) {
// a filter is pushed above the table function
FlinkLogicalCalc calc = (FlinkLogicalCalc) right;
RelNode input = ((RelSubset) calc.getInput()).getOriginal();
if (input instanceof FlinkLogicalTableFunctionScan) {
FlinkLogicalTableFunctionScan scan = (FlinkLogicalTableFunctionScan) input;
// return true if the table function is python table function
return PythonUtil.isPythonCall(scan.getCall(), null);
}
}
return false;
}
Aggregations