- [#2080] Syntax error in rendered SQL when using limit().offset() with aliased projections in SQL Server - [#3575] SQL Server doesn't support referencing column aliases in ORDER BY clause expressions
This commit is contained in:
parent
ee0aade684
commit
6ae9daf558
@ -44,11 +44,11 @@ import static java.util.Arrays.asList;
|
||||
// ...
|
||||
// ...
|
||||
// ...
|
||||
// ...
|
||||
import static org.jooq.impl.DSL.count;
|
||||
import static org.jooq.impl.DSL.inline;
|
||||
import static org.jooq.impl.DSL.lower;
|
||||
import static org.jooq.impl.DSL.param;
|
||||
import static org.jooq.impl.DSL.select;
|
||||
import static org.jooq.impl.DSL.table;
|
||||
import static org.jooq.impl.DSL.val;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
@ -514,13 +514,8 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, UU, I, IPK, T7
|
||||
}
|
||||
|
||||
public void testLimitAliased() throws Exception {
|
||||
/* [pro] xx
|
||||
xx xxxxxxxxxxxxxxx xxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx x
|
||||
xxxxxxxxxxxxxxxxxxxx xxxxxx xx xxxxxx xxxxxxxx
|
||||
xxxxxxx
|
||||
x
|
||||
|
||||
xx [/pro] */
|
||||
assumeFamilyNotIn();
|
||||
|
||||
// [#2080] Some databases generate ORDER BY clauses within their ranking
|
||||
// functions. There are some syntax problems, when selectable columns
|
||||
// have aliases
|
||||
@ -570,6 +565,40 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, UU, I, IPK, T7
|
||||
|
||||
assertEquals(2, r4.size());
|
||||
assertEquals(asList(3, 2), r4.getValues("xx"));
|
||||
|
||||
// Nested expressions
|
||||
Result<Record2<String, Integer>> r5 =
|
||||
create().select(TBook_TITLE().as("yy"), TBook_ID().as("xx"))
|
||||
.from(TBook())
|
||||
.orderBy(TBook_ID().as("xx").sortAsc(4, 1, 3, 2))
|
||||
.limit(param("x", 1), param("y", 2))
|
||||
.fetch();
|
||||
|
||||
assertEquals(2, r5.size());
|
||||
assertEquals(asList(1, 3), r5.getValues("xx"));
|
||||
|
||||
// Subqueries
|
||||
switch (dialect().family()) {
|
||||
/* [pro] xx
|
||||
xx xxxxx xxxxxxxx xx xxx xxxxxx xxxx xxxx xxxxxxx xxx xxxxx xx xxxxxxx xxxx
|
||||
xxxx xxxx
|
||||
xxxx xxxxxxx
|
||||
xxxxxxxxxxxxxxxxxxxx xxxxxxxxx xxxxxx xxxxxxxxxx xxxx xxxxx xx xxxxxxxxxxx
|
||||
xxxxxx
|
||||
xx [/pro] */
|
||||
|
||||
default: {
|
||||
Result<Record2<String, Integer>> r6 =
|
||||
create().select(TBook_TITLE().as("yy"), TBook_ID().as("xx"))
|
||||
.from(TBook())
|
||||
.orderBy(select(TAuthor_LAST_NAME().as("xx")).from(TAuthor()).where(TAuthor_ID().eq(TBook_AUTHOR_ID())).asField())
|
||||
.limit(param("x", 1), param("y", 2))
|
||||
.fetch();
|
||||
|
||||
assertEquals(2, r6.size());
|
||||
assertEquals(asList(4, 1), r6.getValues("xx"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testLimitBindValues() throws Exception {
|
||||
|
||||
@ -2301,7 +2301,7 @@ public abstract class jOOQAbstractTest<
|
||||
new OrderByTests(this).testLimitWithLOBs();
|
||||
}
|
||||
|
||||
// [#2080] TODO @Test
|
||||
@Test
|
||||
public void testLimitAliased() throws Exception {
|
||||
new OrderByTests(this).testLimitAliased();
|
||||
}
|
||||
|
||||
@ -66,10 +66,13 @@ import static org.jooq.SQLDialect.SQLITE;
|
||||
import static org.jooq.impl.DSL.falseCondition;
|
||||
import static org.jooq.impl.DSL.field;
|
||||
import static org.jooq.impl.DSL.select;
|
||||
import static org.jooq.impl.Utils.DATA_OVERRIDE_ALIASES_IN_ORDER_BY;
|
||||
import static org.jooq.impl.Utils.DATA_UNALIAS_ALIASES_IN_ORDER_BY;
|
||||
import static org.jooq.impl.Utils.list;
|
||||
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Context;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.QueryPart;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.SQLDialect;
|
||||
@ -225,8 +228,34 @@ class Alias<Q extends QueryPart> extends AbstractQueryPart {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* [pro] xx
|
||||
xx xxxxxxx xxxxx xxxxxx xxxxx xxxxxxx xx xxx xxxxxx xxxxx xx xxxxxxx
|
||||
xxxx xx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xx xxxx xx xxxxxxx xxxxxxxxxx xxxxxx x
|
||||
xxxxxxxxxxxxxxxxxxxxxx
|
||||
x
|
||||
xx [/pro] */
|
||||
else {
|
||||
context.literal(alias);
|
||||
String actualAlias = alias;
|
||||
|
||||
/* [pro] xx
|
||||
xx xxxxxxx xxxxxxxx xxx xxxxxx xxxxx xx xxxx x xxxxxxxxx xxxxx xx xxxxxxxxx
|
||||
xx xx xxx xxxxxx xxxxxx
|
||||
xxxxxxxx xxxxxx x xxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
xx xxxxxxx xx xxxxx x
|
||||
xxxxxxxxxx xxxxxxxxxxxxxx x xxxxxxxxxxxx xxxxxxxxxx
|
||||
xxxxxxxxxx xxxxxxxxxxxxx x xxxxxxxxxxxx xxxxxxxxxx
|
||||
|
||||
xxx xxxx x x xx x x xxxxxxxxxxxxxxxxxxxxxx xxxx x
|
||||
xx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx x
|
||||
xxxxxxxxxxx x xxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
xxxxxx
|
||||
x
|
||||
x
|
||||
x
|
||||
xx [/pro] */
|
||||
|
||||
context.literal(actualAlias);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -84,9 +84,11 @@ import static org.jooq.impl.DSL.row;
|
||||
// ...
|
||||
import static org.jooq.impl.Utils.DATA_LOCALLY_SCOPED_DATA_MAP;
|
||||
import static org.jooq.impl.Utils.DATA_OMIT_INTO_CLAUSE;
|
||||
import static org.jooq.impl.Utils.DATA_OVERRIDE_ALIASES_IN_ORDER_BY;
|
||||
// ...
|
||||
import static org.jooq.impl.Utils.DATA_ROW_VALUE_EXPRESSION_PREDICATE_SUBQUERY;
|
||||
import static org.jooq.impl.Utils.DATA_SELECT_INTO_TABLE;
|
||||
import static org.jooq.impl.Utils.DATA_UNALIAS_ALIASES_IN_ORDER_BY;
|
||||
import static org.jooq.impl.Utils.DATA_WINDOW_DEFINITIONS;
|
||||
import static org.jooq.impl.Utils.DATA_WRAP_DERIVED_TABLES_IN_PARENTHESES;
|
||||
|
||||
@ -444,35 +446,52 @@ class SelectQueryImpl<R extends Record> extends AbstractSelect<R> implements Sel
|
||||
x xxxxxxxx xxx xxxxx x xxxxxx xxxxxx xx xxx xxxxxx xxxxxxxxxxxxxxxx
|
||||
x xxxxxx xxxxxxxxxxxxxxxxxxxxxxxxx xxx xxxxxx xxxxxxxxxxxxxxxxxx xxxxxxxx
|
||||
xx
|
||||
xxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
xxxxxxx xxxxx xxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxx x
|
||||
|
||||
xx xxxxxxxxxx xxxxxxxx xxxxxxxxxx
|
||||
xxxxxxxxxx xxxxxxxxxxxxxx x xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
xxxxx xxxxxxxxxx xxxxxxxxxxxxxx x xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
|
||||
xx xxx xxx xxxxx
|
||||
xxxxxxxx xxxxxxxxxxxxx x xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
xxxxx xxxxxxxx xxxxxxxxxxxxx x xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
|
||||
xx xxx xxx xx
|
||||
xxxxxxxx xxxxxxxxxxxxxxxx x xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
xxxxx xxxxxxxx xxxxxxxxxxxxxxxx x xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
|
||||
xx xxxxxxxxx xx xxx xxxxxxx xx xxx xxxxxxxxxx xx xx
|
||||
xx xxxxxxx xxx xx xxxx x xx xx xxxx xx xxxxx xxxxx xxxxx xxxxx xxxx xxxxx xxx xxxxxx xxx xxxxxxxxx
|
||||
xxxxxxxxxx xxxxxxxxxxxxxxxxx x xxxxxxxxxxxxxx
|
||||
xxxxx xxxxxxxxxx xxxxxxxxxxxxxxxxx x xxxxxxxxxxxxxx
|
||||
xxxxxxxxxxxxxxxxxxxxxxx xx x
|
||||
x xxx xxxxxxx x xxxxxxxxxxxxxx x
|
||||
x xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxx
|
||||
|
||||
xx xxxxxxx xxxx xxxxxxxx xx xxxxxxxx xx xxxxxxx xxx xxxxxxxxxxxx xxxxxxx
|
||||
xx xxxxx xxxxxxx xxx xxxxxxxx xxxxxxxxxx xxxxxxxx xxx xxxxxxxxxxxx xxxxxxx
|
||||
xx xxxxxxxx xx xxx xxxxxxxx xxxxx xx xxxxxx xxx xxx xxx xxxxxxxxxxx xxxx
|
||||
xx xxx xxxxxxxxxx
|
||||
xxxxxxxx
|
||||
x xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
x xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
xxxx
|
||||
xx
|
||||
|
||||
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx x xx x
|
||||
xxx xxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxx x
|
||||
xxxxxxxxx
|
||||
xxxxxx xxxx xxxxxxxxxxxxxxxxx xx x
|
||||
|
||||
xx xxxxxxx xxxxxx xxxx xx xxxxxx xxxxxxx xxxx xxx xxxxxxxxxxx xxxxxx xxxxxx
|
||||
xx xxx xxxxxxxxxx xxxx xxx xxxxx xxxxxxx xxxxxxxxxx xxxxx xx xxxxxxx
|
||||
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxx
|
||||
|
||||
xx xxxxxxx xxxx xxxxxxxx xx xxxxxxxx xx xxxxxxx xxx xxxxxxxxxxxx xxxxxxx
|
||||
xx xxxxx xxxxxxx xxx xxxxxxxx xxxxxxxxxx xxxxxxxx xxx xxxxxxxxxxxx xxxxxxx
|
||||
xx xxxxxxxx xx xxx xxxxxxxx xxxxx xx xxxxxx xxx xxx xxx xxxxxxxxxxx xxxx
|
||||
xx xxx xxxxxxxxxx
|
||||
xxxxxxxxxxxxxxxx
|
||||
x xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
x xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
xx
|
||||
|
||||
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
x
|
||||
xxxxxxxxxxx
|
||||
|
||||
xx xx xx xxx xx xx xxx xx xx xxxxx
|
||||
xxxxxxxxxx xxxxxxxxxxxxxxx x xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxx
|
||||
xxxxx xxxxxxxxxx xxxxxxxxxxxxxxx x xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxx
|
||||
|
||||
xxxxxxx xxxxxxxx x xxxxxxxxxxxxxxx
|
||||
|
||||
@ -486,7 +505,7 @@ class SelectQueryImpl<R extends Record> extends AbstractSelect<R> implements Sel
|
||||
xxxxxxxxxxxxxxxx
|
||||
xxxxxxxxxxxxxxxx
|
||||
|
||||
xxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxx
|
||||
xxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxx
|
||||
|
||||
xxxxxxxxxxxxxxxxxxxxxx
|
||||
xxxxxxxxxxxxxxxxxx
|
||||
@ -553,7 +572,7 @@ class SelectQueryImpl<R extends Record> extends AbstractSelect<R> implements Sel
|
||||
xxxxxxxxxxxxxxxxxxxx
|
||||
xxxxxxxxxxxxxxxxx
|
||||
|
||||
xxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxx
|
||||
xxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxx
|
||||
|
||||
xxx xxxxxxxxxxxxxxxxxx
|
||||
xxxxxxxxxxxxxxxx
|
||||
@ -578,14 +597,14 @@ class SelectQueryImpl<R extends Record> extends AbstractSelect<R> implements Sel
|
||||
* This part is common to any type of limited query
|
||||
*/
|
||||
private final void toSQLReference0(Context<?> context) {
|
||||
toSQLReference0(context, null);
|
||||
toSQLReference0(context, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method renders the main part of a query without the LIMIT clause.
|
||||
* This part is common to any type of limited query
|
||||
*/
|
||||
private final void toSQLReference0(Context<?> context, Field<?>[] alternativeFields) {
|
||||
private final void toSQLReference0(Context<?> context, Field<?>[] originalFields, Field<?>[] alternativeFields) {
|
||||
SQLDialect dialect = context.dialect();
|
||||
SQLDialect family = dialect.family();
|
||||
|
||||
@ -889,8 +908,31 @@ class SelectQueryImpl<R extends Record> extends AbstractSelect<R> implements Sel
|
||||
.keyword(orderBySiblings ? "siblings" : "")
|
||||
.sql(" ")
|
||||
.keyword("by")
|
||||
.sql(" ")
|
||||
.visit(getOrderBy());
|
||||
.sql(" ");
|
||||
|
||||
/* [pro] xx
|
||||
|
||||
xx xxxxxxx xxx xxxxxx xxxxx xx xxxx xxxx xxxxxxx xxxxxxx xxx xxxxxxxxxxx xxxxxx xxxxxxx
|
||||
xx xxxx xxx xxxxxx xxxxxxx xx xxxx xx xxxxxxx xxxx xx xx xxxxxxxxxx
|
||||
xx xxxxxxx xx xxxxxxxxxx x
|
||||
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxx
|
||||
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
x
|
||||
|
||||
xx xxxxxxx xxxx xxxxxxx xxx xxxxxx xxx xxxx xxxx xxxxxx xxxxxxx xxxx xxx xxxxxx xxxxxx
|
||||
xx xxx xx xxxx xxx xxxxxxx xxxx xxxx xxxxxxxxxx xx xxxxxxx xxxxxx xxxxxxxxxxx xxx
|
||||
xx xxxxxxxxx xxxx xxxx xxxxx xx xxx xxxxx xx xxxxxx
|
||||
xxxx xx xxxxxxxxxxxxxxx xx xxxxx x
|
||||
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxx xxxxxxxx x xxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxx xxx
|
||||
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
x
|
||||
xxxx
|
||||
xx [/pro] */
|
||||
{
|
||||
context.visit(getOrderBy());
|
||||
}
|
||||
}
|
||||
|
||||
/* [pro] xx
|
||||
@ -1215,8 +1257,11 @@ class SelectQueryImpl<R extends Record> extends AbstractSelect<R> implements Sel
|
||||
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
xxxxxx
|
||||
|
||||
xxxx xxxxxxxxxx
|
||||
xxxx xxxxxxx
|
||||
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
xxxxxx
|
||||
|
||||
xxxx xxxxxxxxxx
|
||||
xxxxxxxx
|
||||
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxx
|
||||
xxxxxx
|
||||
|
||||
@ -275,6 +275,22 @@ final class Utils {
|
||||
*/
|
||||
static final String DATA_DEFAULT_TRANSACTION_PROVIDER_CONNECTION = "org.jooq.configuration.default-transaction-provider-connection-provider";
|
||||
|
||||
/**
|
||||
* [#2080] When emulating OFFSET pagination in certain databases, synthetic
|
||||
* aliases are generated that must be referenced also in
|
||||
* <code>ORDER BY</code> clauses, in lieu of their corresponding original
|
||||
* aliases.
|
||||
*/
|
||||
static final String DATA_OVERRIDE_ALIASES_IN_ORDER_BY = "org.jooq.configuration.override-aliases-in-order-by";
|
||||
|
||||
/**
|
||||
* [#2080] When emulating OFFSET pagination in certain databases, synthetic
|
||||
* aliases are generated that must be referenced also in
|
||||
* <code>ORDER BY</code> clauses, in lieu of their corresponding original
|
||||
* aliases.
|
||||
*/
|
||||
static final String DATA_UNALIAS_ALIASES_IN_ORDER_BY = "org.jooq.configuration.unalias-aliases-in-order-by";
|
||||
|
||||
/**
|
||||
* [#3381] The table to be used for the {@link Clause#SELECT_INTO} clause.
|
||||
*/
|
||||
|
||||
Loading…
Reference in New Issue
Block a user