final RexWinAggCall aggCall = new RexWinAggCall( over.getAggOperator(), over.getType(), toInputRefs(over.operands),
final RexWinAggCall aggCall = new RexWinAggCall( over.getAggOperator(), over.getType(), toInputRefs(over.operands),
@Override public RexNode visitOver(RexOver over, P arg) { boolean[] update = {false}; List<RexNode> clonedOperands = visitList(over.operands, update, arg); RexWindow window = visitWindow(over.getWindow(), arg); if (update[0] || (window != over.getWindow())) { // REVIEW jvs 8-Mar-2005: This doesn't take into account // the fact that a rewrite may have changed the result type. // To do that, we would need to take a RexBuilder and // watch out for special operators like CAST and NEW where // the type is embedded in the original call. return new RexOver( over.getType(), over.getAggOperator(), clonedOperands, window, over.isDistinct()); } else { return over; } }
public RexNode visitOver(RexOver over) { boolean[] update = {false}; List<RexNode> clonedOperands = visitList(over.operands, update); RexWindow window = visitWindow(over.getWindow()); if (update[0] || (window != over.getWindow())) { // REVIEW jvs 8-Mar-2005: This doesn't take into account // the fact that a rewrite may have changed the result type. // To do that, we would need to take a RexBuilder and // watch out for special operators like CAST and NEW where // the type is embedded in the original call. return new RexOver( over.getType(), over.getAggOperator(), clonedOperands, window, over.isDistinct()); } else { return over; } }
public RexNode visitOver(RexOver over) { boolean[] update = {false}; List<RexNode> clonedOperands = visitList(over.operands, update); RexWindow window = visitWindow(over.getWindow()); if (update[0] || (window != over.getWindow())) { // REVIEW jvs 8-Mar-2005: This doesn't take into account // the fact that a rewrite may have changed the result type. // To do that, we would need to take a RexBuilder and // watch out for special operators like CAST and NEW where // the type is embedded in the original call. return new RexOver( over.getType(), over.getAggOperator(), clonedOperands, window, over.isDistinct()); } else { return over; } }
private SqlCall toSql(RexProgram program, RexOver rexOver) { final RexWindow rexWindow = rexOver.getWindow(); final SqlNodeList partitionList = new SqlNodeList( toSql(program, rexWindow.partitionKeys), POS); ImmutableList.Builder<SqlNode> orderNodes = ImmutableList.builder(); if (rexWindow.orderKeys != null) { for (RexFieldCollation rfc : rexWindow.orderKeys) { orderNodes.add(toSql(program, rfc)); } } final SqlNodeList orderList = new SqlNodeList(orderNodes.build(), POS); final SqlLiteral isRows = SqlLiteral.createBoolean(rexWindow.isRows(), POS); final SqlNode lowerBound = createSqlWindowBound(rexWindow.getLowerBound()); final SqlNode upperBound = createSqlWindowBound(rexWindow.getUpperBound()); // null defaults to true. // During parsing the allowPartial == false (e.g. disallow partial) // is expand into CASE expression and is handled as a such. // Not sure if we can collapse this CASE expression back into // "disallow partial" and set the allowPartial = false. final SqlLiteral allowPartial = null; final SqlWindow sqlWindow = SqlWindow.create(null, null, partitionList, orderList, isRows, lowerBound, upperBound, allowPartial, POS); final List<SqlNode> nodeList = toSql(program, rexOver.getOperands()); return createOverCall(rexOver.getAggOperator(), nodeList, sqlWindow); }
rexOver.getAggOperator().createCall(POS, nodeList);
/** * Indicates if the given OVER clause has a window frame that is automatically added by * Calcite if the frame is not specified. */ public static boolean hasDefaultFrame(RexOver over) { // When Calcite parses an OVER clause with no frame, // it inject a 'default' frame depending on the function. // 1. For ROW_NUMBER(), it generates ROWS UNBOUNDED PRECEDING and CURRENT ROW. // 2. For others, it generates RANGE UNBOUNDED PRECEDING and UNBOUNDED FOLLOWING if unsorted. // 3. If it's not ROW_NUMBER(), and it is sorted, Calcite uses RANGE UNBOUNDED PRECEDING AND CURRENT ROW // Adding these unnecessary frames cause some RDBMSes (eg SQL Server) to fail. // // This code happens in SqlToRelConverter.convertOver(), SqlValidatorImpl.resolveWindow(), // and SqlWindow.create()/SqlWindow.populateBounds(). return // Note: intentionally not simplifying this boolean for clarity. (over.getAggOperator() == SqlStdOperatorTable.ROW_NUMBER && over.getWindow().isRows() && over.getWindow().getLowerBound().isUnbounded() && over.getWindow().getLowerBound().isPreceding() && over.getWindow().getUpperBound().isCurrentRow()) // First condition. || (!over.getWindow().isRows() && over.getWindow().orderKeys.isEmpty() && over.getWindow().getLowerBound().isUnbounded() && over.getWindow().getLowerBound().isPreceding() && over.getWindow().getUpperBound().isUnbounded() && over.getWindow().getUpperBound().isFollowing()) // Second condition. || (!over.getWindow().isRows() && !over.getWindow().orderKeys.isEmpty() && over.getWindow().getLowerBound().isUnbounded() && over.getWindow().getLowerBound().isPreceding() && !over.getWindow().getUpperBound().isUnbounded() && over.getWindow().getUpperBound().isCurrentRow()); // Third condition. } }