Source:
private static Value[] getCompareRow(Session session, ArrayList<Value[]> orderedRows, SortOrder sortOrder, int currentRow, WindowFrameBound bound, boolean add) { int sortIndex = sortOrder.getQueryColumnIndexes()[0]; OpType opType = add ^ (sortOrder.getSortTypes()[0] & SortOrder.DESCENDING) != 0 ? OpType.PLUS : OpType.MINUS; Value[] row = orderedRows.get(currentRow); Value[] newRow = row.clone(); Value currentValue = row[sortIndex]; switch (currentValue.getType()) { case Value.BYTE: case Value.SHORT: case Value.INT: case Value.LONG: case Value.DECIMAL: case Value.DOUBLE: case Value.FLOAT: case Value.TIME: case Value.DATE: case Value.TIMESTAMP: case Value.TIMESTAMP_TZ: case Value.INTERVAL_YEAR: case Value.INTERVAL_MONTH: case Value.INTERVAL_DAY: case Value.INTERVAL_HOUR: case Value.INTERVAL_MINUTE: case Value.INTERVAL_SECOND: case Value.INTERVAL_YEAR_TO_MONTH: case Value.INTERVAL_DAY_TO_HOUR: case Value.INTERVAL_DAY_TO_MINUTE: case Value.INTERVAL_DAY_TO_SECOND: case Value.INTERVAL_HOUR_TO_MINUTE: case Value.INTERVAL_HOUR_TO_SECOND: case Value.INTERVAL_MINUTE_TO_SECOND: break; default: throw DbException.getInvalidValueException("ORDER BY value for RANGE frame", currentValue.getTraceSQL()); } Value range = getValueOffset(bound, orderedRows.get(currentRow), session); Value newValue = new BinaryOperation(opType, ValueExpression.get(currentValue), ValueExpression.get(range)) .optimize(session).getValue(session); newRow[sortIndex] = newValue; return newRow; }

Target:
private static Value[] getCompareRow(Session session, ArrayList<Value[]> orderedRows, SortOrder sortOrder, int currentRow, WindowFrameBound bound, boolean add) { int sortIndex = sortOrder.getQueryColumnIndexes()[0]; Value[] row = orderedRows.get(currentRow); Value currentValue = row[sortIndex]; int type = currentValue.getType(); Value newValue; Value range = getValueOffset(bound, orderedRows.get(currentRow), session); switch (type) { case Value.NULL: newValue = ValueNull.INSTANCE; break; case Value.BYTE: case Value.SHORT: case Value.INT: case Value.LONG: case Value.DECIMAL: case Value.DOUBLE: case Value.FLOAT: case Value.TIME: case Value.DATE: case Value.TIMESTAMP: case Value.TIMESTAMP_TZ: case Value.INTERVAL_YEAR: case Value.INTERVAL_MONTH: case Value.INTERVAL_DAY: case Value.INTERVAL_HOUR: case Value.INTERVAL_MINUTE: case Value.INTERVAL_SECOND: case Value.INTERVAL_YEAR_TO_MONTH: case Value.INTERVAL_DAY_TO_HOUR: case Value.INTERVAL_DAY_TO_MINUTE: case Value.INTERVAL_DAY_TO_SECOND: case Value.INTERVAL_HOUR_TO_MINUTE: case Value.INTERVAL_HOUR_TO_SECOND: case Value.INTERVAL_MINUTE_TO_SECOND: OpType opType = add ^ (sortOrder.getSortTypes()[0] & SortOrder.DESCENDING) != 0 ? OpType.PLUS : OpType.MINUS; try { newValue = new BinaryOperation(opType, ValueExpression.get(currentValue), ValueExpression.get(range)) .optimize(session).getValue(session).convertTo(type); } catch (DbException ex) { switch (ex.getErrorCode()) { case ErrorCode.NUMERIC_VALUE_OUT_OF_RANGE_1: case ErrorCode.NUMERIC_VALUE_OUT_OF_RANGE_2: return null; } throw ex; } break; default: throw DbException.getInvalidValueException("unsupported type of sort key for RANGE units", currentValue.getTraceSQL()); } Value[] newRow = row.clone(); newRow[sortIndex] = newValue; return newRow; }