Skip to content

Commit

Permalink
fix(cluster helper func): double quoting in keyspace names
Browse files Browse the repository at this point in the history
When keyspace names start with a digit, they are returned with
surrounding double quotes. This can lead to double quoting in CQL
statements that can lead to SCT failure. This commit updates the
get_test_keyspaces func to strip these extra quotes. If keyspace
isnt quoted the change is harmless
  • Loading branch information
timtimb0t committed Mar 4, 2025
1 parent 5df8e28 commit 58b7e7d
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 4 deletions.
9 changes: 5 additions & 4 deletions sdcm/nemesis.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
from elasticsearch.exceptions import ConnectionTimeout as ElasticSearchConnectionTimeout
from argus.common.enums import NemesisStatus

from sdcm.utils.cql_utils import cql_unquote_if_needed
from sdcm import wait
from sdcm.audit import Audit, AuditConfiguration, AuditStore
from sdcm.cluster import (
Expand Down Expand Up @@ -2065,7 +2066,7 @@ def _prepare_test_table(self, ks='keyspace1', table=None):
ks_cfs = self.cluster.get_non_system_ks_cf_list(db_node=self.target_node)
table_exist = f'{ks}.{table}' in ks_cfs if table else True

test_keyspaces = self.cluster.get_test_keyspaces()
test_keyspaces = [cql_unquote_if_needed(ks) for ks in self.cluster.get_test_keyspaces()]
# if keyspace or table doesn't exist, create it by cassandra-stress
if ks not in test_keyspaces or not table_exist:
stress_cmd = "cassandra-stress write n=400000 cl=QUORUM -mode native cql3 " \
Expand Down Expand Up @@ -3093,7 +3094,7 @@ def execute_data_validation_thread(command_template, keyspace_name, number_of_ro

self.log.info("Restoring the keyspace %s", chosen_snapshot_info["keyspace_name"])
location_list = [f"{self.cluster.params.get('backup_bucket_backend')}:{target_bucket}"]
test_keyspaces = [keyspace.replace('"', '') for keyspace in self.cluster.get_test_keyspaces()]
test_keyspaces = [cql_unquote_if_needed(keyspace) for keyspace in self.cluster.get_test_keyspaces()]
# Keyspace names that start with a digit are surrounded by quotation marks in the output of a describe query
if chosen_snapshot_info["keyspace_name"] not in test_keyspaces:
self.log.info("Restoring the schema of the keyspace '%s'",
Expand Down Expand Up @@ -3169,7 +3170,7 @@ def _mgmt_backup(self, backup_specific_tables):
location = f"{backup_bucket_backend}:{backup_bucket_location.split()[0]}"
self._delete_existing_backups(mgr_cluster)
if backup_specific_tables:
non_test_keyspaces = self.cluster.get_test_keyspaces()
non_test_keyspaces = [cql_unquote_if_needed(ks) for ks in self.cluster.get_test_keyspaces()]
mgr_task = mgr_cluster.create_backup_task(location_list=[location, ], keyspace_list=non_test_keyspaces)
else:
mgr_task = mgr_cluster.create_backup_task(location_list=[location, ])
Expand Down Expand Up @@ -4410,7 +4411,7 @@ def _enable_disable_table_encryption(self, enable_kms_key_rotation, additional_s
node.restart_scylla()

# Create table with encryption
keyspace_name, table_name = self.cluster.get_test_keyspaces()[0], 'tmp_encrypted_table'
keyspace_name, table_name = cql_unquote_if_needed(self.cluster.get_test_keyspaces()[0]), 'tmp_encrypted_table'
self.log.info("Create '%s.%s' table with server encryption", keyspace_name, table_name)
with self.cluster.cql_connection_patient(self.target_node, keyspace=keyspace_name) as session:
# NOTE: scylla-bench expects following table structure:
Expand Down
21 changes: 21 additions & 0 deletions sdcm/utils/cql_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,24 @@ def cql_quote_if_needed(identifier: str) -> str:
if not identifier_regex.match(identifier):
return f'"{identifier}"'
return identifier


def cql_unquote_if_needed(identifier: str):
"""
This function only removes the quotes if both the first and last characters
of the cql_response are double quotes. This ensures that any quotes inside the
cql_response remain intact.
For example:
- '"5gb_sizetiered_6_1"' becomes '5gb_sizetiered_6_1'
- '5gb_sizetiered_6_1' remains unchanged.
Args:
identifier (str): Raw CQL response that might be quoted.
Returns:
str: The unquoted identifier if the outer quotes are present, otherwise the original response.
"""
if identifier and len(identifier) >= 2 and identifier.startswith('"') and identifier.endswith('"'):
return identifier[1:-1]
return identifier

0 comments on commit 58b7e7d

Please sign in to comment.