I'm using jOOQ to generate queries to run against Athena (AKA PrestoDB/Trino)
To do this, I am using SQLDialects.DEFAULT
, and it works because I use very basic query functionalities.
However, jOOQ renders queries like this:
select *
from "Artist"
limit 10
offset 10
God knows why, but the order of limit
and offset
seem to matter, and the query only works if written with the order swapped:
select *
from "Artist"
offset 10
limit 10
Is there a class I can subclass, to modify the statement render function so that the order of these are swapped? Or any other way of implementing this myself?
There isn't a simple way to change something as fundamental as the SELECT
clause order (or any other SELECT
clause syntax) so easily in jOOQ, simply, because this was never a requirement for core jOOQ usage, other than supporting fringe SQL dialects. Since the support of a SQL dialect is a lot of work in jOOQ (with all the integration tests, edge cases, etc.) and since market shares of those dialects are low, it has simply never been a priority to improve this in jOOQ.
You may be tempted to think that this is "just" about the order of keywords in this one case. "Only this one case." It never is. It never stops, and the subtle differences in dialects never end. Just look at the jOOQ code base to get an idea of how weirdly different vendors choose to make their dialects. In this particular case, one would think that it seems extremely obvious and simple to make this clause MySQL / PostgreSQL / SQLite compatible, so your best chance is to make a case with the vendor for a feature request. It should be in their own best interest to be more compatible with the market leaders, to facilitate migration.
ExecuteListener
and a simple regex. Whenever you encounter limit (\d+|\?) offset (\d+|\?)
, just swap the values (and bind values!). This might work reasonably well for top level selects. It's obviously harder if you're using LIMIT .. OFFSET
in nested selects, but probably still doable.org.jooq.impl.Limit
. It contains all the rendering logic for this clause. If that's your only patch, then it might be possible to upgrade jOOQ. But obviously, patching is a slippery slope, as you may start patching all sorts of clauses, making upgrades impossible.resultQuery("{0} offset {1} limit {2}", actualSelect, val(10), val(10))
. This doesn't scale well, but if it's only about 1-2 queries, it might sufficeSQLDialect.DEFAULT
I must warn you, at this point, that the behaviour of SQLDialect.DEFAULT
is unspecified. Its main purpose is to produce something when you call QueryPart.toString()
on a QueryPart
that is not an Attachable
, where a better SQLDialect
is unavailable. The DEFAULT
dialect may change between minor releases (or even patch releases, if there's an important bug in some toString()
method), so any implementation you base on this is at risk of breaking with every upgrade.
... would be to have support for these dialects in jOOQ: