diff --git a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java index d924c50735..555d749e53 100644 --- a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java @@ -1353,7 +1353,7 @@ final class ParserImpl implements Parser { } private static final SelectQueryImpl parseQueryExpressionBody(ParserContext ctx, Integer degree, WithImpl with, SelectQueryImpl prefix) { - SelectQueryImpl result = parseQueryTerm(ctx, degree, with, prefix); + SelectQueryImpl lhs = parseQueryTerm(ctx, degree, with, prefix); CombineOperator combine; while ((combine = parseCombineOperatorIf(ctx, false)) != null) { @@ -1361,31 +1361,32 @@ final class ParserImpl implements Parser { ctx.scopeStart(); if (degree == null) - degree = Tools.degree(result); + degree = Tools.degree(lhs); + SelectQueryImpl rhs = degreeCheck(ctx, degree, parseQueryTerm(ctx, degree, null, null)); switch (combine) { case UNION: - result = (SelectQueryImpl) result.union(parseQueryTerm(ctx, degree, null, null)); + lhs = (SelectQueryImpl) lhs.union(rhs); break; case UNION_ALL: - result = (SelectQueryImpl) result.unionAll(parseQueryTerm(ctx, degree, null, null)); + lhs = (SelectQueryImpl) lhs.unionAll(rhs); break; case EXCEPT: - result = (SelectQueryImpl) result.except(parseQueryTerm(ctx, degree, null, null)); + lhs = (SelectQueryImpl) lhs.except(rhs); break; case EXCEPT_ALL: - result = (SelectQueryImpl) result.exceptAll(parseQueryTerm(ctx, degree, null, null)); + lhs = (SelectQueryImpl) lhs.exceptAll(rhs); break; default: throw ctx.internalError(); } } - return result; + return lhs; } private static final SelectQueryImpl parseQueryTerm(ParserContext ctx, Integer degree, WithImpl with, SelectQueryImpl prefix) { - SelectQueryImpl result = prefix != null ? prefix : parseQueryPrimary(ctx, degree, with); + SelectQueryImpl lhs = prefix != null ? prefix : parseQueryPrimary(ctx, degree, with); CombineOperator combine; while ((combine = parseCombineOperatorIf(ctx, true)) != null) { @@ -1393,21 +1394,36 @@ final class ParserImpl implements Parser { ctx.scopeStart(); if (degree == null) - degree = Tools.degree(result); + degree = Tools.degree(lhs); + SelectQueryImpl rhs = degreeCheck(ctx, degree, parseQueryPrimary(ctx, degree, null)); switch (combine) { case INTERSECT: - result = (SelectQueryImpl) result.intersect(parseQueryPrimary(ctx, degree, null)); + lhs = (SelectQueryImpl) lhs.intersect(rhs); break; case INTERSECT_ALL: - result = (SelectQueryImpl) result.intersectAll(parseQueryPrimary(ctx, degree, null)); + lhs = (SelectQueryImpl) lhs.intersectAll(rhs); break; default: throw ctx.internalError(); } } - return result; + return lhs; + } + + private static SelectQueryImpl degreeCheck(ParserContext ctx, int expected, SelectQueryImpl s) { + if (expected == 0) + return s; + + int actual = Tools.degree(s); + if (actual == 0) + return s; + + if (expected != actual) + throw ctx.exception("Select list must contain " + expected + " columns. Got: " + actual); + + return s; } private static final SelectQueryImpl parseQueryPrimary(ParserContext ctx, Integer degree, WithImpl with) { @@ -1468,7 +1484,7 @@ final class ParserImpl implements Parser { List select = parseSelectList(ctx); degreeCheck: - if (degree != null && select.size() != degree) { + if (degree != null && !degree.equals(0) && !degree.equals(select.size())) { for (SelectFieldOrAsterisk s : select) if (!(s instanceof Field)) break degreeCheck;