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));
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 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 ); }
/** * 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; }
/** * 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; }
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));