use of org.apache.calcite.rex.RexLocalRef 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.RexLocalRef in project calcite by apache.
the class LogicalWindow method toInputRefs.
private static List<RexNode> toInputRefs(final List<? extends RexNode> operands) {
return new AbstractList<RexNode>() {
public int size() {
return operands.size();
}
public RexNode get(int index) {
final RexNode operand = operands.get(index);
if (operand instanceof RexInputRef) {
return operand;
}
assert operand instanceof RexLocalRef;
final RexLocalRef ref = (RexLocalRef) operand;
return new RexInputRef(ref.getIndex(), ref.getType());
}
};
}
use of org.apache.calcite.rex.RexLocalRef in project calcite by apache.
the class LogicalWindow method addWindows.
private static void addWindows(Multimap<WindowKey, RexOver> windowMap, RexOver over, final int inputFieldCount) {
final RexWindow aggWindow = over.getWindow();
// Look up or create a window.
RelCollation orderKeys = getCollation(Lists.newArrayList(Iterables.filter(aggWindow.orderKeys, new PredicateImpl<RexFieldCollation>() {
public boolean test(RexFieldCollation rexFieldCollation) {
// then we can ignore such ORDER BY key.
return rexFieldCollation.left instanceof RexLocalRef;
}
})));
ImmutableBitSet groupSet = ImmutableBitSet.of(getProjectOrdinals(aggWindow.partitionKeys));
final int groupLength = groupSet.length();
if (inputFieldCount < groupLength) {
// If PARTITION BY references constant, we can ignore such partition key.
// All the inputs after inputFieldCount are literals, thus we can clear.
groupSet = groupSet.except(ImmutableBitSet.range(inputFieldCount, groupLength));
}
WindowKey windowKey = new WindowKey(groupSet, orderKeys, aggWindow.isRows(), aggWindow.getLowerBound(), aggWindow.getUpperBound());
windowMap.put(windowKey, over);
}
use of org.apache.calcite.rex.RexLocalRef in project calcite by apache.
the class RexToLixTranslator method deref.
/**
* Dereferences an expression if it is a
* {@link org.apache.calcite.rex.RexLocalRef}.
*/
public RexNode deref(RexNode expr) {
if (expr instanceof RexLocalRef) {
RexLocalRef ref = (RexLocalRef) expr;
final RexNode e2 = program.getExprList().get(ref.getIndex());
assert ref.getType().equals(e2.getType());
return e2;
} else {
return expr;
}
}
use of org.apache.calcite.rex.RexLocalRef in project calcite by apache.
the class CalcRelSplitter method computeTopologicalOrdering.
/**
* Computes the order in which to visit expressions, so that we decide the
* level of an expression only after the levels of lower expressions have
* been decided.
*
* <p>First, we need to ensure that an expression is visited after all of
* its inputs.
*
* <p>Further, if the expression is a member of a cohort, we need to visit
* it after the inputs of all other expressions in that cohort. With this
* condition, expressions in the same cohort will very likely end up in the
* same level.
*
* <p>Note that if there are no cohorts, the expressions from the
* {@link RexProgram} are already in a suitable order. We perform the
* topological sort just to ensure that the code path is well-trodden.
*
* @param exprs Expressions
* @param cohorts List of cohorts, each of which is a set of expr ordinals
* @return Expression ordinals in topological order
*/
private List<Integer> computeTopologicalOrdering(RexNode[] exprs, List<Set<Integer>> cohorts) {
final DirectedGraph<Integer, DefaultEdge> graph = DefaultDirectedGraph.create();
for (int i = 0; i < exprs.length; i++) {
graph.addVertex(i);
}
for (int i = 0; i < exprs.length; i++) {
final RexNode expr = exprs[i];
final Set<Integer> cohort = findCohort(cohorts, i);
final Set<Integer> targets;
if (cohort == null) {
targets = Collections.singleton(i);
} else {
targets = cohort;
}
expr.accept(new RexVisitorImpl<Void>(true) {
public Void visitLocalRef(RexLocalRef localRef) {
for (Integer target : targets) {
graph.addEdge(localRef.getIndex(), target);
}
return null;
}
});
}
TopologicalOrderIterator<Integer, DefaultEdge> iter = new TopologicalOrderIterator<>(graph);
final List<Integer> permutation = new ArrayList<>();
while (iter.hasNext()) {
permutation.add(iter.next());
}
return permutation;
}
Aggregations