From 5bb189f477f6a2e5a9b0f228f3b0103269146bea Mon Sep 17 00:00:00 2001 From: lukaseder Date: Tue, 24 Sep 2013 22:31:46 +0200 Subject: [PATCH] [#2580] Bad SQL rendered when combining DISTINCT with LIMIT .. OFFSET in DB2, SQL Server --- .../jooq/test/_/testcases/OrderByTests.java | 26 +++++++++++++++++++ .../src/org/jooq/test/jOOQAbstractTest.java | 5 ++++ .../java/org/jooq/impl/SelectQueryImpl.java | 20 +++++++++++++- 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/jOOQ-test/src/org/jooq/test/_/testcases/OrderByTests.java b/jOOQ-test/src/org/jooq/test/_/testcases/OrderByTests.java index a54244fc8e..9bbd26790a 100644 --- a/jOOQ-test/src/org/jooq/test/_/testcases/OrderByTests.java +++ b/jOOQ-test/src/org/jooq/test/_/testcases/OrderByTests.java @@ -307,6 +307,32 @@ extends BaseTest extends AbstractSelect implements Sel // window function, calculating row numbers for the LIMIT .. OFFSET clause RenderContext local = new DefaultRenderContext(context); local.subquery(true); - toSQLReference0(local, rowNumber().over().orderBy(getNonEmptyOrderBy()).as(rownumName)); + + // [#2580] When DISTINCT is applied, we mustn't use ROW_NUMBER() OVER(), + // which changes the DISTINCT semantics. Instead, use DENSE_RANK() OVER(), + // ordering by the SELECT's ORDER BY clause AND all the expressions from + // the projection + if (distinct) { + List> order = new ArrayList>(); + order.addAll(getNonEmptyOrderBy()); + + // TODO: Challenge this with lots of additional tests, improve readability + for (Field field : getSelect()) + order.add(field.asc()); + toSQLReference0(local, denseRank().over().orderBy(order).as(rownumName)); + } + else { + toSQLReference0(local, rowNumber().over().orderBy(getNonEmptyOrderBy()).as(rownumName)); + } String enclosed = local.render(); context.keyword("select * from (")