diff --git a/locator/network_topology_strategy.cc b/locator/network_topology_strategy.cc index 6d9e05a5aa..61b685d336 100644 --- a/locator/network_topology_strategy.cc +++ b/locator/network_topology_strategy.cc @@ -58,9 +58,12 @@ network_topology_strategy::network_topology_strategy(replication_strategy_params } if (boost::iequals(key, "replication_factor")) { - throw exceptions::configuration_exception( - "replication_factor is an option for SimpleStrategy, not " - "NetworkTopologyStrategy"); + if (boost::equals(key, "replication_factor")) { + on_internal_error(rslogger, "replication_factor should have been replaced with a DC:RF mapping by now"); + } else { + throw exceptions::configuration_exception(format( + "'{}' is not a valid option, did you mean (lowercase) 'replication_factor'?", key)); + } } auto rf = parse_replication_factor(val); @@ -274,9 +277,8 @@ void network_topology_strategy::validate_options(const gms::feature_service& fs) validate_tablet_options(*this, fs, _config_options); for (auto& c : _config_options) { if (c.first == sstring("replication_factor")) { - throw exceptions::configuration_exception( - "replication_factor is an option for simple_strategy, not " - "network_topology_strategy"); + on_internal_error(rslogger, format("'replication_factor' tag should be unrolled into a list of DC:RF by now." + "_config_options:{}", _config_options)); } parse_replication_factor(c.second); } diff --git a/test/cqlpy/test_keyspace.py b/test/cqlpy/test_keyspace.py index be5f0b4672..2c72bb4d84 100644 --- a/test/cqlpy/test_keyspace.py +++ b/test/cqlpy/test_keyspace.py @@ -95,6 +95,19 @@ def test_create_keyspace_double_with(cql): with pytest.raises(SyntaxException): cql.execute('CREATE KEYSPACE ks WITH WITH DURABLE_WRITES = true') +# Scylla accepts 'replication_factor' in CREATE KEYSPACE statement, +# but while CQL syntax is case-insensitive, tags within json are case-sensitive, +# hence anything else than the lowercase 'replication_factor' should be rejected. +# Reproduces #15336 +def test_create_keyspace_with_case_sensitive_replication_factor_tag(cql): + ks = unique_name() + # lowercase 'replication_factor' should be accepted + with new_test_keyspace(cql, "WITH REPLICATION = { 'class' : 'NetworkTopologyStrategy', 'replication_factor' : 3 }"): + pass + # 'replication_factor' in any other case than the lowercase should be rejected + with pytest.raises(ConfigurationException): + cql.execute(f"CREATE KEYSPACE {ks} WITH REPLICATION = {{ 'class' : 'NetworkTopologyStrategy', 'Replication_factor' : 3 }}") + # Test trying a non-existent keyspace - with or without the IF EXISTS flag. # This test demonstrates a change of the exception produced between Cassandra 4.0 # and earlier versions (with Scylla behaving like the earlier versions).