How to multiply a Duration column and an Int colum...
# exposed
s
How to multiply a Duration column and an Int column? I'm doing something like this:
Copy code
GameplayRecordTable
    .select((GameplayRecordTable.duration * GameplayRecordTable.players).sum())
But the multiplication operator
*
does not work with
Duration
and
Int
. Any way around this? Thanks
r
Is your field of type
java.time.Duration
or
kotlin.time.Duration
?
o
@Stephcraft Hi, could you also add the table definition? I will try to reproduce your problem.
s
Here is my table definition: @Oleg Babichev
Copy code
import org.jetbrains.exposed.sql.kotlin.datetime.duration

object GameplayRecordTable: IntIdTable() {
    val duration = duration("duration")
    val players = integer("players")
}
So the type is
kotlin.time.Duration
@Ronny Bräunlich
I'll try this, not sure if its the good approach (I think it actually casts in sql, but multiplication with a duration and integer is possible in sql):
Copy code
(GameplayRecordTable.duration.castTo(LongColumnType()) * GameplayRecordTable.players.castTo(LongColumnType())).sum()
SQL:
Copy code
SELECT duration * players FROM `GameplayRecord`
Actually Duration is a BigInt in MySQL*
This worked, but having support for the
*
operator might be the better approach
c
Hi @Stephcraft There's no need to cast if you don't want to. There is a huge number of left- and right-side operator type combinations that may be accepted by SQL, which may not be covered by the out-of-the-box
TimesOp<T, S : T>
parameters. So the existing infix operator can be customized to fit any type combination that you require:
Copy code
// for example, this assumes that the query result you want is of type Duration

class DurationTimesOp<S : Number>(
    expr1: Expression<Duration>,
    expr2: Expression<S>
) : CustomOperator<Duration>(
    "*",
    KotlinDurationColumnType(),
    expr1,
    expr2
)

infix operator fun <S : Number> ExpressionWithColumnType<Duration>.times(
    other: Expression<S>
): DurationTimesOp<S> = DurationTimesOp(this, other)
This would allow you to continue using your first original query above. If
Duration * Int
is just one of many combos that you need, you could take this even further and eliminate the type-safety imposed by Exposed by creating your own version that accepts any combination:
Copy code
class GeneralTimesOp<T, S>(
    expr1: Expression<T>,
    expr2: Expression<S>,
    columnType: IColumnType<T & Any>
) : CustomOperator<T>(
    "*",
    columnType,
    expr1,
    expr2
)

infix operator fun <T, S> ExpressionWithColumnType<T>.times(
    other: Expression<S>
): GeneralTimesOp<T, S> = GeneralTimesOp(this, other, this.columnType)
MySQL, for example, technically even allows
Int * String
as valid SQL.
🙌 1
s
Thanks!
👍 1