Skip to content

Commit

Permalink
Adds support for INTERVAL minus INTERVAL
Browse files Browse the repository at this point in the history
  • Loading branch information
johnedquinn committed Feb 20, 2025
1 parent 9933104 commit 5b0c9c6
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,11 @@ class IntervalMinusTests {
@Execution(ExecutionMode.CONCURRENT)
fun timestampZMinusInterval(tc: SuccessTestCase) = tc.run()

@Disabled("We haven't yet implemented INTERVAL - INTERVAL yet.")
@ParameterizedTest
@MethodSource("intervalMinusIntervalYMCases")
@Execution(ExecutionMode.CONCURRENT)
fun intervalMinusIntervalYM(tc: SuccessTestCase) = tc.run()

@Disabled("We haven't yet implemented INTERVAL - INTERVAL yet.")
@ParameterizedTest
@MethodSource("intervalMinusIntervalDTCases")
@Execution(ExecutionMode.CONCURRENT)
Expand Down Expand Up @@ -220,103 +218,98 @@ class IntervalMinusTests {
SuccessTestCase("${case.arg0} - ${case.arg1}", case.expected)
}

// These tests aren't correct. They're disabled anyway and are just a placeholder.
@JvmStatic
fun intervalMinusIntervalYMCases() = listOf(
// INTERVAL YEAR + Others
Input(INTERVAL_Y, INTERVAL_Y, Datum.intervalYearMonth(2, 0, 2)),
Input(INTERVAL_Y, INTERVAL_M, Datum.intervalYearMonth(1, 1, 2)),
Input(INTERVAL_Y, INTERVAL_YM, Datum.intervalYearMonth(2, 1, 2)),
Input(INTERVAL_Y, INTERVAL_Y, Datum.intervalYearMonth(0, 0, 2)),
Input(INTERVAL_Y, INTERVAL_M, Datum.intervalYearMonth(0, 11, 2)),
Input(INTERVAL_Y, INTERVAL_YM, Datum.intervalYearMonth(0, -1, 2)),

// INTERVAL MONTH + Others
Input(INTERVAL_M, INTERVAL_M, Datum.intervalYearMonth(0, 2, 2)),
Input(INTERVAL_M, INTERVAL_YM, Datum.intervalYearMonth(1, 2, 2)),
Input(INTERVAL_M, INTERVAL_M, Datum.intervalYearMonth(0, 0, 2)),
Input(INTERVAL_M, INTERVAL_YM, Datum.intervalYearMonth(-1, 0, 2)),

// INTERVAL YEAR TO MONTH + Others
Input(INTERVAL_YM, INTERVAL_YM, Datum.intervalYearMonth(2, 2, 2)),
Input(INTERVAL_YM, INTERVAL_YM, Datum.intervalYearMonth(0, 0, 2)),
).map { case ->
SuccessTestCase("${case.arg0} - ${case.arg1}", case.expected)
}

// These tests aren't correct. They're disabled anyway and are just a placeholder.
@JvmStatic
fun intervalMinusIntervalDTCases() = listOf(
// INTERVAL DAY + Others
Input(INTERVAL_D, INTERVAL_D, Datum.intervalDaySecond(2, 0, 0, 0, 0, 2, 6)),
Input(INTERVAL_D, INTERVAL_H, Datum.intervalDaySecond(1, 1, 0, 0, 0, 2, 6)),
Input(INTERVAL_D, INTERVAL_MIN, Datum.intervalDaySecond(1, 0, 1, 0, 0, 2, 6)),
Input(INTERVAL_D, INTERVAL_S, Datum.intervalDaySecond(1, 0, 0, 1, NANO, 2, 6)),
Input(INTERVAL_D, INTERVAL_DTH, Datum.intervalDaySecond(2, 1, 0, 0, 0, 2, 6)),
Input(INTERVAL_D, INTERVAL_DTM, Datum.intervalDaySecond(2, 1, 1, 0, 0, 2, 6)),
Input(INTERVAL_D, INTERVAL_DTS, Datum.intervalDaySecond(2, 1, 1, 1, NANO, 2, 6)),
Input(INTERVAL_D, INTERVAL_HM, Datum.intervalDaySecond(1, 1, 1, 0, 0, 2, 6)),
Input(INTERVAL_D, INTERVAL_HTS, Datum.intervalDaySecond(1, 1, 1, 1, NANO, 2, 6)),
Input(INTERVAL_D, INTERVAL_MTS, Datum.intervalDaySecond(1, 0, 1, 1, NANO, 2, 6)),
Input(INTERVAL_D, INTERVAL_D, Datum.intervalDaySecond(0, 0, 0, 0, 0, 2, 6)),
Input(INTERVAL_D, INTERVAL_H, Datum.intervalDaySecond(1, -1, 0, 0, 0, 2, 6)),
Input(INTERVAL_D, INTERVAL_MIN, Datum.intervalDaySecond(1, 0, -1, 0, 0, 2, 6)),
Input(INTERVAL_D, INTERVAL_S, Datum.intervalDaySecond(1, 0, 0, -1, -NANO, 2, 6)),
Input(INTERVAL_D, INTERVAL_DTH, Datum.intervalDaySecond(0, -1, 0, 0, 0, 2, 6)),
Input(INTERVAL_D, INTERVAL_DTM, Datum.intervalDaySecond(0, -1, -1, 0, 0, 2, 6)),
Input(INTERVAL_D, INTERVAL_DTS, Datum.intervalDaySecond(0, -1, -1, -1, -NANO, 2, 6)),
Input(INTERVAL_D, INTERVAL_HM, Datum.intervalDaySecond(1, -1, -1, 0, 0, 2, 6)),
Input(INTERVAL_D, INTERVAL_HTS, Datum.intervalDaySecond(1, -1, -1, -1, -NANO, 2, 6)),
Input(INTERVAL_D, INTERVAL_MTS, Datum.intervalDaySecond(1, 0, -1, -1, -NANO, 2, 6)),

// INTERVAL HOUR + Others
Input(INTERVAL_H, INTERVAL_H, Datum.intervalDaySecond(0, 2, 0, 0, 0, 2, 6)),
Input(INTERVAL_H, INTERVAL_MIN, Datum.intervalDaySecond(0, 1, 1, 0, 0, 2, 6)),
Input(INTERVAL_H, INTERVAL_S, Datum.intervalDaySecond(0, 1, 0, 1, NANO, 2, 6)),
Input(INTERVAL_H, INTERVAL_HM, Datum.intervalDaySecond(0, 2, 1, 0, 0, 2, 6)),
Input(INTERVAL_H, INTERVAL_HTS, Datum.intervalDaySecond(0, 2, 1, 1, NANO, 2, 6)),
Input(INTERVAL_H, INTERVAL_MTS, Datum.intervalDaySecond(0, 1, 1, 1, NANO, 2, 6)),
Input(INTERVAL_H, INTERVAL_H, Datum.intervalDaySecond(0, 0, 0, 0, 0, 2, 6)),
Input(INTERVAL_H, INTERVAL_MIN, Datum.intervalDaySecond(0, 1, -1, 0, 0, 2, 6)),
Input(INTERVAL_H, INTERVAL_S, Datum.intervalDaySecond(0, 1, 0, -1, -NANO, 2, 6)),
Input(INTERVAL_H, INTERVAL_HM, Datum.intervalDaySecond(0, 0, -1, 0, 0, 2, 6)),
Input(INTERVAL_H, INTERVAL_HTS, Datum.intervalDaySecond(0, 0, -1, -1, -NANO, 2, 6)),
Input(INTERVAL_H, INTERVAL_MTS, Datum.intervalDaySecond(0, 1, -1, -1, -NANO, 2, 6)),

// INTERVAL MINUTE + Others
Input(INTERVAL_MIN, INTERVAL_MIN, Datum.intervalDaySecond(0, 0, 2, 0, 0, 2, 6)),
Input(INTERVAL_MIN, INTERVAL_S, Datum.intervalDaySecond(0, 0, 1, 1, NANO, 2, 6)),
Input(INTERVAL_MIN, INTERVAL_DTH, Datum.intervalDaySecond(1, 1, 1, 0, 0, 2, 6)),
Input(INTERVAL_MIN, INTERVAL_DTM, Datum.intervalDaySecond(1, 1, 2, 0, 0, 2, 6)),
Input(INTERVAL_MIN, INTERVAL_DTS, Datum.intervalDaySecond(1, 1, 2, 1, NANO, 2, 6)),
Input(INTERVAL_MIN, INTERVAL_HM, Datum.intervalDaySecond(0, 1, 2, 0, 0, 2, 6)),
Input(INTERVAL_MIN, INTERVAL_HTS, Datum.intervalDaySecond(0, 1, 2, 1, NANO, 2, 6)),
Input(INTERVAL_MIN, INTERVAL_MTS, Datum.intervalDaySecond(0, 0, 2, 1, NANO, 2, 6)),
Input(INTERVAL_MIN, INTERVAL_MIN, Datum.intervalDaySecond(0, 0, 0, 0, 0, 2, 6)),
Input(INTERVAL_MIN, INTERVAL_S, Datum.intervalDaySecond(0, 0, 1, -1, -NANO, 2, 6)),
Input(INTERVAL_MIN, INTERVAL_DTH, Datum.intervalDaySecond(-1, -1, 1, 0, 0, 2, 6)),
Input(INTERVAL_MIN, INTERVAL_DTM, Datum.intervalDaySecond(-1, -1, 0, 0, 0, 2, 6)),
Input(INTERVAL_MIN, INTERVAL_DTS, Datum.intervalDaySecond(-1, -1, 0, -1, -NANO, 2, 6)),
Input(INTERVAL_MIN, INTERVAL_HM, Datum.intervalDaySecond(0, -1, 0, 0, 0, 2, 6)),
Input(INTERVAL_MIN, INTERVAL_HTS, Datum.intervalDaySecond(0, -1, 0, -1, -NANO, 2, 6)),
Input(INTERVAL_MIN, INTERVAL_MTS, Datum.intervalDaySecond(0, 0, 0, -1, -NANO, 2, 6)),

// INTERVAL SECOND + Others
Input(INTERVAL_S, INTERVAL_S, Datum.intervalDaySecond(0, 0, 0, 2, NANOS, 2, 6)),
Input(INTERVAL_S, INTERVAL_DTH, Datum.intervalDaySecond(1, 1, 0, 1, NANO, 2, 6)),
Input(INTERVAL_S, INTERVAL_DTM, Datum.intervalDaySecond(1, 1, 1, 1, NANO, 2, 6)),
Input(INTERVAL_S, INTERVAL_DTS, Datum.intervalDaySecond(1, 1, 1, 2, NANOS, 2, 6)),
Input(INTERVAL_S, INTERVAL_HM, Datum.intervalDaySecond(0, 1, 1, 1, NANO, 2, 6)),
Input(INTERVAL_S, INTERVAL_HTS, Datum.intervalDaySecond(0, 1, 1, 2, NANOS, 2, 6)),
Input(INTERVAL_S, INTERVAL_MTS, Datum.intervalDaySecond(0, 0, 1, 2, NANOS, 2, 6)),
Input(INTERVAL_S, INTERVAL_S, Datum.intervalDaySecond(0, 0, 0, 0, 0, 2, 6)),
Input(INTERVAL_S, INTERVAL_DTH, Datum.intervalDaySecond(-1, -1, 0, 1, NANO, 2, 6)),
Input(INTERVAL_S, INTERVAL_DTM, Datum.intervalDaySecond(-1, -1, -1, 1, NANO, 2, 6)),
Input(INTERVAL_S, INTERVAL_DTS, Datum.intervalDaySecond(-1, -1, -1, 0, 0, 2, 6)),
Input(INTERVAL_S, INTERVAL_HM, Datum.intervalDaySecond(0, -1, -1, 1, NANO, 2, 6)),
Input(INTERVAL_S, INTERVAL_HTS, Datum.intervalDaySecond(0, -1, -1, 0, 0, 2, 6)),
Input(INTERVAL_S, INTERVAL_MTS, Datum.intervalDaySecond(0, 0, -1, 0, 0, 2, 6)),

// INTERVAL DAY TO HOUR + Others
Input(INTERVAL_DTH, INTERVAL_DTH, Datum.intervalDaySecond(2, 2, 0, 0, 0, 2, 6)),
Input(INTERVAL_DTH, INTERVAL_DTM, Datum.intervalDaySecond(2, 2, 1, 0, 0, 2, 6)),
Input(INTERVAL_DTH, INTERVAL_DTS, Datum.intervalDaySecond(2, 2, 1, 1, NANO, 2, 6)),
Input(INTERVAL_DTH, INTERVAL_HM, Datum.intervalDaySecond(1, 2, 1, 0, 0, 2, 6)),
Input(INTERVAL_DTH, INTERVAL_HTS, Datum.intervalDaySecond(1, 2, 1, 1, NANO, 2, 6)),
Input(INTERVAL_DTH, INTERVAL_MTS, Datum.intervalDaySecond(1, 1, 1, 1, NANO, 2, 6)),
Input(INTERVAL_DTH, INTERVAL_DTH, Datum.intervalDaySecond(0, 0, 0, 0, 0, 2, 6)),
Input(INTERVAL_DTH, INTERVAL_DTM, Datum.intervalDaySecond(0, 0, -1, 0, 0, 2, 6)),
Input(INTERVAL_DTH, INTERVAL_DTS, Datum.intervalDaySecond(0, 0, -1, -1, -NANO, 2, 6)),
Input(INTERVAL_DTH, INTERVAL_HM, Datum.intervalDaySecond(1, 0, -1, 0, 0, 2, 6)),
Input(INTERVAL_DTH, INTERVAL_HTS, Datum.intervalDaySecond(1, 0, -1, -1, -NANO, 2, 6)),
Input(INTERVAL_DTH, INTERVAL_MTS, Datum.intervalDaySecond(1, 1, -1, -1, -NANO, 2, 6)),

// INTERVAL DAY TO MINUTE + Others
Input(INTERVAL_DTM, INTERVAL_DTM, Datum.intervalDaySecond(2, 2, 2, 0, 0, 2, 6)),
Input(INTERVAL_DTM, INTERVAL_DTS, Datum.intervalDaySecond(2, 2, 2, 1, NANO, 2, 6)),
Input(INTERVAL_DTM, INTERVAL_HM, Datum.intervalDaySecond(1, 2, 2, 0, 0, 2, 6)),
Input(INTERVAL_DTM, INTERVAL_HTS, Datum.intervalDaySecond(1, 2, 2, 1, NANO, 2, 6)),
Input(INTERVAL_DTM, INTERVAL_MTS, Datum.intervalDaySecond(1, 1, 2, 1, NANO, 2, 6)),
Input(INTERVAL_DTM, INTERVAL_DTM, Datum.intervalDaySecond(0, 0, 0, 0, 0, 2, 6)),
Input(INTERVAL_DTM, INTERVAL_DTS, Datum.intervalDaySecond(0, 0, 0, -1, -NANO, 2, 6)),
Input(INTERVAL_DTM, INTERVAL_HM, Datum.intervalDaySecond(1, 0, 0, 0, 0, 2, 6)),
Input(INTERVAL_DTM, INTERVAL_HTS, Datum.intervalDaySecond(1, 0, 0, -1, -NANO, 2, 6)),
Input(INTERVAL_DTM, INTERVAL_MTS, Datum.intervalDaySecond(1, 1, 0, -1, -NANO, 2, 6)),

// INTERVAL DAY TO SECOND + Others
Input(INTERVAL_DTS, INTERVAL_DTS, Datum.intervalDaySecond(2, 2, 2, 2, NANOS, 2, 6)),
Input(INTERVAL_DTS, INTERVAL_HM, Datum.intervalDaySecond(1, 2, 2, 1, NANO, 2, 6)),
Input(INTERVAL_DTS, INTERVAL_HTS, Datum.intervalDaySecond(1, 2, 2, 2, NANOS, 2, 6)),
Input(INTERVAL_DTS, INTERVAL_MTS, Datum.intervalDaySecond(1, 1, 2, 2, NANOS, 2, 6)),
Input(INTERVAL_DTS, INTERVAL_DTS, Datum.intervalDaySecond(0, 0, 0, 0, 0, 2, 6)),
Input(INTERVAL_DTS, INTERVAL_HM, Datum.intervalDaySecond(1, 0, 0, 1, NANO, 2, 6)),
Input(INTERVAL_DTS, INTERVAL_HTS, Datum.intervalDaySecond(1, 0, 0, 0, 0, 2, 6)),
Input(INTERVAL_DTS, INTERVAL_MTS, Datum.intervalDaySecond(1, 1, 0, 0, 0, 2, 6)),

// INTERVAL HOUR TO MINUTE + Others
Input(INTERVAL_HM, INTERVAL_HM, Datum.intervalDaySecond(0, 2, 2, 0, 0, 2, 6)),
Input(INTERVAL_HM, INTERVAL_HTS, Datum.intervalDaySecond(0, 2, 2, 1, NANO, 2, 6)),
Input(INTERVAL_HM, INTERVAL_MTS, Datum.intervalDaySecond(0, 1, 2, 1, NANO, 2, 6)),
Input(INTERVAL_HM, INTERVAL_HM, Datum.intervalDaySecond(0, 0, 0, 0, 0, 2, 6)),
Input(INTERVAL_HM, INTERVAL_HTS, Datum.intervalDaySecond(0, 0, 0, -1, -NANO, 2, 6)),
Input(INTERVAL_HM, INTERVAL_MTS, Datum.intervalDaySecond(0, 1, 0, -1, -NANO, 2, 6)),

// INTERVAL HOUR TO SECOND + Others
Input(INTERVAL_HTS, INTERVAL_HTS, Datum.intervalDaySecond(0, 2, 2, 2, NANOS, 2, 6)),
Input(INTERVAL_HTS, INTERVAL_MTS, Datum.intervalDaySecond(0, 1, 2, 2, NANOS, 2, 6)),
Input(INTERVAL_HTS, INTERVAL_HTS, Datum.intervalDaySecond(0, 0, 0, 0, 0, 2, 6)),
Input(INTERVAL_HTS, INTERVAL_MTS, Datum.intervalDaySecond(0, 1, 0, 0, 0, 2, 6)),

// INTERVAL MINUTE TO SECOND + Others
Input(INTERVAL_MTS, INTERVAL_MTS, Datum.intervalDaySecond(0, 0, 2, 2, NANOS, 2, 6))
).flatMap { case ->
listOf(
SuccessTestCase("${case.arg0} - ${case.arg1}", case.expected),
SuccessTestCase("${case.arg1} - ${case.arg0}", case.expected),
)
Input(INTERVAL_MTS, INTERVAL_MTS, Datum.intervalDaySecond(0, 0, 0, 0, 0, 2, 6))
).map { case ->
SuccessTestCase("${case.arg0} - ${case.arg1}", case.expected)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ class OpArithmeticTest : PartiQLTyperTestBase() {
).map { inputs.get("basics", it)!! }

val argsMap: Map<TestResult, Set<List<PType>>> = buildMap {
val successArgs = allNumberPType.let { cartesianProduct(it, it) } + allDatePType.let { cartesianProduct(it, it) } + allTimePType.let { cartesianProduct(it, it) } + allTimeStampPType.let { cartesianProduct(it, it) } + cartesianProduct(allDatePType, allIntervalType) + cartesianProduct(allTimePType, allIntervalDTType) + cartesianProduct(allTimeStampPType, allIntervalType)
val successArgs = allNumberPType.let { cartesianProduct(it, it) } + allDatePType.let { cartesianProduct(it, it) } + allTimePType.let { cartesianProduct(it, it) } + allTimeStampPType.let { cartesianProduct(it, it) } + cartesianProduct(allDatePType, allIntervalType) + cartesianProduct(allTimePType, allIntervalDTType) + cartesianProduct(allTimeStampPType, allIntervalType) + cartesianProduct(allIntervalYMType, allIntervalYMType) + cartesianProduct(allIntervalDTType, allIntervalDTType)
val failureArgs = cartesianProduct(
allSupportedPType,
allSupportedPType
Expand All @@ -126,6 +126,8 @@ class OpArithmeticTest : PartiQLTyperTestBase() {
arg0 in allTimePType && arg1 in allIntervalType -> arg0
arg0 in allTimeStampPType && arg1 in allTimeStampPType -> PType.intervalDaySecond(9, 0)
arg0 in allTimeStampPType && arg1 in allIntervalType -> arg0
arg0 in allIntervalYMType && arg1 in allIntervalYMType -> PType.intervalYearMonth(9)
arg0 in allIntervalDTType && arg1 in allIntervalDTType -> PType.intervalDaySecond(9, 0)
arg0 == arg1 -> arg1
// TODO arg0 == StaticType.DECIMAL && arg1 == StaticType.FLOAT -> arg1 // TODO: The cast table is wrong. Honestly, it should be deleted.
// TODO arg1 == StaticType.DECIMAL && arg0 == StaticType.FLOAT -> arg0 // TODO: The cast table is wrong
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,31 +18,36 @@ static void checkScale(int scale) {
}

static void checkUsingPrecision(int value, int precision) {
if (value < -Math.pow(10, precision) || value > Math.pow(10, precision) - 1) {
long newValue = Math.abs((long) value);
if (newValue < -Math.pow(10, precision) || newValue > Math.pow(10, precision) - 1) {
throw new IllegalArgumentException("Value " + value + " is out of range for precision " + precision);
}
}

static void checkHours(int hours) {
if (hours < 0 || hours > 23) {
long newHours = Math.abs((long) hours);
if (newHours > 23) {
throw new IllegalArgumentException("Hours must be between 0 and 23 inclusive");
}
}

static void checkMinutes(int minutes) {
if (minutes < 0 || minutes > 59) {
long newMinutes = Math.abs((long) minutes);
if (newMinutes > 59) {
throw new IllegalArgumentException("Minutes must be between 0 and 59 inclusive");
}
}

static void checkSeconds(int seconds) {
if (seconds < 0 || seconds > 59) {
long newSeconds = Math.abs((long) seconds);
if (newSeconds > 59) {
throw new IllegalArgumentException("Seconds must be between 0 and 59 inclusive");
}
}

static void checkMonths(int months) {
if (months < 0 || months > 11) {
long newMonths = Math.abs((long) months);
if (newMonths > 11) {
throw new IllegalArgumentException("Months must be between 0 and 11 inclusive");
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,15 @@ public int getYears() throws InvalidOperationException, NullPointerException {
public int getMonths() throws InvalidOperationException, NullPointerException {
return _months;
}

@Override
public String toString() {
return "DatumIntervalYearMonth{" +
"_years=" + _years +
", _months=" + _months +
", precision=" + precision +
", intervalCode=" + intervalCode +
", _type=" + _type +
'}';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,50 @@ internal object FnMinus : DiadicArithmeticOperator("minus") {
}
}

override fun getIntervalInstance(lhs: PType, rhs: PType): Fn? {
return when {
lhs.code() == PType.INTERVAL_DT && rhs.code() == PType.INTERVAL_DT -> {
val p: Int = lhs.precision // TODO: Do we need to calculate a new precision?
val s: Int = 6 // TODO: Do we need to calculate a new fractional precision?
basic(PType.intervalDaySecond(p, s)) { args ->
val interval0 = args[0]
val interval1 = args[1]
subtractIntervalDayTimes(interval0, interval1, p, s)
}
}
lhs.code() == PType.INTERVAL_YM && rhs.code() == PType.INTERVAL_YM -> {
val p: Int = lhs.precision // TODO: Do we need to calculate a new precision?
basic(PType.intervalYearMonth(p)) { args ->
val interval0 = args[0]
val interval1 = args[1]
subtractIntervalYearMonths(interval0, interval1, p)
}
}
else -> null
}
}

private fun subtractIntervalYearMonths(lhs: Datum, rhs: Datum, precision: Int): Datum {
val (months, yearsRemainder) = getRemainder(lhs.months - rhs.months, 12)
val years = lhs.years - rhs.years - yearsRemainder
return Datum.intervalYearMonth(years, months, precision)
}

private fun subtractIntervalDayTimes(lhs: Datum, rhs: Datum, precision: Int, scale: Int): Datum {
val (nanos, secondsRemainder) = getRemainder(lhs.nanos - rhs.nanos, 1_000_000_000)
val (seconds, minutesRemainder) = getRemainder(lhs.seconds - rhs.seconds - secondsRemainder, 60)
val (minutes, hoursRemainder) = getRemainder(lhs.minutes - rhs.minutes - minutesRemainder, 60)
val (hours, daysRemainder) = getRemainder(lhs.hours - rhs.hours - hoursRemainder, 12)
val days = lhs.days - rhs.days - daysRemainder
return Datum.intervalDaySecond(days, hours, minutes, seconds, nanos, precision, scale)
}

private fun getRemainder(value: Int, divisor: Int): Pair<Int, Int> {
val remainder = value % divisor
val quotient = value / divisor
return remainder to quotient
}

override fun getBigIntInstance(bigIntLhs: PType, bigIntRhs: PType): Fn {
return basic(PType.bigint()) { args ->
val arg0 = args[0].long
Expand Down

0 comments on commit 5b0c9c6

Please sign in to comment.