[jOOQ/jOOQ#11587] Fix ordering of TOP_LEVEL_CTE

This commit is contained in:
Lukas Eder 2021-03-08 22:54:57 +01:00
parent 0203c6f67c
commit 08f98dc81a
5 changed files with 23 additions and 15 deletions

View File

@ -67,6 +67,7 @@ import static org.jooq.SQLDialect.POSTGRES;
// ...
// ...
import static org.jooq.conf.SettingsTools.renderLocale;
import static org.jooq.impl.CommonTableExpressionList.markTopLevelCteAndAccept;
import static org.jooq.impl.DSL.name;
import static org.jooq.impl.DSL.select;
import static org.jooq.impl.DSL.unquotedName;
@ -348,10 +349,7 @@ abstract class AbstractDMLQuery<R extends Record> extends AbstractRowCountQuery
if (w != null)
ctx.visit(w);
else
ctx.scopeMarkStart(TOP_LEVEL_CTE.beforeFirst)
.scopeMarkEnd(TOP_LEVEL_CTE.beforeFirst)
.scopeMarkStart(TOP_LEVEL_CTE.afterLast)
.scopeMarkEnd(TOP_LEVEL_CTE.afterLast);
markTopLevelCteAndAccept(ctx, c -> {});
boolean previousDeclareFields = ctx.declareFields();

View File

@ -39,6 +39,8 @@ package org.jooq.impl;
import static org.jooq.impl.ScopeMarker.TOP_LEVEL_CTE;
import java.util.function.Consumer;
import org.jooq.CommonTableExpression;
import org.jooq.Context;
@ -56,11 +58,15 @@ final class CommonTableExpressionList extends QueryPartList<CommonTableExpressio
@Override
public void accept(Context<?> ctx) {
markTopLevelCteAndAccept(ctx, c -> super.accept(c));
}
static void markTopLevelCteAndAccept(Context<?> ctx, Consumer<? super Context<?>> consumer) {
if (ctx.subqueryLevel() == 0)
ctx.scopeMarkStart(TOP_LEVEL_CTE.beforeFirst)
.scopeMarkEnd(TOP_LEVEL_CTE.beforeFirst);
super.accept(ctx);
consumer.accept(ctx);
if (ctx.subqueryLevel() == 0)
ctx.scopeMarkStart(TOP_LEVEL_CTE.afterLast)

View File

@ -130,7 +130,10 @@ enum ScopeMarker {
ctx.sql(' ');
}
// [#11587] Recurse to allow for deeply nested CTE
ctx.scopeStart().data(DATA_TOP_LEVEL_CTE, new TopLevelCte());
ctx.declareCTE(true).visit(cte).declareCTE(false);
ctx.scopeEnd();
if (noWith) {
if (single)

View File

@ -102,7 +102,6 @@ import static org.jooq.SQLDialect.SQLITE;
// ...
// ...
// ...
// ...
import static org.jooq.SortOrder.DESC;
import static org.jooq.conf.ParamType.INLINED;
import static org.jooq.impl.AsteriskImpl.SUPPORT_NATIVE_EXCEPT;
@ -112,6 +111,7 @@ import static org.jooq.impl.CombineOperator.INTERSECT;
import static org.jooq.impl.CombineOperator.INTERSECT_ALL;
import static org.jooq.impl.CombineOperator.UNION;
import static org.jooq.impl.CombineOperator.UNION_ALL;
import static org.jooq.impl.CommonTableExpressionList.markTopLevelCteAndAccept;
import static org.jooq.impl.DSL.asterisk;
import static org.jooq.impl.DSL.createTable;
import static org.jooq.impl.DSL.falseCondition;
@ -166,7 +166,6 @@ import static org.jooq.impl.SQLDataType.JSON;
import static org.jooq.impl.SQLDataType.JSONB;
import static org.jooq.impl.SQLDataType.VARCHAR;
import static org.jooq.impl.SQLDataType.XML;
import static org.jooq.impl.ScopeMarker.TOP_LEVEL_CTE;
import static org.jooq.impl.Tools.EMPTY_FIELD;
import static org.jooq.impl.Tools.EMPTY_SORTFIELD;
import static org.jooq.impl.Tools.fieldArray;
@ -251,7 +250,6 @@ import org.jooq.TablePartitionByStep;
// ...
import org.jooq.WindowDefinition;
import org.jooq.XML;
import org.jooq.conf.ParamType;
import org.jooq.exception.DataAccessException;
import org.jooq.impl.ForLock.ForLockMode;
import org.jooq.impl.ForLock.ForLockWaitMode;
@ -262,8 +260,6 @@ import org.jooq.tools.Convert;
import org.jooq.tools.JooqLogger;
import org.jooq.tools.StringUtils;
import org.jetbrains.annotations.NotNull;
/**
* A sub-select is a <code>SELECT</code> statement that can be combined with
* other <code>SELECT</code> statement in <code>UNION</code>s and similar
@ -1348,11 +1344,8 @@ final class SelectQueryImpl<R extends Record> extends AbstractResultQuery<R> imp
if (with != null)
context.visit(with);
else if (topLevelCte && context.subqueryLevel() == 0)
context.scopeMarkStart(TOP_LEVEL_CTE.beforeFirst)
.scopeMarkEnd(TOP_LEVEL_CTE.beforeFirst)
.scopeMarkStart(TOP_LEVEL_CTE.afterLast)
.scopeMarkEnd(TOP_LEVEL_CTE.afterLast);
else if (topLevelCte)
markTopLevelCteAndAccept(context, c -> {});
pushWindow(context);

View File

@ -37,6 +37,9 @@
*/
package org.jooq.impl;
import static org.jooq.impl.CommonTableExpressionList.markTopLevelCteAndAccept;
import org.jooq.Context;
import org.jooq.QueryPart;
import org.jooq.impl.ScopeMarker.ScopeContent;
@ -50,6 +53,11 @@ final class TopLevelCte extends QueryPartList<QueryPart> implements ScopeContent
*/
private static final long serialVersionUID = 9211135511038680791L;
@Override
public void accept(Context<?> ctx) {
markTopLevelCteAndAccept(ctx, c -> super.accept(c));
}
@Override
public final boolean declaresCTE() {
return true;