Skip to content

Commit 7902d0e

Browse files
committed
Use bind markers for SELECT … LIMIT when possible.
When using bind markers (named/by index) we now apply bind markers for LIMIT to avoid excessive prepared statement amounts. See #1401
1 parent 0131eeb commit 7902d0e

File tree

4 files changed

+30
-11
lines changed

4 files changed

+30
-11
lines changed

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/StatementFactory.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -632,17 +632,19 @@ private StatementBuilder<Select> createSelect(Query query, CassandraPersistentEn
632632

633633
StatementBuilder<Select> select = createSelectAndOrder(selectors, tableName, filter, sort);
634634

635-
// TODO: Bind marker
636-
if (query.getLimit() > 0) {
637-
select.apply(it -> it.limit(Math.toIntExact(query.getLimit())));
638-
}
639-
640635
if (query.isAllowFiltering()) {
641636
select.apply(Select::allowFiltering);
642637
}
643638

644639
select.onBuild(statementBuilder -> query.getPagingState().ifPresent(statementBuilder::setPagingState));
645640

641+
if (query.getLimit() > 0) {
642+
643+
int limit = Math.toIntExact(query.getLimit());
644+
select.bind((statement, factory) -> factory.ifBoundOrInline(bindings -> statement.limit(bindings.bind(limit)),
645+
() -> statement.limit(limit)));
646+
}
647+
646648
query.getQueryOptions()
647649
.ifPresent(it -> select.transform(statement -> QueryOptionsUtil.addQueryOptions(statement, it)));
648650

spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/StatementFactoryUnitTests.java

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import org.springframework.data.cassandra.core.query.Query;
4242
import org.springframework.data.cassandra.core.query.Update;
4343
import org.springframework.data.cassandra.domain.Group;
44+
import org.springframework.data.domain.Limit;
4445
import org.springframework.data.domain.Sort;
4546

4647
import com.datastax.oss.driver.api.core.CqlIdentifier;
@@ -136,8 +137,8 @@ void shouldMapSelectQueryWithTtlColumns() {
136137
assertThat(select.build(ParameterHandling.INLINE).getQuery()).isEqualTo("SELECT ttl(email) FROM group");
137138
}
138139

139-
@Test // #1008
140-
void shouldMapSelectQueryWithSortLimitAndAllowFiltering() {
140+
@Test // GH-1008
141+
void shouldMapSelectQueryWithSort() {
141142

142143
Query query = Query.empty().sort(Sort.by(DESC, "email", "age"));
143144

@@ -148,6 +149,22 @@ void shouldMapSelectQueryWithSortLimitAndAllowFiltering() {
148149
.isEqualTo("SELECT * FROM group ORDER BY email DESC,age DESC");
149150
}
150151

152+
@Test // GH-1401
153+
void shouldMapSelectQueryWithLimit() {
154+
155+
Query query = Query.query(Criteria.where("email").is("e@mail")).limit(Limit.of(10));
156+
157+
StatementBuilder<Select> select = statementFactory.select(query,
158+
converter.getMappingContext().getRequiredPersistentEntity(Group.class));
159+
160+
assertThat(select.build(ParameterHandling.INLINE).getQuery())
161+
.isEqualTo("SELECT * FROM group WHERE email='e@mail' LIMIT 10");
162+
163+
SimpleStatement statement = select.build(ParameterHandling.BY_INDEX);
164+
assertThat(statement.getQuery()).isEqualTo("SELECT * FROM group WHERE email=? LIMIT ?");
165+
assertThat(statement.getPositionalValues()).containsExactly("e@mail", 10);
166+
}
167+
151168
@Test // DATACASS-343
152169
void shouldMapSelectQueryWithSortByEmbeddedLimitAndAllowFiltering() {
153170

spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/PartTreeCassandraQueryUnitTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -242,12 +242,12 @@ void shouldCreateDeleteQuery() {
242242
assertThat(statement.getQuery()).isEqualTo("DELETE FROM person WHERE lastname=?");
243243
}
244244

245-
@Test // DATACASS-512
245+
@Test // DATACASS-512, GH-1401
246246
void shouldCreateExistsQuery() {
247247

248248
SimpleStatement statement = deriveQueryFromMethod(Repo.class, "existsBy", new Class[0]);
249249

250-
assertThat(statement.getQuery()).isEqualTo("SELECT * FROM person LIMIT 1");
250+
assertThat(statement.getQuery()).isEqualTo("SELECT * FROM person LIMIT ?");
251251
}
252252

253253
private String deriveQueryFromMethod(String method, Object... args) {

spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/ReactivePartTreeCassandraQueryUnitTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,13 +149,13 @@ void shouldCreateDeleteQuery() {
149149
assertThat(statement.getQuery()).isEqualTo("DELETE FROM person WHERE lastname=?");
150150
}
151151

152-
@Test // DATACASS-512
152+
@Test // DATACASS-512, GH-1401
153153
void shouldCreateExistsQuery() {
154154

155155
SimpleStatement statement = deriveQueryFromMethod(PartTreeCassandraQueryUnitTests.Repo.class, "existsBy",
156156
new Class[0]);
157157

158-
assertThat(statement.getQuery()).isEqualTo("SELECT * FROM person LIMIT 1");
158+
assertThat(statement.getQuery()).isEqualTo("SELECT * FROM person LIMIT ?");
159159
}
160160

161161
private String deriveQueryFromMethod(String method, Object... args) {

0 commit comments

Comments
 (0)