Skip to content

Commit d37e3e5

Browse files
committed
Pull version information from systel.local, when version info is not
present
1 parent f3e0c62 commit d37e3e5

File tree

2 files changed

+57
-4
lines changed

2 files changed

+57
-4
lines changed

cassandra/metadata.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,9 @@ def export_schema_as_string(self):
139139
def refresh(self, connection, timeout, target_type=None, change_type=None, fetch_size=None,
140140
metadata_request_timeout=None, **kwargs):
141141

142-
server_version = self.get_host(connection.original_endpoint).release_version
143-
dse_version = self.get_host(connection.original_endpoint).dse_version
142+
host = self.get_host(connection.original_endpoint)
143+
server_version = host.release_version if host else None
144+
dse_version = host.dse_version if host else None
144145
parser = get_schema_parser(connection, server_version, dse_version, timeout, metadata_request_timeout, fetch_size)
145146

146147
if not target_type:
@@ -3409,8 +3410,27 @@ def __init__(
34093410
self.to_clustering_columns = to_clustering_columns
34103411

34113412

3413+
def get_column_from_system_local(connection, column_name: str, timeout, metadata_request_timeout) -> str:
3414+
success, local_result = connection.wait_for_response(
3415+
QueryMessage(
3416+
query=maybe_add_timeout_to_query(
3417+
"SELECT " + column_name + " FROM system.local WHERE key='local'",
3418+
metadata_request_timeout),
3419+
consistency_level=ConsistencyLevel.ONE)
3420+
, timeout=timeout, fail_on_error=False)
3421+
if not success or not local_result.parsed_rows:
3422+
return ""
3423+
local_rows = dict_factory(local_result.column_names, local_result.parsed_rows)
3424+
local_row = local_rows[0]
3425+
return local_row.get(column_name)
3426+
3427+
34123428
def get_schema_parser(connection, server_version, dse_version, timeout, metadata_request_timeout, fetch_size=None):
3413-
version = Version(server_version)
3429+
if server_version is None and dse_version is None:
3430+
server_version = get_column_from_system_local(connection, "release_version", timeout, metadata_request_timeout)
3431+
dse_version = get_column_from_system_local(connection, "dse_version", timeout, metadata_request_timeout)
3432+
3433+
version = Version(server_version or "0")
34143434
if dse_version:
34153435
v = Version(dse_version)
34163436
if v >= Version('6.8.0'):

tests/unit/test_metadata.py

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,11 @@
3030
UserType, KeyspaceMetadata, get_schema_parser,
3131
_UnknownStrategy, ColumnMetadata, TableMetadata,
3232
IndexMetadata, Function, Aggregate,
33-
Metadata, TokenMap, ReplicationFactor)
33+
Metadata, TokenMap, ReplicationFactor,
34+
SchemaParserDSE68)
3435
from cassandra.policies import SimpleConvictionPolicy
3536
from cassandra.pool import Host
37+
from cassandra.protocol import QueryMessage
3638
from tests.util import assertCountEqual
3739
import pytest
3840

@@ -616,6 +618,37 @@ def test_build_index_as_cql(self):
616618
assert index_meta.as_cql_query() == "CREATE CUSTOM INDEX index_name_here ON keyspace_name_here.table_name_here (column_name_here) USING 'class_name_here'"
617619

618620

621+
class SchemaParserLookupTests(unittest.TestCase):
622+
623+
def test_reads_versions_from_system_local_when_missing(self):
624+
connection = Mock()
625+
626+
release_version_resp = Mock()
627+
release_version_resp.column_names = ["release_version"]
628+
release_version_resp.parsed_rows = [["4.0.0"]]
629+
630+
dse_version_resp = Mock()
631+
dse_version_resp.column_names = ["dse_version"]
632+
dse_version_resp.parsed_rows = [["6.8.0"]]
633+
634+
def mock_system_local(query, *args, **kwargs):
635+
if not isinstance(query, QueryMessage):
636+
raise RuntimeError("first argument should be a QueryMessage")
637+
if "release_version" in query.query:
638+
return (True, release_version_resp)
639+
if "dse_version" in query.query:
640+
return (True, dse_version_resp)
641+
raise RuntimeError("unexpected query")
642+
643+
connection.wait_for_response.side_effect = mock_system_local
644+
645+
parser = get_schema_parser(connection, None, None, 0.1, None)
646+
647+
assert isinstance(parser, SchemaParserDSE68)
648+
message = connection.wait_for_response.call_args[0][0]
649+
assert "system.local" in message.query
650+
651+
619652
class UnicodeIdentifiersTests(unittest.TestCase):
620653
"""
621654
Exercise cql generation with unicode characters. Keyspace, Table, and Index names

0 commit comments

Comments
 (0)