private SqlNode createSqlWindowBound(RexWindowBound rexWindowBound) { if (rexWindowBound.isCurrentRow()) { return SqlWindow.createCurrentRow(POS); } if (rexWindowBound.isPreceding()) { if (rexWindowBound.isUnbounded()) { return SqlWindow.createUnboundedPreceding(POS); } else { SqlNode literal = toSql(null, rexWindowBound.getOffset()); return SqlWindow.createPreceding(literal, POS); } } if (rexWindowBound.isFollowing()) { if (rexWindowBound.isUnbounded()) { return SqlWindow.createUnboundedFollowing(POS); } else { SqlNode literal = toSql(null, rexWindowBound.getOffset()); return SqlWindow.createFollowing(literal, POS); } } throw new AssertionError("Unsupported Window bound: " + rexWindowBound); }
private SqlNode createSqlWindowBound(RexWindowBound rexWindowBound) { if (rexWindowBound.isCurrentRow()) { return SqlWindow.createCurrentRow(POS); } if (rexWindowBound.isPreceding()) { if (rexWindowBound.isUnbounded()) { return SqlWindow.createUnboundedPreceding(POS); } else { SqlNode literal = toSql(null, rexWindowBound.getOffset()); return SqlWindow.createPreceding(literal, POS); } } if (rexWindowBound.isFollowing()) { if (rexWindowBound.isUnbounded()) { return SqlWindow.createUnboundedFollowing(POS); } else { SqlNode literal = toSql(null, rexWindowBound.getOffset()); return SqlWindow.createFollowing(literal, POS); } } throw new AssertionError("Unsupported Window bound: " + rexWindowBound); }
if (bound.isFollowing()) { b = Expressions.add(b, offs); } else { Expression offs = translator.translate(node); if (bound.isFollowing()) { val = Expressions.add(val, offs); } else {
if (bound.isFollowing()) { b = Expressions.add(b, offs); } else { Expression offs = translator.translate(node); if (bound.isFollowing()) { val = Expressions.add(val, offs); } else {
/** * 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. } }