[#7171] Add support for UNNEST. Fix LATERAL

This commit is contained in:
lukaseder 2018-04-26 14:09:57 +02:00
parent 863ade3b3c
commit e0f958a219
3 changed files with 34 additions and 24 deletions

View File

@ -440,12 +440,12 @@ sortField = field [ 'ASC' | 'DESC' ] [ 'NULLS FIRST' | 'NULLS LAST' ]
tables = table { ',' table }
;
table = tableFactor { unqualifiedJoin | innerJoin | outerJoin | semiAntiJoin }
table = lateral { unqualifiedJoin | innerJoin | outerJoin | semiAntiJoin }
;
unqualifiedJoin =
( 'CROSS JOIN' | 'CROSS APPLY' | 'OUTER APPLY' | 'NATURAL' [ ( 'LEFT' | 'RIGHT' ) [ 'OUTER' ] ] 'JOIN' )
tableFactor
lateral
;
innerJoin =
@ -463,13 +463,18 @@ outerJoin =
semiAntiJoin = 'LEFT' ( 'SEMI' | 'ANTI' ) 'JOIN' table joinQualification
;
lateral =
'LATERAL' tableFactor
| tableFactor
;
tableFactor =
'LATERAL' '(' select ')' [ correlationName ]
| tableFunction [ correlationName ]
| '(' select ')' [ correlationName ]
| values [ correlationName ]
| tableName [ versions ] [ correlationName ] [ tableHints ]
tableName [ versions ] [ correlationName ] [ tableHints ]
| '(' table ')' [ correlationName ]
| '(' select ')' [ correlationName ]
| tableFunction [ correlationName ]
| 'UNNEST' '(' field ')'
| values [ correlationName ]
;
tableFunction =

View File

@ -8531,17 +8531,13 @@ public class DSL {
*/
@Support({ H2, HSQLDB, POSTGRES })
public static Table<?> unnest(Field<?> cursor) {
if (cursor == null) {
if (cursor == null)
throw new IllegalArgumentException();
}
// The field is an actual CURSOR or REF CURSOR returned from a stored
// procedure or from a NESTED TABLE
else if (cursor.getType() == Result.class) {
else if (cursor.getType() == Result.class)
return new org.jooq.impl.FunctionTable<Record>(cursor);
}
@ -8554,9 +8550,8 @@ public class DSL {
// The field is a regular array
else if (cursor.getType().isArray() && cursor.getType() != byte[].class) {
else if (cursor.getType().isArray() && cursor.getType() != byte[].class)
return new ArrayTable(cursor);
}
// The field has any other type. Try to make it an array
throw new SQLDialectNotSupportedException("Converting arbitrary types into array tables is currently not supported");

View File

@ -221,6 +221,7 @@ import static org.jooq.impl.DSL.translate;
import static org.jooq.impl.DSL.trim;
import static org.jooq.impl.DSL.trunc;
import static org.jooq.impl.DSL.unique;
import static org.jooq.impl.DSL.unnest;
import static org.jooq.impl.DSL.user;
import static org.jooq.impl.DSL.values;
import static org.jooq.impl.DSL.varPop;
@ -3385,7 +3386,7 @@ final class ParserImpl implements Parser {
}
private static final Table<?> parseTable(ParserContext ctx) {
Table<?> result = parseTableFactor(ctx);
Table<?> result = parseLateral(ctx);
for (;;) {
Table<?> joined = parseJoinedTableIf(ctx, result);
@ -3396,20 +3397,29 @@ final class ParserImpl implements Parser {
}
}
private static final Table<?> parseLateral(ParserContext ctx) {
if (parseKeywordIf(ctx, "LATERAL"))
return lateral(parseTableFactor(ctx));
else
return parseTableFactor(ctx);
}
private static final Table<?> parseTableFactor(ParserContext ctx) {
Table<?> result = null;
// TODO [#5306] Support FINAL TABLE (<data change statement>)
// TOOD ONLY ( table primary )
if (parseKeywordIf(ctx, "LATERAL")) {
if (parseFunctionNameIf(ctx, "UNNEST")) {
parse(ctx, '(');
result = lateral(parseSelect(ctx));
Field<?> f = parseField(ctx, Type.A);
// Work around a missing feature in unnest()
if (!f.getType().isArray())
f = f.coerce(f.getDataType().getArrayDataType());
result = unnest(f);
parse(ctx, ')');
}
else if (parseFunctionNameIf(ctx, "UNNEST")) {
// TODO
throw ctx.notImplemented("UNNEST");
}
else if (parseFunctionNameIf(ctx, "GENERATE_SERIES")) {
parse(ctx, '(');
Field from = toField(ctx, parseConcat(ctx, Type.N));
@ -3693,7 +3703,7 @@ final class ParserImpl implements Parser {
}
private static final Table<?> parseJoinedTable(ParserContext ctx) {
Table<?> result = parseTableFactor(ctx);
Table<?> result = parseLateral(ctx);
for (;;) {
Table<?> joined = parseJoinedTableIf(ctx, result);
@ -3711,7 +3721,7 @@ final class ParserImpl implements Parser {
if (joinType == null)
return null;
Table<?> right = joinType.qualified() ? parseTable(ctx) : parseTableFactor(ctx);
Table<?> right = joinType.qualified() ? parseTable(ctx) : parseLateral(ctx);
TableOptionalOnStep<?> s0;
TablePartitionByStep<?> s1;