Skip to content

Conversation

@brfrn169
Copy link
Collaborator

@brfrn169 brfrn169 commented Jun 18, 2025

Description

This PR updates the code to handle Get and Scan with conjunctions correctly in Consensus Commit.

When users specify conjunctions for Get and Scan operations, the same conjunctions also need to be applied to the columns in the before images. The reason is explained in the following Javadoc—please refer to it for details:

https://github.com/scalar-labs/scalardb/pull/2786/files#diff-acc93f1366b03168017001646c7217f7dd1f3c7cbe8a41b6a9a8484dc5ef0905R482-R546

Related issues and/or PRs

N/A

Changes made

  • Update the code to convert the conjunctions when users specify conjunctions for Get and Scan operations.

Checklist

The following is a best-effort checklist. If any items in this checklist are not applicable to this PR or are dependent on other, unmerged PRs, please still mark the checkboxes after you have read and understood each item.

  • I have commented my code, particularly in hard-to-understand areas.
  • I have updated the documentation to reflect the changes.
  • I have considered whether similar issues could occur in other products, components, or modules if this PR is for bug fixes.
  • Any remaining open issues linked to this PR are documented and up-to-date (Jira, GitHub, etc.).
  • Tests (unit, integration, etc.) have been added for the changes.
  • My changes generate no new warnings.
  • Any dependent changes in other PRs have been merged and published.

Additional notes (optional)

N/A

Release notes

Fixed a bug where records could be missed when executing Get or Scan with conjunctions in Consensus Commit.

@brfrn169 brfrn169 requested a review from Copilot June 18, 2025 04:59
@brfrn169 brfrn169 self-assigned this Jun 18, 2025
Copy link
Contributor

Copilot AI left a 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 fixes a bug in handling Get and Scan operations with conjunctions in Consensus Commit by filtering records based on before image conditions. Key changes include updating the read and scan methods to correctly throw exceptions for uncommitted records, introducing optional filtering with conjunctions, and adding logic to convert conjunctions for before image conditions.

Reviewed Changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.

File Description
core/src/main/java/com/scalar/db/transaction/consensuscommit/CrudHandler.java Updated read and scan handling with conjunctions and before image conditions
core/src/main/java/com/scalar/db/api/LikeExpression.java Minor documentation and type refinements for text columns
core/src/main/java/com/scalar/db/api/ConditionBuilder.java Added a buildLikeExpression utility method with corresponding documentation
Comments suppressed due to low confidence (2)

core/src/main/java/com/scalar/db/transaction/consensuscommit/CrudHandler.java:267

  • [nitpick] Consider renaming the variable 'ret' to a more descriptive name such as 'filteredResult' to enhance code readability.
    Optional<TransactionResult> ret = Optional.of(result);

core/src/main/java/com/scalar/db/transaction/consensuscommit/CrudHandler.java:165

  • If 'result' is empty and 'get.getConjunctions()' is not empty, the subsequent call to 'result.get()' in the throw statement will cause a NoSuchElementException. Consider handling the empty result case explicitly without calling 'result.get()'.
    if (result.isPresent() || get.getConjunctions().isEmpty()) {

Copy link
Contributor

@feeblefakie feeblefakie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, looking good.
Left one suggestion for the comment.

* | 0 | 1 | 200 | PREPARED | 1000 | COMMITTED |
* </pre>
*
* If we scan records with the condition `column = 1000`, we will only retrieve the first record,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The description is a bit weird to me.
How about something like below?

If we scan records with the condition "column = 1000" without converting the condition (conjunction), we only get the first record, not the second one, because the condition does not match. However, the second record has not been committed yet, so we should still retrieve it, considering the possibility that the record will be rolled back.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 683337b. Thanks!

@brfrn169 brfrn169 requested a review from feeblefakie June 18, 2025 06:44
Copy link
Contributor

@feeblefakie feeblefakie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thank you!


@Test
public void
get_WithConjunction_ForCommittedRecordWhoseBeforeImageMatchesConjunction_ShouldNotReturnRecordAfterLazyRecovery()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC, the final state is already COMMITTED and no lazy recovery occurs?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! Let me fix it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 6c16dcd. Thanks!

Copy link
Contributor

@komamitsu komamitsu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! 👍

Copy link
Contributor

@jnmt jnmt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for finding the bug. Overall looks good to me. I just left a confirmation. PTAL!

Comment on lines +171 to +180
if (key != null) {
putIntoReadSetInSnapshot(key, result);
} else {
// Only for a Get with index, the argument `key` is null

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());
putIntoReadSetInSnapshot(key, result);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmation. The issue we discussed before (unexpected snapshot overwrite) will be resolved in another PR, or am I missing the point?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will address that issue in another PR. Thanks!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. Thank you!

@brfrn169 brfrn169 requested a review from jnmt June 18, 2025 08:57
Copy link
Contributor

@jnmt jnmt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you!

putIntoReadSetInSnapshot(key, result);
}
if (!get.getConjunctions().isEmpty()) {
// Check if the result matches the conjunctions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's likely this check exists because we get records based on not only the current image but also before image using OR conditions. We would like to filter the case where the second record is committed in the example of the Javadoc comment. If my understanding is correct, it might be nice to have a comment like this for future readers to easily grasp the reasoning.

Suggested change
// Check if the result matches the conjunctions
// Because we also get records whose before images match the conjunctions, we need to check if
// the current status of the records actually match the conjunctions.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 4ec25d6. Thanks!

Comment on lines +171 to +180
if (key != null) {
putIntoReadSetInSnapshot(key, result);
} else {
// Only for a Get with index, the argument `key` is null

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());
putIntoReadSetInSnapshot(key, result);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. Thank you!

putIntoReadSetInSnapshot(key, Optional.of(result));
Optional<TransactionResult> ret = Optional.of(result);
if (!scan.getConjunctions().isEmpty()) {
// Check if the result matches the conjunctions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto.

Suggested change
// Check if the result matches the conjunctions
// Because we also get records whose before images match the conjunctions, we need to check if
// the current status of the records actually match the conjunctions.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 4ec25d6. Thanks!

@brfrn169 brfrn169 merged commit aadc7f8 into master Jun 18, 2025
53 checks passed
@brfrn169
Copy link
Collaborator Author

@Torch3333 I'll merge this. Please take a look when you have time!

@brfrn169 brfrn169 deleted the handle-get-and-scan-with-conjunctions-correcctly-in-consensus-commit branch June 18, 2025 14:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants