/** Creates a call to a windowed agg. */ public RexNode makeOver( RelDataType type, SqlAggFunction operator, List<RexNode> exprs, List<RexNode> partitionKeys, ImmutableList<RexFieldCollation> orderKeys, RexWindowBound lowerBound, RexWindowBound upperBound, boolean physical, boolean allowPartial, boolean nullWhenCountZero) { assert operator != null; assert exprs != null; assert partitionKeys != null; assert orderKeys != null; final RexWindow window = makeWindow(partitionKeys, orderKeys, lowerBound, upperBound, physical); final RexOver over = new RexOver(type, operator, exprs, window); RexNode result = over; // This should be correct but need time to go over test results. // Also want to look at combing with section below. if (nullWhenCountZero) { final RelDataType bigintType = getTypeFactory().createSqlType(SqlTypeName.BIGINT); result = makeCall( SqlStdOperatorTable.CASE, makeCall( SqlStdOperatorTable.GREATER_THAN, new RexOver(bigintType, SqlStdOperatorTable.COUNT, exprs, window), makeLiteral(BigDecimal.ZERO, bigintType, SqlTypeName.DECIMAL)), ensureType( type, // SUM0 is non-nullable, thus need a cast new RexOver( typeFactory.createTypeWithNullability(type, false), operator, exprs, window), false), makeCast(type, constantNull())); } if (!allowPartial) { Util.permAssert(physical, "DISALLOW PARTIAL over RANGE"); final RelDataType bigintType = getTypeFactory().createSqlType(SqlTypeName.BIGINT); // todo: read bound result = makeCall( SqlStdOperatorTable.CASE, makeCall( SqlStdOperatorTable.GREATER_THAN_OR_EQUAL, new RexOver( bigintType, SqlStdOperatorTable.COUNT, ImmutableList.<RexNode>of(), window), makeLiteral(BigDecimal.valueOf(2), bigintType, SqlTypeName.DECIMAL)), result, constantNull); } return result; }