You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by jb...@apache.org on 2011/05/10 21:47:51 UTC

svn commit: r1101615 [1/2] - in /cassandra/trunk: ./ bin/ contrib/ doc/cql/ drivers/java/src/org/apache/cassandra/cql/jdbc/ drivers/java/test/org/apache/cassandra/cql/ drivers/py/cql/ interface/thrift/gen-java/org/apache/cassandra/thrift/ src/java/org/...

Author: jbellis
Date: Tue May 10 19:47:50 2011
New Revision: 1101615

URL: http://svn.apache.org/viewvc?rev=1101615&view=rev
Log:
merge from 0.8.1

Added:
    cassandra/trunk/src/java/org/apache/cassandra/cql/Attributes.java
      - copied unchanged from r1101613, cassandra/branches/cassandra-0.8.1/src/java/org/apache/cassandra/cql/Attributes.java
    cassandra/trunk/src/java/org/apache/cassandra/db/marshal/AbstractCompositeType.java
      - copied unchanged from r1101613, cassandra/branches/cassandra-0.8.1/src/java/org/apache/cassandra/db/marshal/AbstractCompositeType.java
    cassandra/trunk/src/java/org/apache/cassandra/db/marshal/CompositeType.java
      - copied unchanged from r1101613, cassandra/branches/cassandra-0.8.1/src/java/org/apache/cassandra/db/marshal/CompositeType.java
    cassandra/trunk/src/java/org/apache/cassandra/db/marshal/DynamicCompositeType.java
      - copied unchanged from r1101613, cassandra/branches/cassandra-0.8.1/src/java/org/apache/cassandra/db/marshal/DynamicCompositeType.java
    cassandra/trunk/src/java/org/apache/cassandra/db/marshal/ReversedType.java
      - copied unchanged from r1101613, cassandra/branches/cassandra-0.8.1/src/java/org/apache/cassandra/db/marshal/ReversedType.java
    cassandra/trunk/src/java/org/apache/cassandra/db/marshal/TypeParser.java
      - copied unchanged from r1101613, cassandra/branches/cassandra-0.8.1/src/java/org/apache/cassandra/db/marshal/TypeParser.java
    cassandra/trunk/test/unit/org/apache/cassandra/db/marshal/CompositeTypeTest.java
      - copied unchanged from r1101613, cassandra/branches/cassandra-0.8.1/test/unit/org/apache/cassandra/db/marshal/CompositeTypeTest.java
    cassandra/trunk/test/unit/org/apache/cassandra/db/marshal/DynamicCompositeTypeTest.java
      - copied unchanged from r1101613, cassandra/branches/cassandra-0.8.1/test/unit/org/apache/cassandra/db/marshal/DynamicCompositeTypeTest.java
    cassandra/trunk/test/unit/org/apache/cassandra/db/marshal/TypeParserTest.java
      - copied unchanged from r1101613, cassandra/branches/cassandra-0.8.1/test/unit/org/apache/cassandra/db/marshal/TypeParserTest.java
Removed:
    cassandra/trunk/bin/clustertool
    cassandra/trunk/bin/clustertool.bat
    cassandra/trunk/src/java/org/apache/cassandra/tools/ClusterCmd.java
Modified:
    cassandra/trunk/   (props changed)
    cassandra/trunk/CHANGES.txt
    cassandra/trunk/NEWS.txt
    cassandra/trunk/contrib/   (props changed)
    cassandra/trunk/doc/cql/CQL.textile
    cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/ColumnDecoder.java
    cassandra/trunk/drivers/java/test/org/apache/cassandra/cql/JdbcDriverTest.java
    cassandra/trunk/drivers/py/cql/__init__.py
    cassandra/trunk/drivers/py/cql/cursor.py
    cassandra/trunk/drivers/py/cql/decoders.py
    cassandra/trunk/interface/thrift/gen-java/org/apache/cassandra/thrift/Cassandra.java   (props changed)
    cassandra/trunk/interface/thrift/gen-java/org/apache/cassandra/thrift/Column.java   (props changed)
    cassandra/trunk/interface/thrift/gen-java/org/apache/cassandra/thrift/InvalidRequestException.java   (props changed)
    cassandra/trunk/interface/thrift/gen-java/org/apache/cassandra/thrift/NotFoundException.java   (props changed)
    cassandra/trunk/interface/thrift/gen-java/org/apache/cassandra/thrift/SuperColumn.java   (props changed)
    cassandra/trunk/src/java/org/apache/cassandra/cli/CliClient.java
    cassandra/trunk/src/java/org/apache/cassandra/config/CFMetaData.java
    cassandra/trunk/src/java/org/apache/cassandra/config/ColumnDefinition.java
    cassandra/trunk/src/java/org/apache/cassandra/config/KSMetaData.java
    cassandra/trunk/src/java/org/apache/cassandra/cql/AbstractModification.java
    cassandra/trunk/src/java/org/apache/cassandra/cql/BatchStatement.java
    cassandra/trunk/src/java/org/apache/cassandra/cql/Cql.g
    cassandra/trunk/src/java/org/apache/cassandra/cql/DeleteStatement.java
    cassandra/trunk/src/java/org/apache/cassandra/cql/QueryProcessor.java
    cassandra/trunk/src/java/org/apache/cassandra/cql/SelectExpression.java
    cassandra/trunk/src/java/org/apache/cassandra/cql/SelectStatement.java
    cassandra/trunk/src/java/org/apache/cassandra/cql/UpdateStatement.java
    cassandra/trunk/src/java/org/apache/cassandra/db/marshal/AbstractType.java
    cassandra/trunk/src/java/org/apache/cassandra/locator/AbstractReplicationStrategy.java
    cassandra/trunk/src/java/org/apache/cassandra/locator/NetworkTopologyStrategy.java
    cassandra/trunk/src/java/org/apache/cassandra/locator/OldNetworkTopologyStrategy.java
    cassandra/trunk/src/java/org/apache/cassandra/locator/SimpleStrategy.java
    cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraServer.java
    cassandra/trunk/src/java/org/apache/cassandra/thrift/ThriftValidation.java
    cassandra/trunk/src/java/org/apache/cassandra/utils/FBUtilities.java
    cassandra/trunk/src/resources/org/apache/cassandra/cli/CliHelp.yaml
    cassandra/trunk/test/system/test_cql.py
    cassandra/trunk/test/unit/org/apache/cassandra/SchemaLoader.java

Propchange: cassandra/trunk/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue May 10 19:47:50 2011
@@ -1,8 +1,8 @@
 /cassandra/branches/cassandra-0.6:922689-1052356,1052358-1053452,1053454,1053456-1081914,1083000
-/cassandra/branches/cassandra-0.7:1026516-1100465,1101021
+/cassandra/branches/cassandra-0.7:1026516-1100900,1101021
 /cassandra/branches/cassandra-0.7.0:1053690-1055654
-/cassandra/branches/cassandra-0.8:1090935-1100898,1100905,1100982,1101034
-/cassandra/branches/cassandra-0.8.1:1101038
+/cassandra/branches/cassandra-0.8:1090935-1101597
+/cassandra/branches/cassandra-0.8.1:1101014-1101613
 /cassandra/tags/cassandra-0.7.0-rc3:1051699-1053689
 /incubator/cassandra/branches/cassandra-0.3:774578-796573
 /incubator/cassandra/branches/cassandra-0.4:810145-834239,834349-834350

Modified: cassandra/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/cassandra/trunk/CHANGES.txt?rev=1101615&r1=1101614&r2=1101615&view=diff
==============================================================================
--- cassandra/trunk/CHANGES.txt (original)
+++ cassandra/trunk/CHANGES.txt Tue May 10 19:47:50 2011
@@ -1,7 +1,14 @@
 1.0-dev
+
+
+0.8.1
  * add support for insert, delete in cql BATCH (CASSANDRA-2537)
  * add support for IN to cql SELECT, UPDATE (CASSANDRA-2553)
  * add timestamp support to cql INSERT, UPDATE, and BATCH (CASSANDRA-2555)
+ * add support for comparator parameters and a generic ReverseType
+   (CASSANDRA-2355)
+ * add CompositeType and DynamicCompositeType (CASSANDRA-2231)
+ * add CQL TTL support (CASSANDRA-2476)
 
 
 0.8.0-?
@@ -17,11 +24,17 @@
    (CASSANDRA-2419)
  * JDBC CQL driver exposes getColumn for access to timestamp
  * JDBC ResultSetMetadata properties added to AbstractType
+ * r/m clustertool (CASSANDRA-2607)
+ * add support for presenting row key as a column in CQL result sets 
+   (CASSANDRA-2622)
+ * Don't allow {LOCAL|EACH}_QUORUM unless strategy is NTS (CASSANDRA-2627)
+ * validate keyspace strategy_options during CQL create (CASSANDRA-2624)
 
 
 0.8.0-beta2
  * fix NPE compacting index CFs (CASSANDRA-2528)
- * Remove checking all column families on startup for compaction candidates (CASSANDRA-2444)
+ * Remove checking all column families on startup for compaction candidates 
+   (CASSANDRA-2444)
  * validate CQL create keyspace options (CASSANDRA-2525)
  * fix nodetool setcompactionthroughput (CASSANDRA-2550)
  * move	gossip heartbeat back to its own thread (CASSANDRA-2554)
@@ -43,12 +56,11 @@
  * improve ignoring of obsolete mutations in index maintenance (CASSANDRA-2401)
  * recognize attempt to drop just the index while leaving the column
    definition alone (CASSANDRA-2619)
- * Don't allow {LOCAL|EACH}_QUORUM unless strategy is NTS (CASSANDRA-2627)
 
 
 0.8.0-beta1
  * remove Avro RPC support (CASSANDRA-926)
- * adds support for columns that act as incr/decr counters 
+ * support for columns that act as incr/decr counters 
    (CASSANDRA-1072, 1937, 1944, 1936, 2101, 2093, 2288, 2105, 2384, 2236, 2342,
    2454)
  * CQL (CASSANDRA-1703, 1704, 1705, 1706, 1707, 1708, 1710, 1711, 1940, 

Modified: cassandra/trunk/NEWS.txt
URL: http://svn.apache.org/viewvc/cassandra/trunk/NEWS.txt?rev=1101615&r1=1101614&r2=1101615&view=diff
==============================================================================
--- cassandra/trunk/NEWS.txt (original)
+++ cassandra/trunk/NEWS.txt Tue May 10 19:47:50 2011
@@ -5,19 +5,18 @@ Upgrading
 ---------
     - Upgrading from version 0.7.1 or later can be done with a rolling
       restart, one node at a time.  You do not need to bring down the
-      whole cluster.
+      whole cluster at once.
     - Running nodetool drain before shutting down the 0.7 node is
       recommended but not required. (Skipping this will result in
       replay of entire commitlog, so it will take longer to restart but
       is otherwise harmless.)
+    - 0.8 is fully API-compatible with 0.7.  You can continue
+      to use your 0.7 clients.
     - Avro record classes used in map/reduce and Hadoop streaming code have
       moved from org.apache.cassandra.avro to org.apache.cassandra.hadoop.avro,
       applications using these classes will need to be updated accordingly.
     - The loadbalance command has been removed from nodetool.  For similar
       behavior, decommission then rebootstrap with empty initial_token.
-    - repair now works on a token range, rather than the entire ring. This
-      means that "run repair against each node" will now repair the ring with
-      no redundant work.
 
 Features
 --------
@@ -37,6 +36,13 @@ Features
       will be removed in a future major release once we are satisfied that
       memtable_total_space_in_mb works adequately.
 
+Tools
+-----
+    - stress and py_stress moved from contrib/ to tools/
+    - clustertool was removed (see 
+      https://issues.apache.org/jira/browse/CASSANDRA-2607 for examples
+      of how to script nodetool across the cluster instead)
+
 Other
 -----
     - In the past, sstable2json would write column names and values as

Propchange: cassandra/trunk/contrib/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue May 10 19:47:50 2011
@@ -1,8 +1,8 @@
 /cassandra/branches/cassandra-0.6/contrib:922689-1052356,1052358-1053452,1053454,1053456-1068009
-/cassandra/branches/cassandra-0.7/contrib:1026516-1100465,1101021
+/cassandra/branches/cassandra-0.7/contrib:1026516-1100900,1101021
 /cassandra/branches/cassandra-0.7.0/contrib:1053690-1055654
-/cassandra/branches/cassandra-0.8/contrib:1090935-1100898,1100905,1100982,1101034
-/cassandra/branches/cassandra-0.8.1/contrib:1101038
+/cassandra/branches/cassandra-0.8/contrib:1090935-1101597
+/cassandra/branches/cassandra-0.8.1/contrib:1101014-1101613
 /cassandra/tags/cassandra-0.7.0-rc3/contrib:1051699-1053689
 /incubator/cassandra/branches/cassandra-0.3/contrib:774578-796573
 /incubator/cassandra/branches/cassandra-0.4/contrib:810145-810987,810994-834239,834349-834350

Modified: cassandra/trunk/doc/cql/CQL.textile
URL: http://svn.apache.org/viewvc/cassandra/trunk/doc/cql/CQL.textile?rev=1101615&r1=1101614&r2=1101615&view=diff
==============================================================================
--- cassandra/trunk/doc/cql/CQL.textile (original)
+++ cassandra/trunk/doc/cql/CQL.textile Tue May 10 19:47:50 2011
@@ -74,7 +74,7 @@ h2. INSERT
 _Synopsis:_
 
 bc.
-INSERT INTO <COLUMN FAMILY> (KEY, <col>, <col>, ...) VALUES (<key>, <val>, <val>, ...) [USING CONSISTENCY <LEVEL> [AND TIMESTAMP <timestamp>]];
+INSERT INTO <COLUMN FAMILY> (KEY, <col>, <col>, ...) VALUES (<key>, <val>, <val>, ...) [USING CONSISTENCY <LEVEL> [AND TIMESTAMP <timestamp>] [AND TTL <timeToLive>]];
 
 An @INSERT@ is used to write one or more columns to a record in a Cassandra column family. No results are returned. 
 
@@ -85,7 +85,7 @@ h2. UPDATE
 _Synopsis:_
 
 bc. 
-UPDATE <COLUMN FAMILY> [USING <CONSISTENCY> [AND TIMESTAMP <timestamp>]]
+UPDATE <COLUMN FAMILY> [USING <CONSISTENCY> [AND TIMESTAMP <timestamp>] [AND TTL <timeToLive>]]
         SET name1 = value1, name2 = value2 WHERE KEY = keyname;
         
 An @UPDATE@ is used to write one or more columns to a record in a Cassandra column family. No results are returned.
@@ -111,6 +111,13 @@ UPDATE ... [USING TIMESTAMP <timestamp>]
 
 @UPDATE@ supports setting client-supplied optional timestamp for modification.
 
+h3. TTL
+
+bc.
+UPDATE ... [USING TTL <timeToLive>] ...
+
+@UPDATE@ supports setting time to live (TTL) for each of the columns in @UPDATE@ statement.
+
 h3. Specifying Columns and Row
 
 bc. 

Modified: cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/ColumnDecoder.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/ColumnDecoder.java?rev=1101615&r1=1101614&r2=1101615&view=diff
==============================================================================
--- cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/ColumnDecoder.java (original)
+++ cassandra/trunk/drivers/java/src/org/apache/cassandra/cql/jdbc/ColumnDecoder.java Tue May 10 19:47:50 2011
@@ -25,14 +25,15 @@ import org.apache.cassandra.config.CFMet
 import org.apache.cassandra.config.ColumnDefinition;
 import org.apache.cassandra.config.ConfigurationException;
 import org.apache.cassandra.db.marshal.AbstractType;
+import org.apache.cassandra.db.marshal.AsciiType;
 import org.apache.cassandra.thrift.*;
 import org.apache.cassandra.utils.ByteBufferUtil;
-import org.apache.cassandra.utils.FBUtilities;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.nio.ByteBuffer;
+import java.nio.charset.CharacterCodingException;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -57,7 +58,7 @@ class ColumnDecoder
             {
                 try
                 {
-                    metadata.put(String.format("%s.%s", ks.getName(), cf.getName()), CFMetaData.convertToCFMetaData(cf));
+                    metadata.put(String.format("%s.%s", ks.getName(), cf.getName()), CFMetaData.fromThrift(cf));
                 }
                 catch (InvalidRequestException e)
                 {
@@ -80,12 +81,30 @@ class ColumnDecoder
     {
 
         CFMetaData md = metadata.get(String.format("%s.%s", keyspace, columnFamily));
+        try
+        {
+            if (ByteBufferUtil.string(name).equalsIgnoreCase(ByteBufferUtil.string(md.getKeyName())))
+                return AsciiType.instance;
+        }
+        catch (CharacterCodingException e)
+        {
+            // not be the key name
+        }
         return md.comparator;
     }
 
     AbstractType getValueType(String keyspace, String columnFamily, ByteBuffer name)
     {
         CFMetaData md = metadata.get(String.format("%s.%s", keyspace, columnFamily));
+        try
+        {
+            if (ByteBufferUtil.string(name).equalsIgnoreCase(ByteBufferUtil.string(md.getKeyName())))
+                return md.getKeyValidator();
+        }
+        catch (CharacterCodingException e)
+        {
+            // not be the key name
+        }
         ColumnDefinition cd = md.getColumnDefinition(name);
         return cd == null ? md.getDefaultValidator() : cd.getValidator();
     }

Modified: cassandra/trunk/drivers/java/test/org/apache/cassandra/cql/JdbcDriverTest.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/drivers/java/test/org/apache/cassandra/cql/JdbcDriverTest.java?rev=1101615&r1=1101614&r2=1101615&view=diff
==============================================================================
--- cassandra/trunk/drivers/java/test/org/apache/cassandra/cql/JdbcDriverTest.java (original)
+++ cassandra/trunk/drivers/java/test/org/apache/cassandra/cql/JdbcDriverTest.java Tue May 10 19:47:50 2011
@@ -33,6 +33,7 @@ import org.junit.BeforeClass;
 import org.junit.Test;
 
 import org.apache.cassandra.db.marshal.*;
+import org.apache.cassandra.utils.ByteBufferUtil;
 import org.apache.cassandra.utils.FBUtilities;
 
 import static junit.framework.Assert.assertEquals;
@@ -120,6 +121,12 @@ public class JdbcDriverTest extends Embe
         expectedMetaData(md, 2, BigInteger.class.getName(), "JdbcInteger", "Keyspace1", "2", Types.BIGINT, IntegerType.class.getSimpleName(), true, false);
         expectedMetaData(md, 3, String.class.getName(), "JdbcInteger", "Keyspace1", "42", Types.VARCHAR, UTF8Type.class.getSimpleName(), false, true);
         
+        rs = stmt.executeQuery("select key, 1, 2, 42 from JdbcInteger where key='" + key + "'");
+        assert rs.next();
+        assert Arrays.equals(rs.getBytes("key"), FBUtilities.hexToBytes(key));
+        assert rs.getObject("1").equals(new BigInteger("36893488147419103232"));
+        assert rs.getString("42").equals("fortytwofortytwo") : rs.getString("42");
+
         stmt.executeUpdate("update JdbcUtf8 set a='aa', b='bb', fortytwo='4242' where key='" + key + "'");
         rs = stmt.executeQuery("select a, b, fortytwo from JdbcUtf8 where key='" + key + "'");
         assert rs.next();

Modified: cassandra/trunk/drivers/py/cql/__init__.py
URL: http://svn.apache.org/viewvc/cassandra/trunk/drivers/py/cql/__init__.py?rev=1101615&r1=1101614&r2=1101615&view=diff
==============================================================================
--- cassandra/trunk/drivers/py/cql/__init__.py (original)
+++ cassandra/trunk/drivers/py/cql/__init__.py Tue May 10 19:47:50 2011
@@ -45,8 +45,6 @@ apilevel = 1.0
 threadsafety = 1 # Threads may share the module, but not connections/cursors.
 paramstyle = 'named'
 
-ROW_KEY = "Row Key"
-
 # TODO: Pull connections out of a pool instead.
 def connect(host, port=9160, keyspace='system', user=None, password=None):
     return connection.Connection(host, port, keyspace, user, password)

Modified: cassandra/trunk/drivers/py/cql/cursor.py
URL: http://svn.apache.org/viewvc/cassandra/trunk/drivers/py/cql/cursor.py?rev=1101615&r1=1101614&r2=1101615&view=diff
==============================================================================
--- cassandra/trunk/drivers/py/cql/cursor.py (original)
+++ cassandra/trunk/drivers/py/cql/cursor.py Tue May 10 19:47:50 2011
@@ -92,16 +92,14 @@ class Cursor:
             return results
 
         def column_families(cf_defs):
-            cfresults = {}
-            if cf_defs:
-                for cf in cf_defs:
-                    cfresults[cf.name] = {"comparator": cf.comparator_type}
-                    cfresults[cf.name]["default_validation_class"] = \
-                             cf.default_validation_class
-                    cfresults[cf.name]["key_validation_class"] = \
-                             cf.key_validation_class
-                    cfresults[cf.name]["columns"] = columns(cf.column_metadata)
-            return cfresults
+            d = {}
+            for cf in cf_defs:
+                d[cf.name] = {'comparator': cf.comparator_type,
+                              'default_validation_class': cf.default_validation_class,
+                              'key_validation_class': cf.key_validation_class,
+                              'columns': columns(cf.column_metadata),
+                              'key_alias': cf.key_alias}
+            return d
 
         schema = {}
         client = self.parent_connection.client

Modified: cassandra/trunk/drivers/py/cql/decoders.py
URL: http://svn.apache.org/viewvc/cassandra/trunk/drivers/py/cql/decoders.py?rev=1101615&r1=1101614&r2=1101615&view=diff
==============================================================================
--- cassandra/trunk/drivers/py/cql/decoders.py (original)
+++ cassandra/trunk/drivers/py/cql/decoders.py Tue May 10 19:47:50 2011
@@ -32,45 +32,44 @@ class SchemaDecoder(object):
 
     def __comparator_for(self, keyspace, column_family):
         cfam = self.__get_column_family_def(keyspace, column_family)
-        if cfam and "comparator" in cfam:
+        if "comparator" in cfam:
             return cfam["comparator"]
         return None
 
     def __validator_for(self, keyspace, column_family, name):
         cfam = self.__get_column_family_def(keyspace, column_family)
-        if cfam:
-            if name in cfam["columns"]:
-                return cfam["columns"][name]
-            return cfam["default_validation_class"]
-        return None
+        if name in cfam["columns"]:
+            return cfam["columns"][name]
+        return cfam["default_validation_class"]
 
     def __keytype_for(self, keyspace, column_family):
         cfam = self.__get_column_family_def(keyspace, column_family)
-        if cfam and "key_validation_class" in cfam:
+        if "key_validation_class" in cfam:
             return cfam["key_validation_class"]
         return None
 
     def decode_description(self, keyspace, column_family, row):
-        key_type = self.__keytype_for(keyspace, column_family)
-        description = [(cql.ROW_KEY, key_type, None, None, None, None, None, False)]
+        description = []
         comparator = self.__comparator_for(keyspace, column_family)
         unmarshal = unmarshallers.get(comparator, unmarshal_noop)
         for column in row.columns:
-            description.append((unmarshal(column.name), comparator, None, None, None, None, True))
-
+            if column.name == self.__get_column_family_def(keyspace, column_family)['key_alias']:
+                description.append((column.name, 'text', None, None, None, None, True))
+            else:
+                description.append((unmarshal(column.name), comparator, None, None, None, None, True))
         return description
 
     def decode_row(self, keyspace, column_family, row):
-        key_type = self.__keytype_for(keyspace, column_family)
-        key = unmarshallers.get(key_type, unmarshal_noop)(row.key)
         comparator = self.__comparator_for(keyspace, column_family)
         unmarshal = unmarshallers.get(comparator, unmarshal_noop)
-        values = [key]
+        values = []
         for column in row.columns:
-            validator = self.__validator_for(keyspace, column_family, column.name)
             if column.value is None:
                 values.append(None)
+                continue
+            if column.name == self.__get_column_family_def(keyspace, column_family)['key_alias']:
+                validator = self.__keytype_for(keyspace, column_family)
             else:
-                values.append(unmarshallers.get(validator, unmarshal_noop)(column.value))
-
+                validator = self.__validator_for(keyspace, column_family, column.name)
+            values.append(unmarshallers.get(validator, unmarshal_noop)(column.value))
         return values

Propchange: cassandra/trunk/interface/thrift/gen-java/org/apache/cassandra/thrift/Cassandra.java
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue May 10 19:47:50 2011
@@ -1,8 +1,8 @@
 /cassandra/branches/cassandra-0.6/interface/thrift/gen-java/org/apache/cassandra/thrift/Cassandra.java:922689-1052356,1052358-1053452,1053454,1053456-1081914,1083000
-/cassandra/branches/cassandra-0.7/interface/thrift/gen-java/org/apache/cassandra/thrift/Cassandra.java:1026516-1100465,1101021
+/cassandra/branches/cassandra-0.7/interface/thrift/gen-java/org/apache/cassandra/thrift/Cassandra.java:1026516-1100900,1101021
 /cassandra/branches/cassandra-0.7.0/interface/thrift/gen-java/org/apache/cassandra/thrift/Cassandra.java:1053690-1055654
-/cassandra/branches/cassandra-0.8/interface/thrift/gen-java/org/apache/cassandra/thrift/Cassandra.java:1090935-1100898,1100905,1100982,1101034
-/cassandra/branches/cassandra-0.8.1/interface/thrift/gen-java/org/apache/cassandra/thrift/Cassandra.java:1101038
+/cassandra/branches/cassandra-0.8/interface/thrift/gen-java/org/apache/cassandra/thrift/Cassandra.java:1090935-1101597
+/cassandra/branches/cassandra-0.8.1/interface/thrift/gen-java/org/apache/cassandra/thrift/Cassandra.java:1101014-1101613
 /cassandra/tags/cassandra-0.7.0-rc3/interface/thrift/gen-java/org/apache/cassandra/thrift/Cassandra.java:1051699-1053689
 /incubator/cassandra/branches/cassandra-0.3/interface/gen-java/org/apache/cassandra/service/Cassandra.java:774578-796573
 /incubator/cassandra/branches/cassandra-0.4/interface/gen-java/org/apache/cassandra/service/Cassandra.java:810145-834239,834349-834350

Propchange: cassandra/trunk/interface/thrift/gen-java/org/apache/cassandra/thrift/Column.java
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue May 10 19:47:50 2011
@@ -1,8 +1,8 @@
 /cassandra/branches/cassandra-0.6/interface/thrift/gen-java/org/apache/cassandra/thrift/Column.java:922689-1052356,1052358-1053452,1053454,1053456-1081914,1083000
-/cassandra/branches/cassandra-0.7/interface/thrift/gen-java/org/apache/cassandra/thrift/Column.java:1026516-1100465,1101021
+/cassandra/branches/cassandra-0.7/interface/thrift/gen-java/org/apache/cassandra/thrift/Column.java:1026516-1100900,1101021
 /cassandra/branches/cassandra-0.7.0/interface/thrift/gen-java/org/apache/cassandra/thrift/Column.java:1053690-1055654
-/cassandra/branches/cassandra-0.8/interface/thrift/gen-java/org/apache/cassandra/thrift/Column.java:1090935-1100898,1100905,1100982,1101034
-/cassandra/branches/cassandra-0.8.1/interface/thrift/gen-java/org/apache/cassandra/thrift/Column.java:1101038
+/cassandra/branches/cassandra-0.8/interface/thrift/gen-java/org/apache/cassandra/thrift/Column.java:1090935-1101597
+/cassandra/branches/cassandra-0.8.1/interface/thrift/gen-java/org/apache/cassandra/thrift/Column.java:1101014-1101613
 /cassandra/tags/cassandra-0.7.0-rc3/interface/thrift/gen-java/org/apache/cassandra/thrift/Column.java:1051699-1053689
 /incubator/cassandra/branches/cassandra-0.3/interface/gen-java/org/apache/cassandra/service/column_t.java:774578-792198
 /incubator/cassandra/branches/cassandra-0.4/interface/gen-java/org/apache/cassandra/service/Column.java:810145-834239,834349-834350

Propchange: cassandra/trunk/interface/thrift/gen-java/org/apache/cassandra/thrift/InvalidRequestException.java
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue May 10 19:47:50 2011
@@ -1,8 +1,8 @@
 /cassandra/branches/cassandra-0.6/interface/thrift/gen-java/org/apache/cassandra/thrift/InvalidRequestException.java:922689-1052356,1052358-1053452,1053454,1053456-1081914,1083000
-/cassandra/branches/cassandra-0.7/interface/thrift/gen-java/org/apache/cassandra/thrift/InvalidRequestException.java:1026516-1100465,1101021
+/cassandra/branches/cassandra-0.7/interface/thrift/gen-java/org/apache/cassandra/thrift/InvalidRequestException.java:1026516-1100900,1101021
 /cassandra/branches/cassandra-0.7.0/interface/thrift/gen-java/org/apache/cassandra/thrift/InvalidRequestException.java:1053690-1055654
-/cassandra/branches/cassandra-0.8/interface/thrift/gen-java/org/apache/cassandra/thrift/InvalidRequestException.java:1090935-1100898,1100905,1100982,1101034
-/cassandra/branches/cassandra-0.8.1/interface/thrift/gen-java/org/apache/cassandra/thrift/InvalidRequestException.java:1101038
+/cassandra/branches/cassandra-0.8/interface/thrift/gen-java/org/apache/cassandra/thrift/InvalidRequestException.java:1090935-1101597
+/cassandra/branches/cassandra-0.8.1/interface/thrift/gen-java/org/apache/cassandra/thrift/InvalidRequestException.java:1101014-1101613
 /cassandra/tags/cassandra-0.7.0-rc3/interface/thrift/gen-java/org/apache/cassandra/thrift/InvalidRequestException.java:1051699-1053689
 /incubator/cassandra/branches/cassandra-0.3/interface/gen-java/org/apache/cassandra/service/InvalidRequestException.java:774578-796573
 /incubator/cassandra/branches/cassandra-0.4/interface/gen-java/org/apache/cassandra/service/InvalidRequestException.java:810145-834239,834349-834350

Propchange: cassandra/trunk/interface/thrift/gen-java/org/apache/cassandra/thrift/NotFoundException.java
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue May 10 19:47:50 2011
@@ -1,8 +1,8 @@
 /cassandra/branches/cassandra-0.6/interface/thrift/gen-java/org/apache/cassandra/thrift/NotFoundException.java:922689-1052356,1052358-1053452,1053454,1053456-1081914,1083000
-/cassandra/branches/cassandra-0.7/interface/thrift/gen-java/org/apache/cassandra/thrift/NotFoundException.java:1026516-1100465,1101021
+/cassandra/branches/cassandra-0.7/interface/thrift/gen-java/org/apache/cassandra/thrift/NotFoundException.java:1026516-1100900,1101021
 /cassandra/branches/cassandra-0.7.0/interface/thrift/gen-java/org/apache/cassandra/thrift/NotFoundException.java:1053690-1055654
-/cassandra/branches/cassandra-0.8/interface/thrift/gen-java/org/apache/cassandra/thrift/NotFoundException.java:1090935-1100898,1100905,1100982,1101034
-/cassandra/branches/cassandra-0.8.1/interface/thrift/gen-java/org/apache/cassandra/thrift/NotFoundException.java:1101038
+/cassandra/branches/cassandra-0.8/interface/thrift/gen-java/org/apache/cassandra/thrift/NotFoundException.java:1090935-1101597
+/cassandra/branches/cassandra-0.8.1/interface/thrift/gen-java/org/apache/cassandra/thrift/NotFoundException.java:1101014-1101613
 /cassandra/tags/cassandra-0.7.0-rc3/interface/thrift/gen-java/org/apache/cassandra/thrift/NotFoundException.java:1051699-1053689
 /incubator/cassandra/branches/cassandra-0.3/interface/gen-java/org/apache/cassandra/service/NotFoundException.java:774578-796573
 /incubator/cassandra/branches/cassandra-0.4/interface/gen-java/org/apache/cassandra/service/NotFoundException.java:810145-834239,834349-834350

Propchange: cassandra/trunk/interface/thrift/gen-java/org/apache/cassandra/thrift/SuperColumn.java
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue May 10 19:47:50 2011
@@ -1,8 +1,8 @@
 /cassandra/branches/cassandra-0.6/interface/thrift/gen-java/org/apache/cassandra/thrift/SuperColumn.java:922689-1052356,1052358-1053452,1053454,1053456-1081914,1083000
-/cassandra/branches/cassandra-0.7/interface/thrift/gen-java/org/apache/cassandra/thrift/SuperColumn.java:1026516-1100465,1101021
+/cassandra/branches/cassandra-0.7/interface/thrift/gen-java/org/apache/cassandra/thrift/SuperColumn.java:1026516-1100900,1101021
 /cassandra/branches/cassandra-0.7.0/interface/thrift/gen-java/org/apache/cassandra/thrift/SuperColumn.java:1053690-1055654
-/cassandra/branches/cassandra-0.8/interface/thrift/gen-java/org/apache/cassandra/thrift/SuperColumn.java:1090935-1100898,1100905,1100982,1101034
-/cassandra/branches/cassandra-0.8.1/interface/thrift/gen-java/org/apache/cassandra/thrift/SuperColumn.java:1101038
+/cassandra/branches/cassandra-0.8/interface/thrift/gen-java/org/apache/cassandra/thrift/SuperColumn.java:1090935-1101597
+/cassandra/branches/cassandra-0.8.1/interface/thrift/gen-java/org/apache/cassandra/thrift/SuperColumn.java:1101014-1101613
 /cassandra/tags/cassandra-0.7.0-rc3/interface/thrift/gen-java/org/apache/cassandra/thrift/SuperColumn.java:1051699-1053689
 /incubator/cassandra/branches/cassandra-0.3/interface/gen-java/org/apache/cassandra/service/superColumn_t.java:774578-792198
 /incubator/cassandra/branches/cassandra-0.4/interface/gen-java/org/apache/cassandra/service/SuperColumn.java:810145-834239,834349-834350

Modified: cassandra/trunk/src/java/org/apache/cassandra/cli/CliClient.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cli/CliClient.java?rev=1101615&r1=1101614&r2=1101615&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cli/CliClient.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cli/CliClient.java Tue May 10 19:47:50 2011
@@ -602,7 +602,7 @@ public class CliClient
             // setting value for output
             valueAsString = valueValidator.getString(ByteBuffer.wrap(columnValue));
             // updating column value validator class
-            updateColumnMetaData(cfDef, columnName, valueValidator.getClass().getName());
+            updateColumnMetaData(cfDef, columnName, valueValidator.toString());
         }
         else
         {
@@ -2159,7 +2159,7 @@ public class CliClient
             // performing ColumnDef local validator update
             if (withUpdate)
             {
-                updateColumnMetaData(columnFamily, columnName, validator.getClass().getName());
+                updateColumnMetaData(columnFamily, columnName, validator.toString());
             }
 
             return value;

Modified: cassandra/trunk/src/java/org/apache/cassandra/config/CFMetaData.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/config/CFMetaData.java?rev=1101615&r1=1101614&r2=1101615&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/config/CFMetaData.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/config/CFMetaData.java Tue May 10 19:47:50 2011
@@ -78,6 +78,7 @@ public final class CFMetaData
     public static final CFMetaData SchemaCf = newSystemMetadata(Migration.SCHEMA_CF, 3, "current state of the schema", UTF8Type.instance, null, DEFAULT_SYSTEM_MEMTABLE_THROUGHPUT_IN_MB);
     public static final CFMetaData IndexCf = newSystemMetadata(SystemTable.INDEX_CF, 5, "indexes that have been completed", UTF8Type.instance, null, DEFAULT_SYSTEM_MEMTABLE_THROUGHPUT_IN_MB);
     public static final CFMetaData NodeIdCf = newSystemMetadata(SystemTable.NODE_ID_CF, 6, "nodeId and their metadata", TimeUUIDType.instance, null, DEFAULT_SYSTEM_MEMTABLE_THROUGHPUT_IN_MB);
+    private static final ByteBuffer DEFAULT_KEY_NAME = ByteBufferUtil.bytes("KEY");
 
     /**
      * @return A calculated memtable throughput size for this machine.
@@ -322,17 +323,17 @@ public final class CFMetaData
         cf.keyspace = new Utf8(ksName);
         cf.name = new Utf8(cfName);
         cf.column_type = new Utf8(cfType.name());
-        cf.comparator_type = new Utf8(comparator.getClass().getName());
+        cf.comparator_type = new Utf8(comparator.toString());
         if (subcolumnComparator != null)
-            cf.subcomparator_type = new Utf8(subcolumnComparator.getClass().getName());
+            cf.subcomparator_type = new Utf8(subcolumnComparator.toString());
         cf.comment = new Utf8(comment);
         cf.row_cache_size = rowCacheSize;
         cf.key_cache_size = keyCacheSize;
         cf.read_repair_chance = readRepairChance;
         cf.replicate_on_write = replicateOnWrite;
         cf.gc_grace_seconds = gcGraceSeconds;
-        cf.default_validation_class = new Utf8(defaultValidator.getClass().getName());
-        cf.key_validation_class = new Utf8(keyValidator.getClass().getName());
+        cf.default_validation_class = new Utf8(defaultValidator.toString());
+        cf.key_validation_class = new Utf8(keyValidator.toString());
         cf.min_compaction_threshold = minCompactionThreshold;
         cf.max_compaction_threshold = maxCompactionThreshold;
         cf.row_cache_save_period_in_seconds = rowCacheSavePeriodInSeconds;
@@ -504,9 +505,9 @@ public final class CFMetaData
         return rowCacheProvider;
     }
 
-    public ByteBuffer getKeyAlias()
+    public ByteBuffer getKeyName()
     {
-        return keyAlias;
+        return keyAlias == null ? DEFAULT_KEY_NAME : keyAlias;
     }
 
     public Map<ByteBuffer, ColumnDefinition> getColumn_metadata()
@@ -628,7 +629,7 @@ public final class CFMetaData
             cf_def.setRow_cache_provider(CFMetaData.DEFAULT_ROW_CACHE_PROVIDER);
     }
 
-    public static CFMetaData convertToCFMetaData(org.apache.cassandra.thrift.CfDef cf_def) throws InvalidRequestException, ConfigurationException
+    public static CFMetaData fromThrift(org.apache.cassandra.thrift.CfDef cf_def) throws InvalidRequestException, ConfigurationException
     {
         ColumnFamilyType cfType = ColumnFamilyType.create(cf_def.column_type);
         if (cfType == null)
@@ -640,7 +641,6 @@ public final class CFMetaData
 
         validateMinMaxCompactionThresholds(cf_def);
         validateMemtableSettings(cf_def);
-        validateAliasCompares(cf_def);
 
         CFMetaData newCFMD = new CFMetaData(cf_def.keyspace,
                                             cf_def.name,
@@ -763,10 +763,10 @@ public final class CFMetaData
         org.apache.cassandra.thrift.CfDef def = new org.apache.cassandra.thrift.CfDef(cfm.ksName, cfm.cfName);
         def.setId(cfm.cfId);
         def.setColumn_type(cfm.cfType.name());
-        def.setComparator_type(cfm.comparator.getClass().getName());
+        def.setComparator_type(cfm.comparator.toString());
         if (cfm.subcolumnComparator != null)
         {
-            def.setSubcomparator_type(cfm.subcolumnComparator.getClass().getName());
+            def.setSubcomparator_type(cfm.subcolumnComparator.toString());
             def.setColumn_type("Super");
         }
         def.setComment(enforceCommentNotNull(cfm.comment));
@@ -775,8 +775,8 @@ public final class CFMetaData
         def.setRead_repair_chance(cfm.readRepairChance);
         def.setReplicate_on_write(cfm.replicateOnWrite);
         def.setGc_grace_seconds(cfm.gcGraceSeconds);
-        def.setDefault_validation_class(cfm.defaultValidator.getClass().getName());
-        def.setKey_validation_class(cfm.keyValidator.getClass().getName());
+        def.setDefault_validation_class(cfm.defaultValidator.toString());
+        def.setKey_validation_class(cfm.keyValidator.toString());
         def.setMin_compaction_threshold(cfm.minCompactionThreshold);
         def.setMax_compaction_threshold(cfm.maxCompactionThreshold);
         def.setRow_cache_save_period_in_seconds(cfm.rowCacheSavePeriodInSeconds);
@@ -785,7 +785,7 @@ public final class CFMetaData
         def.setMemtable_throughput_in_mb(cfm.memtableThroughputInMb);
         def.setMemtable_operations_in_millions(cfm.memtableOperationsInMillions);
         def.setMerge_shards_chance(cfm.mergeShardsChance);
-        def.setKey_alias(cfm.keyAlias);
+        def.setKey_alias(cfm.getKeyName());
         List<org.apache.cassandra.thrift.ColumnDef> column_meta = new ArrayList< org.apache.cassandra.thrift.ColumnDef>(cfm.column_metadata.size());
         for (ColumnDefinition cd : cfm.column_metadata.values())
         {
@@ -793,7 +793,7 @@ public final class CFMetaData
             tcd.setIndex_name(cd.getIndexName());
             tcd.setIndex_type(cd.getIndexType());
             tcd.setName(cd.name);
-            tcd.setValidation_class(cd.getValidator().getClass().getName());
+            tcd.setValidation_class(cd.getValidator().toString());
             column_meta.add(tcd);
         }
         def.setColumn_metadata(column_meta);
@@ -808,10 +808,10 @@ public final class CFMetaData
         def.keyspace = cfm.ksName;
         def.id = cfm.cfId;
         def.column_type = cfm.cfType.name();
-        def.comparator_type = cfm.comparator.getClass().getName();
+        def.comparator_type = cfm.comparator.toString();
         if (cfm.subcolumnComparator != null)
         {
-            def.subcomparator_type = cfm.subcolumnComparator.getClass().getName();
+            def.subcomparator_type = cfm.subcolumnComparator.toString();
             def.column_type = "Super";
         }
         def.comment = enforceCommentNotNull(cfm.comment);
@@ -820,7 +820,7 @@ public final class CFMetaData
         def.read_repair_chance = cfm.readRepairChance;
         def.replicate_on_write = cfm.replicateOnWrite;
         def.gc_grace_seconds = cfm.gcGraceSeconds;
-        def.default_validation_class = cfm.defaultValidator == null ? null : cfm.defaultValidator.getClass().getName();
+        def.default_validation_class = cfm.defaultValidator == null ? null : cfm.defaultValidator.toString();
         def.min_compaction_threshold = cfm.minCompactionThreshold;
         def.max_compaction_threshold = cfm.maxCompactionThreshold;
         def.row_cache_save_period_in_seconds = cfm.rowCacheSavePeriodInSeconds;
@@ -838,7 +838,7 @@ public final class CFMetaData
             tcd.index_name = cd.getIndexName();
             tcd.index_type = cd.getIndexType() == null ? null : org.apache.cassandra.db.migration.avro.IndexType.valueOf(cd.getIndexType().name());
             tcd.name = ByteBufferUtil.clone(cd.name);
-            tcd.validation_class = cd.getValidator().getClass().getName();
+            tcd.validation_class = cd.getValidator().toString();
             column_meta.add(tcd);
         }
         def.column_metadata = column_meta; 
@@ -970,13 +970,6 @@ public final class CFMetaData
             DatabaseDescriptor.validateMemtableOperations(cf_def.memtable_operations_in_millions);
     }
 
-    public static void validateAliasCompares(org.apache.cassandra.thrift.CfDef cf_def) throws ConfigurationException
-    {
-        AbstractType comparator = DatabaseDescriptor.getComparator(cf_def.comparator_type);
-        if (cf_def.key_alias != null)
-            comparator.validate(cf_def.key_alias);
-    }
-
     public static void validateAliasCompares(org.apache.cassandra.db.migration.avro.CfDef cf_def) throws ConfigurationException
     {
         AbstractType comparator = DatabaseDescriptor.getComparator(cf_def.comparator_type);

Modified: cassandra/trunk/src/java/org/apache/cassandra/config/ColumnDefinition.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/config/ColumnDefinition.java?rev=1101615&r1=1101614&r2=1101615&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/config/ColumnDefinition.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/config/ColumnDefinition.java Tue May 10 19:47:50 2011
@@ -79,7 +79,7 @@ public class ColumnDefinition
     {
         org.apache.cassandra.db.migration.avro.ColumnDef cd = new org.apache.cassandra.db.migration.avro.ColumnDef();
         cd.name = name;
-        cd.validation_class = new Utf8(validator.getClass().getName());
+        cd.validation_class = new Utf8(validator.toString());
         cd.index_type = index_type == null ? null :
             Enum.valueOf(org.apache.cassandra.db.migration.avro.IndexType.class, index_type.name());
         cd.index_name = index_name == null ? null : new Utf8(index_name);

Modified: cassandra/trunk/src/java/org/apache/cassandra/config/KSMetaData.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/config/KSMetaData.java?rev=1101615&r1=1101614&r2=1101615&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/config/KSMetaData.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/config/KSMetaData.java Tue May 10 19:47:50 2011
@@ -18,10 +18,7 @@
 
 package org.apache.cassandra.config;
 
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
+import java.util.*;
 
 import org.apache.commons.lang.ObjectUtils;
 
@@ -29,6 +26,7 @@ import org.apache.avro.util.Utf8;
 import org.apache.cassandra.io.SerDeUtils;
 import org.apache.cassandra.locator.AbstractReplicationStrategy;
 import org.apache.cassandra.locator.NetworkTopologyStrategy;
+import org.apache.cassandra.thrift.CfDef;
 import org.apache.cassandra.thrift.KsDef;
 
 import org.apache.commons.lang.StringUtils;
@@ -51,7 +49,7 @@ public final class KSMetaData
         this.cfMetaData = Collections.unmodifiableMap(cfmap);
     }
 
-    public static Map<String, String> backwardsCompatibleOptions(KsDef ks_def)
+    public static Map<String, String> forwardsCompatibleOptions(KsDef ks_def)
     {
         Map<String, String> options;
         if (ks_def.isSetReplication_factor())
@@ -165,4 +163,24 @@ public final class KSMetaData
         ret.put("replication_factor", rf.toString());
         return ret;
     }
+
+    public static KSMetaData fromThrift(KsDef ksd, CFMetaData... cfDefs) throws ConfigurationException
+    {
+        return new KSMetaData(ksd.name,
+                              AbstractReplicationStrategy.getClass(ksd.strategy_class),
+                              forwardsCompatibleOptions(ksd),
+                              cfDefs);
+    }
+
+    public static KsDef toThrift(KSMetaData ksm)
+    {
+        List<CfDef> cfDefs = new ArrayList<CfDef>();
+        for (CFMetaData cfm : ksm.cfMetaData().values())
+            cfDefs.add(CFMetaData.convertToThrift(cfm));
+        KsDef ksdef = new KsDef(ksm.name, ksm.strategyClass.getName(), cfDefs);
+        ksdef.setStrategy_options(ksm.strategyOptions);
+        if (ksm.strategyOptions != null && ksm.strategyOptions.containsKey("replication_factor"))
+            ksdef.setReplication_factor(Integer.parseInt(ksm.strategyOptions.get("replication_factor")));
+        return ksdef;
+    }
 }

Modified: cassandra/trunk/src/java/org/apache/cassandra/cql/AbstractModification.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cql/AbstractModification.java?rev=1101615&r1=1101614&r2=1101615&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/AbstractModification.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/AbstractModification.java Tue May 10 19:47:50 2011
@@ -33,17 +33,19 @@ public abstract class AbstractModificati
     protected final String columnFamily;
     protected final ConsistencyLevel cLevel;
     protected final Long timestamp;
+    protected final int timeToLive;
 
-    public AbstractModification(String columnFamily, ConsistencyLevel cLevel)
+    public AbstractModification(String columnFamily, Attributes attrs)
     {
-        this(columnFamily, cLevel, null);
+        this(columnFamily, attrs.getConsistencyLevel(), attrs.getTimestamp(), attrs.getTimeToLive());
     }
 
-    public AbstractModification(String columnFamily, ConsistencyLevel cLevel, Long timestamp)
+    public AbstractModification(String columnFamily, ConsistencyLevel cLevel, Long timestamp, int timeToLive)
     {
         this.columnFamily = columnFamily;
         this.cLevel = cLevel;
         this.timestamp = timestamp;
+        this.timeToLive = timeToLive;
     }
 
     public String getColumnFamily()
@@ -76,6 +78,11 @@ public abstract class AbstractModificati
         return timestamp != null;
     }
 
+    public int getTimeToLive()
+    {
+        return timeToLive;
+    }
+
     /**
      * Convert statement into a list of mutations to apply on the server
      *

Modified: cassandra/trunk/src/java/org/apache/cassandra/cql/BatchStatement.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cql/BatchStatement.java?rev=1101615&r1=1101614&r2=1101615&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/BatchStatement.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/BatchStatement.java Tue May 10 19:47:50 2011
@@ -43,18 +43,22 @@ public class BatchStatement
     // global timestamp to apply for each mutation
     protected final Long timestamp;
 
+    // global time to live
+    protected final int timeToLive;
+
     /**
      * Creates a new BatchStatement from a list of statements and a
      * Thrift consistency level.
      *
      * @param statements a list of UpdateStatements
-     * @param level Thrift consistency level enum
+     * @param attrs additional attributes for statement (CL, timestamp, timeToLive)
      */
-    public BatchStatement(List<AbstractModification> statements, ConsistencyLevel level, Long timestamp)
+    public BatchStatement(List<AbstractModification> statements, Attributes attrs)
     {
         this.statements = statements;
-        consistency = level;
-        this.timestamp = timestamp;
+        this.consistency = attrs.getConsistencyLevel();
+        this.timestamp = attrs.getTimestamp();
+        this.timeToLive = attrs.getTimeToLive();
     }
 
     public List<AbstractModification> getStatements()
@@ -67,6 +71,11 @@ public class BatchStatement
         return consistency;
     }
 
+    public int getTimeToLive()
+    {
+        return timeToLive;
+    }
+
     public List<RowMutation> getMutations(String keyspace, ClientState clientState) throws InvalidRequestException
     {
         List<RowMutation> batch = new LinkedList<RowMutation>();

Modified: cassandra/trunk/src/java/org/apache/cassandra/cql/Cql.g
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cql/Cql.g?rev=1101615&r1=1101614&r2=1101615&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/Cql.g (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/Cql.g Tue May 10 19:47:50 2011
@@ -169,8 +169,8 @@ selectExpression returns [SelectExpressi
       ( K_REVERSED { reversed = true; } )?
       ( first=term { $expr = new SelectExpression(first, count, reversed); }
             (',' next=term { $expr.and(next); })*
-      | start=term RANGEOP finish=term { $expr = new SelectExpression(start, finish, count, reversed); }
-      | '\*' { $expr = new SelectExpression(new Term(), new Term(), count, reversed); }
+      | start=term RANGEOP finish=term { $expr = new SelectExpression(start, finish, count, reversed, false); }
+      | '\*' { $expr = new SelectExpression(new Term(), new Term(), count, reversed, true); }
       )
     ;
 
@@ -201,9 +201,7 @@ whereClause returns [WhereClause clause]
  */
 insertStatement returns [UpdateStatement expr]
     : {
-          Long timestamp = null;
-          ConsistencyLevel cLevel = null;
-
+          Attributes attrs = new Attributes();
           Map<Term, Term> columns = new HashMap<Term, Term>();
 
           List<Term> columnNames  = new ArrayList<Term>();
@@ -213,19 +211,20 @@ insertStatement returns [UpdateStatement
           '(' K_KEY    ( ',' column_name=term  { columnNames.add($column_name.item); } )+ ')'
         K_VALUES
           '(' key=term ( ',' column_value=term { columnValues.add($column_value.item); })+ ')'
-        ( usingClause[cLevel, timestamp] )?
+        ( usingClause[attrs] )?
       {
-          return new UpdateStatement($columnFamily.text, cLevel, columnNames, columnValues, Collections.singletonList(key), timestamp);
+          return new UpdateStatement($columnFamily.text, columnNames, columnValues, Collections.singletonList(key), attrs);
       }
     ;
 
-usingClause[ConsistencyLevel cLevel, Long timestamp]
-    : K_USING usingClauseObjective[cLevel, timestamp] ( K_AND? usingClauseObjective[cLevel, timestamp] )?
+usingClause[Attributes attrs]
+    : K_USING usingClauseObjective[attrs] ( K_AND? usingClauseObjective[attrs] )*
     ;
 
-usingClauseObjective[ConsistencyLevel cLevel, Long timestamp]
-    : K_CONSISTENCY K_LEVEL  { cLevel = ConsistencyLevel.valueOf($K_LEVEL.text); }
-    | K_TIMESTAMP ts=INTEGER { timestamp = Long.valueOf($ts.text); }
+usingClauseObjective[Attributes attrs]
+    : K_CONSISTENCY K_LEVEL  { attrs.setConsistencyLevel(ConsistencyLevel.valueOf($K_LEVEL.text)); }
+    | K_TIMESTAMP ts=INTEGER { attrs.setTimestamp(Long.valueOf($ts.text)); }
+    | K_TTL t=INTEGER        { attrs.setTimeToLive(Integer.parseInt($t.text)); }
     ;
 
 /**
@@ -254,15 +253,16 @@ usingClauseObjective[ConsistencyLevel cL
  */
 batchStatement returns [BatchStatement expr]
     : {
-          Long timestamp = null;
-          ConsistencyLevel cLevel = ConsistencyLevel.ONE;
+          Attributes attrs = new Attributes();
+          attrs.setConsistencyLevel(ConsistencyLevel.ONE);
+
           List<AbstractModification> statements = new ArrayList<AbstractModification>();
       }
-      K_BEGIN K_BATCH ( usingClause[cLevel, timestamp] )?
+      K_BEGIN K_BATCH ( usingClause[attrs] )?
           s1=batchStatementObjective ';'? { statements.add(s1); } ( sN=batchStatementObjective ';'? { statements.add(sN); } )*
       K_APPLY K_BATCH endStmnt
       {
-          return new BatchStatement(statements, cLevel, timestamp);
+          return new BatchStatement(statements, attrs);
       }
     ;
 
@@ -287,19 +287,18 @@ batchStatementObjective returns [Abstrac
  */
 updateStatement returns [UpdateStatement expr]
     : {
-          Long timestamp = null;
-          ConsistencyLevel cLevel = null;
+          Attributes attrs = new Attributes();
           Map<Term, Term> columns = new HashMap<Term, Term>();
           List<Term> keyList = null;
       }
       K_UPDATE columnFamily=( IDENT | STRING_LITERAL | INTEGER )
-          ( usingClause[cLevel, timestamp] )?
+          ( usingClause[attrs] )?
           K_SET termPair[columns] (',' termPair[columns])*
           K_WHERE ( K_KEY '=' key=term { keyList = Collections.singletonList(key); }
                     |
                     K_KEY K_IN '(' keys=termList { keyList = $keys.items; } ')' )
       {
-          return new UpdateStatement($columnFamily.text, cLevel, columns, keyList, timestamp);
+          return new UpdateStatement($columnFamily.text, columns, keyList, attrs);
       }
     ;
 
@@ -321,7 +320,8 @@ deleteStatement returns [DeleteStatement
       }
       K_DELETE
           ( cols=termList { columnsList = $cols.items; })?
-          K_FROM columnFamily=( IDENT | STRING_LITERAL | INTEGER ) ( K_USING K_CONSISTENCY K_LEVEL )?
+          K_FROM columnFamily=( IDENT | STRING_LITERAL | INTEGER )
+          ( K_USING K_CONSISTENCY K_LEVEL { cLevel = ConsistencyLevel.valueOf($K_LEVEL.text); } )?
           K_WHERE ( K_KEY '=' key=term           { keyList = Collections.singletonList(key); }
                   | K_KEY K_IN '(' keys=termList { keyList = $keys.items; } ')'
                   )?
@@ -396,7 +396,7 @@ comparatorType
     ;
 
 term returns [Term item]
-    : ( t=STRING_LITERAL | t=INTEGER | t=UUID | t=IDENT ) { $item = new Term($t.text, $t.type); }
+    : ( t=K_KEY | t=STRING_LITERAL | t=INTEGER | t=UUID | t=IDENT ) { $item = new Term($t.text, $t.type); }
     ;
 
 termList returns [List<Term> items]
@@ -466,6 +466,7 @@ K_PRIMARY:     P R I M A R Y;
 K_INTO:        I N T O;
 K_VALUES:      V A L U E S;
 K_TIMESTAMP:   T I M E S T A M P;
+K_TTL:         T T L;
 
 // Case-insensitive alpha characters
 fragment A: ('a'|'A');

Modified: cassandra/trunk/src/java/org/apache/cassandra/cql/DeleteStatement.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cql/DeleteStatement.java?rev=1101615&r1=1101614&r2=1101615&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/DeleteStatement.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/DeleteStatement.java Tue May 10 19:47:50 2011
@@ -48,7 +48,7 @@ public class DeleteStatement extends Abs
     
     public DeleteStatement(List<Term> columns, String columnFamily, ConsistencyLevel cLevel, List<Term> keys)
     {
-        super(columnFamily, cLevel, null);
+        super(columnFamily, cLevel, null, 0);
 
         this.columns = columns;
         this.keys = keys;

Modified: cassandra/trunk/src/java/org/apache/cassandra/cql/QueryProcessor.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cql/QueryProcessor.java?rev=1101615&r1=1101614&r2=1101615&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/QueryProcessor.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/QueryProcessor.java Tue May 10 19:47:50 2011
@@ -23,12 +23,15 @@ package org.apache.cassandra.cql;
 
 import java.io.IOException;
 import java.nio.ByteBuffer;
+import java.nio.charset.CharacterCodingException;
 import java.util.*;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeoutException;
 
+import com.google.common.base.Predicates;
+import com.google.common.collect.Maps;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -36,25 +39,15 @@ import org.antlr.runtime.*;
 import org.apache.cassandra.auth.Permission;
 import org.apache.cassandra.concurrent.Stage;
 import org.apache.cassandra.concurrent.StageManager;
-import org.apache.cassandra.config.CFMetaData;
-import org.apache.cassandra.config.ColumnDefinition;
-import org.apache.cassandra.config.ConfigurationException;
-import org.apache.cassandra.config.DatabaseDescriptor;
-import org.apache.cassandra.config.KSMetaData;
+import org.apache.cassandra.config.*;
 import org.apache.cassandra.db.*;
 import org.apache.cassandra.db.filter.QueryPath;
-import org.apache.cassandra.db.migration.AddColumnFamily;
-import org.apache.cassandra.db.migration.AddKeyspace;
-import org.apache.cassandra.db.migration.DropColumnFamily;
-import org.apache.cassandra.db.migration.DropKeyspace;
-import org.apache.cassandra.db.migration.Migration;
-import org.apache.cassandra.db.migration.UpdateColumnFamily;
-import org.apache.cassandra.db.migration.avro.CfDef;
 import org.apache.cassandra.db.marshal.AbstractType;
 import org.apache.cassandra.db.marshal.MarshalException;
-import org.apache.cassandra.dht.AbstractBounds;
-import org.apache.cassandra.dht.Bounds;
-import org.apache.cassandra.dht.IPartitioner;
+import org.apache.cassandra.db.migration.*;
+import org.apache.cassandra.db.migration.avro.CfDef;
+import org.apache.cassandra.dht.*;
+import org.apache.cassandra.dht.Token;
 import org.apache.cassandra.locator.AbstractReplicationStrategy;
 import org.apache.cassandra.service.ClientState;
 import org.apache.cassandra.service.StorageProxy;
@@ -64,9 +57,6 @@ import org.apache.cassandra.thrift.*;
 import org.apache.cassandra.utils.ByteBufferUtil;
 import org.apache.cassandra.utils.FBUtilities;
 
-import com.google.common.base.Predicates;
-import com.google.common.collect.Maps;
-
 import static org.apache.cassandra.thrift.ThriftValidation.validateColumnFamily;
 
 public class QueryProcessor
@@ -77,19 +67,13 @@ public class QueryProcessor
     throws InvalidRequestException, TimedOutException, UnavailableException
     {
         QueryPath queryPath = new QueryPath(select.getColumnFamily());
-        AbstractType<?> comparator = select.getComparator(keyspace);
-        List<ReadCommand> commands = new ArrayList<ReadCommand>();
-
-        assert select.getKeys().size() == 1;
         CFMetaData metadata = validateColumnFamily(keyspace, select.getColumnFamily(), false);
+        List<ReadCommand> commands = new ArrayList<ReadCommand>();
 
         // ...of a list of column names
         if (!select.isColumnRange())
         {
-            Collection<ByteBuffer> columnNames = new ArrayList<ByteBuffer>();
-            for (Term column : select.getColumnNames())
-                columnNames.add(column.getByteBuffer(comparator));
-
+            Collection<ByteBuffer> columnNames = getColumnNames(select, metadata);
             validateColumnNames(columnNames);
 
             for (Term rawKey: select.getKeys())
@@ -103,6 +87,7 @@ public class QueryProcessor
         // ...a range (slice) of column names
         else
         {
+            AbstractType<?> comparator = select.getComparator(keyspace);
             ByteBuffer start = select.getColumnStart().getByteBuffer(comparator);
             ByteBuffer finish = select.getColumnFinish().getByteBuffer(comparator);
 
@@ -136,6 +121,19 @@ public class QueryProcessor
         }
     }
 
+    private static List<ByteBuffer> getColumnNames(SelectStatement select, CFMetaData metadata) throws InvalidRequestException
+    {
+        String keyString = getKeyString(metadata);
+        List<ByteBuffer> columnNames = new ArrayList<ByteBuffer>();
+        for (Term column : select.getColumnNames())
+        {
+            // skip the key for the slice op; we'll add it to the resultset in extractThriftColumns
+            if (!column.getText().equalsIgnoreCase(keyString))
+                columnNames.add(column.getByteBuffer(metadata.comparator));
+        }
+        return columnNames;
+    }
+
     private static List<org.apache.cassandra.db.Row> multiRangeSlice(String keyspace, SelectStatement select)
     throws TimedOutException, UnavailableException, InvalidRequestException
     {
@@ -153,12 +151,19 @@ public class QueryProcessor
                                 ? select.getKeyFinish().getByteBuffer(keyType)
                                 : (new Term()).getByteBuffer();
 
-        AbstractBounds bounds = new Bounds(p.getToken(startKey), p.getToken(finishKey));
+        Token startToken = p.getToken(startKey), finishToken = p.getToken(finishKey);
+        if (startToken.compareTo(finishToken) > 0 && !finishToken.equals(p.getMinimumToken()))
+        {
+            if (p instanceof RandomPartitioner)
+                throw new InvalidRequestException("Start key's md5 sorts after end key's md5. This is not allowed; you probably should not specify end key at all, under RandomPartitioner");
+            else
+                throw new InvalidRequestException("Start key must sort before (or equal to) finish key in your partitioner!");
+        }
+        AbstractBounds bounds = new Bounds(startToken, finishToken);
         
         CFMetaData metadata = validateColumnFamily(keyspace, select.getColumnFamily(), false);
-        AbstractType<?> comparator = metadata.getComparatorFor(null);
         // XXX: Our use of Thrift structs internally makes me Sad. :(
-        SlicePredicate thriftSlicePredicate = slicePredicateFromSelect(select, comparator);
+        SlicePredicate thriftSlicePredicate = slicePredicateFromSelect(select, metadata);
         validateSlicePredicate(metadata, thriftSlicePredicate);
 
         int limit = select.isKeyRange() && select.getKeyStart() != null
@@ -210,16 +215,15 @@ public class QueryProcessor
     throws TimedOutException, UnavailableException, InvalidRequestException
     {
         CFMetaData metadata = validateColumnFamily(keyspace, select.getColumnFamily(), false);
-        AbstractType<?> comparator = metadata.getComparatorFor(null);
         // XXX: Our use of Thrift structs internally (still) makes me Sad. :~(
-        SlicePredicate thriftSlicePredicate = slicePredicateFromSelect(select, comparator);
+        SlicePredicate thriftSlicePredicate = slicePredicateFromSelect(select, metadata);
         validateSlicePredicate(metadata, thriftSlicePredicate);
         
         List<IndexExpression> expressions = new ArrayList<IndexExpression>();
         for (Relation columnRelation : select.getColumnRelations())
         {
             // Left and right side of relational expression encoded according to comparator/validator.
-            ByteBuffer entity = columnRelation.getEntity().getByteBuffer(comparator);
+            ByteBuffer entity = columnRelation.getEntity().getByteBuffer(metadata.comparator);
             ByteBuffer value = columnRelation.getValue().getByteBuffer(select.getValueValidator(keyspace, entity));
             
             expressions.add(new IndexExpression(entity,
@@ -286,7 +290,7 @@ public class QueryProcessor
         }
     }
     
-    private static SlicePredicate slicePredicateFromSelect(SelectStatement select, AbstractType<?> comparator)
+    private static SlicePredicate slicePredicateFromSelect(SelectStatement select, CFMetaData metadata)
     throws InvalidRequestException
     {
         SlicePredicate thriftSlicePredicate = new SlicePredicate();
@@ -294,18 +298,15 @@ public class QueryProcessor
         if (select.isColumnRange() || select.getColumnNames().size() == 0)
         {
             SliceRange sliceRange = new SliceRange();
-            sliceRange.start = select.getColumnStart().getByteBuffer(comparator);
-            sliceRange.finish = select.getColumnFinish().getByteBuffer(comparator);
+            sliceRange.start = select.getColumnStart().getByteBuffer(metadata.comparator);
+            sliceRange.finish = select.getColumnFinish().getByteBuffer(metadata.comparator);
             sliceRange.reversed = select.isColumnsReversed();
             sliceRange.count = select.getColumnsLimit();
             thriftSlicePredicate.slice_range = sliceRange;
         }
         else
         {
-            List<ByteBuffer> columnNames = new ArrayList<ByteBuffer>();
-            for (Term column : select.getColumnNames())
-                columnNames.add(column.getByteBuffer(comparator));
-            thriftSlicePredicate.column_names = columnNames;
+            thriftSlicePredicate.column_names = getColumnNames(select, metadata);
         }
         
         return thriftSlicePredicate;
@@ -480,19 +481,17 @@ public class QueryProcessor
         // Some statements won't have (or don't need) a keyspace (think USE, or CREATE).
         if (StatementType.requiresKeyspace.contains(statement.type))
             keyspace = clientState.getKeyspace();
-        
+
         CqlResult result = new CqlResult();
         
         logger.debug("CQL statement type: {}", statement.type.toString());
         CFMetaData metadata;
-        AbstractType<?> comparator;
         switch (statement.type)
         {
             case SELECT:
                 SelectStatement select = (SelectStatement)statement.statement;
                 clientState.hasColumnFamilyAccess(select.getColumnFamily(), Permission.READ);
                 metadata = validateColumnFamily(keyspace, select.getColumnFamily(), false);
-                comparator = metadata.getComparatorFor(null);
                 validateSelect(keyspace, select);
                 
                 List<org.apache.cassandra.db.Row> rows;
@@ -529,7 +528,7 @@ public class QueryProcessor
                 
                 List<CqlRow> cqlRows = new ArrayList<CqlRow>();
                 result.type = CqlResultType.ROWS;
-                
+
                 // Create the result set
                 for (org.apache.cassandra.db.Row row : rows)
                 {
@@ -537,7 +536,7 @@ public class QueryProcessor
                     if (row.cf == null)
                         continue;
 
-                    List<Column> thriftColumns = extractThriftColumns(select, comparator, row);
+                    List<Column> thriftColumns = extractThriftColumns(select, metadata, row);
                     // Create a new row, add the columns to it, and then add it to the list of rows
                     CqlRow cqlRow = new CqlRow();
                     cqlRow.key = row.key.key;
@@ -560,6 +559,9 @@ public class QueryProcessor
             case BATCH:
                 BatchStatement batch = (BatchStatement) statement.statement;
 
+                if (batch.getTimeToLive() != 0)
+                    throw new InvalidRequestException("Global TTL on the BATCH statement is not supported.");
+
                 for (AbstractModification up : batch.getStatements())
                 {
                     if (up.isSetConsistencyLevel())
@@ -616,7 +618,6 @@ public class QueryProcessor
             
             case DELETE:
                 DeleteStatement delete = (DeleteStatement)statement.statement;
-
                 try
                 {
                     StorageProxy.mutate(delete.prepareRowMutations(keyspace, clientState), delete.getConsistencyLevel());
@@ -637,10 +638,12 @@ public class QueryProcessor
                 
                 try
                 {
-                    KSMetaData ksm = new KSMetaData(create.getName(),
-                                                    AbstractReplicationStrategy.getClass(create.getStrategyClass()),
-                                                    create.getStrategyOptions());
-                    applyMigrationOnStage(new AddKeyspace(ksm));
+                    KsDef ksd = new KsDef(create.getName(),
+                                          create.getStrategyClass(),
+                                          Collections.<org.apache.cassandra.thrift.CfDef>emptyList())
+                                .setStrategy_options(create.getStrategyOptions());
+                    ThriftValidation.validateKsDef(ksd);
+                    applyMigrationOnStage(new AddKeyspace(KSMetaData.fromThrift(ksd)));
                 }
                 catch (ConfigurationException e)
                 {
@@ -794,11 +797,17 @@ public class QueryProcessor
         return null;    // We should never get here.
     }
 
-    private static List<Column> extractThriftColumns(SelectStatement select, AbstractType<?> comparator, Row row)
+    private static List<Column> extractThriftColumns(SelectStatement select, CFMetaData metadata, Row row)
     {
         List<Column> thriftColumns = new ArrayList<Column>();
         if (select.isColumnRange())
         {
+            if (select.isWildcard())
+            {
+                // prepend key
+                thriftColumns.add(new Column(metadata.getKeyName()).setValue(row.key.key).setTimestamp(-1));
+            }
+
             // preserve comparator order
             for (IColumn c : row.cf.getSortedColumns())
             {
@@ -809,13 +818,23 @@ public class QueryProcessor
         }
         else
         {
+            String keyString = getKeyString(metadata);
+
             // order columns in the order they were asked for
             for (Term term : select.getColumnNames())
             {
+                if (term.getText().equalsIgnoreCase(keyString))
+                {
+                    // preserve case of key as it was requested
+                    ByteBuffer requestedKey = ByteBufferUtil.bytes(term.getText());
+                    thriftColumns.add(new Column(requestedKey).setValue(row.key.key).setTimestamp(-1));
+                    continue;
+                }
+
                 ByteBuffer name;
                 try
                 {
-                    name = term.getByteBuffer(comparator);
+                    name = term.getByteBuffer(metadata.comparator);
                 }
                 catch (InvalidRequestException e)
                 {
@@ -831,6 +850,20 @@ public class QueryProcessor
         return thriftColumns;
     }
 
+    private static String getKeyString(CFMetaData metadata)
+    {
+        String keyString;
+        try
+        {
+            keyString = ByteBufferUtil.string(metadata.getKeyName());
+        }
+        catch (CharacterCodingException e)
+        {
+            throw new AssertionError(e);
+        }
+        return keyString;
+    }
+
     private static CQLStatement getStatement(String queryStr) throws InvalidRequestException, RecognitionException
     {
         // Lexer and parser

Modified: cassandra/trunk/src/java/org/apache/cassandra/cql/SelectExpression.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cql/SelectExpression.java?rev=1101615&r1=1101614&r2=1101615&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/SelectExpression.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/SelectExpression.java Tue May 10 19:47:50 2011
@@ -37,6 +37,7 @@ public class SelectExpression
     
     private int numColumns = MAX_COLUMNS_DEFAULT;
     private boolean reverseColumns = false;
+    private final boolean wildcard;
     private Term start, finish;
     private List<Term> columns;
     
@@ -48,12 +49,13 @@ public class SelectExpression
      * @param count the number of columns to limit the results to
      * @param reverse true to reverse column order
      */
-    public SelectExpression(Term start, Term finish, int count, boolean reverse)
+    public SelectExpression(Term start, Term finish, int count, boolean reverse, boolean wildcard)
     {
         this.start = start;
         this.finish = finish;
         numColumns = count;
         reverseColumns = reverse;
+        this.wildcard = wildcard;
     }
     
     /**
@@ -65,6 +67,7 @@ public class SelectExpression
      */
     public SelectExpression(Term first, int count, boolean reverse)
     {
+        wildcard = false;
         columns = new ArrayList<Term>();
         columns.add(first);
         numColumns = count;
@@ -125,4 +128,9 @@ public class SelectExpression
     {
         return columns;
     }
+
+    public boolean isWildcard()
+    {
+        return wildcard;
+    }
 }

Modified: cassandra/trunk/src/java/org/apache/cassandra/cql/SelectStatement.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cql/SelectStatement.java?rev=1101615&r1=1101614&r2=1101615&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/SelectStatement.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/SelectStatement.java Tue May 10 19:47:50 2011
@@ -81,6 +81,11 @@ public class SelectStatement
     {
         return expression.isColumnRange();
     }
+
+    public boolean isWildcard()
+    {
+        return expression.isWildcard();
+    }
     
     public List<Term> getColumnNames()
     {

Modified: cassandra/trunk/src/java/org/apache/cassandra/cql/UpdateStatement.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cql/UpdateStatement.java?rev=1101615&r1=1101614&r2=1101615&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/UpdateStatement.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/UpdateStatement.java Tue May 10 19:47:50 2011
@@ -53,32 +53,20 @@ public class UpdateStatement extends Abs
      * level, and key term.
      * 
      * @param columnFamily column family name
-     * @param cLevel the thrift consistency level
      * @param columns a map of column name/values pairs
      * @param keys the keys to update
-     * @param timestamp timestamp to use for mutation, if set to null then System.currentTimeMillis()
+     * @param attrs additional attributes for statement (CL, timestamp, timeToLive)
      */
-    public UpdateStatement(String columnFamily, ConsistencyLevel cLevel, Map<Term, Term> columns, List<Term> keys, Long timestamp)
+    public UpdateStatement(String columnFamily,
+                           Map<Term, Term> columns,
+                           List<Term> keys,
+                           Attributes attrs)
     {
-        super(columnFamily, cLevel, timestamp);
+        super(columnFamily, attrs);
 
         this.columns = columns;
         this.keys = keys;
     }
-
-    /**
-     * Creates a new UpdateStatement from a column family name, columns map,
-     * and key term.
-     * 
-     * @param columnFamily column family name
-     * @param columns a map of column name/values pairs
-     * @param keys the keys to update
-     * @param timestamp timestamp to use for mutation, if set to null then System.currentTimeMillis()
-     */
-    public UpdateStatement(String columnFamily, Map<Term, Term> columns, List<Term> keys, Long timestamp)
-    {
-        this(columnFamily, null, columns, keys, timestamp);
-    }
     
     /**
      * Creates a new UpdateStatement from a column family name, a consistency level,
@@ -86,20 +74,18 @@ public class UpdateStatement extends Abs
      * alternate update format, <code>INSERT</code>.
      * 
      * @param columnFamily column family name
-     * @param cLevel the thrift consistency level
      * @param columnNames list of column names
      * @param columnValues list of column values (corresponds to names)
      * @param keys the keys to update
-     * @param timestamp timestamp to use for mutation, if set to null then System.currentTimeMillis()
+     * @param attrs additional attributes for statement (CL, timestamp, timeToLive)
      */
     public UpdateStatement(String columnFamily,
-                           ConsistencyLevel cLevel,
                            List<Term> columnNames,
                            List<Term> columnValues,
                            List<Term> keys,
-                           Long timestamp)
+                           Attributes attrs)
     {
-        super(columnFamily, cLevel, timestamp);
+        super(columnFamily, attrs);
 
         this.columnNames = columnNames;
         this.columnValues = columnValues;
@@ -184,7 +170,8 @@ public class UpdateStatement extends Abs
             validateColumn(metadata, colName, colValue);
             rm.add(new QueryPath(columnFamily, null, colName),
                    colValue,
-                   (timestamp == null) ? getTimestamp() : timestamp);
+                   (timestamp == null) ? getTimestamp() : timestamp,
+                   getTimeToLive());
         }
 
         return rm;
@@ -224,11 +211,13 @@ public class UpdateStatement extends Abs
     
     public String toString()
     {
-        return String.format("UpdateStatement(columnFamily=%s, keys=%s, columns=%s, consistency=%s)",
+        return String.format("UpdateStatement(columnFamily=%s, keys=%s, columns=%s, consistency=%s, timestamp=%s, timeToLive=%s)",
                              columnFamily,
                              keys,
                              columns,
-                             cLevel);
+                             getConsistencyLevel(),
+                             timestamp,
+                             timeToLive);
     }
     
     public AbstractType<?> getKeyType(String keyspace)

Modified: cassandra/trunk/src/java/org/apache/cassandra/db/marshal/AbstractType.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/db/marshal/AbstractType.java?rev=1101615&r1=1101614&r2=1101615&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/db/marshal/AbstractType.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/db/marshal/AbstractType.java Tue May 10 19:47:50 2011
@@ -24,7 +24,9 @@ package org.apache.cassandra.db.marshal;
 import java.nio.ByteBuffer;
 import java.util.Collection;
 import java.util.Comparator;
+import java.util.Map;
 
+import org.apache.cassandra.config.ConfigurationException;
 import org.apache.cassandra.db.IColumn;
 import static org.apache.cassandra.io.sstable.IndexHelper.IndexInfo;
 
@@ -159,4 +161,28 @@ public abstract class AbstractType<T> im
     public abstract int getScale(T obj);
     public abstract int getJdbcType();
     public abstract boolean needsQuotes();
+
+    public static AbstractType parseDefaultParameters(AbstractType baseType, TypeParser parser) throws ConfigurationException
+    {
+        Map<String, String> parameters = parser.getKeyValueParameters();
+        String reversed = parameters.get("reversed");
+        if (reversed != null && (reversed.isEmpty() || reversed.equals("true")))
+        {
+            return ReversedType.getInstance(baseType);
+        }
+        else
+        {
+            return baseType;
+        }
+    }
+
+    /**
+     * This must be overriden by subclasses if necessary so that for any
+     * AbstractType, this == TypeParser.parse(toString()).
+     */
+    @Override
+    public String toString()
+    {
+        return getClass().getName();
+    }
 }

Modified: cassandra/trunk/src/java/org/apache/cassandra/locator/AbstractReplicationStrategy.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/locator/AbstractReplicationStrategy.java?rev=1101615&r1=1101614&r2=1101615&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/locator/AbstractReplicationStrategy.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/locator/AbstractReplicationStrategy.java Tue May 10 19:47:50 2011
@@ -289,4 +289,19 @@ public abstract class AbstractReplicatio
         String className = cls.contains(".") ? cls : "org.apache.cassandra.locator." + cls;
         return FBUtilities.classForName(className, "replication strategy");
     }
+
+    protected void validateReplicationFactor(String rf) throws ConfigurationException
+    {
+        try
+        {
+            if (Integer.parseInt(rf) < 0)
+            {
+                throw new ConfigurationException("Replication factor must be non-negative; found " + rf);
+            }
+        }
+        catch (NumberFormatException e2)
+        {
+            throw new ConfigurationException("Replication factor must be numeric; found " + rf);
+        }
+    }
 }

Modified: cassandra/trunk/src/java/org/apache/cassandra/locator/NetworkTopologyStrategy.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/locator/NetworkTopologyStrategy.java?rev=1101615&r1=1101614&r2=1101615&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/locator/NetworkTopologyStrategy.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/locator/NetworkTopologyStrategy.java Tue May 10 19:47:50 2011
@@ -146,13 +146,9 @@ public class NetworkTopologyStrategy ext
 
     public void validateOptions() throws ConfigurationException
     {
-        for (Entry<String,String> e : this.configOptions.entrySet())
+        for (Entry<String, String> e : this.configOptions.entrySet())
         {
-            int rf = Integer.parseInt(e.getValue());
-            if (rf < 0)
-            {
-                throw new ConfigurationException("Replication factor for NTS must be non-negative. dc: " +e.getKey()+", rf: "+rf);
-            }
+            validateReplicationFactor(e.getValue());
         }
 
     }

Modified: cassandra/trunk/src/java/org/apache/cassandra/locator/OldNetworkTopologyStrategy.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/locator/OldNetworkTopologyStrategy.java?rev=1101615&r1=1101614&r2=1101615&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/locator/OldNetworkTopologyStrategy.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/locator/OldNetworkTopologyStrategy.java Tue May 10 19:47:50 2011
@@ -111,18 +111,10 @@ public class OldNetworkTopologyStrategy 
 
     public void validateOptions() throws ConfigurationException
     {
-        if (this.configOptions == null)
+        if (configOptions == null || configOptions.get("replication_factor") == null)
         {
-            throw new ConfigurationException("OldNetworkTopologyStrategy requires a replication_factor strategy option.");
-        }
-        if (this.configOptions.get("replication_factor") == null)
-        {
-            throw new ConfigurationException("OldNetworkTopologyStrategy requires a replication_factor strategy option.");
-        }
-        int rf = Integer.parseInt(this.configOptions.get("replication_factor"));
-        if (rf < 0)
-        {
-            throw new ConfigurationException("Replication factor for OldNetworkTopologyStrategy must be non-negative, "+rf+" given.");
+            throw new ConfigurationException("SimpleStrategy requires a replication_factor strategy option.");
         }
+        validateReplicationFactor(configOptions.get("replication_factor"));
     }
 }

Modified: cassandra/trunk/src/java/org/apache/cassandra/locator/SimpleStrategy.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/locator/SimpleStrategy.java?rev=1101615&r1=1101614&r2=1101615&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/locator/SimpleStrategy.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/locator/SimpleStrategy.java Tue May 10 19:47:50 2011
@@ -70,18 +70,10 @@ public class SimpleStrategy extends Abst
 
     public void validateOptions() throws ConfigurationException
     {
-        if (this.configOptions == null)
+        if (configOptions == null || configOptions.get("replication_factor") == null)
         {
             throw new ConfigurationException("SimpleStrategy requires a replication_factor strategy option.");
         }
-        if (this.configOptions.get("replication_factor") == null)
-        {
-            throw new ConfigurationException("SimpleStrategy requires a replication_factor strategy option.");
-        }
-        int rf = Integer.parseInt(this.configOptions.get("replication_factor"));
-        if (rf < 0)
-        {
-            throw new ConfigurationException("Replication factor for SimpleStrategy must be non-negative, "+rf+" given.");
-        }
+        validateReplicationFactor(configOptions.get("replication_factor"));
     }
 }

Modified: cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraServer.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraServer.java?rev=1101615&r1=1101614&r2=1101615&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraServer.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraServer.java Tue May 10 19:47:50 2011
@@ -578,12 +578,7 @@ public class CassandraServer implements 
         if (ksm == null)
             throw new NotFoundException();
 
-        List<CfDef> cfDefs = new ArrayList<CfDef>();
-        for (CFMetaData cfm : ksm.cfMetaData().values())
-            cfDefs.add(CFMetaData.convertToThrift(cfm));
-        KsDef ksdef = new KsDef(ksm.name, ksm.strategyClass.getName(), cfDefs);
-        ksdef.setStrategy_options(ksm.strategyOptions);
-        return ksdef;
+        return KSMetaData.toThrift(ksm);
     }
 
     public List<KeySlice> get_range_slices(ColumnParent column_parent, SlicePredicate predicate, KeyRange range, ConsistencyLevel consistency_level)
@@ -809,7 +804,7 @@ public class CassandraServer implements 
 
         try
         {
-            applyMigrationOnStage(new AddColumnFamily(CFMetaData.convertToCFMetaData(cf_def)));
+            applyMigrationOnStage(new AddColumnFamily(CFMetaData.fromThrift(cf_def)));
             return DatabaseDescriptor.getDefsVersion().toString();
         }
         catch (ConfigurationException e)
@@ -874,16 +869,11 @@ public class CassandraServer implements 
             for (CfDef cfDef : ks_def.cf_defs)
             {
                 ThriftValidation.validateCfDef(cfDef);
-                cfDefs.add(CFMetaData.convertToCFMetaData(cfDef));
+                cfDefs.add(CFMetaData.fromThrift(cfDef));
             }
 
             ThriftValidation.validateKsDef(ks_def);
-            KSMetaData ksm = new KSMetaData(ks_def.name,
-                                            AbstractReplicationStrategy.getClass(ks_def.strategy_class),
-                                            KSMetaData.backwardsCompatibleOptions(ks_def),
-                                            cfDefs.toArray(new CFMetaData[cfDefs.size()]));
-
-            applyMigrationOnStage(new AddKeyspace(ksm));
+            applyMigrationOnStage(new AddKeyspace(KSMetaData.fromThrift(ks_def, cfDefs.toArray(new CFMetaData[cfDefs.size()]))));
             return DatabaseDescriptor.getDefsVersion().toString();
         }
         catch (ConfigurationException e)
@@ -941,10 +931,7 @@ public class CassandraServer implements 
         try
         {
             ThriftValidation.validateKsDef(ks_def);
-            KSMetaData ksm = new KSMetaData(ks_def.name,
-                                            AbstractReplicationStrategy.getClass(ks_def.strategy_class),
-                                            KSMetaData.backwardsCompatibleOptions(ks_def));
-            applyMigrationOnStage(new UpdateKeyspace(ksm));
+            applyMigrationOnStage(new UpdateKeyspace(KSMetaData.fromThrift(ks_def)));
             return DatabaseDescriptor.getDefsVersion().toString();
         }
         catch (ConfigurationException e)