Search code examples
javasqlpostgresqljooq

How to use rows of different cardinality with union


How can I write the following SQL query in jOOQ?

select row (user1."surname", user1."id") from "user" as user1
union all
select row (user2."id") from "user" as user2

Doing it like this does not compile, because the two rows are Row2 and Row1, which are not the same type, obviously.

db.select(row(user1.SURNAME, user1.ID)).from(user1)
.unionAll(select(row(user2.ID)).from(user2))
.fetch()

The only workaround solution I found is using row(Collection<?> values), however it seems like there must be a better way of doing it.

db.select(row(listOf(user1.SURNAME, user1.ID))).from(user1)
.unionAll(select(row(listOf(user2.ID))).from(user2))
.fetch()

Solution

  • The question seems to be "how can I tell the compiler to prefer the varargs overload row(SelectField...) over the typed overloads such as row(SelectField, SelectField) in order to get rid of type safety.

    There isn't really any better way than using listOf() or *arrayOf() (with the spread operator) in Kotlin, just like in Java you'd have to use List.of() or new SelectField[] { ... } to tell the compiler to use the collection overloads, because varargs overloads are always deprioritised by the compilers if there's a more specific, applicable overload. Usually, this is the desired behaviour because usually, you want type safety.