- [#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:
Lukas Eder 2014-08-20 15:50:08 +02:00
parent ee0aade684
commit 6ae9daf558
5 changed files with 148 additions and 29 deletions

View File

@ -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 {

View File

@ -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();
}

View File

@ -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);
}
}

View File

@ -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

View File

@ -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.
*/