in backend/engine/src/main/java/com/epam/deltix/quantgrid/engine/node/plan/local/DateRangeLocal.java [71:265]
public Table execute(Table table) {
DoubleColumn date1Column = expression(0, 0).evaluate();
Util.verify(date1Column.size() == table.size());
DoubleColumn date2Column = expression(0, 1).evaluate();
Util.verify(date2Column.size() == table.size());
DoubleColumn incrementColumn = expression(0, 2).evaluate();
Util.verify(incrementColumn.size() == table.size());
DoubleColumn dateTypeColumn = expression(0, 3).evaluate();
Util.verify(dateTypeColumn.size() == table.size());
int size = Util.toIntSize(table.size());
LongArrayList refs = new LongArrayList(size);
DoubleArrayList days = new DoubleArrayList(size);
for (int i = 0; i < size; i++) {
double date1 = date1Column.get(i);
double date2 = date2Column.get(i);
double originalIncrement = incrementColumn.get(i);
double originalDateType = dateTypeColumn.get(i);
if (!Doubles.isValue(date1) || !Doubles.isValue(date2) ||
!Doubles.isValue(originalIncrement) || !Doubles.isValue(originalDateType)) {
continue;
}
double increment = (int) Math.round(originalIncrement);
DateRangeType dateType = DateRangeType.fromId((int) Math.round(dateTypeColumn.get(i)));
if (date1 > date2) {
throw new IllegalArgumentException("Invalid function DATERANGE argument \"date1\" or \"date2\": expected \"date1\" is greater or equal to \"date2\"");
}
if (increment <= 0) {
throw new IllegalArgumentException("Invalid function DATERANGE argument \"increment\": expected positive value of type INTEGER");
}
if (dateType == null) {
throw new IllegalArgumentException("Invalid function DATERANGE argument \"date_type\": expected value of type INTEGER from 1 to 9");
}
int dayOfWeek;
int startDay;
double currentDay, currentMonth, currentYear, currentDate;
switch (dateType) {
case SECOND:
for (long j = (long) (date1 * DateFunctions.SECONDS_IN_DAY); j <= (long) (date2 * DateFunctions.SECONDS_IN_DAY); j += increment) {
refs.add(i);
days.add((double) j / DateFunctions.SECONDS_IN_DAY);
}
break;
case MINUTE:
for (int j = (int) Math.ceil(date1 * DateFunctions.MINUTES_IN_DAY); j <= (int) (date2 * DateFunctions.MINUTES_IN_DAY); j += increment) {
refs.add(i);
days.add((double) j / DateFunctions.MINUTES_IN_DAY);
}
break;
case HOUR:
for (int j = (int) Math.ceil(date1 * DateFunctions.HOURS_IN_DAY); j <= (int) (date2 * DateFunctions.HOURS_IN_DAY); j += increment) {
refs.add(i);
days.add((double) j / DateFunctions.HOURS_IN_DAY);
}
break;
case DAY:
startDay = (int) Math.ceil(date1);
for (int j = startDay; j <= (int) date2; j += increment) {
refs.add(i);
days.add(j);
}
break;
case WORKDAY:
startDay = (int) Math.ceil(date1);
dayOfWeek = Dates.getLocalDate(startDay).getDayOfWeek().getValue() - 1;
int remainingDaysBeforeAdd = 0;
for (int j = startDay; j <= (int) (date2); ++j, dayOfWeek = (dayOfWeek + 1) % 7) {
if (dayOfWeek > 4) {
continue;
}
if (remainingDaysBeforeAdd == 0) {
refs.add(i);
days.add(j);
}
++remainingDaysBeforeAdd;
if (remainingDaysBeforeAdd == increment) {
remainingDaysBeforeAdd = 0;
}
}
break;
case WEEK:
startDay = (int) Math.ceil(date1);
dayOfWeek = Dates.getLocalDate(startDay).getDayOfWeek().getValue() - 1;
for (int j = startDay + (6 - dayOfWeek); j <= (int) date2; j += 7 * increment) {
refs.add(i);
days.add(j);
}
break;
case MONTH:
startDay = (int) Math.ceil(date1);
currentDay = Dates.getDay(startDay) - 1;
currentMonth = Dates.getMonth(startDay) - 1;
currentYear = Dates.getYear(startDay);
if (currentDay > 0) {
++currentMonth;
if (currentMonth == 12) {
currentMonth = 0;
++currentYear;
}
}
currentDate = Dates.of(currentYear, currentMonth + 1, 1);
while (currentDate <= (int) date2) {
refs.add(i);
days.add(currentDate);
currentMonth += increment;
if (currentMonth >= 12) {
currentYear += currentMonth / 12;
currentMonth = currentMonth % 12;
}
currentDate = Dates.of(currentYear, currentMonth + 1, 1);
}
break;
case QUARTER:
startDay = (int) Math.ceil(date1);
currentDay = Dates.getDay(startDay) - 1;
currentMonth = Dates.getMonth(startDay) - 1;
currentYear = Dates.getYear(startDay);
if (currentMonth % 3 != 0 || currentDay > 0) {
if (currentMonth >= 8) {
++currentYear;
currentMonth = 0;
} else {
++currentMonth;
currentMonth += 3 - currentMonth % 3;
}
}
currentDate = Dates.of(currentYear, currentMonth + 1, 1);
while (currentDate <= (int) date2) {
refs.add(i);
days.add(currentDate);
currentMonth += 3 * increment;
if (currentMonth >= 12) {
currentYear += currentMonth / 12;
currentMonth = currentMonth % 12;
}
currentDate = Dates.of(currentYear, currentMonth + 1, 1);
}
break;
case YEAR:
startDay = (int) Math.ceil(date1);
currentDay = Dates.getDay(startDay) - 1;
currentMonth = Dates.getMonth(startDay) - 1;
currentYear = Dates.getYear(startDay);
if (currentMonth > 0 || currentDay > 0) {
++currentYear;
}
currentDate = Dates.of(currentYear, 1, 1);
while (currentDate <= (int) date2) {
refs.add(i);
days.add(currentDate);
currentYear += increment;
currentDate = Dates.of(currentYear, 1, 1);
}
break;
}
}
Table left = LocalTable.indirectOf(table, refs);
LocalTable right = new LocalTable(new DoubleDirectColumn(days));
return LocalTable.compositeOf(left, right);
}