use of org.apache.calcite.rex.RexNode in project flink by apache.
the class FlinkRelDecorrelator method decorrelateRel.
/**
* Rewrite Correlator into a left outer join.
*
* @param rel Correlator
*/
public Frame decorrelateRel(LogicalCorrelate rel) {
//
// Rewrite logic:
//
// The original left input will be joined with the new right input that
// has generated correlated variables propagated up. For any generated
// cor vars that are not used in the join key, pass them along to be
// joined later with the CorrelatorRels that produce them.
//
// the right input to Correlator should produce correlated variables
final RelNode oldLeft = rel.getInput(0);
final RelNode oldRight = rel.getInput(1);
final Frame leftFrame = getInvoke(oldLeft, rel);
final Frame rightFrame = getInvoke(oldRight, rel);
if (leftFrame == null || rightFrame == null) {
// If any input has not been rewritten, do not rewrite this rel.
return null;
}
if (rightFrame.corVarOutputPos.isEmpty()) {
return null;
}
assert rel.getRequiredColumns().cardinality() <= rightFrame.corVarOutputPos.keySet().size();
// Change correlator rel into a join.
// Join all the correlated variables produced by this correlator rel
// with the values generated and propagated from the right input
final SortedMap<Correlation, Integer> corVarOutputPos = new TreeMap<>(rightFrame.corVarOutputPos);
final List<RexNode> conditions = new ArrayList<>();
final List<RelDataTypeField> newLeftOutput = leftFrame.r.getRowType().getFieldList();
int newLeftFieldCount = newLeftOutput.size();
final List<RelDataTypeField> newRightOutput = rightFrame.r.getRowType().getFieldList();
for (Map.Entry<Correlation, Integer> rightOutputPos : Lists.newArrayList(corVarOutputPos.entrySet())) {
final Correlation corVar = rightOutputPos.getKey();
if (!corVar.corr.equals(rel.getCorrelationId())) {
continue;
}
final int newLeftPos = leftFrame.oldToNewOutputPos.get(corVar.field);
final int newRightPos = rightOutputPos.getValue();
conditions.add(rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, RexInputRef.of(newLeftPos, newLeftOutput), new RexInputRef(newLeftFieldCount + newRightPos, newRightOutput.get(newRightPos).getType())));
// remove this cor var from output position mapping
corVarOutputPos.remove(corVar);
}
// vars that are not used in the join key.
for (Correlation corVar : corVarOutputPos.keySet()) {
int newPos = corVarOutputPos.get(corVar) + newLeftFieldCount;
corVarOutputPos.put(corVar, newPos);
}
// then add any cor var from the left input. Do not need to change
// output positions.
corVarOutputPos.putAll(leftFrame.corVarOutputPos);
// Create the mapping between the output of the old correlation rel
// and the new join rel
final Map<Integer, Integer> mapOldToNewOutputPos = Maps.newHashMap();
int oldLeftFieldCount = oldLeft.getRowType().getFieldCount();
int oldRightFieldCount = oldRight.getRowType().getFieldCount();
assert rel.getRowType().getFieldCount() == oldLeftFieldCount + oldRightFieldCount;
// Left input positions are not changed.
mapOldToNewOutputPos.putAll(leftFrame.oldToNewOutputPos);
// Right input positions are shifted by newLeftFieldCount.
for (int i = 0; i < oldRightFieldCount; i++) {
mapOldToNewOutputPos.put(i + oldLeftFieldCount, rightFrame.oldToNewOutputPos.get(i) + newLeftFieldCount);
}
final RexNode condition = RexUtil.composeConjunction(rexBuilder, conditions, false);
RelNode newJoin = LogicalJoin.create(leftFrame.r, rightFrame.r, condition, ImmutableSet.<CorrelationId>of(), rel.getJoinType().toJoinType());
return register(rel, newJoin, mapOldToNewOutputPos, corVarOutputPos);
}
use of org.apache.calcite.rex.RexNode in project storm by apache.
the class TridentCalcRel method tridentPlan.
@Override
public void tridentPlan(TridentPlanCreator planCreator) throws Exception {
// SingleRel
RelNode input = getInput();
StormRelUtils.getStormRelInput(input).tridentPlan(planCreator);
Stream inputStream = planCreator.pop().toStream();
String stageName = StormRelUtils.getStageName(this);
RelDataType inputRowType = getInput(0).getRowType();
List<String> outputFieldNames = getRowType().getFieldNames();
int outputCount = outputFieldNames.size();
// filter
ExecutableExpression filterInstance = null;
RexLocalRef condition = program.getCondition();
if (condition != null) {
RexNode conditionNode = program.expandLocalRef(condition);
filterInstance = planCreator.createScalarInstance(Lists.newArrayList(conditionNode), inputRowType, StormRelUtils.getClassName(this));
}
// projection
ExecutableExpression projectionInstance = null;
List<RexLocalRef> projectList = program.getProjectList();
if (projectList != null && !projectList.isEmpty()) {
List<RexNode> expandedNodes = new ArrayList<>();
for (RexLocalRef project : projectList) {
expandedNodes.add(program.expandLocalRef(project));
}
projectionInstance = planCreator.createScalarInstance(expandedNodes, inputRowType, StormRelUtils.getClassName(this));
}
if (projectionInstance == null && filterInstance == null) {
// it shouldn't be happen
throw new IllegalStateException("Either projection or condition, or both should be provided.");
}
final Stream finalStream = inputStream.flatMap(new EvaluationCalc(filterInstance, projectionInstance, outputCount, planCreator.getDataContext()), new Fields(outputFieldNames)).name(stageName);
planCreator.addStream(finalStream);
}
use of org.apache.calcite.rex.RexNode in project storm by apache.
the class TridentFilterRel method tridentPlan.
@Override
public void tridentPlan(TridentPlanCreator planCreator) throws Exception {
// SingleRel
RelNode input = getInput();
StormRelUtils.getStormRelInput(input).tridentPlan(planCreator);
Stream inputStream = planCreator.pop().toStream();
String stageName = StormRelUtils.getStageName(this);
List<RexNode> childExps = getChildExps();
RelDataType inputRowType = getInput(0).getRowType();
String filterClassName = StormRelUtils.getClassName(this);
ExecutableExpression filterInstance = planCreator.createScalarInstance(childExps, inputRowType, filterClassName);
IAggregatableStream finalStream = inputStream.filter(new EvaluationFilter(filterInstance, planCreator.getDataContext())).name(stageName);
planCreator.addStream(finalStream);
}
use of org.apache.calcite.rex.RexNode in project storm by apache.
the class RelNodeCompiler method visitFilter.
@Override
public Void visitFilter(Filter filter, List<Void> inputStreams) throws Exception {
beginStage(filter);
List<RexNode> childExps = filter.getChildExps();
RelDataType inputRowType = filter.getInput(0).getRowType();
pw.print("Context context = new StormContext(Processor.dataContext);\n");
pw.print("context.values = _data.toArray();\n");
pw.print("Object[] outputValues = new Object[1];\n");
pw.write(rexCompiler.compileToBlock(childExps, inputRowType).toString());
String r = "((Boolean) outputValues[0])";
if (filter.getCondition().getType().isNullable()) {
pw.print(String.format(" if (%s != null && %s) { ctx.emit(_data); }\n", r, r));
} else {
pw.print(String.format(" if (%s) { ctx.emit(_data); }\n", r, r));
}
endStage();
return null;
}
use of org.apache.calcite.rex.RexNode in project storm by apache.
the class RelNodeCompiler method visitProject.
@Override
public Void visitProject(Project project, List<Void> inputStreams) throws Exception {
beginStage(project);
List<RexNode> childExps = project.getChildExps();
RelDataType inputRowType = project.getInput(0).getRowType();
int outputCount = project.getRowType().getFieldCount();
pw.print("Context context = new StormContext(Processor.dataContext);\n");
pw.print("context.values = _data.toArray();\n");
pw.print(String.format("Object[] outputValues = new Object[%d];\n", outputCount));
pw.write(rexCompiler.compileToBlock(childExps, inputRowType).toString());
pw.print(" ctx.emit(new Values(outputValues));\n");
endStage();
return null;
}
Aggregations