use of org.apache.calcite.rex.RexOver in project hive by apache.
the class HiveRelColumnsAlignment method align.
public RelNode align(Project rel, List<RelFieldCollation> collations) {
// 1) We extract the collations indices
boolean containsWindowing = false;
for (RexNode childExp : rel.getChildExps()) {
if (childExp instanceof RexOver) {
// TODO: support propagation for partitioning/ordering in windowing
containsWindowing = true;
break;
}
}
ImmutableList.Builder<RelFieldCollation> propagateCollations = ImmutableList.builder();
if (!containsWindowing) {
for (RelFieldCollation c : collations) {
RexNode rexNode = rel.getChildExps().get(c.getFieldIndex());
if (rexNode instanceof RexInputRef) {
int newIdx = ((RexInputRef) rexNode).getIndex();
propagateCollations.add(c.copy((newIdx)));
}
}
}
// 2) We propagate
final RelNode child = dispatchAlign(rel.getInput(), propagateCollations.build());
// 3) Return new Project
return rel.copy(rel.getTraitSet(), ImmutableList.of(child));
}
use of org.apache.calcite.rex.RexOver in project hive by apache.
the class HiveWindowingFixRule method onMatch.
@Override
public void onMatch(RelOptRuleCall call) {
Project project = call.rel(0);
Aggregate aggregate = call.rel(1);
// 1. We go over the expressions in the project operator
// and we separate the windowing nodes that are result
// of an aggregate expression from the rest of nodes
final int groupingFields = aggregate.getGroupCount() + aggregate.getIndicatorCount();
Set<String> projectExprsDigest = new HashSet<String>();
Map<String, RexNode> windowingExprsDigestToNodes = new HashMap<String, RexNode>();
for (RexNode r : project.getChildExps()) {
if (r instanceof RexOver) {
RexOver rexOverNode = (RexOver) r;
// Operands
for (RexNode operand : rexOverNode.getOperands()) {
if (operand instanceof RexInputRef && ((RexInputRef) operand).getIndex() >= groupingFields) {
windowingExprsDigestToNodes.put(operand.toString(), operand);
}
}
// Partition keys
for (RexNode partitionKey : rexOverNode.getWindow().partitionKeys) {
if (partitionKey instanceof RexInputRef && ((RexInputRef) partitionKey).getIndex() >= groupingFields) {
windowingExprsDigestToNodes.put(partitionKey.toString(), partitionKey);
}
}
// Order keys
for (RexFieldCollation orderKey : rexOverNode.getWindow().orderKeys) {
if (orderKey.left instanceof RexInputRef && ((RexInputRef) orderKey.left).getIndex() >= groupingFields) {
windowingExprsDigestToNodes.put(orderKey.left.toString(), orderKey.left);
}
}
} else {
projectExprsDigest.add(r.toString());
}
}
// 2. We check whether there is a column needed by the
// windowing operation that is missing in the
// project expressions. For instance, if the windowing
// operation is over an aggregation column, Hive expects
// that column to be in the Select clause of the query.
// The idea is that if there is a column missing, we will
// replace the old project operator by two new project
// operators:
// - a project operator containing the original columns
// of the project operator plus all the columns that were
// missing
// - a project on top of the previous one, that will take
// out the columns that were missing and were added by the
// previous project
// These data structures are needed to create the new project
// operator (below)
final List<RexNode> belowProjectExprs = new ArrayList<RexNode>();
final List<String> belowProjectColumnNames = new ArrayList<String>();
// This data structure is needed to create the new project
// operator (top)
final List<RexNode> topProjectExprs = new ArrayList<RexNode>();
final int projectCount = project.getChildExps().size();
for (int i = 0; i < projectCount; i++) {
belowProjectExprs.add(project.getChildExps().get(i));
belowProjectColumnNames.add(project.getRowType().getFieldNames().get(i));
topProjectExprs.add(RexInputRef.of(i, project.getRowType()));
}
boolean windowingFix = false;
for (Entry<String, RexNode> windowingExpr : windowingExprsDigestToNodes.entrySet()) {
if (!projectExprsDigest.contains(windowingExpr.getKey())) {
windowingFix = true;
belowProjectExprs.add(windowingExpr.getValue());
int colIndex = 0;
String alias = "window_col_" + colIndex;
while (belowProjectColumnNames.contains(alias)) {
alias = "window_col_" + (colIndex++);
}
belowProjectColumnNames.add(alias);
}
}
if (!windowingFix) {
// We do not need to do anything, we bail out
return;
}
// 3. We need to fix it, we create the two replacement project
// operators
RelNode newProjectRel = projectFactory.createProject(aggregate, belowProjectExprs, belowProjectColumnNames);
RelNode newTopProjectRel = projectFactory.createProject(newProjectRel, topProjectExprs, project.getRowType().getFieldNames());
call.transformTo(newTopProjectRel);
}
use of org.apache.calcite.rex.RexOver in project hive by apache.
the class HiveFilterProjectTransposeRule method getCommonPartitionCols.
private static Set<Integer> getCommonPartitionCols(List<RexNode> projections) {
RexOver overClause;
boolean firstOverClause = true;
Set<Integer> commonPartitionKeys = new HashSet<Integer>();
for (RexNode expr : projections) {
if (expr instanceof RexOver) {
overClause = (RexOver) expr;
if (firstOverClause) {
firstOverClause = false;
commonPartitionKeys.addAll(getPartitionCols(overClause.getWindow().partitionKeys));
} else {
commonPartitionKeys.retainAll(getPartitionCols(overClause.getWindow().partitionKeys));
}
}
}
return commonPartitionKeys;
}
use of org.apache.calcite.rex.RexOver in project hive by apache.
the class HiveProjectMergeRule method matches.
@Override
public boolean matches(RelOptRuleCall call) {
// Currently we do not support merging windowing functions with other
// windowing functions i.e. embedding windowing functions within each
// other
final Project topProject = call.rel(0);
final Project bottomProject = call.rel(1);
for (RexNode expr : topProject.getChildExps()) {
if (expr instanceof RexOver) {
Set<Integer> positions = HiveCalciteUtil.getInputRefs(expr);
for (int pos : positions) {
if (bottomProject.getChildExps().get(pos) instanceof RexOver) {
return false;
}
}
}
}
return super.matches(call);
}
Aggregations