postgresqljdbcjooq

jOOQ fails to parse EXPLAIN ANALYZE with parsing connection


I'm using jOOQ with a parsing connection (withParseDialect(...) and other .withParse...() settings) to log and transform SQL statements.

My connection is initialized with custom Settings as shown here:

private Settings createSettings() {
    return new Settings()
        .withParseDialect(SQLDialect.ORACLE)
        .withParseUnknownFunctions(ParseUnknownFunctions.IGNORE)
        .withTransformTableListsToAnsiJoin(true)
        .withTransformUnneededArithmeticExpressions(TransformUnneededArithmeticExpressions.ALWAYS)
        .withTransformRownum(Transformation.ALWAYS)
        .withRenderQuotedNames(RenderQuotedNames.EXPLICIT_DEFAULT_UNQUOTED)
        .withRenderCoalesceToEmptyStringInConcat(true)
        .withRenderOptionalAsKeywordForFieldAliases(RenderOptionalKeyword.ON)
        .withRenderOptionalAsKeywordForTableAliases(RenderOptionalKeyword.ON)
        .withRenderNameCase(RenderNameCase.UPPER)
        .withBatchSize(500); // Custom batch size
}

When I try to run and parse a query like:

EXPLAIN ANALYZE SELECT * FROM employees WHERE active_emp = 1;

When I try to parse the query with JOOQ (e.g., for introspection purposes), I get a parsing error: org.jooq.ParserException: Unsupported syntax: EXPLAIN

I’m not using DSLContext.fetch() here — just plain JDBC with a connection initialized with parsing Settings.

Stack:

Question:

Is there a way to support or skip EXPLAIN ANALYZE in a parsing setup like this? Or should I bypass jOOQ parsing for such statements?

Thanks!


Solution

  • You can use the ParseListener SPI to intercept parse calls, e.g. like this:

    ParseListener.onParseStart(ctx -> {
        if (ctx.parseKeywordIf("EXPLAIN ANALYZE")) {
            // Do something with this...
        }
    });
    

    Alternatively, just patch the query string prior to sending it to jOOQ's parser, or delimit sections that jOOQ should ignore with the ignore comments. From the documentation:

    -- jOOQ doesn't see this
    /* [jooq ignore start] */
    CREATE SCHEMA s1;
    SET SCHEMA s1;
    /* [jooq ignore stop] */
    
    -- ... but only this:
    CREATE TABLE t (i INTEGER);