Hello! After updating to newest version of exposed...
# exposed
r
Hello! After updating to newest version of exposed (ColumnType changes) my custom abs() function is not working for nullable columns. I tried to create other method for nullable type, but I have no idea how to make it compile. Default version
Copy code
class Abs<T : Number>(
    val expr: Expression<T>,
    columnType: IColumnType<T>
) : Function<T>(columnType), WindowFunction<T?> {
    override fun toQueryBuilder(queryBuilder: QueryBuilder): Unit = queryBuilder { append("ABS(", expr, ")") }

    override fun over(): WindowFunctionDefinition<T?> {
        return WindowFunctionDefinition(columnType, this)
    }
}

fun <T : Number> ExpressionWithColumnType<T>.abs() = Abs(this, this.columnType)
My experiment with nullable type:
Copy code
class AbsNullable<T : Number?>(
    val expr: Expression<T>,
    columnType: IColumnType<T>
) : Function<T>(columnType), WindowFunction<T?> {
    override fun toQueryBuilder(queryBuilder: QueryBuilder): Unit = queryBuilder { append("ABS(", expr, ")") }

    override fun over(): WindowFunctionDefinition<T?> {
        return WindowFunctionDefinition(columnType, this)
    }
}

fun <T : Number?> ExpressionWithColumnType<T>.abs() = AbsNullable(this, this.columnType)
But compiler throws error for columnType like on screenshot Do you have any ideas how to configure functions for nullable columns? Or maybe is there built in function for absolute value in exposed?
c
Hi @Rafał Kuźmiński There are quite a few built-in classes available for math functions and trigonometric functions, one of which is
AbsFunction
. But these classes are not set up to implement the
WindowFunction
interface, which you seem to need. This single function class works with both nullable and non-nullable columns for me:
Copy code
class Abs<T : Number?>(
    val expr: Expression<T>,
    columnType: IColumnType<T & Any>
) : Function<T?>(columnType), WindowFunction<T?> {
    override fun toQueryBuilder(
        queryBuilder: QueryBuilder
    ) { queryBuilder { append("ABS(", expr, ")") } }

    override fun over(): WindowFunctionDefinition<T?> {
        return WindowFunctionDefinition(columnType, this)
    }
}

fun <T : Number?> ExpressionWithColumnType<T>.abs(): Abs<T> = Abs(this, this.columnType)
Alternatively you could take a look at how our
Min
and
Max
classes are implemented.