How to return an array of JSON objects rather the a collection of rows using JOOQ & PostgreSQL

SQL Server FOR JSON semantics

That's precisely what the SQL Server FOR JSON clause does, which jOOQ supports and which it can emulate for you on other dialects as well:

ctx.select(T.A, T.B)
   .from(T)
   .forJSON().path()
   .fetch();

PostgreSQL native functionality

If you prefer using native functions directly, you will have to do with plain SQL templating for now, as some of these functions aren't yet supported by jOOQ, including:

  • JSONB_PRETTY (no plans of supporting it yet)
  • ARRAY_TO_JSON (https://github.com/jOOQ/jOOQ/issues/12841)
  • ROW_TO_JSON (https://github.com/jOOQ/jOOQ/issues/10685)

It seems quite simple to write a utility that does precisely this:

public static ResultQuery<Record1<JSONB>> json(Select<?> subquery) {
    return ctx
        .select(field(
            "jsonb_pretty(array_to_json(array_agg(row_to_json(r)))::jsonb)", 
            JSONB.class
         ))
        .from(subquery.asTable("r"))
}

And now, you can execute any query in your desired form:

JSONB result = ctx.fetchValue(json(select(T.A, T.B).from(T)));

Converting between PG arrays and JSON arrays

A note on performance. It seems that you're converting between data types a bit often. Specifically, I'd suggest you avoid aggregating a PostgreSQL array and turning that into a JSON array, but to use JSONB_AGG() directly. I haven't tested this, but it seems to me that the extra data structure seems unnecessary.