Skip to content

Commit 926bdef

Browse files
committed
Don't return empty routing key when partition key is unbound
DefaultBoundStatement#getRoutingKey has logic to infer the routing key when no one has explicitly called setRoutingKey or otherwise set the routing key on the statement. It however doesn't check for cases where nothing has been bound yet on the statement. This causes more problems if the user decides to get a BoundStatementBuilder from the PreparedStatement, set some fields on it, and then copy it by constructing new BoundStatementBuilder objects with the BoundStatement as a parameter, since the empty ByteBuffer gets copied to all bound statements, resulting in all requests being targeted to the same Cassandra node in a token-aware load balancing policy.
1 parent 741df6f commit 926bdef

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

core/src/main/java/com/datastax/oss/driver/internal/core/cql/DefaultBoundStatement.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,8 @@ public ByteBuffer getRoutingKey() {
358358
if (indices.isEmpty()) {
359359
return null;
360360
} else if (indices.size() == 1) {
361-
return getBytesUnsafe(indices.get(0));
361+
int index = indices.get(0);
362+
return isSet(index) ? getBytesUnsafe(index) : null;
362363
} else {
363364
ByteBuffer[] components = new ByteBuffer[indices.size()];
364365
for (int i = 0; i < components.length; i++) {

integration-tests/src/test/java/com/datastax/oss/driver/core/cql/PreparedStatementIT.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,25 @@ private void should_infer_routing_information_when_partition_key_is_bound(String
475475
assertThat(tokenFactory.hash(boundStatement.getRoutingKey())).isEqualTo(expectedToken);
476476
}
477477

478+
@Test
479+
public void should_return_null_routing_information_when_single_partition_key_is_unbound() {
480+
should_return_null_routing_information_when_single_partition_key_is_unbound(
481+
"SELECT a FROM prepared_statement_test WHERE a = ?");
482+
should_return_null_routing_information_when_single_partition_key_is_unbound(
483+
"INSERT INTO prepared_statement_test (a) VALUES (?)");
484+
should_return_null_routing_information_when_single_partition_key_is_unbound(
485+
"UPDATE prepared_statement_test SET b = 1 WHERE a = ?");
486+
should_return_null_routing_information_when_single_partition_key_is_unbound(
487+
"DELETE FROM prepared_statement_test WHERE a = ?");
488+
}
489+
490+
private void should_return_null_routing_information_when_single_partition_key_is_unbound(
491+
String queryString) {
492+
CqlSession session = sessionRule.session();
493+
BoundStatement boundStatement = session.prepare(queryString).bind();
494+
assertThat(boundStatement.getRoutingKey()).isNull();
495+
}
496+
478497
private static Iterable<Row> firstPageOf(CompletionStage<AsyncResultSet> stage) {
479498
return CompletableFutures.getUninterruptibly(stage).currentPage();
480499
}

0 commit comments

Comments
 (0)