Skip to content

Commit bfe95a7

Browse files
committed
Fix NPE that occurs with delete w/o clustering key
1 parent 0faf2d9 commit bfe95a7

File tree

2 files changed

+104
-11
lines changed

2 files changed

+104
-11
lines changed

core/src/main/java/com/scalar/db/transaction/consensuscommit/CommitMutationComposer.java

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import com.scalar.db.api.ConditionBuilder;
1010
import com.scalar.db.api.Consistency;
1111
import com.scalar.db.api.Delete;
12+
import com.scalar.db.api.DeleteBuilder;
1213
import com.scalar.db.api.Mutation;
1314
import com.scalar.db.api.Operation;
1415
import com.scalar.db.api.Put;
@@ -114,17 +115,20 @@ private Put composePut(Operation base, @Nullable TransactionResult result)
114115

115116
private Delete composeDelete(Operation base, @Nullable TransactionResult result)
116117
throws ExecutionException {
117-
return Delete.newBuilder()
118-
.namespace(base.forNamespace().get())
119-
.table(base.forTable().get())
120-
.partitionKey(getPartitionKey(base, result))
121-
.clusteringKey(getClusteringKey(base, result).orElse(null))
122-
.consistency(Consistency.LINEARIZABLE)
123-
.condition(
124-
ConditionBuilder.deleteIf(ConditionBuilder.column(ID).isEqualToText(id))
125-
.and(ConditionBuilder.column(STATE).isEqualToInt(TransactionState.DELETED.get()))
126-
.build())
127-
.build();
118+
DeleteBuilder.Buildable deleteBuilder =
119+
Delete.newBuilder()
120+
.namespace(base.forNamespace().get())
121+
.table(base.forTable().get())
122+
.partitionKey(getPartitionKey(base, result))
123+
.consistency(Consistency.LINEARIZABLE)
124+
.condition(
125+
ConditionBuilder.deleteIf(ConditionBuilder.column(ID).isEqualToText(id))
126+
.and(
127+
ConditionBuilder.column(STATE).isEqualToInt(TransactionState.DELETED.get()))
128+
.build());
129+
getClusteringKey(base, result).ifPresent(deleteBuilder::clusteringKey);
130+
131+
return deleteBuilder.build();
128132
}
129133

130134
private Key getPartitionKey(Operation base, @Nullable TransactionResult result)

core/src/test/java/com/scalar/db/transaction/consensuscommit/CommitMutationComposerTest.java

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,25 @@ private Delete prepareDelete() {
118118
.build();
119119
}
120120

121+
private Put preparePutWithoutCk() {
122+
Key partitionKey = Key.ofText(ANY_NAME_1, ANY_TEXT_1);
123+
return Put.newBuilder()
124+
.namespace(ANY_NAMESPACE_NAME)
125+
.table(ANY_TABLE_NAME)
126+
.partitionKey(partitionKey)
127+
.intValue(ANY_NAME_3, ANY_INT_1)
128+
.build();
129+
}
130+
131+
private Delete prepareDeleteWithoutCk() {
132+
Key partitionKey = Key.ofText(ANY_NAME_1, ANY_TEXT_1);
133+
return Delete.newBuilder()
134+
.namespace(ANY_NAMESPACE_NAME)
135+
.table(ANY_TABLE_NAME)
136+
.partitionKey(partitionKey)
137+
.build();
138+
}
139+
121140
private Get prepareGet() {
122141
Key partitionKey = Key.ofText(ANY_NAME_1, ANY_TEXT_1);
123142
Key clusteringKey = Key.ofText(ANY_NAME_2, ANY_TEXT_2);
@@ -220,6 +239,52 @@ public void add_PutAndNullResultGiven_ShouldComposePutWithPutIfCondition()
220239
assertThat(actual).isEqualTo(expected);
221240
}
222241

242+
@Test
243+
public void add_PutWithoutCkAndPreparedResultGiven_ShouldComposePutWithPutIfCondition()
244+
throws ExecutionException {
245+
// Arrange
246+
Put put = preparePutWithoutCk();
247+
TransactionResult result = prepareResult(TransactionState.PREPARED);
248+
249+
// Act
250+
composer.add(put, result);
251+
252+
// Assert
253+
Put actual = (Put) composer.get().get(0);
254+
Put expected =
255+
Put.newBuilder()
256+
.namespace(put.forNamespace().get())
257+
.table(put.forTable().get())
258+
.partitionKey(put.getPartitionKey())
259+
.consistency(Consistency.LINEARIZABLE)
260+
.condition(
261+
ConditionBuilder.putIf(ConditionBuilder.column(ID).isEqualToText(ANY_ID))
262+
.and(
263+
ConditionBuilder.column(STATE)
264+
.isEqualToInt(TransactionState.PREPARED.get()))
265+
.build())
266+
.bigIntValue(COMMITTED_AT, ANY_TIME_2)
267+
.intValue(STATE, TransactionState.COMMITTED.get())
268+
.textValue(BEFORE_ID, null)
269+
.intValue(BEFORE_STATE, null)
270+
.intValue(BEFORE_VERSION, null)
271+
.bigIntValue(BEFORE_PREPARED_AT, null)
272+
.bigIntValue(BEFORE_COMMITTED_AT, null)
273+
.intValue(BEFORE_PREFIX + ANY_NAME_3, null)
274+
.booleanValue(BEFORE_PREFIX + ANY_NAME_4, null)
275+
.bigIntValue(BEFORE_PREFIX + ANY_NAME_5, null)
276+
.floatValue(BEFORE_PREFIX + ANY_NAME_6, null)
277+
.doubleValue(BEFORE_PREFIX + ANY_NAME_7, null)
278+
.textValue(BEFORE_PREFIX + ANY_NAME_8, null)
279+
.blobValue(BEFORE_PREFIX + ANY_NAME_9, (byte[]) null)
280+
.dateValue(BEFORE_PREFIX + ANY_NAME_10, null)
281+
.timeValue(BEFORE_PREFIX + ANY_NAME_11, null)
282+
.timestampValue(BEFORE_PREFIX + ANY_NAME_12, null)
283+
.timestampTZValue(BEFORE_PREFIX + ANY_NAME_13, null)
284+
.build();
285+
assertThat(actual).isEqualTo(expected);
286+
}
287+
223288
@Test
224289
public void add_DeleteAndDeletedResultGiven_ShouldComposeDeleteWithDeleteIfCondition()
225290
throws ExecutionException {
@@ -267,6 +332,30 @@ public void add_DeleteAndNullResultGiven_ShouldComposeDeleteWithDeleteIfConditio
267332
assertThat(actual).isEqualTo(delete);
268333
}
269334

335+
@Test
336+
public void add_DeleteWithoutCkAndDeletedResultGiven_ShouldComposeDeleteWithDeleteIfCondition()
337+
throws ExecutionException {
338+
// Arrange
339+
Delete delete = prepareDeleteWithoutCk();
340+
TransactionResult result = prepareResult(TransactionState.DELETED);
341+
342+
// Act
343+
composer.add(delete, result);
344+
345+
// Assert
346+
Delete actual = (Delete) composer.get().get(0);
347+
delete =
348+
Delete.newBuilder(delete)
349+
.consistency(Consistency.LINEARIZABLE)
350+
.condition(
351+
ConditionBuilder.deleteIf(ConditionBuilder.column(ID).isEqualToText(ANY_ID))
352+
.and(
353+
ConditionBuilder.column(STATE).isEqualToInt(TransactionState.DELETED.get()))
354+
.build())
355+
.build();
356+
assertThat(actual).isEqualTo(delete);
357+
}
358+
270359
@Test
271360
public void add_SelectionAndPreparedResultGiven_ShouldComposePutForRollforward()
272361
throws ExecutionException {

0 commit comments

Comments
 (0)