diff --git a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java index 9330c8c3f6..8a0e763122 100644 --- a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java @@ -1924,7 +1924,7 @@ final class DefaultParseContext extends AbstractScope implements ParseContext { result.addGroupBy(groupingSets(fieldSets.toArray((Collection[]) EMPTY_COLLECTION))); } else { - groupBy = parseList(',', c -> c.parseField()); + groupBy = parseOrdinaryGroupingSets(); if (parseKeywordIf("WITH ROLLUP")) result.addGroupBy(rollup(groupBy.toArray(EMPTY_FIELD))); @@ -1938,6 +1938,30 @@ final class DefaultParseContext extends AbstractScope implements ParseContext { return false; } + private final List parseOrdinaryGroupingSets() { + List result = new ArrayList<>(); + + do { + + // [#14159] Explicit ROW expressions are actual RowAsFields. + // Other parenthesised expressions are grouping column reference lists + if (peekKeyword("ROW")) { + result.add(parseField()); + } + else { + FieldOrRow fr = parseFieldOrRow(); + + if (fr instanceof Field f) + result.add(f); + else + result.addAll(asList(((Row) fr).fields())); + } + } + while (parseIf(',')); + + return result; + } + private final boolean parseQueryPrimaryConnectBy(SelectQueryImpl result) { if (!ignoreProEdition() && parseKeywordIf("CONNECT BY") && requireProEdition()) {