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/09/04 19:42:52 UTC
[1/2] git commit: Update CQL pseudo-maps to real maps
Updated Branches:
refs/heads/trunk f61d88488 -> 769fe895a
Update CQL pseudo-maps to real maps
patch by xedin; reviewed by slebresne for CASSANDRA-4497
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/769fe895
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/769fe895
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/769fe895
Branch: refs/heads/trunk
Commit: 769fe895a36868c47101f681f5fdd721bee1ad62
Parents: 3bfe5fb
Author: Sylvain Lebresne <sy...@datastax.com>
Authored: Tue Sep 4 19:41:33 2012 +0200
Committer: Sylvain Lebresne <sy...@datastax.com>
Committed: Tue Sep 4 19:41:33 2012 +0200
----------------------------------------------------------------------
CHANGES.txt | 1 +
NEWS.txt | 10 ++-
.../org/apache/cassandra/config/CFMetaData.java | 3 +-
src/java/org/apache/cassandra/cql3/CFPropDefs.java | 59 +++++++++------
src/java/org/apache/cassandra/cql3/Cql.g | 41 ++++++++---
.../cql3/statements/AlterTableStatement.java | 6 +-
.../statements/CreateColumnFamilyStatement.java | 7 +--
.../cql3/statements/CreateKeyspaceStatement.java | 31 +++++---
8 files changed, 103 insertions(+), 55 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/769fe895/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 256d5ec..d6b40ba 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -46,6 +46,7 @@
* (cql3) fix defining more than one PK to be invalid (CASSANDRA-4477)
* remove schema agreement checking from all external APIs (Thrift, CQL and CQL3) (CASSANDRA-4487)
* add Murmur3Partitioner and make it default for new installations (CASSANDRA-3772)
+ * (cql3) update pseudo-map syntax to use map syntax (CASSANDRA-4497)
1.1.5
http://git-wip-us.apache.org/repos/asf/cassandra/blob/769fe895/NEWS.txt
----------------------------------------------------------------------
diff --git a/NEWS.txt b/NEWS.txt
index 56bb1dc..731040a 100644
--- a/NEWS.txt
+++ b/NEWS.txt
@@ -31,7 +31,7 @@ Upgrading
remove nodes in this way with a mixed 1.1 (or lower) / 1.2 cluster,
is not supported.
- The somewhat ill-concieved CollatingOrderPreservingPartitioner
- has been removed. Use RandomPartitioner (recommended) or
+ has been removed. Use Murmur3Partitioner (recommended) or
ByteOrderedPartitioner instead.
- Global option hinted_handoff_throttle_delay_in_ms has been removed.
hinted_handoff_throttle_in_kb has been added instead.
@@ -41,6 +41,14 @@ Upgrading
- The default partitioner was changed from RandomPartitioner to
Murmur3Partitioner which provides faster hashing as well as
improved performance with secondary indexes.
+ - CQL3 is now considered final in this release. Compared to the beta
+ version that is part of 1.1, this final version has a few additions
+ (collections), but also some changes in the syntax for the options of the
+ create/alter keyspace/table statements. Typically, the syntax to create a
+ keyspace is now:
+ CREATE KEYSPACE ks WITH replication = { 'class' : 'CompactionStrategy',
+ 'replication_faction' : 2 };
+ Please refer to the CQL3 documentation for details.
Features
--------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/769fe895/src/java/org/apache/cassandra/config/CFMetaData.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/config/CFMetaData.java b/src/java/org/apache/cassandra/config/CFMetaData.java
index bb9a5a6..dbe0c6f 100644
--- a/src/java/org/apache/cassandra/config/CFMetaData.java
+++ b/src/java/org/apache/cassandra/config/CFMetaData.java
@@ -149,8 +149,7 @@ public final class CFMetaData
+ "mutation blob,"
+ "PRIMARY KEY (target_id, hint_id, message_version)"
+ ") WITH COMPACT STORAGE "
- + "AND COMPACTION_STRATEGY_OPTIONS:MIN_COMPACTION_THRESHOLD=0 "
- + "AND COMPACTION_STRATEGY_OPTIONS:MAX_COMPACTION_THRESHOLD=0 "
+ + "AND COMPACTION={'class' : 'SizeTieredCompactionStrategy', 'min_threshold' : 0, 'max_threshold' : 0} "
+ "AND COMMENT='hints awaiting delivery'");
public static final CFMetaData PeersCf = compile(12, "CREATE TABLE " + SystemTable.PEERS_CF + " ("
http://git-wip-us.apache.org/repos/asf/cassandra/blob/769fe895/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 db85522..b7207fe 100644
--- a/src/java/org/apache/cassandra/cql3/CFPropDefs.java
+++ b/src/java/org/apache/cassandra/cql3/CFPropDefs.java
@@ -20,8 +20,8 @@ package org.apache.cassandra.cql3;
import com.google.common.collect.Sets;
import org.apache.cassandra.config.CFMetaData;
import org.apache.cassandra.config.ConfigurationException;
-import org.apache.cassandra.io.compress.CompressionParameters;
import org.apache.cassandra.db.compaction.AbstractCompactionStrategy;
+import org.apache.cassandra.io.compress.CompressionParameters;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -38,10 +38,10 @@ public class CFPropDefs
public static final String KW_READREPAIRCHANCE = "read_repair_chance";
public static final String KW_DCLOCALREADREPAIRCHANCE = "dclocal_read_repair_chance";
public static final String KW_GCGRACESECONDS = "gc_grace_seconds";
- public static final String KW_MINCOMPACTIONTHRESHOLD = "min_compaction_threshold";
- public static final String KW_MAXCOMPACTIONTHRESHOLD = "max_compaction_threshold";
+ public static final String KW_MINCOMPACTIONTHRESHOLD = "min_threshold";
+ public static final String KW_MAXCOMPACTIONTHRESHOLD = "max_threshold";
public static final String KW_REPLICATEONWRITE = "replicate_on_write";
- public static final String KW_COMPACTION_STRATEGY_CLASS = "compaction_strategy_class";
+ public static final String KW_COMPACTION_STRATEGY_CLASS = "class";
public static final String KW_CACHING = "caching";
public static final String KW_BF_FP_CHANCE = "bloom_filter_fp_chance";
@@ -50,8 +50,8 @@ public class CFPropDefs
public static final Set<String> obsoleteKeywords = new HashSet<String>();
public static final Set<String> allowedKeywords = new HashSet<String>();
- public static final String COMPACTION_OPTIONS_PREFIX = "compaction_strategy_options";
- public static final String COMPRESSION_PARAMETERS_PREFIX = "compression_parameters";
+ public static final String COMPACTION_PARAMETERS = "compaction";
+ public static final String COMPRESSION_PARAMETERS = "compression";
static
{
@@ -60,10 +60,16 @@ public class CFPropDefs
keywords.add(KW_DCLOCALREADREPAIRCHANCE);
keywords.add(KW_GCGRACESECONDS);
keywords.add(KW_REPLICATEONWRITE);
- keywords.add(KW_COMPACTION_STRATEGY_CLASS);
keywords.add(KW_CACHING);
keywords.add(KW_BF_FP_CHANCE);
+ obsoleteKeywords.add("compaction_strategy_class");
+ obsoleteKeywords.add("compaction_strategy_options");
+ obsoleteKeywords.add("min_compaction_threshold");
+ obsoleteKeywords.add("max_compaction_threshold");
+ obsoleteKeywords.add("compaction_parameters");
+ obsoleteKeywords.add("compression_parameters");
+
allowedKeywords.addAll(keywords);
allowedKeywords.addAll(obsoleteKeywords);
}
@@ -85,31 +91,38 @@ public class CFPropDefs
for (String obsolete : Sets.intersection(properties.keySet(), obsoleteKeywords))
logger.warn("Ignoring obsolete property {}", obsolete);
- if (properties.containsKey(KW_COMPACTION_STRATEGY_CLASS))
+ if (!compactionStrategyOptions.isEmpty())
{
- compactionStrategyClass = CFMetaData.createCompactionStrategy(properties.get(KW_COMPACTION_STRATEGY_CLASS));
- compactionStrategyOptions.remove(KW_COMPACTION_STRATEGY_CLASS);
+ if (compactionStrategyOptions.containsKey(KW_COMPACTION_STRATEGY_CLASS))
+ {
+ compactionStrategyClass = CFMetaData.createCompactionStrategy(compactionStrategyOptions.get(KW_COMPACTION_STRATEGY_CLASS));
+ compactionStrategyOptions.remove(KW_COMPACTION_STRATEGY_CLASS);
+ }
+ else
+ {
+ throw new ConfigurationException("Missing sub-option '" + KW_COMPACTION_STRATEGY_CLASS + "' for the '" + COMPACTION_PARAMETERS + "' option.");
+ }
}
}
/** Map a keyword to the corresponding value */
public void addProperty(String name, String value)
{
- String[] composite = name.split(":");
- if (composite.length > 1)
+ properties.put(name, value);
+ }
+
+ public void addProperty(String name, Map<String, String> value)
+ {
+ if (name.equalsIgnoreCase(COMPACTION_PARAMETERS))
{
- if (composite[0].equals(COMPACTION_OPTIONS_PREFIX))
- {
- compactionStrategyOptions.put(composite[1], value);
- return;
- }
- else if (composite[0].equals(COMPRESSION_PARAMETERS_PREFIX))
- {
- compressionParameters.put(composite[1], value);
- return;
- }
+ for (Map.Entry<String, String> entry : value.entrySet())
+ compactionStrategyOptions.put(entry.getKey().toLowerCase(), entry.getValue());
+ }
+ else if (name.equalsIgnoreCase(COMPRESSION_PARAMETERS))
+ {
+ for (Map.Entry<String, String> entry : value.entrySet())
+ compressionParameters.put(entry.getKey().toLowerCase(), entry.getValue());
}
- properties.put(name, value);
}
public void addAll(Map<String, String> propertyMap)
http://git-wip-us.apache.org/repos/asf/cassandra/blob/769fe895/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 5a67820..8c43851 100644
--- a/src/java/org/apache/cassandra/cql3/Cql.g
+++ b/src/java/org/apache/cassandra/cql3/Cql.g
@@ -76,6 +76,26 @@ options {
if (op == null && (value.isBindMarker() || Long.parseLong(value.getText()) > 0))
throw new MissingTokenException(102, stream, value);
}
+
+ public Map<String, String> convertMap(Map<Term, Term> terms)
+ {
+ if (terms == null || terms.isEmpty())
+ return Collections.<String, String>emptyMap();
+
+ Map<String, String> res = new HashMap<String, String>(terms.size());
+
+ for (Map.Entry<Term, Term> entry : terms.entrySet())
+ {
+ // Because the parser tries to be smart and recover on error (to
+ // allow displaying more than one error I suppose), we have null
+ // entries in there. Just skip those, a proper error will be thrown in the end.
+ if (entry.getKey() == null || entry.getValue() == null)
+ break;
+ res.put(entry.getKey().getText(), entry.getValue().getText());
+ }
+
+ return res;
+ }
}
@lexer::header {
@@ -349,7 +369,7 @@ batchStatementObjective returns [ModificationStatement statement]
*/
createKeyspaceStatement returns [CreateKeyspaceStatement expr]
: K_CREATE K_KEYSPACE ks=keyspaceName
- K_WITH props=properties { $expr = new CreateKeyspaceStatement(ks, props); }
+ K_WITH props=mapProperties { $expr = new CreateKeyspaceStatement(ks, props); }
;
/**
@@ -380,7 +400,7 @@ pkDef[CreateColumnFamilyStatement.RawStatement expr]
;
cfamProperty[CreateColumnFamilyStatement.RawStatement expr]
- : k=property '=' v=propertyValue { $expr.addProperty(k, v); }
+ : property[expr.properties]
| K_COMPACT K_STORAGE { $expr.setCompactStorage(); }
| K_CLUSTERING K_ORDER K_BY '(' cfamOrdering[expr] (',' cfamOrdering[expr])* ')'
;
@@ -407,13 +427,14 @@ 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 (property[props]
+ ( K_AND property[props] )* { type = AlterTableStatement.Type.OPTS; })
)
{
$expr = new AlterTableStatement(cf, type, id, v, props);
@@ -553,9 +574,9 @@ operation returns [Operation op]
| '+' ml=map_literal { $op = MapOperation.Put(ml); }
;
-property returns [String str]
- @init{ StringBuilder sb = new StringBuilder(); }
- : c1=cident { sb.append(c1); } ( ':' cn=cident { sb.append(':').append(cn); } )* { $str = sb.toString(); }
+property[CFPropDefs props]
+ : k=cident '=' (simple=propertyValue { $props.addProperty(k.toString(), simple); }
+ | map=map_literal { $props.addProperty(k.toString(), convertMap(map)); })
;
propertyValue returns [String str]
@@ -563,9 +584,9 @@ 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); } )*
+mapProperties returns [Map<String, Map<String, String>> props]
+ @init { $props = new HashMap<String, Map<String, String>>(); }
+ : k=cident '=' v=map_literal { $props.put(k.toString(), convertMap(v)); } (K_AND kn=cident '=' vn=map_literal { $props.put(kn.toString(), convertMap(vn)); } )*
;
// Either a string or a list of terms
http://git-wip-us.apache.org/repos/asf/cassandra/blob/769fe895/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 ff24945..c9d4f45 100644
--- a/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java
@@ -42,15 +42,15 @@ public class AlterTableStatement extends SchemaAlteringStatement
public final Type oType;
public final ParsedType validator;
public final ColumnIdentifier columnName;
- private final CFPropDefs cfProps = new CFPropDefs();
+ private final CFPropDefs cfProps;
- public AlterTableStatement(CFName name, Type type, ColumnIdentifier columnName, ParsedType validator, Map<String, String> propertyMap)
+ public AlterTableStatement(CFName name, Type type, ColumnIdentifier columnName, ParsedType 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 announceMigration() throws InvalidRequestException, ConfigurationException
http://git-wip-us.apache.org/repos/asf/cassandra/blob/769fe895/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 b8618b0..3c97f90 100644
--- a/src/java/org/apache/cassandra/cql3/statements/CreateColumnFamilyStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/CreateColumnFamilyStatement.java
@@ -131,7 +131,7 @@ public class CreateColumnFamilyStatement extends SchemaAlteringStatement
public static class RawStatement extends CFStatement
{
private final Map<ColumnIdentifier, ParsedType> definitions = new HashMap<ColumnIdentifier, ParsedType>();
- private final CFPropDefs properties = new CFPropDefs();
+ public final CFPropDefs properties = new CFPropDefs();
private final List<List<ColumnIdentifier>> keyAliases = new ArrayList<List<ColumnIdentifier>>();
private final List<ColumnIdentifier> columnAliases = new ArrayList<ColumnIdentifier>();
@@ -334,11 +334,6 @@ public class CreateColumnFamilyStatement extends SchemaAlteringStatement
columnAliases.add(alias);
}
- public void addProperty(String name, String value)
- {
- properties.addProperty(name, value);
- }
-
public void setOrdering(ColumnIdentifier alias, boolean reversed)
{
definedOrdering.put(alias, reversed);
http://git-wip-us.apache.org/repos/asf/cassandra/blob/769fe895/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 262c6aa..0c426b3 100644
--- a/src/java/org/apache/cassandra/cql3/statements/CreateKeyspaceStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/CreateKeyspaceStatement.java
@@ -34,8 +34,11 @@ import org.apache.cassandra.thrift.ThriftValidation;
/** A <code>CREATE KEYSPACE</code> statement parsed from a CQL query. */
public class CreateKeyspaceStatement extends SchemaAlteringStatement
{
+ private static String REPLICATION_PARAMETERS_PREFIX = "replication";
+ private static String REPLICATION_STRATEGY_CLASS_KEY = "class";
+
private final String name;
- private final Map<String, String> attrs;
+ private final Map<String, Map<String, String>> attrs;
private String strategyClass;
private final Map<String, String> strategyOptions = new HashMap<String, String>();
@@ -46,7 +49,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, Map<String, Map<String, String>> attrs)
{
super();
this.name = name;
@@ -72,15 +75,23 @@ 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");
+ if (!attrs.containsKey(REPLICATION_PARAMETERS_PREFIX))
+ throw new InvalidRequestException("missing required argument '" + REPLICATION_PARAMETERS_PREFIX + "'");
+
+ Map<String, String> replication_parameters = attrs.get(REPLICATION_PARAMETERS_PREFIX);
+
+ strategyClass = replication_parameters.get(REPLICATION_STRATEGY_CLASS_KEY);
+
+ if (strategyClass == null)
+ throw new InvalidRequestException("missing required field '" + REPLICATION_STRATEGY_CLASS_KEY + "' for '" + REPLICATION_PARAMETERS_PREFIX + "' option");
- // optional
- for (String key : attrs.keySet())
- if ((key.contains(":")) && (key.startsWith("strategy_options")))
- strategyOptions.put(key.split(":")[1], attrs.get(key));
+ for (Map.Entry<String, String> entry : replication_parameters.entrySet())
+ {
+ if (entry.getKey().equals(REPLICATION_STRATEGY_CLASS_KEY))
+ continue;
+
+ strategyOptions.put(entry.getKey(), entry.getValue());
+ }
// trial run to let ARS validate class + per-class options
try