mirror of
https://github.com/querydsl/querydsl.git
synced 2026-06-13 21:01:01 +08:00
Merge pull request #1835 from querydsl/i1834
Improve limit/offset handling
This commit is contained in:
commit
c1377f699e
@ -91,6 +91,9 @@ public class SQLServer2005Templates extends SQLServerTemplates {
|
||||
for (OrderSpecifier<?> os : metadata.getOrderBy()) {
|
||||
rn.orderBy(os);
|
||||
}
|
||||
if (metadata.getOrderBy().isEmpty()) {
|
||||
rn.orderBy(Expressions.currentTimestamp().asc());
|
||||
}
|
||||
FactoryExpression<?> pr = Projections.appending(metadata.getProjection(), rn.as("rn"));
|
||||
metadata.setProjection(FactoryExpressionUtils.wrap(pr));
|
||||
metadata.clearOrderBy();
|
||||
|
||||
@ -13,12 +13,15 @@
|
||||
*/
|
||||
package com.querydsl.sql;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.querydsl.core.QueryFlag;
|
||||
import com.querydsl.core.QueryFlag.Position;
|
||||
import com.querydsl.core.QueryMetadata;
|
||||
import com.querydsl.core.QueryModifiers;
|
||||
import com.querydsl.core.types.Expression;
|
||||
import com.querydsl.core.types.Path;
|
||||
import com.querydsl.core.types.dsl.Expressions;
|
||||
|
||||
/**
|
||||
@ -67,20 +70,54 @@ public class SQLServer2012Templates extends SQLServerTemplates {
|
||||
public void serialize(QueryMetadata metadata, boolean forCountRow, SQLSerializer context) {
|
||||
if (!forCountRow && metadata.getModifiers().isRestricting() && metadata.getOrderBy().isEmpty()
|
||||
&& !metadata.getJoins().isEmpty()) {
|
||||
metadata = metadata.clone();
|
||||
QueryModifiers mod = metadata.getModifiers();
|
||||
// use top if order by is empty
|
||||
if (mod.getOffset() == null) {
|
||||
// select top ...
|
||||
metadata = metadata.clone();
|
||||
metadata.addFlag(new QueryFlag(QueryFlag.Position.AFTER_SELECT,
|
||||
Expressions.template(Integer.class, topTemplate, mod.getLimit())));
|
||||
context.serializeForQuery(metadata, forCountRow);
|
||||
} else {
|
||||
throw new IllegalStateException("offset not supported without order by");
|
||||
// order by first column
|
||||
metadata.addOrderBy(Expressions.ONE.asc());
|
||||
}
|
||||
} else {
|
||||
context.serializeForQuery(metadata, forCountRow);
|
||||
}
|
||||
context.serializeForQuery(metadata, forCountRow);
|
||||
|
||||
if (!metadata.getFlags().isEmpty()) {
|
||||
context.serialize(Position.END, metadata.getFlags());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serializeDelete(QueryMetadata metadata, RelationalPath<?> entity, SQLSerializer context) {
|
||||
// limit
|
||||
QueryModifiers mod = metadata.getModifiers();
|
||||
if (mod.isRestricting()) {
|
||||
metadata = metadata.clone();
|
||||
metadata.addFlag(new QueryFlag(QueryFlag.Position.AFTER_SELECT,
|
||||
Expressions.template(Integer.class, topTemplate, mod.getLimit())));
|
||||
}
|
||||
|
||||
context.serializeForDelete(metadata, entity);
|
||||
|
||||
if (!metadata.getFlags().isEmpty()) {
|
||||
context.serialize(Position.END, metadata.getFlags());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serializeUpdate(QueryMetadata metadata, RelationalPath<?> entity,
|
||||
Map<Path<?>, Expression<?>> updates, SQLSerializer context) {
|
||||
// limit
|
||||
QueryModifiers mod = metadata.getModifiers();
|
||||
if (mod.isRestricting()) {
|
||||
metadata = metadata.clone();
|
||||
metadata.addFlag(new QueryFlag(QueryFlag.Position.AFTER_SELECT,
|
||||
Expressions.template(Integer.class, topTemplate, mod.getLimit())));
|
||||
}
|
||||
|
||||
context.serializeForUpdate(metadata, entity, updates);
|
||||
|
||||
if (!metadata.getFlags().isEmpty()) {
|
||||
context.serialize(Position.END, metadata.getFlags());
|
||||
|
||||
@ -67,12 +67,22 @@ public class SQLServer2005TemplatesTest extends AbstractSQLTemplatesTest {
|
||||
@Test
|
||||
public void modifiers() {
|
||||
query.from(survey1).limit(5).offset(3);
|
||||
query.orderBy(survey1.id.asc());
|
||||
query.getMetadata().setProjection(survey1.id);
|
||||
assertEquals("select * from (" +
|
||||
" select survey1.ID, row_number() over () as rn from SURVEY survey1) a " +
|
||||
" select survey1.ID, row_number() over (order by survey1.ID asc) as rn from SURVEY survey1) a " +
|
||||
"where rn > ? and rn <= ? order by rn", query.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void modifiers_noOrder() {
|
||||
query.from(survey1).limit(5).offset(3);
|
||||
query.getMetadata().setProjection(survey1.id);
|
||||
assertEquals("select * from (" +
|
||||
" select survey1.ID, row_number() over (order by current_timestamp asc) as rn from SURVEY survey1) a " +
|
||||
"where rn > ? and rn <= ? order by rn", query.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nextVal() {
|
||||
Operation<String> nextval = ExpressionUtils.operation(String.class, SQLOps.NEXTVAL, ConstantImpl.create("myseq"));
|
||||
|
||||
@ -24,6 +24,8 @@ import com.querydsl.core.types.Operation;
|
||||
import com.querydsl.core.types.Path;
|
||||
import com.querydsl.core.types.dsl.Expressions;
|
||||
import com.querydsl.core.types.dsl.NumberExpression;
|
||||
import com.querydsl.sql.dml.SQLDeleteClause;
|
||||
import com.querydsl.sql.dml.SQLUpdateClause;
|
||||
|
||||
|
||||
public class SQLServer2012TemplatesTest extends AbstractSQLTemplatesTest {
|
||||
@ -67,6 +69,33 @@ public class SQLServer2012TemplatesTest extends AbstractSQLTemplatesTest {
|
||||
assertEquals("select top 5 survey1.ID from SURVEY survey1", query.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void limitOffset() {
|
||||
query.from(survey1).limit(5).offset(5);
|
||||
query.getMetadata().setProjection(survey1.id);
|
||||
assertEquals("select survey1.ID from SURVEY survey1 " +
|
||||
"order by 1 asc " +
|
||||
"offset ? rows fetch next ? rows only", query.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void delete_limit() {
|
||||
SQLDeleteClause clause = new SQLDeleteClause(null, createTemplates(), survey1);
|
||||
clause.where(survey1.name.eq("Bob"));
|
||||
clause.limit(5);
|
||||
assertEquals("delete top 5 from SURVEY\n" +
|
||||
"where SURVEY.NAME = ?", clause.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void update_limit() {
|
||||
SQLUpdateClause clause = new SQLUpdateClause(null, createTemplates(), survey1);
|
||||
clause.set(survey1.name, "Bob");
|
||||
clause.limit(5);
|
||||
assertEquals("update top 5 SURVEY\n" +
|
||||
"set NAME = ?", clause.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void modifiers() {
|
||||
query.from(survey1).limit(5).offset(3).orderBy(survey1.id.asc());
|
||||
|
||||
Loading…
Reference in New Issue
Block a user