Skip to content

CASSANALYTICS-183: Pass quoted identifiers to sidecar API calls for mixed-case keyspace/table restore - #226

Open
bianca-stanciu29 wants to merge 7 commits into
apache:trunkfrom
bianca-stanciu29:CASSANALYTICS-183
Open

bianca-stanciu29 wants to merge 7 commits into
apache:trunkfrom
bianca-stanciu29:CASSANALYTICS-183

Conversation

@bianca-stanciu29

@bianca-stanciu29 bianca-stanciu29 commented Jul 22, 2026 •

Copy link
Copy Markdown

Problem

When quoteIdentifiers=true, Analytics must preserve case-sensitive
keyspace and table names when constructing Sidecar requests.

Some request paths were passing raw names instead of quoted identifiers.
For example, a keyspace created as "MyKeyspace" could be looked up as
mykeyspace, causing restore operations to fail with:

Keyspace does not exist: MyKeyspace

Solution

Add maybeQuotedKeyspace() and maybeQuotedTable() to QualifiedTableName,
reusing its existing maybeQuote() helper.

Use these accessors when constructing cloud-storage restore requests:

  • Restore-job creation, summary, update, and abort.
  • Direct and coordinated restore-slice requests.
  • Coordinated restore-job progress requests.

Also apply identifier quoting to bulk-writer token-range requests and
pass the existing quoted identifiers into reader sizing/table-statistics
requests.

Compatibility

Keep keyspace() and table() as raw-name accessors so existing callers
outside the Sidecar request boundaries retain their current behavior.

The new accessors apply quoting only when quoteIdentifiers=true.
When quoteIdentifiers=false, names remain unchanged.

Related Sidecar change

CASSSIDECAR-475 addresses identifier resolution during metadata lookup
inside Sidecar. This PR addresses how Analytics supplies identifiers
to the affected Sidecar APIs.

https://issues.apache.org/jira/browse/CASSSIDECAR-475

private TokenRangeReplicasResponse getTokenRangesAndReplicaSets()
{
CassandraContext context = getCassandraContext();
String quotedKeyspace = maybeQuotedIdentifier(bridge(), conf.quoteIdentifiers, conf.keyspace);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: change name to maybeQuotedKeyspace?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Done, renamed the local variable to maybeQuotedKeyspace in CassandraClusterInfo.

}

@Test
void testCreateRestoreJobUsesQuotedIdentifiers() throws Exception

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What do you think about adding quoted identifiers tests to the other modified APIs?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Done, added tests for quoted identifiers in the direct and coordinated restore-slice requests, coordinated restore-job progress, cluster schema and token-range requests, and dynamic sizing/table-stats calls.

/**
* @return the keyspace name, quoted with double quotes when {@code quoteIdentifiers} is set
*/
public String maybeQuotedKeyspace()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Wondering here if we really need wrappers with the "maybe*" prefix, or we can just use this as default for keyspace() and table(). What do you think @yifan-c / @frankgh ?

@bianca-stanciu29 bianca-stanciu29 Oct 2, 2026 •

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

@bbotella @yifan-c @frankgh I think we should keep keyspace() and table() as raw-name accessors. They’re also used for SSTable metadata, local data-layer setup, and job statistics, so returning quoted names would require checking those callers too. The separate maybeQuoted accessors let us apply quoting when building Sidecar requests without changing other uses. CASSSIDECAR-475 fixes the metadata lookup inside Sidecar, but that’s separate from what these analytics accessors return. What do you think?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Hi @bbotella @yifan-c @frankgh, any further thoughts on keeping the raw-name accessors? If the approach looks good, could I get a +1 to merge into trunk? Thanks!

bianca-stanciu29 and others added 2 commits October 2, 2026 10:47
Rename the conditional keyspace value and verify quoted names in restore, coordinated, topology, and sizing requests.
@yifan-c yifan-c changed the title [CASSANALYTICS-183] - Pass quoted identifiers to sidecar API calls for mixed-case keyspace/table restore CASSANALYTICS-183: Pass quoted identifiers to sidecar API calls for mixed-case keyspace/table restore Oct 6, 2026

@yifan-c yifan-c left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hi @bianca-stanciu29,

First of all, thanks for sending the fix! It is real. I'd apologies for the belated review as well.

Please see my comments inline.

Comment on lines +68 to +75
/**
* @return the keyspace name, quoted with double quotes when {@code quoteIdentifiers} is set
*/
public String maybeQuotedKeyspace()
{
return maybeQuote(keyspace);
}

@yifan-c yifan-c Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Instead of adding the maybeQuotedX methods, could you please use the helper org.apache.cassandra.bridge.CassandraBridgeFactory#maybeQuotedIdentifier for code consistency? You can find code example in org.apache.cassandra.spark.bulkwriter.SidecarDataTransferApi.

Comment on lines -296 to +297
.tokenRangeReplicas(new ArrayList<>(context.getCluster()), conf.keyspace)
.tokenRangeReplicas(new ArrayList<>(context.getCluster()), maybeQuotedKeyspace)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please drop this change.

Mixed-case is already proven working in org.apache.cassandra.analytics.QuoteIdentifiersWriteTest. Quoting the name could cause regression.

In Sidecar, TokenRangeReplicaMapHandler retrieves range info from JMX endpoints, which take case-sensitive string and require no quotes.

Comment on lines -1192 to +1194
return SizingFactory.create(replicationFactor, options, consistencyLevel, keyspace, table, datacenter, sidecar, sidecarPort, ringFuture);
return SizingFactory.create(replicationFactor, options, consistencyLevel,
maybeQuotedKeyspace, maybeQuotedTable, datacenter,
sidecar, sidecarPort, ringFuture);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please drop this change. It is unrelated to the fix for the restore path.

Sizing is backed by TableStatsHandler and JMX internally in Sidecar. Quoting the name could regress.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants