Skip to content

Commit cc720db

Browse files
committed
Fix
1 parent e07c4ea commit cc720db

File tree

2 files changed

+108
-6
lines changed

2 files changed

+108
-6
lines changed

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

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,15 @@ public void check(Get get, TransactionContext context) throws ExecutionException
7878
// Additional checks for SERIALIZABLE isolation level
7979
if (context.isolation == Isolation.SERIALIZABLE) {
8080
// Don't allow index gets
81-
if (ScalarDbUtils.isSecondaryIndexSpecified(get, metadata.getTableMetadata())) {
82-
throw new IllegalArgumentException(
83-
CoreError.CONSENSUS_COMMIT_INDEX_GET_NOT_ALLOWED_IN_SERIALIZABLE.buildMessage());
81+
TableMetadata tableMetadata = metadata.getTableMetadata();
82+
if (ScalarDbUtils.isSecondaryIndexSpecified(get, tableMetadata)) {
83+
// If the index column is part of the primary key, it's allowed
84+
String indexKeyColumnName = get.getPartitionKey().getColumns().get(0).getName();
85+
if (!tableMetadata.getPartitionKeyNames().contains(indexKeyColumnName)
86+
&& !tableMetadata.getClusteringKeyNames().contains(indexKeyColumnName)) {
87+
throw new IllegalArgumentException(
88+
CoreError.CONSENSUS_COMMIT_INDEX_GET_NOT_ALLOWED_IN_SERIALIZABLE.buildMessage());
89+
}
8490
}
8591
}
8692
}
@@ -137,9 +143,15 @@ public void check(Scan scan, TransactionContext context) throws ExecutionExcepti
137143
// Additional checks for SERIALIZABLE isolation level
138144
if (context.isolation == Isolation.SERIALIZABLE) {
139145
// Don't allow index scans
140-
if (ScalarDbUtils.isSecondaryIndexSpecified(scan, metadata.getTableMetadata())) {
141-
throw new IllegalArgumentException(
142-
CoreError.CONSENSUS_COMMIT_INDEX_SCAN_NOT_ALLOWED_IN_SERIALIZABLE.buildMessage());
146+
TableMetadata tableMetadata = metadata.getTableMetadata();
147+
if (ScalarDbUtils.isSecondaryIndexSpecified(scan, tableMetadata)) {
148+
// If the index column is part of the primary key, it's allowed
149+
String indexKeyColumnName = scan.getPartitionKey().getColumns().get(0).getName();
150+
if (!tableMetadata.getPartitionKeyNames().contains(indexKeyColumnName)
151+
&& !tableMetadata.getClusteringKeyNames().contains(indexKeyColumnName)) {
152+
throw new IllegalArgumentException(
153+
CoreError.CONSENSUS_COMMIT_INDEX_SCAN_NOT_ALLOWED_IN_SERIALIZABLE.buildMessage());
154+
}
143155
}
144156

145157
// If the scan is a cross-partition scan (ScanAll), don't allow conditions on indexed columns

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

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,50 @@ public void checkForGet_WithSecondaryIndexInSerializable_ShouldThrowIllegalArgum
284284
.isInstanceOf(IllegalArgumentException.class);
285285
}
286286

287+
@Test
288+
public void
289+
checkForGet_WithIndexKeyUsingPartitionKeyInSerializable_ShouldNotThrowException() {
290+
// Arrange
291+
TableMetadata metadata =
292+
TableMetadata.newBuilder()
293+
.addColumn("pk", DataType.INT)
294+
.addColumn("col", DataType.INT)
295+
.addPartitionKey("pk")
296+
.addSecondaryIndex("pk")
297+
.build();
298+
when(tableMetadata.getTableMetadata()).thenReturn(metadata);
299+
300+
Get get = Get.newBuilder().namespace("ns").table("tbl").indexKey(Key.ofInt("pk", 100)).build();
301+
TransactionContext context =
302+
new TransactionContext("txId", null, Isolation.SERIALIZABLE, false, false);
303+
304+
// Act Assert
305+
assertThatCode(() -> checker.check(get, context)).doesNotThrowAnyException();
306+
}
307+
308+
@Test
309+
public void
310+
checkForGet_WithIndexKeyUsingClusteringKeyInSerializable_ShouldNotThrowException() {
311+
// Arrange
312+
TableMetadata metadata =
313+
TableMetadata.newBuilder()
314+
.addColumn("pk", DataType.INT)
315+
.addColumn("ck", DataType.INT)
316+
.addColumn("col", DataType.INT)
317+
.addPartitionKey("pk")
318+
.addClusteringKey("ck")
319+
.addSecondaryIndex("ck")
320+
.build();
321+
when(tableMetadata.getTableMetadata()).thenReturn(metadata);
322+
323+
Get get = Get.newBuilder().namespace("ns").table("tbl").indexKey(Key.ofInt("ck", 100)).build();
324+
TransactionContext context =
325+
new TransactionContext("txId", null, Isolation.SERIALIZABLE, false, false);
326+
327+
// Act Assert
328+
assertThatCode(() -> checker.check(get, context)).doesNotThrowAnyException();
329+
}
330+
287331
@Test
288332
public void checkForGet_ValidGet_ShouldNotThrowException() {
289333
// Arrange
@@ -402,6 +446,52 @@ public void checkForScan_WithSecondaryIndexInSerializable_ShouldThrowIllegalArgu
402446
.isInstanceOf(IllegalArgumentException.class);
403447
}
404448

449+
@Test
450+
public void
451+
checkForScan_WithIndexKeyUsingPartitionKeyInSerializable_ShouldNotThrowException() {
452+
// Arrange
453+
TableMetadata metadata =
454+
TableMetadata.newBuilder()
455+
.addColumn("pk", DataType.INT)
456+
.addColumn("col", DataType.INT)
457+
.addPartitionKey("pk")
458+
.addSecondaryIndex("pk")
459+
.build();
460+
when(tableMetadata.getTableMetadata()).thenReturn(metadata);
461+
462+
Scan scan =
463+
Scan.newBuilder().namespace("ns").table("tbl").indexKey(Key.ofInt("pk", 100)).build();
464+
TransactionContext context =
465+
new TransactionContext("txId", null, Isolation.SERIALIZABLE, false, false);
466+
467+
// Act Assert
468+
assertThatCode(() -> checker.check(scan, context)).doesNotThrowAnyException();
469+
}
470+
471+
@Test
472+
public void
473+
checkForScan_WithIndexKeyUsingClusteringKeyInSerializable_ShouldNotThrowException() {
474+
// Arrange
475+
TableMetadata metadata =
476+
TableMetadata.newBuilder()
477+
.addColumn("pk", DataType.INT)
478+
.addColumn("ck", DataType.INT)
479+
.addColumn("col", DataType.INT)
480+
.addPartitionKey("pk")
481+
.addClusteringKey("ck")
482+
.addSecondaryIndex("ck")
483+
.build();
484+
when(tableMetadata.getTableMetadata()).thenReturn(metadata);
485+
486+
Scan scan =
487+
Scan.newBuilder().namespace("ns").table("tbl").indexKey(Key.ofInt("ck", 100)).build();
488+
TransactionContext context =
489+
new TransactionContext("txId", null, Isolation.SERIALIZABLE, false, false);
490+
491+
// Act Assert
492+
assertThatCode(() -> checker.check(scan, context)).doesNotThrowAnyException();
493+
}
494+
405495
@Test
406496
public void
407497
checkForScan_ScanAllWithConditionOnIndexedColumnInSerializable_ShouldThrowIllegalArgumentException() {

0 commit comments

Comments
 (0)