You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by sl...@apache.org on 2012/10/04 11:22:37 UTC
git commit: Add AlterKeyspace statement to 1.1
Updated Branches:
refs/heads/cassandra-1.1 59a6a5d82 -> 2ce7b9b3a
Add AlterKeyspace statement to 1.1
patch by slebresne; reviewed by xedin for CASSANDRA-4611
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/2ce7b9b3
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/2ce7b9b3
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/2ce7b9b3
Branch: refs/heads/cassandra-1.1
Commit: 2ce7b9b3ada14182067c934c475c6ab899086355
Parents: 59a6a5d
Author: Sylvain Lebresne <sy...@datastax.com>
Authored: Thu Oct 4 11:19:21 2012 +0200
Committer: Sylvain Lebresne <sy...@datastax.com>
Committed: Thu Oct 4 11:19:21 2012 +0200
----------------------------------------------------------------------
CHANGES.txt | 1 +
.../org/apache/cassandra/config/KSMetaData.java | 8 +-
.../org/apache/cassandra/cql/QueryProcessor.java | 3 +-
src/java/org/apache/cassandra/cql3/CFPropDefs.java | 123 +++------------
src/java/org/apache/cassandra/cql3/Cql.g | 35 +++--
src/java/org/apache/cassandra/cql3/KSPropDefs.java | 89 +++++++++++
.../apache/cassandra/cql3/PropertyDefinitions.java | 122 ++++++++++++++
.../cql3/statements/AlterKeyspaceStatement.java | 95 +++++++++++
.../cql3/statements/AlterTableStatement.java | 10 +-
.../statements/CreateColumnFamilyStatement.java | 23 ++-
.../cql3/statements/CreateKeyspaceStatement.java | 31 ++---
11 files changed, 387 insertions(+), 153 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2ce7b9b3/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index d803c0f..cb725cc 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -16,6 +16,7 @@
* Fix CQL3 'is reversed' logic (CASSANDRA-4716)
* (CQL3) Don't return ReversedType in result set metadata (CASSANDRA-4717)
* Pluggable Thrift transport factories for CLI (CASSANDRA-4609)
+ * Backport adding AlterKeyspace statement (CASSANDRA-4611)
Merged from 1.0:
* Switch from NBHM to CHM in MessagingService's callback map, which
prevents OOM in long-running instances (CASSANDRA-4708)
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2ce7b9b3/src/java/org/apache/cassandra/config/KSMetaData.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/config/KSMetaData.java b/src/java/org/apache/cassandra/config/KSMetaData.java
index 7b27875..a5fccc3 100644
--- a/src/java/org/apache/cassandra/config/KSMetaData.java
+++ b/src/java/org/apache/cassandra/config/KSMetaData.java
@@ -60,18 +60,18 @@ public final class KSMetaData
}
// For new user created keyspaces (through CQL)
- public static KSMetaData newKeyspace(String name, String strategyName, Map<String, String> options) throws ConfigurationException
+ public static KSMetaData newKeyspace(String name, String strategyName, Map<String, String> options, boolean durableWrites) throws ConfigurationException
{
Class<? extends AbstractReplicationStrategy> cls = AbstractReplicationStrategy.getClass(strategyName);
if (cls.equals(LocalStrategy.class))
throw new ConfigurationException("Unable to use given strategy class: LocalStrategy is reserved for internal use.");
- return newKeyspace(name, cls, options, Collections.<CFMetaData>emptyList());
+ return newKeyspace(name, cls, options, durableWrites, Collections.<CFMetaData>emptyList());
}
- public static KSMetaData newKeyspace(String name, Class<? extends AbstractReplicationStrategy> strategyClass, Map<String, String> options, Iterable<CFMetaData> cfDefs)
+ public static KSMetaData newKeyspace(String name, Class<? extends AbstractReplicationStrategy> strategyClass, Map<String, String> options, boolean durablesWrites, Iterable<CFMetaData> cfDefs)
{
- return new KSMetaData(name, strategyClass, options, true, cfDefs);
+ return new KSMetaData(name, strategyClass, options, durablesWrites, cfDefs);
}
public static KSMetaData cloneWith(KSMetaData ksm, Iterable<CFMetaData> cfDefs)
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2ce7b9b3/src/java/org/apache/cassandra/cql/QueryProcessor.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql/QueryProcessor.java b/src/java/org/apache/cassandra/cql/QueryProcessor.java
index 4a829c6..ab1c15b 100644
--- a/src/java/org/apache/cassandra/cql/QueryProcessor.java
+++ b/src/java/org/apache/cassandra/cql/QueryProcessor.java
@@ -700,7 +700,8 @@ public class QueryProcessor
{
KSMetaData ksm = KSMetaData.newKeyspace(create.getName(),
create.getStrategyClass(),
- create.getStrategyOptions());
+ create.getStrategyOptions(),
+ true);
ThriftValidation.validateKeyspaceNotYetExisting(ksm.name);
MigrationManager.announceNewKeyspace(ksm);
validateSchemaIsSettled();
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2ce7b9b3/src/java/org/apache/cassandra/cql3/CFPropDefs.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/CFPropDefs.java b/src/java/org/apache/cassandra/cql3/CFPropDefs.java
index 01e14fb..ab209dd 100644
--- a/src/java/org/apache/cassandra/cql3/CFPropDefs.java
+++ b/src/java/org/apache/cassandra/cql3/CFPropDefs.java
@@ -18,7 +18,16 @@
*/
package org.apache.cassandra.cql3;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
import com.google.common.collect.Sets;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import org.apache.cassandra.config.CFMetaData;
import org.apache.cassandra.config.ConfigurationException;
import org.apache.cassandra.db.compaction.AbstractCompactionStrategy;
@@ -29,12 +38,7 @@ import org.apache.cassandra.thrift.InvalidRequestException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-public class CFPropDefs
+public class CFPropDefs extends PropertyDefinitions
{
private static Logger logger = LoggerFactory.getLogger(CFPropDefs.class);
@@ -89,7 +93,6 @@ public class CFPropDefs
allowedKeywords.addAll(obsoleteKeywords);
}
- public final Map<String, String> properties = new HashMap<String, String>();
private Class<? extends AbstractCompactionStrategy> compactionStrategyClass = null;
public final Map<String, String> compactionStrategyOptions = new HashMap<String, String>();
public final Map<String, String> compressionParameters = new HashMap<String, String>()
@@ -115,18 +118,9 @@ public class CFPropDefs
}
}
- /* If not comparator/validator is not specified, default to text (BytesType is the wrong default for CQL
- * since it uses hex terms). If the value specified is not found in the comparators map, assume the user
- * knows what they are doing (a custom comparator/validator for example), and pass it on as-is.
- */
-
- public void validate() throws ConfigurationException
+ public void validate() throws ConfigurationException, InvalidRequestException
{
- // Catch the case where someone passed a kwarg that is not recognized.
- for (String bogus : Sets.difference(properties.keySet(), allowedKeywords))
- throw new ConfigurationException(bogus + " is not a valid keyword argument for CREATE TABLE");
- for (String obsolete : Sets.intersection(properties.keySet(), obsoleteKeywords))
- logger.warn("Ignoring obsolete property {}", obsolete);
+ validate(keywords, obsoleteKeywords);
if (properties.containsKey(KW_COMPACTION_STRATEGY_CLASS))
{
@@ -135,8 +129,8 @@ public class CFPropDefs
}
}
- /** Map a keyword to the corresponding value */
- public void addProperty(String name, String value)
+ @Override
+ public void addProperty(String name, String value) throws InvalidRequestException
{
String[] composite = name.split(":");
if (composite.length > 1)
@@ -152,24 +146,13 @@ public class CFPropDefs
return;
}
}
- properties.put(name, value);
- }
-
- public void addAll(Map<String, String> propertyMap)
- {
- for (Map.Entry<String, String> entry : propertyMap.entrySet())
- addProperty(entry.getKey(), entry.getValue());
- }
-
- public Boolean hasProperty(String name)
- {
- return properties.containsKey(name);
+ super.addProperty(name, value);
}
- public void applyToCFMetadata(CFMetaData cfm) throws ConfigurationException
+ public void applyToCFMetadata(CFMetaData cfm) throws ConfigurationException, InvalidRequestException
{
if (hasProperty(KW_COMMENT))
- cfm.comment(get(KW_COMMENT));
+ cfm.comment(getString(KW_COMMENT, ""));
cfm.readRepairChance(getDouble(KW_READREPAIRCHANCE, cfm.getReadRepairChance()));
cfm.dcLocalReadRepairChance(getDouble(KW_DCLOCALREADREPAIRCHANCE, cfm.getDcLocalReadRepair()));
@@ -181,80 +164,12 @@ public class CFPropDefs
cfm.bloomFilterFpChance(getDouble(KW_BF_FP_CHANCE, cfm.getBloomFilterFpChance()));
if (compactionStrategyClass != null)
+ {
cfm.compactionStrategyClass(compactionStrategyClass);
-
- if (!compactionStrategyOptions.isEmpty())
cfm.compactionStrategyOptions(new HashMap<String, String>(compactionStrategyOptions));
-
- if (!compressionParameters.isEmpty())
- cfm.compressionParameters(CompressionParameters.create(compressionParameters));
- }
-
- public String get(String name)
- {
- return properties.get(name);
- }
-
- public String getString(String key, String defaultValue)
- {
- String value = properties.get(key);
- return value != null ? value : defaultValue;
- }
-
- // Return a property value, typed as a Boolean
- public Boolean getBoolean(String key, Boolean defaultValue)
- {
- String value = properties.get(key);
- return (value == null) ? defaultValue : value.toLowerCase().matches("(1|true|yes)");
- }
-
- // Return a property value, typed as a Double
- public Double getDouble(String key, Double defaultValue) throws ConfigurationException
- {
- Double result;
- String value = properties.get(key);
-
- if (value == null)
- result = defaultValue;
- else
- {
- try
- {
- result = Double.parseDouble(value);
- }
- catch (NumberFormatException e)
- {
- throw new ConfigurationException(String.format("%s not valid for \"%s\"", value, key));
- }
}
- return result;
- }
-
- // Return a property value, typed as an Integer
- public Integer getInt(String key, Integer defaultValue) throws ConfigurationException
- {
- String value = properties.get(key);
- return toInt(key, value, defaultValue);
- }
-
- public static Integer toInt(String key, String value, Integer defaultValue) throws ConfigurationException
- {
- Integer result;
- if (value == null)
- result = defaultValue;
- else
- {
- try
- {
- result = Integer.parseInt(value);
- }
- catch (NumberFormatException e)
- {
- throw new ConfigurationException(String.format("%s not valid for \"%s\"", value, key));
- }
- }
- return result;
+ cfm.compressionParameters(CompressionParameters.create(compressionParameters));
}
@Override
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2ce7b9b3/src/java/org/apache/cassandra/cql3/Cql.g
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/Cql.g b/src/java/org/apache/cassandra/cql3/Cql.g
index f0481f6..387e694 100644
--- a/src/java/org/apache/cassandra/cql3/Cql.g
+++ b/src/java/org/apache/cassandra/cql3/Cql.g
@@ -144,6 +144,7 @@ cqlStatement returns [ParsedStatement stmt]
| st15=grantStatement { $stmt = st15; }
| st16=revokeStatement { $stmt = st16; }
| st17=listGrantsStatement { $stmt = st17; }
+ | st18=alterKeyspaceStatement { $stmt = st18; }
;
/*
@@ -341,8 +342,9 @@ batchStatementObjective returns [ModificationStatement statement]
* CREATE KEYSPACE <KEYSPACE> WITH attr1 = value1 AND attr2 = value2;
*/
createKeyspaceStatement returns [CreateKeyspaceStatement expr]
+ @init { KSPropDefs attrs = new KSPropDefs(); }
: K_CREATE K_KEYSPACE ks=keyspaceName
- K_WITH props=properties { $expr = new CreateKeyspaceStatement(ks, props); }
+ K_WITH properties[attrs] { $expr = new CreateKeyspaceStatement(ks, attrs); }
;
/**
@@ -368,7 +370,7 @@ cfamColumns[CreateColumnFamilyStatement.RawStatement expr]
;
cfamProperty[CreateColumnFamilyStatement.RawStatement expr]
- : k=property '=' v=propertyValue { $expr.addProperty(k, v); }
+ : k=propertyKey '=' v=propertyValue { try { $expr.addProperty(k, v); } catch (InvalidRequestException e) { addRecognitionError(e.getMessage()); } }
| K_COMPACT K_STORAGE { $expr.setCompactStorage(); }
| K_CLUSTERING K_ORDER K_BY '(' cfamOrdering[expr] (',' cfamOrdering[expr])* ')'
;
@@ -387,6 +389,16 @@ createIndexStatement returns [CreateIndexStatement expr]
;
/**
+ * ALTER KEYSPACE <KS> WITH <property> = <value>;
+ */
+alterKeyspaceStatement returns [AlterKeyspaceStatement expr]
+ @init { KSPropDefs attrs = new KSPropDefs(); }
+ : K_ALTER K_KEYSPACE ks=keyspaceName
+ K_WITH properties[attrs] { $expr = new AlterKeyspaceStatement(ks, attrs); }
+ ;
+
+
+/**
* ALTER COLUMN FAMILY <CF> ALTER <column> TYPE <newtype>;
* ALTER COLUMN FAMILY <CF> ADD <column> <newtype>;
* ALTER COLUMN FAMILY <CF> DROP <column>;
@@ -395,13 +407,13 @@ createIndexStatement returns [CreateIndexStatement expr]
alterTableStatement returns [AlterTableStatement expr]
@init {
AlterTableStatement.Type type = null;
- props = new HashMap<String, String>();
+ CFPropDefs props = new CFPropDefs();
}
: K_ALTER K_COLUMNFAMILY cf=columnFamilyName
( K_ALTER id=cident K_TYPE v=comparatorType { type = AlterTableStatement.Type.ALTER; }
| K_ADD id=cident v=comparatorType { type = AlterTableStatement.Type.ADD; }
| K_DROP id=cident { type = AlterTableStatement.Type.DROP; }
- | K_WITH props=properties { type = AlterTableStatement.Type.OPTS; }
+ | K_WITH properties[props] { type = AlterTableStatement.Type.OPTS; }
)
{
$expr = new AlterTableStatement(cf, type, id, v, props);
@@ -545,7 +557,15 @@ termPairWithOperation[Map<ColumnIdentifier, Operation> columns]
)
;
-property returns [String str]
+properties[PropertyDefinitions props]
+ : property[props] (K_AND property[props])*
+ ;
+
+property[PropertyDefinitions props]
+ : k=propertyKey '=' simple=propertyValue { try { $props.addProperty(k, simple); } catch (InvalidRequestException e) { addRecognitionError(e.getMessage()); } }
+ ;
+
+propertyKey returns [String str]
@init{ StringBuilder sb = new StringBuilder(); }
: c1=cident { sb.append(c1); } ( ':' cn=cident { sb.append(':').append(cn); } )* { $str = sb.toString(); }
;
@@ -555,11 +575,6 @@ propertyValue returns [String str]
| u=unreserved_keyword { $str = u; }
;
-properties returns [Map<String, String> props]
- @init{ $props = new HashMap<String, String>(); }
- : k1=property '=' v1=propertyValue { $props.put(k1, v1); } (K_AND kn=property '=' vn=propertyValue { $props.put(kn, vn); } )*
- ;
-
relation returns [Relation rel]
: name=cident type=('=' | '<' | '<=' | '>=' | '>') t=term { $rel = new Relation($name.id, $type.text, $t.term); }
| K_TOKEN '(' name=cident ')' type=('=' |'<' | '<=' | '>=' | '>') t=extendedTerm { $rel = new Relation($name.id, $type.text, $t.term, true); }
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2ce7b9b3/src/java/org/apache/cassandra/cql3/KSPropDefs.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/KSPropDefs.java b/src/java/org/apache/cassandra/cql3/KSPropDefs.java
new file mode 100644
index 0000000..d480df4
--- /dev/null
+++ b/src/java/org/apache/cassandra/cql3/KSPropDefs.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cassandra.cql3;
+
+import java.util.*;
+
+import org.apache.cassandra.config.KSMetaData;
+import org.apache.cassandra.config.ConfigurationException;
+import org.apache.cassandra.thrift.InvalidRequestException;
+
+public class KSPropDefs extends PropertyDefinitions
+{
+ public static final String KW_DURABLE_WRITES = "durable_writes";
+
+ public static final String KW_REPLICATION_STRATEGY = "strategy_class";
+
+ public static final Set<String> keywords = new HashSet<String>();
+ public static final Set<String> obsoleteKeywords = new HashSet<String>();
+
+ static
+ {
+ keywords.add(KW_DURABLE_WRITES);
+ keywords.add(KW_REPLICATION_STRATEGY);
+ }
+
+ private String strategyClass;
+ private final Map<String, String> strategyOptions = new HashMap<String, String>();
+
+ public void validate() throws ConfigurationException, InvalidRequestException
+ {
+ validate(keywords, obsoleteKeywords);
+
+ if (!properties.containsKey("strategy_class"))
+ throw new InvalidRequestException("missing required argument \"strategy_class\"");
+ strategyClass = properties.get("strategy_class");
+ }
+
+ @Override
+ public void addProperty(String name, String value) throws InvalidRequestException
+ {
+ // optional
+ if (name.contains(":") && name.startsWith("strategy_options"))
+ strategyOptions.put(name.split(":")[1], value);
+ else
+ super.addProperty(name, value);
+ }
+
+ public String getReplicationStrategyClass()
+ {
+ return strategyClass;
+ }
+
+ public Map<String, String> getReplicationOptions()
+ {
+ return strategyOptions;
+ }
+
+ public KSMetaData asKSMetadata(String ksName) throws InvalidRequestException, ConfigurationException
+ {
+ return KSMetaData.newKeyspace(ksName, getReplicationStrategyClass(), getReplicationOptions(), getBoolean(KW_DURABLE_WRITES, true));
+ }
+
+ public KSMetaData asKSMetadataUpdate(KSMetaData old) throws InvalidRequestException, ConfigurationException
+ {
+ String sClass = strategyClass;
+ Map<String, String> sOptions = getReplicationOptions();
+ if (sClass == null)
+ {
+ sClass = old.strategyClass.getName();
+ sOptions = old.strategyOptions;
+ }
+ return KSMetaData.newKeyspace(old.name, sClass, sOptions, getBoolean(KW_DURABLE_WRITES, old.durableWrites));
+ }
+}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2ce7b9b3/src/java/org/apache/cassandra/cql3/PropertyDefinitions.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/PropertyDefinitions.java b/src/java/org/apache/cassandra/cql3/PropertyDefinitions.java
new file mode 100644
index 0000000..75b8ba5
--- /dev/null
+++ b/src/java/org/apache/cassandra/cql3/PropertyDefinitions.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cassandra.cql3;
+
+import java.util.*;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.cassandra.thrift.InvalidRequestException;
+
+public class PropertyDefinitions
+{
+ protected static final Logger logger = LoggerFactory.getLogger(PropertyDefinitions.class);
+
+ protected final Map<String, String> properties = new HashMap<String, String>();
+
+ public void addProperty(String name, String value) throws InvalidRequestException
+ {
+ if (properties.put(name, value) != null)
+ throw new InvalidRequestException(String.format("Multiple definition for property '%s'", name));
+ }
+
+ public void validate(Set<String> keywords, Set<String> obsolete) throws InvalidRequestException
+ {
+ for (String name : properties.keySet())
+ {
+ if (keywords.contains(name))
+ continue;
+
+ if (obsolete.contains(name))
+ logger.warn("Ignoring obsolete property {}", name);
+ else
+ throw new InvalidRequestException(String.format("Unknown property '%s'", name));
+ }
+ }
+
+ protected String getSimple(String name) throws InvalidRequestException
+ {
+ return properties.get(name);
+ }
+
+ public Boolean hasProperty(String name)
+ {
+ return properties.containsKey(name);
+ }
+
+ public String getString(String key, String defaultValue) throws InvalidRequestException
+ {
+ String value = getSimple(key);
+ return value != null ? value : defaultValue;
+ }
+
+ // Return a property value, typed as a Boolean
+ public Boolean getBoolean(String key, Boolean defaultValue) throws InvalidRequestException
+ {
+ String value = getSimple(key);
+ return (value == null) ? defaultValue : value.toLowerCase().matches("(1|true|yes)");
+ }
+
+ // Return a property value, typed as a Double
+ public Double getDouble(String key, Double defaultValue) throws InvalidRequestException
+ {
+ String value = getSimple(key);
+ if (value == null)
+ {
+ return defaultValue;
+ }
+ else
+ {
+ try
+ {
+ return Double.valueOf(value);
+ }
+ catch (NumberFormatException e)
+ {
+ throw new InvalidRequestException(String.format("Invalid double value %s for '%s'", value, key));
+ }
+ }
+ }
+
+ // Return a property value, typed as an Integer
+ public Integer getInt(String key, Integer defaultValue) throws InvalidRequestException
+ {
+ String value = getSimple(key);
+ return toInt(key, value, defaultValue);
+ }
+
+ public static Integer toInt(String key, String value, Integer defaultValue) throws InvalidRequestException
+ {
+ if (value == null)
+ {
+ return defaultValue;
+ }
+ else
+ {
+ try
+ {
+ return Integer.valueOf(value);
+ }
+ catch (NumberFormatException e)
+ {
+ throw new InvalidRequestException(String.format("Invalid integer value %s for '%s'", value, key));
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2ce7b9b3/src/java/org/apache/cassandra/cql3/statements/AlterKeyspaceStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/AlterKeyspaceStatement.java b/src/java/org/apache/cassandra/cql3/statements/AlterKeyspaceStatement.java
new file mode 100644
index 0000000..644fd24
--- /dev/null
+++ b/src/java/org/apache/cassandra/cql3/statements/AlterKeyspaceStatement.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cassandra.cql3.statements;
+
+import org.apache.cassandra.auth.Permission;
+import org.apache.cassandra.config.ConfigurationException;
+import org.apache.cassandra.config.DatabaseDescriptor;
+import org.apache.cassandra.config.KSMetaData;
+import org.apache.cassandra.config.Schema;
+import org.apache.cassandra.cql3.KSPropDefs;
+import org.apache.cassandra.db.Table;
+import org.apache.cassandra.locator.AbstractReplicationStrategy;
+import org.apache.cassandra.service.ClientState;
+import org.apache.cassandra.service.MigrationManager;
+import org.apache.cassandra.service.StorageService;
+import org.apache.cassandra.thrift.InvalidRequestException;
+import org.apache.cassandra.thrift.SchemaDisagreementException;
+
+public class AlterKeyspaceStatement extends SchemaAlteringStatement
+{
+ private final String name;
+ private final KSPropDefs attrs;
+
+ public AlterKeyspaceStatement(String name, KSPropDefs attrs)
+ {
+ super();
+ this.name = name;
+ this.attrs = attrs;
+ }
+
+ public void checkAccess(ClientState state) throws InvalidRequestException
+ {
+ state.hasKeyspaceAccess(name, Permission.ALTER);
+ }
+
+ @Override
+ public void validate(ClientState state) throws InvalidRequestException, SchemaDisagreementException
+ {
+ super.validate(state);
+
+ KSMetaData ksm = Schema.instance.getKSMetaData(name);
+ if (ksm == null)
+ throw new InvalidRequestException("Unknown keyspace " + name);
+ if (ksm.name.equalsIgnoreCase(Table.SYSTEM_TABLE))
+ throw new InvalidRequestException("Cannot alter system keyspace");
+
+ try
+ {
+ attrs.validate();
+
+ if (attrs.getReplicationStrategyClass() == null && !attrs.getReplicationOptions().isEmpty())
+ {
+ throw new InvalidRequestException("Missing replication strategy class");
+ }
+ else if (attrs.getReplicationStrategyClass() != null)
+ {
+ // trial run to let ARS validate class + per-class options
+ AbstractReplicationStrategy.createReplicationStrategy(name,
+ AbstractReplicationStrategy.getClass(attrs.getReplicationStrategyClass()),
+ StorageService.instance.getTokenMetadata(),
+ DatabaseDescriptor.getEndpointSnitch(),
+ attrs.getReplicationOptions());
+ }
+ }
+ catch (ConfigurationException e)
+ {
+ throw new InvalidRequestException(e.getMessage());
+ }
+ }
+
+ public void announceMigration() throws InvalidRequestException, ConfigurationException
+ {
+ KSMetaData ksm = Schema.instance.getKSMetaData(name);
+ // In the (very) unlikely case the keyspace was dropped since validate()
+ if (ksm == null)
+ throw new InvalidRequestException("Unknown keyspace " + name);
+
+ MigrationManager.announceKeyspaceUpdate(attrs.asKSMetadataUpdate(ksm));
+ }
+}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2ce7b9b3/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java b/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java
index 7867019..965b27e 100644
--- a/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java
@@ -23,9 +23,7 @@ import java.util.*;
import org.apache.cassandra.auth.Permission;
import org.apache.cassandra.cql3.*;
import org.apache.cassandra.config.*;
-import org.apache.cassandra.db.marshal.AbstractType;
-import org.apache.cassandra.db.marshal.CompositeType;
-import org.apache.cassandra.db.marshal.CounterColumnType;
+import org.apache.cassandra.db.marshal.*;
import org.apache.cassandra.service.ClientState;
import org.apache.cassandra.service.MigrationManager;
import org.apache.cassandra.thrift.InvalidRequestException;
@@ -42,15 +40,15 @@ public class AlterTableStatement extends SchemaAlteringStatement
public final Type oType;
public final String validator;
public final ColumnIdentifier columnName;
- private final CFPropDefs cfProps = new CFPropDefs();
+ private final CFPropDefs cfProps;
- public AlterTableStatement(CFName name, Type type, ColumnIdentifier columnName, String validator, Map<String, String> propertyMap)
+ public AlterTableStatement(CFName name, Type type, ColumnIdentifier columnName, String validator, CFPropDefs cfProps)
{
super(name);
this.oType = type;
this.columnName = columnName;
this.validator = validator; // used only for ADD/ALTER commands
- this.cfProps.addAll(propertyMap);
+ this.cfProps = cfProps;
}
public void checkAccess(ClientState state) throws InvalidRequestException
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2ce7b9b3/src/java/org/apache/cassandra/cql3/statements/CreateColumnFamilyStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/CreateColumnFamilyStatement.java b/src/java/org/apache/cassandra/cql3/statements/CreateColumnFamilyStatement.java
index 763db28..286f265 100644
--- a/src/java/org/apache/cassandra/cql3/statements/CreateColumnFamilyStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/CreateColumnFamilyStatement.java
@@ -108,14 +108,7 @@ public class CreateColumnFamilyStatement extends SchemaAlteringStatement
comparator,
null);
- newCFMD.defaultValidator(defaultValidator)
- .columnMetadata(getColumns())
- .keyValidator(keyValidator)
- .keyAlias(keyAlias)
- .columnAliases(columnAliases)
- .valueAlias(valueAlias);
-
- properties.applyToCFMetadata(newCFMD);
+ applyPropertiesTo(newCFMD);
}
catch (ConfigurationException e)
{
@@ -124,6 +117,18 @@ public class CreateColumnFamilyStatement extends SchemaAlteringStatement
return newCFMD;
}
+ public void applyPropertiesTo(CFMetaData cfmd) throws InvalidRequestException, ConfigurationException
+ {
+ cfmd.defaultValidator(defaultValidator)
+ .columnMetadata(getColumns())
+ .keyValidator(keyValidator)
+ .keyAlias(keyAlias)
+ .columnAliases(columnAliases)
+ .valueAlias(valueAlias);
+
+ properties.applyToCFMetadata(cfmd);
+ }
+
public static class RawStatement extends CFStatement
{
private final Map<ColumnIdentifier, String> definitions = new HashMap<ColumnIdentifier, String>();
@@ -277,7 +282,7 @@ public class CreateColumnFamilyStatement extends SchemaAlteringStatement
columnAliases.add(alias);
}
- public void addProperty(String name, String value)
+ public void addProperty(String name, String value) throws InvalidRequestException
{
properties.addProperty(name, value);
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2ce7b9b3/src/java/org/apache/cassandra/cql3/statements/CreateKeyspaceStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/CreateKeyspaceStatement.java b/src/java/org/apache/cassandra/cql3/statements/CreateKeyspaceStatement.java
index 863a869..9b36531 100644
--- a/src/java/org/apache/cassandra/cql3/statements/CreateKeyspaceStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/CreateKeyspaceStatement.java
@@ -26,6 +26,7 @@ import org.apache.cassandra.config.ConfigurationException;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.config.KSMetaData;
import org.apache.cassandra.config.Schema;
+import org.apache.cassandra.cql3.KSPropDefs;
import org.apache.cassandra.locator.AbstractReplicationStrategy;
import org.apache.cassandra.service.ClientState;
import org.apache.cassandra.service.MigrationManager;
@@ -38,9 +39,7 @@ import org.apache.cassandra.thrift.ThriftValidation;
public class CreateKeyspaceStatement extends SchemaAlteringStatement
{
private final String name;
- private final Map<String, String> attrs;
- private String strategyClass;
- private Map<String, String> strategyOptions = new HashMap<String, String>();
+ private final KSPropDefs attrs;
/**
* Creates a new <code>CreateKeyspaceStatement</code> instance for a given
@@ -49,7 +48,7 @@ public class CreateKeyspaceStatement extends SchemaAlteringStatement
* @param name the name of the keyspace to create
* @param attrs map of the raw keyword arguments that followed the <code>WITH</code> keyword.
*/
- public CreateKeyspaceStatement(String name, Map<String, String> attrs)
+ public CreateKeyspaceStatement(String name, KSPropDefs attrs)
{
super();
this.name = name;
@@ -80,24 +79,19 @@ public class CreateKeyspaceStatement extends SchemaAlteringStatement
if (name.length() > Schema.NAME_LENGTH)
throw new InvalidRequestException(String.format("Keyspace names shouldn't be more than %s characters long (got \"%s\")", Schema.NAME_LENGTH, name));
- // required
- if (!attrs.containsKey("strategy_class"))
- throw new InvalidRequestException("missing required argument \"strategy_class\"");
- strategyClass = attrs.get("strategy_class");
-
- // optional
- for (String key : attrs.keySet())
- if ((key.contains(":")) && (key.startsWith("strategy_options")))
- strategyOptions.put(key.split(":")[1], attrs.get(key));
-
- // trial run to let ARS validate class + per-class options
try
{
+ attrs.validate();
+
+ if (attrs.getReplicationStrategyClass() == null)
+ throw new ConfigurationException("Missing mandatory replication strategy class");
+
+ // trial run to let ARS validate class + per-class options
AbstractReplicationStrategy.createReplicationStrategy(name,
- AbstractReplicationStrategy.getClass(strategyClass),
+ AbstractReplicationStrategy.getClass(attrs.getReplicationStrategyClass()),
StorageService.instance.getTokenMetadata(),
DatabaseDescriptor.getEndpointSnitch(),
- strategyOptions);
+ attrs.getReplicationOptions());
}
catch (ConfigurationException e)
{
@@ -107,8 +101,7 @@ public class CreateKeyspaceStatement extends SchemaAlteringStatement
public void announceMigration() throws InvalidRequestException, ConfigurationException
{
- KSMetaData ksm = KSMetaData.newKeyspace(name, strategyClass, strategyOptions);
ThriftValidation.validateKeyspaceNotYetExisting(name);
- MigrationManager.announceNewKeyspace(ksm);
+ MigrationManager.announceNewKeyspace(attrs.asKSMetadata(name));
}
}