diff --git a/jOOQ-manual/src/main/resources/org/jooq/web/grammar-3.12.txt b/jOOQ-manual/src/main/resources/org/jooq/web/grammar-3.12.txt index 0886fcbd2f..3a46d77a84 100644 --- a/jOOQ-manual/src/main/resources/org/jooq/web/grammar-3.12.txt +++ b/jOOQ-manual/src/main/resources/org/jooq/web/grammar-3.12.txt @@ -476,8 +476,12 @@ tables = table { ',' table } table = lateral { unqualifiedJoin | innerJoin | outerJoin | semiAntiJoin } ; +optionallyQualifiedJoin = 'CROSS JOIN' +( table joinQualification | lateral ) +; + unqualifiedJoin = -( 'CROSS JOIN' | 'CROSS APPLY' | 'OUTER APPLY' | 'NATURAL' [ ( 'LEFT' | 'RIGHT' ) [ 'OUTER' ] ] 'JOIN' ) +( 'CROSS APPLY' | 'OUTER APPLY' | 'NATURAL' [ ( 'LEFT' | 'RIGHT' | 'FULL' ) [ 'OUTER' ] ] 'JOIN' ) lateral ; diff --git a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java index d807dd93a6..c2bb6dff25 100644 --- a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java @@ -4132,24 +4132,34 @@ final class ParserImpl implements Parser { case STRAIGHT_JOIN: case LEFT_SEMI_JOIN: case LEFT_ANTI_JOIN: - if (parseKeywordIf(ctx, "ON")) { + if (parseKeywordIf(ctx, "ON")) return s2.on(parseCondition(ctx)); - } - else if (parseKeywordIf(ctx, "USING")) { - parse(ctx, '('); - Table result = s2.using(Tools.fieldsByName(parseIdentifiers(ctx).toArray(EMPTY_NAME))); - parse(ctx, ')'); - - return result; - } + else if (parseKeywordIf(ctx, "USING")) + return parseJoinUsing(ctx, s2); else throw ctx.expected("ON", "USING"); + case CROSS_JOIN: + if (parseKeywordIf(ctx, "ON")) + return left.join(right).on(parseCondition(ctx)); + else if (parseKeywordIf(ctx, "USING")) + return parseJoinUsing(ctx, left.join(right)); + + // No break + default: return s0; } } + private static final Table parseJoinUsing(ParserContext ctx, TableOnStep join) { + parse(ctx, '('); + Table result = join.using(Tools.fieldsByName(parseIdentifiers(ctx).toArray(EMPTY_NAME))); + parse(ctx, ')'); + + return result; + } + private static final List parseSelectList(ParserContext ctx) { List result = new ArrayList();