From 1bef9d479165a78fca5f798bb071b26189fbc4c8 Mon Sep 17 00:00:00 2001 From: lukaseder Date: Mon, 17 Apr 2017 17:45:12 +0200 Subject: [PATCH] [#5955] Oracle doubly parenthesised ROW expressions --- .../main/java/org/jooq/impl/ParserImpl.java | 70 ++++++++++++++++--- 1 file changed, 62 insertions(+), 8 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java index a18c29d0ea..059b16276a 100644 --- a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java @@ -2013,7 +2013,23 @@ class ParserImpl implements Parser { private static final RowN parseTuple(ParserContext ctx, Integer degree, boolean allowDoubleParens) { parse(ctx, '('); - RowN row = row(parseFields(ctx)); + List fieldsOrRows; + + if (allowDoubleParens) + fieldsOrRows = parseFieldsOrRows(ctx); + else + fieldsOrRows = parseFields(ctx); + + RowN row; + + if (fieldsOrRows.size() == 0) + row = row(); + else if (fieldsOrRows.get(0) instanceof Field) + row = row(fieldsOrRows); + else if (fieldsOrRows.size() == 1) + row = (RowN) fieldsOrRows.get(0); + else + throw ctx.exception(); if (degree != null && row.size() != degree) throw ctx.exception(); @@ -2135,10 +2151,25 @@ class ParserImpl implements Parser { return result; } + private static final List parseFieldsOrRows(ParserContext ctx) { + parseWhitespaceIf(ctx); + + List result = new ArrayList(); + do { + result.add(parseFieldOrRow(ctx)); + } + while (parseIf(ctx, ',')); + return result; + } + private static final Field parseField(ParserContext ctx) { return parseField(ctx, null); } + private static final FieldOrRow parseFieldOrRow(ParserContext ctx) { + return parseFieldOrRow(ctx, null); + } + private static final RowN parseRow(ParserContext ctx) { return parseRow(ctx, null); } @@ -2189,6 +2220,13 @@ class ParserImpl implements Parser { } } + private static final FieldOrRow parseFieldOrRow(ParserContext ctx, Type type) { + if (B.is(type)) + return toFieldOrRow(ctx, parseOr(ctx)); + else + return parseConcat(ctx, type); + } + private static final Field parseField(ParserContext ctx, Type type) { if (B.is(type)) return toField(ctx, parseOr(ctx)); @@ -2210,6 +2248,19 @@ class ParserImpl implements Parser { throw ctx.exception(); } + private static final FieldOrRow toFieldOrRow(ParserContext ctx, QueryPart part) { + if (part == null) + return null; + else if (part instanceof Field) + return (Field) part; + else if (part instanceof Condition) + return field((Condition) part); + else if (part instanceof Row) + return (Row) part; + else + throw ctx.exception(); + } + private static final Field toField(ParserContext ctx, QueryPart part) { if (part == null) return null; @@ -2672,16 +2723,19 @@ class ParserImpl implements Parser { return field; } else { - Field r = parseField(ctx, type); + FieldOrRow r = parseFieldOrRow(ctx, type); List> list = null; - while (parseIf(ctx, ',')) { - if (list == null) { - list = new ArrayList>(); - list.add(r); - } + if (r instanceof Field) { + while (parseIf(ctx, ',')) { + if (list == null) { + list = new ArrayList>(); + list.add((Field) r); + } - list.add(parseField(ctx, type)); + // TODO Allow for nesting ROWs + list.add(parseField(ctx, type)); + } } parse(ctx, ')');