Skip to content

Conversation

@brfrn169
Copy link
Collaborator

@brfrn169 brfrn169 commented Nov 21, 2025

Description

This PR introduces a new method isConsistentVirtualTableReadGuaranteed() method to the StorageInfo interface to indicate whether a storage guarantees consistent reads for virtual tables.

Implementation:

  • Cassandra: Returns false (doesn't support virtual tables)
  • Cosmos DB: Returns false (doesn't support virtual tables)
  • DynamoDB: Returns false (doesn't support virtual tables)
  • JDBC: Dynamically determines based on the database's transaction isolation level:
    • MySQL/MariaDB: true if isolation level is REPEATABLE READ or SERIALIZABLE
    • PostgreSQL/YugabyteDB: true if isolation level is REPEATABLE READ or SERIALIZABLE
    • Oracle: true if isolation level is SERIALIZABLE
    • SQL Server: true if isolation level is REPEATABLE READ or SERIALIZABLE
    • SQLite: true if isolation level is SERIALIZABLE
    • DB2: true if isolation level is REPEATABLE READ or SERIALIZABLE

Related issues and/or PRs

N/A

Changes made

  • Added StorageInfo#isConsistentVirtualTableReadGuaranteed() method to indicate whether a storage guarantees consistent reads for virtual tables

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

Added isConsistentVirtualTableReadGuaranteed() method to the StorageInfo interface to indicate whether a storage guarantees consistent reads for virtual tables.

Copilot AI review requested due to automatic review settings November 21, 2025 04:23
@brfrn169 brfrn169 self-assigned this Nov 21, 2025
@brfrn169 brfrn169 added the enhancement New feature or request label Nov 21, 2025
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @brfrn169, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enhances the StorageInfo interface by adding a new method to explicitly communicate whether a given storage backend provides consistent reads for virtual tables. This allows the system to adapt its behavior based on the underlying storage's capabilities, particularly for JDBC-based databases where consistency depends on the configured transaction isolation level. The change ensures that the system can accurately reflect the consistency guarantees offered by different data sources when dealing with virtualized data.

Highlights

  • New Method for Virtual Table Read Consistency: Introduced isConsistentVirtualTableRead() to the StorageInfo interface, allowing storage backends to declare whether they guarantee consistent reads for virtual tables.
  • JDBC Dynamic Consistency Check: For JDBC-based storages, the isConsistentVirtualTableRead() status is dynamically determined based on the current transaction isolation level and the specific RDB engine's capabilities (e.g., REPEATABLE READ for MySQL/PostgreSQL, SERIALIZABLE for Oracle).
  • Storage-Specific Implementations: Cassandra, Cosmos DB, DynamoDB, and Object Storage implementations of StorageInfo now explicitly return false for isConsistentVirtualTableRead(), as they do not support virtual tables.
  • Internal API Note: Added a Javadoc note to DistributedStorageAdmin clarifying that StorageInfo is primarily for internal use and may be subject to breaking changes.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This PR introduces a new method isConsistentVirtualTableRead() to the StorageInfo interface. The implementation looks good, especially the dynamic check for JDBC storages. I've found a few issues, including a potential bug in StorageInfoImpl where equals() and hashCode() are not updated, and an incorrect isolation level for SQLite. I've also suggested a refactoring for the new tests in JdbcAdminTest to reduce duplication.

Also, please note there is an inconsistency in the method name between the PR description/release notes (isConsistentReadGuaranteed) and the actual implementation (isConsistentVirtualTableRead). It would be good to make them consistent.

Copilot finished reviewing on behalf of brfrn169 November 21, 2025 04:27
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 adds a new isConsistentVirtualTableRead() method to the StorageInfo interface to indicate whether a storage backend guarantees consistent reads for virtual tables. The implementation is storage-specific: most storage backends (Cassandra, Cosmos DB, DynamoDB, Object Storage) return false as they don't support virtual tables, while JDBC implementations dynamically determine the value based on the database's transaction isolation level.

Key changes:

  • Added isConsistentVirtualTableRead() method to StorageInfo interface with appropriate documentation
  • Implemented the method in StorageInfoImpl with a new boolean field
  • Updated all storage implementations (Cassandra, Cosmos, DynamoDB, Object Storage, JDBC, MultiStorage) to provide the new parameter
  • Added database-specific logic in each RdbEngine implementation to determine minimum isolation levels for consistent reads

Reviewed Changes

Copilot reviewed 24 out of 24 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
core/src/main/java/com/scalar/db/api/StorageInfo.java Added new isConsistentVirtualTableRead() method to interface
core/src/main/java/com/scalar/db/api/DistributedStorageAdmin.java Added documentation note that getStorageInfo is for internal use
core/src/main/java/com/scalar/db/common/StorageInfoImpl.java Added new boolean field and getter implementation
core/src/main/java/com/scalar/db/storage/jdbc/RdbEngineStrategy.java Added getMinimumIsolationLevelForConsistencyReads() method to interface
core/src/main/java/com/scalar/db/storage/jdbc/RdbEngine*.java Implemented isolation level logic for MySQL, PostgreSQL, Oracle, SQL Server, SQLite, and DB2
core/src/main/java/com/scalar/db/storage/jdbc/JdbcAdmin.java Changed getStorageInfo() to dynamically determine consistent read guarantee based on isolation level
core/src/main/java/com/scalar/db/storage/cassandra/CassandraAdmin.java Updated to pass false for consistent virtual table reads
core/src/main/java/com/scalar/db/storage/cosmos/CosmosAdmin.java Updated to pass false for consistent virtual table reads
core/src/main/java/com/scalar/db/storage/dynamo/DynamoAdmin.java Updated to pass false for consistent virtual table reads
core/src/main/java/com/scalar/db/storage/objectstorage/ObjectStorageAdmin.java Updated to pass false for consistent virtual table reads
core/src/main/java/com/scalar/db/storage/objectstorage/ObjectStorageWrapper.java Enhanced documentation for close() method (unrelated to main feature)
core/src/main/java/com/scalar/db/storage/multistorage/MultiStorageAdmin.java Updated to forward the new field from underlying storage
Test files Updated all test instantiations of StorageInfoImpl to include the new boolean parameter and added comprehensive tests for isolation level behavior

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +395 to +396
// In SQLite, READ COMMITTED and higher isolation levels guarantee consistent reads
return Connection.TRANSACTION_READ_COMMITTED;
Copy link

Copilot AI Nov 21, 2025

Choose a reason for hiding this comment

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

The comment states "In SQLite, READ COMMITTED and higher isolation levels guarantee consistent reads", but this may be misleading. SQLite's transaction isolation is different from standard SQL databases - it uses a simpler locking model. SQLite's "SERIALIZABLE" isolation (which is its default and only true isolation level) is what provides consistent reads. The JDBC driver may report different isolation levels, but SQLite doesn't actually implement READ COMMITTED in the traditional sense.

Consider verifying this behavior with SQLite's actual isolation level semantics and updating the comment to be more accurate, or changing the return value to Connection.TRANSACTION_SERIALIZABLE if that's what SQLite actually provides.

Suggested change
// In SQLite, READ COMMITTED and higher isolation levels guarantee consistent reads
return Connection.TRANSACTION_READ_COMMITTED;
// In SQLite, only SERIALIZABLE isolation is truly supported and guarantees consistent reads.
return Connection.TRANSACTION_SERIALIZABLE;

Copilot uses AI. Check for mistakes.
Copy link
Contributor

Choose a reason for hiding this comment

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

@brfrn169
I also quickly checked it, and it seems like it's true that SQLite only provides only SERIALIZABLE.
https://sqlite.org/isolation.html

Can we still set TRANSACTION_READ_COMMITTED through JDBC? (and it's ignored in the SQLite side?)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@feeblefakie My understanding is that the isolation levels except TRANSACTION_READ_UNCOMMITTED are effectively treated as TRANSACTION_SERIALIZABLE. Therefore, we can accept TRANSACTION_READ_COMMITTED, TRANSACTION_REPEATABLE_READ, and TRANSACTION_SERIALIZABLE.

What do you think?

Can we still set TRANSACTION_READ_COMMITTED through JDBC? (and it's ignored in the SQLite side?)

Yes, it seems like we can set TRANSACTION_READ_COMMITTED through JDBC without any errors.


@Override
public int getMinimumIsolationLevelForConsistencyReads() {
// In PostgreSQL, REPEATABLE READ and SERIALIZABLE isolation levels guarantee consistent reads
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you elaborate why READ_COMMITTED doesn't work for the virtual table consistent reads? It would be great if you'll write down it as a comment here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

A virtual table is composed of two source tables, and although we read data through the joined view, the underlying reads are actually performed on both source tables. In READ_COMMITTED isolation, this may lead to observing an inconsistent snapshot—for example, reading an older state from the left source table and a newer state from the right source table.

To prevent this situation, we need a consistent snapshot across both source tables. In PostgreSQL, this requires using the REPEATABLE READ or SERIALIZABLE isolation level.

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! Thank you!
Left some comments and suggestions.

Comment on lines +395 to +396
// In SQLite, READ COMMITTED and higher isolation levels guarantee consistent reads
return Connection.TRANSACTION_READ_COMMITTED;
Copy link
Contributor

Choose a reason for hiding this comment

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

@brfrn169
I also quickly checked it, and it seems like it's true that SQLite only provides only SERIALIZABLE.
https://sqlite.org/isolation.html

Can we still set TRANSACTION_READ_COMMITTED through JDBC? (and it's ignored in the SQLite side?)

@brfrn169 brfrn169 changed the title Add isConsistentVirtualTableRead() to StorageInfo Add isConsistentVirtualTableReadGuaranteed() to StorageInfo Nov 21, 2025
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!
But, I left one suggestion. PTAL!


String getTableNamesInNamespaceSql();

int getMinimumIsolationLevelForConsistentVirtualTableReads();
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
int getMinimumIsolationLevelForConsistentVirtualTableReads();
int getMinimumIsolationLevelForConsistentVirtualTableRead();

Should it be consistent with isConsistentVirtualTableReadGuaranteed?

Copy link
Contributor

@Torch3333 Torch3333 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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants