Пример #1
0
  /** 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;
  }