Skip to content

Commit 7471988

Browse files
committed
Fix
1 parent e07c4ea commit 7471988

File tree

2 files changed

+104
-6
lines changed

2 files changed

+104
-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: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,48 @@ public void checkForGet_WithSecondaryIndexInSerializable_ShouldThrowIllegalArgum
284284
.isInstanceOf(IllegalArgumentException.class);
285285
}
286286

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

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

0 commit comments

Comments
 (0)