Torc
Torc

Reputation: 1312

jOOQ Dynamic WITH Clause

I am unable to find documentation on how to dynamically construct WITH Clauses (i.e. Common Table Expressions / CTEs) in jOOQ. My use case is this :

I am attempting to use the following, with no luck:

    SelectQuery<Record> query =
        getQuery(
            dslContext,
            selectFields,
            fromClause,
            groupFields,
            conditionClause,
            orderFields,
            query.getOffset(),
            query.getLimit());

    // WORKS JUST FINE
    Supplier<Stream<Map<String, Object>>> results = () ->
        query
            .fetchStream()
            .map(Record::intoMap);

    // make a nested query here. static for now.
    // DOES NOT WORK
    Supplier<Stream<Map<String, Object>>> resultsWith =
        () ->
            DSL.with("s1")
                .as(query) // Shouldn't I be able to reference a SelectQuery here?
                .select()
                .from(table(name("s1")))
                .fetchStream()
                .map(Record::intoMap);

query.toString() looks something like this:

select 
  table1.field1,
  coalesce( 
    table1.id, 
    table2.id) as table1.id_table2.id, 
  count(*) as table2.field1.count, 
  sum(table2.field2) as table2.field2.sum
  from table1.table1 as table1
  full outer join table2.table2 as table2
  on table1.id = table2.id
  where table1.field2 < 3000.0
  group by 
  table1.id_table2.id,
  table1.field1
  order by table1.field1 asc
  limit 100

What I would like to do at a minimum is to reference the coalesced field above in additional downstream queries. Ideally I would not be limited at all in the manner or number of dynamic references I could make when constructing a WITH clause in jOOQ. In the end, I want to be able to dynamically create queries such as these, which show CTEs referencing CTEs too :

-- WITH Clause usage is preferrable
with
  myFirstSelection as (
    select
      (id + 100) as newfield
    from table1.table1 n
  ),
  mySecondSelection as (
    select
      (newField + 200) as newerField
    from myFirstSelection
  )
select
* 
from mySecondSelection
;

-- Inline queries, while not ideal, would be permissible
select 
* 
from (
  select
  (newField + 200) as newerField
  from (
    select
      (id + 100) as newField
    from table1.table1 n
  ) as myFirstSelection
) as mySecondSelection
;

Would that even be possible? Or am I limited to static tables and static selections?


LINKS

stackoverflow

jOOQ Website

GitHub

jOOQ Google Group

Upvotes: 2

Views: 1409

Answers (1)

Torc
Torc

Reputation: 1312

The issue turned out to be an issue with Jackson deserialization in a property in my JSON payload which gets turned into my query. I was getting a NullPointerException when one of the properties was getting converted into a part of the query class. With regards to jOOQ, this example works fine. As an addition, this is a testing query which sums the first field by referencing relative position in the result-set :

    /* Output looks like this : 
    +-----------------+
    |sum_of_everything|
    +-----------------+
    |              100|
    +-----------------+
     */

    Supplier<Stream<Map<String, Object>>> resultsWith =
        () ->
            dslContext
                .with("s1")
                .as(query)
                .select(sum(field("1", Integer.class)).as("sum_of_everything"))
                .from(table(name("s1")))
                .fetchStream()
                .map(Record::intoMap);

This supplier can be returned as a response in a RESTful framework to stream results back to the requestor.

Upvotes: 1

Related Questions