case PRECEDING: if (amt == null) { rwb = RexWindowBound.create(SqlWindow.createUnboundedPreceding(pos), null); } else { sc = (SqlCall) SqlWindow.createPreceding(amt, pos); rwb = RexWindowBound.create(sc, cluster.getRexBuilder().makeCall(sc.getOperator(), amtLiteral)); rwb = RexWindowBound.create(SqlWindow.createCurrentRow(new SqlParserPos(1, 1)), null); break; rwb = RexWindowBound.create(SqlWindow.createUnboundedFollowing(new SqlParserPos(1, 1)), null); } else { sc = (SqlCall) SqlWindow.createFollowing(amt, pos); rwb = RexWindowBound.create(sc, cluster.getRexBuilder().makeCall(sc.getOperator(), amtLiteral));
private BoundarySpec getWindowBound(RexWindowBound wb) { BoundarySpec boundarySpec; if (wb.isCurrentRow()) { boundarySpec = new BoundarySpec(Direction.CURRENT); } else { final Direction direction; final int amt; if (wb.isPreceding()) { direction = Direction.PRECEDING; } else { direction = Direction.FOLLOWING; } if (wb.isUnbounded()) { amt = BoundarySpec.UNBOUNDED_AMOUNT; } else { amt = RexLiteral.intValue(wb.getOffset()); } boundarySpec = new BoundarySpec(direction, amt); } return boundarySpec; }
public static Bound newBound(RexWindowBound windowBound) { return new Bound(windowBound.isUnbounded(), windowBound.isCurrentRow() ? 0 : Long.MIN_VALUE); //TODO: Get offset to work } }
} else { Expression startTmp = group.lowerBound.isUnbounded() || startUnchecked == i_ ? startUnchecked : builder4.append("startTmp", startUnchecked, minX)); Expression endTmp = group.upperBound.isUnbounded() || endUnchecked == i_ ? endUnchecked : builder4.append("endTmp", group.lowerBound.isUnbounded() && group.lowerBound.isPreceding() ? Expressions.constant(false) : Expressions.notEqual(startX, prevStart);
/** * Returns if the window is guaranteed to have rows. * This is useful to refine data type of window aggregates. * For instance sum(non-nullable) over (empty window) is NULL. * * @return true when the window is non-empty * * @see org.apache.calcite.rel.core.Window.Group#isAlwaysNonEmpty() * @see SqlOperatorBinding#getGroupCount() * @see org.apache.calcite.sql.validate.SqlValidatorImpl#resolveWindow(SqlNode, org.apache.calcite.sql.validate.SqlValidatorScope, boolean) */ public boolean isAlwaysNonEmpty() { final SqlWindow tmp; if (lowerBound == null || upperBound == null) { // Keep the current window unmodified tmp = new SqlWindow(getParserPosition(), null, null, partitionList, orderList, isRows, lowerBound, upperBound, allowPartial); tmp.populateBounds(); } else { tmp = this; } if (tmp.lowerBound instanceof SqlLiteral && tmp.upperBound instanceof SqlLiteral) { int lowerKey = RexWindowBound.create(tmp.lowerBound, null).getOrderKey(); int upperKey = RexWindowBound.create(tmp.upperBound, null).getOrderKey(); return lowerKey > -1 && lowerKey <= upperKey; } return false; }
private Pair<Expression, Expression> getRowCollationKey( BlockBuilder builder, PhysType inputPhysType, Group group, int windowIdx) { if (!(group.isRows || (group.upperBound.isUnbounded() && group.lowerBound.isUnbounded()))) { Pair<Expression, Expression> pair = inputPhysType.generateCollationKey( group.collation().getFieldCollations()); // optimize=false to prevent inlining of object create into for-loops return Pair.of( builder.append("keySelector" + windowIdx, pair.left, false), builder.append("keyComparator" + windowIdx, pair.right, false)); } else { return Pair.of(null, null); } }
public R visitOver(RexOver over) { R r = visitCall(over); if (!deep) { return null; } final RexWindow window = over.getWindow(); for (RexFieldCollation orderKey : window.orderKeys) { orderKey.left.accept(this); } for (RexNode partitionKey : window.partitionKeys) { partitionKey.accept(this); } window.getLowerBound().accept(this); window.getUpperBound().accept(this); return r; }
public static Bound newBound(RexWindowBound windowBound) { return new Bound(windowBound.isUnbounded(), windowBound.isCurrentRow() ? 0 : Long.MIN_VALUE); //TODO: Get offset to work } }
} else { Expression startTmp = group.lowerBound.isUnbounded() || startUnchecked == i_ ? startUnchecked : builder4.append("startTmp", startUnchecked, minX)); Expression endTmp = group.upperBound.isUnbounded() || endUnchecked == i_ ? endUnchecked : builder4.append("endTmp", group.lowerBound.isUnbounded() && group.lowerBound.isPreceding() ? Expressions.constant(false) : Expressions.notEqual(startX, prevStart);
/** * Returns if the window is guaranteed to have rows. * This is useful to refine data type of window aggregates. * For instance sum(non-nullable) over (empty window) is NULL. * * @return true when the window is non-empty * * @see org.apache.calcite.rel.core.Window.Group#isAlwaysNonEmpty() * @see SqlOperatorBinding#getGroupCount() * @see org.apache.calcite.sql.validate.SqlValidatorImpl#resolveWindow(SqlNode, org.apache.calcite.sql.validate.SqlValidatorScope, boolean) */ public boolean isAlwaysNonEmpty() { final SqlWindow tmp; if (lowerBound == null || upperBound == null) { // Keep the current window unmodified tmp = new SqlWindow(getParserPosition(), null, null, partitionList, orderList, isRows, lowerBound, upperBound, allowPartial); tmp.populateBounds(); } else { tmp = this; } if (tmp.lowerBound instanceof SqlLiteral && tmp.upperBound instanceof SqlLiteral) { int lowerKey = RexWindowBound.create(tmp.lowerBound, null).getOrderKey(); int upperKey = RexWindowBound.create(tmp.upperBound, null).getOrderKey(); return lowerKey > -1 && lowerKey <= upperKey; } return false; }
private Pair<Expression, Expression> getRowCollationKey( BlockBuilder builder, PhysType inputPhysType, Group group, int windowIdx) { if (!(group.isRows || (group.upperBound.isUnbounded() && group.lowerBound.isUnbounded()))) { Pair<Expression, Expression> pair = inputPhysType.generateCollationKey( group.collation().getFieldCollations()); // optimize=false to prevent inlining of object create into for-loops return Pair.of( builder.append("keySelector" + windowIdx, pair.left, false), builder.append("keyComparator" + windowIdx, pair.right, false)); } else { return Pair.of(null, null); } }
public R visitOver(RexOver over) { R r = visitCall(over); if (!deep) { return null; } final RexWindow window = over.getWindow(); for (RexFieldCollation orderKey : window.orderKeys) { orderKey.left.accept(this); } for (RexNode partitionKey : window.partitionKeys) { partitionKey.accept(this); } window.getLowerBound().accept(this); window.getUpperBound().accept(this); return r; }
private BoundarySpec getWindowBound(RexWindowBound wb) { BoundarySpec boundarySpec; if (wb.isCurrentRow()) { boundarySpec = new BoundarySpec(Direction.CURRENT); } else { final Direction direction; final int amt; if (wb.isPreceding()) { direction = Direction.PRECEDING; } else { direction = Direction.FOLLOWING; } if (wb.isUnbounded()) { amt = BoundarySpec.UNBOUNDED_AMOUNT; } else { amt = RexLiteral.intValue(wb.getOffset()); } boundarySpec = new BoundarySpec(direction, amt); } return boundarySpec; }
case PRECEDING: if (amt == null) { rwb = RexWindowBound.create(SqlWindow.createUnboundedPreceding(pos), null); } else { sc = (SqlCall) SqlWindow.createPreceding(amt, pos); rwb = RexWindowBound.create(sc, cluster.getRexBuilder().makeCall(sc.getOperator(), amtLiteral)); rwb = RexWindowBound.create(SqlWindow.createCurrentRow(new SqlParserPos(1, 1)), null); break; rwb = RexWindowBound.create(SqlWindow.createUnboundedFollowing(new SqlParserPos(1, 1)), null); } else { sc = (SqlCall) SqlWindow.createFollowing(amt, pos); rwb = RexWindowBound.create(sc, cluster.getRexBuilder().makeCall(sc.getOperator(), amtLiteral));
public RexWindow visitWindow(RexWindow window) { boolean[] update = {false}; List<RexFieldCollation> clonedOrderKeys = visitFieldCollations(window.orderKeys, update); List<RexNode> clonedPartitionKeys = visitList(window.partitionKeys, update); RexWindowBound lowerBound = window.getLowerBound().accept(this); RexWindowBound upperBound = window.getUpperBound().accept(this); if (update[0] || (lowerBound != window.getLowerBound() && lowerBound != null) || (upperBound != window.getUpperBound() && upperBound != null)) { return new RexWindow( clonedPartitionKeys, clonedOrderKeys, lowerBound, upperBound, window.isRows()); } else { return window; } }
private ASTNode getWindowBound(RexWindowBound wb) { ASTNode wbAST = null; if (wb.isCurrentRow()) { wbAST = ASTBuilder.createAST(HiveParser.KW_CURRENT, "CURRENT"); } else { if (wb.isPreceding()) wbAST = ASTBuilder.createAST(HiveParser.KW_PRECEDING, "PRECEDING"); else wbAST = ASTBuilder.createAST(HiveParser.KW_FOLLOWING, "FOLLOWING"); if (wb.isUnbounded()) { wbAST.addChild(ASTBuilder.createAST(HiveParser.KW_UNBOUNDED, "UNBOUNDED")); } else { ASTNode offset = wb.getOffset().accept(this); wbAST.addChild(offset); } } return wbAST; }
public RexNode makeOver( SqlAggFunction operator, List<RexNode> expressions, List<RexNode> partitionKeys ) { final Set<SqlKind> flags = EnumSet.noneOf(SqlKind.class); // TODO // This is a temporal fix to make HAWQ work with OVER + UNLIMITED BOUNDS // HAWQ requires ORDER BY if andy BOUNDS are set even unlimited upper and lower BOUNDS (which is equal to // the entire partition - e.g. not setting BOUNDs at all -- // Note that the unnecessary ORDER BY have negative performance impact and has to be remove once either HAWQ // start supporting unbounded bounds without order by or Calcite can generate shorthand OVER PARTITION BY // syntax. List<RexFieldCollation> orderKeys = expressions.stream().map( rexNode -> new RexFieldCollation(rexNode, flags)).collect(Collectors.toList()); return makeOver( operator, expressions, partitionKeys, ImmutableList.copyOf(orderKeys), RexWindowBound.create(SqlWindow.createUnboundedPreceding(SqlParserPos.ZERO), null), RexWindowBound.create(SqlWindow.createUnboundedFollowing(SqlParserPos.ZERO), null), true, true, false ); }
public RexWindow visitWindow(RexWindow window) { boolean[] update = {false}; List<RexFieldCollation> clonedOrderKeys = visitFieldCollations(window.orderKeys, update); List<RexNode> clonedPartitionKeys = visitList(window.partitionKeys, update); RexWindowBound lowerBound = window.getLowerBound().accept(this); RexWindowBound upperBound = window.getUpperBound().accept(this); if (update[0] || (lowerBound != window.getLowerBound() && lowerBound != null) || (upperBound != window.getUpperBound() && upperBound != null)) { return new RexWindow( clonedPartitionKeys, clonedOrderKeys, lowerBound, upperBound, window.isRows()); } else { return window; } }
private ASTNode getWindowBound(RexWindowBound wb) { ASTNode wbAST = null; if (wb.isCurrentRow()) { wbAST = ASTBuilder.createAST(HiveParser.KW_CURRENT, "CURRENT"); } else { if (wb.isPreceding()) wbAST = ASTBuilder.createAST(HiveParser.KW_PRECEDING, "PRECEDING"); else wbAST = ASTBuilder.createAST(HiveParser.KW_FOLLOWING, "FOLLOWING"); if (wb.isUnbounded()) { wbAST.addChild(ASTBuilder.createAST(HiveParser.KW_UNBOUNDED, "UNBOUNDED")); } else { ASTNode offset = wb.getOffset().accept(this); wbAST.addChild(offset); } } return wbAST; }
case PRECEDING: if (amt == null) { rwb = RexWindowBound.create(SqlWindow.createUnboundedPreceding(pos), null); } else { sc = (SqlCall) SqlWindow.createPreceding(amt, pos); rwb = RexWindowBound.create(sc, cluster.getRexBuilder().makeCall(sc.getOperator(), amtLiteral)); rwb = RexWindowBound.create(SqlWindow.createCurrentRow(new SqlParserPos(1, 1)), null); break; rwb = RexWindowBound.create(SqlWindow.createUnboundedFollowing(new SqlParserPos(1, 1)), null); } else { sc = (SqlCall) SqlWindow.createFollowing(amt, pos); rwb = RexWindowBound.create(sc, cluster.getRexBuilder().makeCall(sc.getOperator(), amtLiteral));