Skip to content

feat: optimize system table queries with column projection (DRIVER-368)#862

Merged
dkropachev merged 1 commit intoscylladb:scylla-3.xfrom
nikagra:driver-368-optimize-system-local-query
May 7, 2026
Merged

feat: optimize system table queries with column projection (DRIVER-368)#862
dkropachev merged 1 commit intoscylladb:scylla-3.xfrom
nikagra:driver-368-optimize-system-local-query

Conversation

@nikagra
Copy link
Copy Markdown

@nikagra nikagra commented Apr 7, 2026

Closes https://scylladb.atlassian.net/browse/DRIVER-368

Backport of the same optimization done for the 4.x driver (DefaultTopologyMonitor), applied here to ControlConnection in the 3.x driver.

On the first connection to each system table (system.local, system.peers, system.peers_v2) the driver issues SELECT * to discover which columns the server exposes. It caches the intersection of those columns with a driver-internal *_COLUMNS_OF_INTEREST set. Subsequent queries project only those columns, reducing bytes on the wire and deserialization work.

Changes:

  • Three LOCAL/PEERS/PEERS_V2_COLUMNS_OF_INTEREST ImmutableSet<String> constants
  • Three volatile Set<String> cache fields (null = uninitialized sentinel)
  • intersectWithNeeded() and buildProjectedQuery() static helpers (@VisibleForTesting)
  • Cache reset in setNewConnection() and peers_v2 fallback path
  • Projected queries in refreshNodeListAndTokenMap(), selectPeersFuture(), and fetchNodeInfo() (system.local only)
  • fetchNodeInfo() uses SELECT * for peer WHERE-clause lookups (single-row reconnection path) to stay compatible with Scassandra primes on non-restarted nodes
  • New ControlConnectionUnitTest.java: 16 pure unit tests, no cluster required

@dkropachev
Copy link
Copy Markdown

@nikagra please check why cicd is failing

@nikagra nikagra marked this pull request as draft April 7, 2026 14:44
@nikagra nikagra requested review from Copilot and dkropachev April 9, 2026 21:26
@nikagra nikagra marked this pull request as ready for review April 9, 2026 21:26
Copy link
Copy Markdown

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 backports the 4.x “system table column projection” optimization to the 3.x driver’s ControlConnection, caching discovered system table columns (via initial SELECT *) and using projected SELECT col1, col2... for subsequent queries to reduce bytes/deserialization work.

Changes:

  • Add *_COLUMNS_OF_INTEREST constants, projected-column caches, and helper methods (intersectWithNeeded, buildProjectedQuery) in ControlConnection.
  • Update control connection system table queries to use projections once caches are warmed, and reset caches on reconnect / peers_v2 fallback.
  • Extend Scassandra priming to include projected-query primes and add unit tests covering the new helpers/caches.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
driver-core/src/main/java/com/datastax/driver/core/ControlConnection.java Adds column-interest sets, cache fields, cache reset, and switches system table queries to projected form after discovery.
driver-core/src/test/java/com/datastax/driver/core/ScassandraCluster.java Re-primes after restart and primes projected queries to match the driver’s new projected system-table queries.
driver-core/src/test/java/com/datastax/driver/core/ControlConnectionUnitTest.java New pure unit tests for projection helpers/constants and cache-field declarations.
driver-core/src/test/java/com/datastax/driver/core/ControlConnectionTest.java Resets column caches when Scassandra primes are cleared to avoid projected-query misses.

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

Comment thread driver-core/src/test/java/com/datastax/driver/core/ScassandraCluster.java Outdated
Comment thread driver-core/src/main/java/com/datastax/driver/core/ControlConnection.java Outdated
Comment thread driver-core/src/test/java/com/datastax/driver/core/ControlConnectionUnitTest.java Outdated
@nikagra nikagra force-pushed the driver-368-optimize-system-local-query branch from 0bf9092 to 4f9a052 Compare April 9, 2026 22:25
@nikagra
Copy link
Copy Markdown
Author

nikagra commented Apr 9, 2026

All CI failures have been resolved. The root issues were: projected WHERE-clause queries not primed in Scassandra for non-restarted nodes (fixed by using SELECT * for peer WHERE lookups in fetchNodeInfo), inconsistent host_id UUIDs across system.local and system.peers primes (fixed by computing UUIDs once per ScassandraCluster instance), and missing contains()-guarded columns in the PEERS/PEERS_V2_COLUMNS_OF_INTEREST sets. All 11 CI checks are now passing on the latest commit.

@nikagra nikagra force-pushed the driver-368-optimize-system-local-query branch from c37c98f to 4f9a052 Compare April 9, 2026 23:27
Comment thread driver-core/src/main/java/com/datastax/driver/core/ControlConnection.java Outdated
Comment thread driver-core/src/main/java/com/datastax/driver/core/ControlConnection.java Outdated
@nikagra nikagra force-pushed the driver-368-optimize-system-local-query branch from ab6f00c to 367ff74 Compare May 5, 2026 13:48
@nikagra nikagra requested a review from dkropachev May 5, 2026 13:50
Copy link
Copy Markdown

@dkropachev dkropachev left a comment

Choose a reason for hiding this comment

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

Looks great, can I ask you to run one experiment, could you please task ask AI to extract this new logic and variables and store them on a separate class, it should make code cleaner.

Comment thread driver-core/src/main/java/com/datastax/driver/core/ControlConnection.java Outdated
@nikagra nikagra force-pushed the driver-368-optimize-system-local-query branch 5 times, most recently from 35d66c5 to 2a7e9d7 Compare May 7, 2026 13:17
@dkropachev
Copy link
Copy Markdown

@nikagra , looks great, squash commits please

On the first query to each system table (system.local, system.peers,
system.peers_v2) the driver sends SELECT * to discover the server's schema.
The result is intersected with the set of columns the driver actually reads
and cached in SystemColumnProjection. Subsequent queries project only those
columns, reducing bytes on the wire and deserialization work.

Key design decisions:
- SystemColumnProjection owns a SystemTable enum (LOCAL, PEERS, PEERS_V2)
  and three unified methods: query(SystemTable), populate(SystemTable,
  ResultSet), and hook(SystemTable, DefaultResultSetFuture).
- populate() is called inside if (row != null) guards for WHERE-clause
  single-row lookups: an empty result still carries ColumnDefinitions in
  the metadata, so the cache must not be warmed from it.
- hook() is used for the async system.peers full-scan path where the
  result always reflects the server schema regardless of row count.
- Column caches are reset on reconnection and on InvalidQueryException so
  a server schema change causes the next query to re-discover columns via
  SELECT *.
- Projected column lists are sorted alphabetically for deterministic query
  strings; ScassandraCluster primes matching projected queries alongside
  SELECT * primes.
- Unit tests in ControlConnectionUnitTest cover intersectWithNeeded(),
  buildProjectedQuery(), hook() success/failure, and cache field modifiers.
@nikagra nikagra force-pushed the driver-368-optimize-system-local-query branch from 2a7e9d7 to 09dc403 Compare May 7, 2026 17:53
@nikagra nikagra requested a review from dkropachev May 7, 2026 17:56
@dkropachev dkropachev merged commit 43de6b3 into scylladb:scylla-3.x May 7, 2026
12 checks passed
@nikagra nikagra deleted the driver-368-optimize-system-local-query branch May 8, 2026 10:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants