Joachim
Joachim

Reputation: 859

Using "lower" and "upper" aggregate functions on JOOQ Postgres range types

I'm using the Postgres numrange type with JOOQ as defined here and want to call the lower/upper aggregate function on the selected ranges. My understanding is that these functions are not actually implemented in the jooq-postgres-extensions module and that I somehow have to implement this myself. Reading through this blog post, the author mentions that these functions have to be implemented yourself and he gives some examples:

static <T extends Comparable<T>> Condition 
    rangeContainsElem(Field<Range<T>> f1, T e) {
    return DSL.condition("range_contains_elem({0}, {1})", f1, val(e));
}
 
static <T extends Comparable<T>> Condition 
    rangeOverlaps(Field<Range<T>> f1, Range<T> f2) {
    return DSL.condition("range_overlaps({0}, {1})", f1, val(f2, f1.getDataType()));
}

However, he does not show any implementation of the lower/upper functions. How are these functions implemented?

Ideally, the end-goal would be to be able to do something like this, where the lower and upper bound of a column of ranges is retrieved:

val rangeMetadata = create.select(
         BigDecimalRange(
             max(upper(RANGE_PARAMETER.VALUE)),
             true,
             min(lower(RANGE_PARAMETER.VALUE)),
             true
         )
     )
     .from(RANGE_PARAMETER)
     .fetch()

Upvotes: 1

Views: 439

Answers (1)

Lukas Eder
Lukas Eder

Reputation: 221265

There isn't a big difference between defining your rangeOverlaps() and a lower() or upper() aggregate function, you can do it exactly the same way. In order to map that data directly into the BigDecimalRange type, you can use:

create.select(
          row(
              max(upper(RANGE_PARAMETER.VALUE)),
              min(lower(RANGE_PARAMETER.VALUE))
          ).mapping { u, l -> bigDecimalRange(u, true, l, true) }
      )
      .from(RANGE_PARAMETER)
      .fetch()

A note regarding:

My understanding is that these functions are not actually implemented in the jooq-postgres-extensions module and that I somehow have to implement this myself

There isn't a big reason why this shouldn't be done. It's just a task that hasn't been implemented yet. I've created an issue for this. Could be useful to support this out of the box: #13828

How to create a plain SQL templating Field<T>

Apparently, there seems to be a difficulty to going from the plain SQL templating Condition (which you already have) to a Field<T>, but it's just the same thing:

public static Field<BigDecimal> upper(Field<? extends BigDecimalRange> f) {
    return DSL.field("upper({0})", SQLDataType.NUMERIC, f);
}

See also:

Upvotes: 1

Related Questions