Author: eevans
Date: Tue Mar 29 23:41:49 2011
New Revision: 1086807
URL: http://svn.apache.org/viewvc?rev=1086807&view=rev
Log:
allow exactly one PRIMARY KEY definition
Patch by eevans
Modified:
cassandra/trunk/src/java/org/apache/cassandra/cql/CreateColumnFamilyStatement.java
cassandra/trunk/test/system/test_cql.py
Modified:
cassandra/trunk/src/java/org/apache/cassandra/cql/CreateColumnFamilyStatement.java
URL:
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cql/CreateColumnFamilyStatement.java?rev=1086807&r1=1086806&r2=1086807&view=diff
==============================================================================
---
cassandra/trunk/src/java/org/apache/cassandra/cql/CreateColumnFamilyStatement.java
(original)
+++
cassandra/trunk/src/java/org/apache/cassandra/cql/CreateColumnFamilyStatement.java
Tue Mar 29 23:41:49 2011
@@ -21,8 +21,10 @@
package org.apache.cassandra.cql;
import java.nio.ByteBuffer;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -87,7 +89,7 @@ public class CreateColumnFamilyStatement
private final String name;
private final Map<Term, String> columns = new HashMap<Term, String>();
private final Map<String, String> properties = new HashMap<String,
String>();
- private String keyValidator;
+ private List<String> keyValidator = new ArrayList<String>();
public CreateColumnFamilyStatement(String name)
{
@@ -150,6 +152,12 @@ public class CreateColumnFamilyStatement
if ((memOps != null) && (memOps <=0))
throw new InvalidRequestException(String.format("%s must be
non-negative and greater than zero",
KW_MEMTABLEOPSINMILLIONS));
+
+ // Ensure that exactly one key has been specified.
+ if (keyValidator.size() < 1)
+ throw new InvalidRequestException("You must specify a PRIMARY
KEY");
+ else if (keyValidator.size() > 1)
+ throw new InvalidRequestException("You may only specify one
PRIMARY KEY");
}
/** Map a column name to a validator for its value */
@@ -160,7 +168,12 @@ public class CreateColumnFamilyStatement
public void setKeyType(String validator)
{
- this.keyValidator = validator;
+ keyValidator.add(validator);
+ }
+
+ public String getKeyType()
+ {
+ return keyValidator.get(0);
}
/** Map a keyword to the corresponding value */
@@ -218,7 +231,6 @@ public class CreateColumnFamilyStatement
// RPC uses BytesType as the default validator/comparator but
BytesType expects hex for string terms, (not convenient).
AbstractType<?> comparator =
DatabaseDescriptor.getComparator(comparators.get(getPropertyString(KW_COMPARATOR,
"utf8")));
String validator = getPropertyString(KW_DEFAULTVALIDATION, "utf8");
- AbstractType<?> keyType =
DatabaseDescriptor.getComparator(comparators.get((keyValidator != null) ?
keyValidator : "utf8"));
newCFMD = new CFMetaData(keyspace,
name,
@@ -242,7 +254,7 @@ public class CreateColumnFamilyStatement
.memOps(getPropertyDouble(KW_MEMTABLEOPSINMILLIONS,
CFMetaData.DEFAULT_MEMTABLE_OPERATIONS_IN_MILLIONS))
.mergeShardsChance(0.0)
.columnMetadata(getColumns(comparator))
- .keyValidator(keyType);
+
.keyValidator(DatabaseDescriptor.getComparator(comparators.get(getKeyType())));
}
catch (ConfigurationException e)
{
Modified: cassandra/trunk/test/system/test_cql.py
URL:
http://svn.apache.org/viewvc/cassandra/trunk/test/system/test_cql.py?rev=1086807&r1=1086806&r2=1086807&view=diff
==============================================================================
--- cassandra/trunk/test/system/test_cql.py (original)
+++ cassandra/trunk/test/system/test_cql.py Tue Mar 29 23:41:49 2011
@@ -365,6 +365,7 @@ class TestCql(ThriftTester):
conn.execute("""
CREATE COLUMNFAMILY NewCf1 (
+ KEY int PRIMARY KEY,
'username' utf8,
'age' int,
'birthdate' long,
@@ -383,25 +384,31 @@ class TestCql(ThriftTester):
assert cfam.comment == "shiny, new, cf"
assert cfam.default_validation_class ==
"org.apache.cassandra.db.marshal.AsciiType"
assert cfam.comparator_type ==
"org.apache.cassandra.db.marshal.UTF8Type"
+ assert cfam.key_validation_class ==
"org.apache.cassandra.db.marshal.IntegerType"
- # No column defs, defaults all-around
- conn.execute("CREATE COLUMNFAMILY NewCf2")
- ksdef = thrift_client.describe_keyspace("CreateCFKeyspace")
- assert len(ksdef.cf_defs) == 2, \
- "expected 2 column families total, found %d" % len(ksdef.cf_defs)
+ # Missing primary key
+ assert_raises(CQLException, conn.execute, "CREATE COLUMNFAMILY NewCf2")
+
+ # Too many primary keys
+ assert_raises(CQLException,
+ conn.execute,
+ """CREATE COLUMNFAMILY NewCf2
+ (KEY int PRIMARY KEY, KEY utf8 PRIMARY KEY)""")
# No column defs
- conn.execute("CREATE COLUMNFAMILY NewCf3 WITH comparator = long")
+ conn.execute("""CREATE COLUMNFAMILY NewCf3
+ (KEY int PRIMARY KEY) WITH comparator = long""")
ksdef = thrift_client.describe_keyspace("CreateCFKeyspace")
- assert len(ksdef.cf_defs) == 3, \
+ assert len(ksdef.cf_defs) == 2, \
"expected 3 column families total, found %d" % len(ksdef.cf_defs)
cfam = [i for i in ksdef.cf_defs if i.name == "NewCf3"][0]
assert cfam.comparator_type ==
"org.apache.cassandra.db.marshal.LongType"
# Column defs, defaults otherwise
- conn.execute("CREATE COLUMNFAMILY NewCf4 ('a' int, 'b' int);")
+ conn.execute("""CREATE COLUMNFAMILY NewCf4
+ (KEY int PRIMARY KEY, 'a' int, 'b' int);""")
ksdef = thrift_client.describe_keyspace("CreateCFKeyspace")
- assert len(ksdef.cf_defs) == 4, \
+ assert len(ksdef.cf_defs) == 3, \
"expected 4 column families total, found %d" % len(ksdef.cf_defs)
cfam = [i for i in ksdef.cf_defs if i.name == "NewCf4"][0]
assert len(cfam.column_metadata) == 2, \
@@ -418,7 +425,7 @@ class TestCql(ThriftTester):
AND strategy_class = 'SimpleStrategy';
""")
conn.execute('USE Keyspace4CFDrop;')
- conn.execute('CREATE COLUMNFAMILY CF4Drop;')
+ conn.execute('CREATE COLUMNFAMILY CF4Drop (KEY int PRIMARY KEY);')
# TODO: temporary (until this can be done with CQL).
ksdef = thrift_client.describe_keyspace("Keyspace4CFDrop")
@@ -433,7 +440,7 @@ class TestCql(ThriftTester):
"creating column indexes"
conn = init()
conn.execute("USE Keyspace1")
- conn.execute("CREATE COLUMNFAMILY CreateIndex1")
+ conn.execute("CREATE COLUMNFAMILY CreateIndex1 (KEY utf8 PRIMARY KEY)")
conn.execute("CREATE INDEX namedIndex ON CreateIndex1 ('items')")
conn.execute("CREATE INDEX ON CreateIndex1 ('stuff')")