-
Notifications
You must be signed in to change notification settings - Fork 40
Handle Get with index correctly in CrudHandler #2700
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Handle Get with index correctly in CrudHandler #2700
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR enhances the CrudHandler to correctly handle Get operations that use a secondary index by deferring key construction until after the storage read and by updating both handler logic and snapshot state accordingly.
- Introduces
@Nullablekey handling inCrudHandler.get,readUnread, andreadfor index-based queries. - Adds a new
Snapshot.Key(Get, Result)constructor to build the key post-read when using an index. - Extends unit and integration tests to verify
Get/Scanwith index flows, including update scenarios and snapshot interactions.
Reviewed Changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| integration-test/.../ConsensusCommitSpecificIntegrationTestBase.java | New integration tests for “get with index” update and scan/update flows. |
| core/src/test/java/com/scalar/db/transaction/consensuscommit/CrudHandlerTest.java | Tests added for readUnread behavior on index-based Get. |
| core/src/main/java/com/scalar/db/transaction/consensuscommit/Snapshot.java | Added a Key(Get, Result) constructor to derive keys after fetching via index. |
| core/src/main/java/com/scalar/db/transaction/consensuscommit/CrudHandler.java | Modified get, readUnread, and read to handle nullable keys for secondary-index Gets. |
Comments suppressed due to low confidence (2)
core/src/test/java/com/scalar/db/transaction/consensuscommit/CrudHandlerTest.java:59
- [nitpick] The constant
ANY_NAME_3is not self-explanatory. Rename it to something likeSECONDARY_INDEX_COLUMNto clarify that it represents the indexed field in these tests.
private static final String ANY_NAME_3 = "name3";
core/src/main/java/com/scalar/db/transaction/consensuscommit/CrudHandler.java:76
- [nitpick] The Javadoc for this method should be updated to explain how secondary-index
Gets are treated (e.g., key construction is deferred and passed asnull). This will help future maintainers understand the dual path.
public Optional<Result> get(Get originalGet) throws CrudException {
core/src/main/java/com/scalar/db/transaction/consensuscommit/CrudHandler.java
Show resolved
Hide resolved
| public Key(Get get) { | ||
| this((Operation) get); | ||
| } | ||
|
|
Copilot
AI
May 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] Add a JavaDoc comment to this constructor clarifying that it builds a snapshot key from an index-based Get and its corresponding Result, detailing which fields are used.
| /** | |
| * Constructs a snapshot key from an index-based {@link Get} operation and its corresponding {@link Result}. | |
| * | |
| * <p>The following fields are used: | |
| * <ul> | |
| * <li>{@code namespace} and {@code table} are extracted from the {@link Get} operation.</li> | |
| * <li>{@code partitionKey} and {@code clusteringKey} are extracted from the {@link Result}.</li> | |
| * </ul> | |
| * | |
| * @param get the {@link Get} operation representing the index-based query | |
| * @param result the {@link Result} containing the actual data for the key | |
| */ |
| public void scanAndUpdate_ScanWithIndexGiven_ShouldUpdate() throws TransactionException { | ||
| // Arrange | ||
| manager.mutate( | ||
| Arrays.asList( |
Copilot
AI
May 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] Since this is Java 9+, consider using List.of(...) instead of Arrays.asList(...) for brevity and to get an immutable list by default.
| Arrays.asList( | |
| List.of( |
ad83939 to
0a0c882
Compare
0a0c882 to
a45f7a9
Compare
| Snapshot.Key key; | ||
| if (ScalarDbUtils.isSecondaryIndexSpecified(get, metadata)) { | ||
| // In case of a Get with index, we don't know the key until we read the record | ||
| key = null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For Get with index, set key to null at this point.
| if (result.isPresent()) { | ||
| // Only when we can get the record with the Get with index, we can put it into the read | ||
| // set | ||
| key = new Snapshot.Key(get, result.get()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Create a Snapshot.Key instance from the result of the Get with index.
feeblefakie
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Thank you!
komamitsu
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! 👍
Torch3333
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thank you!
Description
Currently, we create a
Snapshot.Keyinstance from theGetobject inCrudHandler, as shown here:scalardb/core/src/main/java/com/scalar/db/transaction/consensuscommit/CrudHandler.java
Line 79 in 63520eb
This approach works for regular Get operations. However, it is incorrect for Get operations using a secondary index, as they do not contain primary key information. In such cases, we should create the
Snapshot.Keyinstance from the result of the secondary index Get operation. This bug can lead to unnecessary implicit pre-reads when updating records retrieved by a secondary index Get operation within a transaction.To fix this issue, this PR updates
CrudHandlerto correctly handle Get operations that use secondary indexes.Related issues and/or PRs
N/A
Changes made
I’ve added some inline comments. Please take a look for the details.
Checklist
Additional notes (optional)
N/A
Release notes
Fixed a bug that caused unnecessary implicit pre-reads when updating records retrieved by a secondary index Get operation within a transaction.