Skip to content

Commit

Permalink
[#5955] Add support for WITH
Browse files Browse the repository at this point in the history
  • Loading branch information
lukaseder committed Mar 25, 2017
1 parent cb3375f commit 06736f4
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 19 deletions.
54 changes: 51 additions & 3 deletions jOOQ/src/main/java/org/jooq/impl/ParserImpl.java
Expand Up @@ -195,6 +195,7 @@
import static org.jooq.impl.ParserImpl.Type.N;
import static org.jooq.impl.ParserImpl.Type.S;
import static org.jooq.impl.Tools.EMPTY_COLLECTION;
import static org.jooq.impl.Tools.EMPTY_COMMON_TABLE_EXPRESSION;
import static org.jooq.impl.Tools.EMPTY_FIELD;
import static org.jooq.impl.Tools.EMPTY_NAME;

Expand Down Expand Up @@ -224,6 +225,7 @@
import org.jooq.CaseConditionStep;
import org.jooq.CaseValueStep;
import org.jooq.CaseWhenStep;
import org.jooq.CommonTableExpression;
import org.jooq.Comparator;
import org.jooq.Condition;
import org.jooq.Configuration;
Expand All @@ -243,6 +245,7 @@
import org.jooq.Delete;
import org.jooq.DeleteFinalStep;
import org.jooq.DeleteWhereStep;
import org.jooq.DerivedColumnList;
import org.jooq.DropIndexFinalStep;
import org.jooq.DropIndexOnStep;
import org.jooq.DropSchemaFinalStep;
Expand Down Expand Up @@ -453,6 +456,13 @@ else if (peekKeyword(ctx, "DROP"))

break;

case 'w':
case 'W':
if (peekKeyword(ctx, "WITH"))
return parseWith(ctx);

break;

case '(':
// TODO are there other possible statement types?
return parseSelect(ctx);
Expand All @@ -473,8 +483,42 @@ else if (peekKeyword(ctx, "DROP"))
// Statement parsing
// -----------------------------------------------------------------------------------------------------------------

private static final Query parseWith(ParserContext ctx) {
parseKeyword(ctx, "WITH");

List<CommonTableExpression<?>> cte = new ArrayList<CommonTableExpression<?>>();
do {

Name table = parseIdentifier(ctx);

// [#6022] Allow unquoted identifiers for columns
parse(ctx, '(');
List<Name> columnNames = parseIdentifiers(ctx);
String[] columns = new String[columnNames.size()];
for (int i = 0; i < columns.length; i++)
columns[i] = columnNames.get(i).last();
parse(ctx, ')');

DerivedColumnList dcl = table.fields(columns);
parseKeyword(ctx, "AS");
parse(ctx, '(');
cte.add(dcl.as(parseSelect(ctx)));
parse(ctx, ')');
}
while (parseIf(ctx, ','));

// TODO Better model API for WITH clause
return parseSelect(ctx, (WithImpl) new WithImpl(ctx.dsl.configuration(), false).with(cte.toArray(EMPTY_COMMON_TABLE_EXPRESSION)));

// TODO Other statements than SELECT
}

private static final SelectQueryImpl<Record> parseSelect(ParserContext ctx) {
SelectQueryImpl<Record> result = parseQueryPrimary(ctx);
return parseSelect(ctx, null);
}

private static final SelectQueryImpl<Record> parseSelect(ParserContext ctx, WithImpl with) {
SelectQueryImpl<Record> result = parseQueryPrimary(ctx, with);
CombineOperator combine;
while ((combine = parseCombineOperatorIf(ctx)) != null) {
switch (combine) {
Expand Down Expand Up @@ -577,8 +621,12 @@ else if (parseKeywordIf(ctx, "SKIP LOCKED"))
}

private static final SelectQueryImpl<Record> parseQueryPrimary(ParserContext ctx) {
return parseQueryPrimary(ctx, null);
}

private static final SelectQueryImpl<Record> parseQueryPrimary(ParserContext ctx, WithImpl with) {
if (parseIf(ctx, '(')) {
SelectQueryImpl<Record> result = parseSelect(ctx);
SelectQueryImpl<Record> result = parseSelect(ctx, with);
parse(ctx, ')');
return result;
}
Expand Down Expand Up @@ -689,7 +737,7 @@ else if (parseKeywordIf(ctx, "GROUPING SETS")) {

// TODO support WINDOW

SelectQueryImpl<Record> result = (SelectQueryImpl<Record>) ctx.dsl.selectQuery();
SelectQueryImpl<Record> result = new SelectQueryImpl<Record>(ctx.dsl.configuration(), with);
if (distinct)
result.setDistinct(distinct);

Expand Down
34 changes: 18 additions & 16 deletions jOOQ/src/main/java/org/jooq/impl/Tools.java
Expand Up @@ -123,6 +123,7 @@
import org.jooq.BindContext;
import org.jooq.Catalog;
import org.jooq.Clause;
import org.jooq.CommonTableExpression;
import org.jooq.Condition;
import org.jooq.Configuration;
import org.jooq.Context;
Expand Down Expand Up @@ -178,27 +179,28 @@
*/
final class Tools {

static final JooqLogger log = JooqLogger.getLogger(Tools.class);
static final JooqLogger log = JooqLogger.getLogger(Tools.class);

// ------------------------------------------------------------------------
// Empty arrays for use with Collection.toArray()
// ------------------------------------------------------------------------

static final Class<?>[] EMPTY_CLASS = {};
static final Clause[] EMPTY_CLAUSE = {};
static final Collection<?>[] EMPTY_COLLECTION = {};
static final ExecuteListener[] EMPTY_EXECUTE_LISTENER = {};
static final Field<?>[] EMPTY_FIELD = {};
static final int[] EMPTY_INT = {};
static final Param<?>[] EMPTY_PARAM = {};
static final Query[] EMPTY_QUERY = {};
static final QueryPart[] EMPTY_QUERYPART = {};
static final Record[] EMPTY_RECORD = {};
static final RowN[] EMPTY_ROWN = {};
static final String[] EMPTY_STRING = {};
static final Name[] EMPTY_NAME = {};
static final TableRecord<?>[] EMPTY_TABLE_RECORD = {};
static final UpdatableRecord<?>[] EMPTY_UPDATABLE_RECORD = {};
static final Class<?>[] EMPTY_CLASS = {};
static final Clause[] EMPTY_CLAUSE = {};
static final Collection<?>[] EMPTY_COLLECTION = {};
static final ExecuteListener[] EMPTY_EXECUTE_LISTENER = {};
static final Field<?>[] EMPTY_FIELD = {};
static final int[] EMPTY_INT = {};
static final Param<?>[] EMPTY_PARAM = {};
static final Query[] EMPTY_QUERY = {};
static final QueryPart[] EMPTY_QUERYPART = {};
static final Record[] EMPTY_RECORD = {};
static final RowN[] EMPTY_ROWN = {};
static final CommonTableExpression<?>[] EMPTY_COMMON_TABLE_EXPRESSION = {};
static final String[] EMPTY_STRING = {};
static final Name[] EMPTY_NAME = {};
static final TableRecord<?>[] EMPTY_TABLE_RECORD = {};
static final UpdatableRecord<?>[] EMPTY_UPDATABLE_RECORD = {};

// ------------------------------------------------------------------------
// Some constants for use with Context.data()
Expand Down

0 comments on commit 06736f4

Please sign in to comment.