Skip to content

Commit

Permalink
[#10699] Parser cannot parse set operations combining SELECT * with S…
Browse files Browse the repository at this point in the history
…ELECT <column list>
  • Loading branch information
lukaseder committed Nov 18, 2020
1 parent 976b359 commit cbbe5e9
Showing 1 changed file with 29 additions and 13 deletions.
42 changes: 29 additions & 13 deletions jOOQ/src/main/java/org/jooq/impl/ParserImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -1352,61 +1352,77 @@ else if (!offsetStandard && !offsetPostgres && parseKeywordIf(ctx, "ROWS")) {
}

private static final SelectQueryImpl<Record> parseQueryExpressionBody(ParserContext ctx, Integer degree, WithImpl with, SelectQueryImpl<Record> prefix) {
SelectQueryImpl<Record> result = parseQueryTerm(ctx, degree, with, prefix);
SelectQueryImpl<Record> lhs = parseQueryTerm(ctx, degree, with, prefix);

CombineOperator combine;
while ((combine = parseCombineOperatorIf(ctx, false)) != null) {
ctx.scopeEnd();
ctx.scopeStart();

if (degree == null)
degree = Tools.degree(result);
degree = Tools.degree(lhs);

SelectQueryImpl<Record> rhs = degreeCheck(ctx, degree, parseQueryTerm(ctx, degree, null, null));
switch (combine) {
case UNION:
result = (SelectQueryImpl<Record>) result.union(parseQueryTerm(ctx, degree, null, null));
lhs = (SelectQueryImpl<Record>) lhs.union(rhs);
break;
case UNION_ALL:
result = (SelectQueryImpl<Record>) result.unionAll(parseQueryTerm(ctx, degree, null, null));
lhs = (SelectQueryImpl<Record>) lhs.unionAll(rhs);
break;
case EXCEPT:
result = (SelectQueryImpl<Record>) result.except(parseQueryTerm(ctx, degree, null, null));
lhs = (SelectQueryImpl<Record>) lhs.except(rhs);
break;
case EXCEPT_ALL:
result = (SelectQueryImpl<Record>) result.exceptAll(parseQueryTerm(ctx, degree, null, null));
lhs = (SelectQueryImpl<Record>) lhs.exceptAll(rhs);
break;
default:
throw ctx.internalError();
}
}

return result;
return lhs;
}

private static final SelectQueryImpl<Record> parseQueryTerm(ParserContext ctx, Integer degree, WithImpl with, SelectQueryImpl<Record> prefix) {
SelectQueryImpl<Record> result = prefix != null ? prefix : parseQueryPrimary(ctx, degree, with);
SelectQueryImpl<Record> lhs = prefix != null ? prefix : parseQueryPrimary(ctx, degree, with);

CombineOperator combine;
while ((combine = parseCombineOperatorIf(ctx, true)) != null) {
ctx.scopeEnd();
ctx.scopeStart();

if (degree == null)
degree = Tools.degree(result);
degree = Tools.degree(lhs);

SelectQueryImpl<Record> rhs = degreeCheck(ctx, degree, parseQueryPrimary(ctx, degree, null));
switch (combine) {
case INTERSECT:
result = (SelectQueryImpl<Record>) result.intersect(parseQueryPrimary(ctx, degree, null));
lhs = (SelectQueryImpl<Record>) lhs.intersect(rhs);
break;
case INTERSECT_ALL:
result = (SelectQueryImpl<Record>) result.intersectAll(parseQueryPrimary(ctx, degree, null));
lhs = (SelectQueryImpl<Record>) lhs.intersectAll(rhs);
break;
default:
throw ctx.internalError();
}
}

return result;
return lhs;
}

private static SelectQueryImpl<Record> degreeCheck(ParserContext ctx, int expected, SelectQueryImpl<Record> 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<Record> parseQueryPrimary(ParserContext ctx, Integer degree, WithImpl with) {
Expand Down Expand Up @@ -1467,7 +1483,7 @@ else if (parseKeywordIf(ctx, "FIRST")) {
List<SelectFieldOrAsterisk> 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;
Expand Down

0 comments on commit cbbe5e9

Please sign in to comment.