Home > Back-end >  Safely casting jOOQ's TableField<*, *> to TableField<*, {some object type}> in Kotl
Safely casting jOOQ's TableField<*, *> to TableField<*, {some object type}> in Kotl

Time:12-23

So I have this function in Kotlin:

fun getJooqOperator(field: TableField<*,*>, value: String): org.jooq.Condition {
  // In this case, "this" is the operator enum. 
  // The combination of field and operator is strictly handled in the front-end (Elm)
  return when (this) {
    EQ -> (field as TableField<*, String>).eq(value)
    NEQ -> (field as TableField<*, String>).ne(value)
    GT -> (field as TableField<*, Int>).gt(Integer.parseInt(value))
  }
}

This piece is used in a Kotlin class that will deserialize some JSON from the front-end. From this JSON, the class will build a jOOQ-query based on the input from the user. This part is about using the correct operator with the corresponding column and input value.

However this will not result in compile errors, IntelliJ is complaining about the casting of the field. I know for sure that these fields can be casted safely for the specific operator enum. This is the warning IntelliJ throws:

Warning from IntelliJ

I don't want to Change type arguments to <*, *>, because without the casting, the jOOQ-condition won't work with the values.

Is there a way to rewrite my function properly, or can I safely ignore these warnings?

CodePudding user response:

Casting

[...] or can I safely ignore these warnings?

I'm not sure what kinds of safety you're expecting here. Your assumption that EQ and NEQ are String based, whereas GT is Int based is quite a strong one. You probably have your reassons for this. If you encode things this way, and know why that is, then yes, you can safely ignore the warnings. This doesn't translate to such casts being "safe" in general, they're not. The * translates to any unknown type, yet in your cast, you make an assumption that effectively, the type should have been known, it's just not possible to express it in your type system.

Coercion

You can always use data type coercion as well, e.g.

return when (this) {
    EQ -> field.coerce(SQLDataType.VARCHAR).eq(value)
    NEQ -> field.coerce(SQLDataType.VARCHAR).ne(value)
    GT -> field.coerce(SQLDataType.INTEGER).gt(Integer.parseInt(value))
}

Although, that does have an effect on the expression tree you're building, unlike the unsafe cast. Probably not an important effect in your case.

  • Related