You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by ee...@apache.org on 2011/03/09 23:00:26 UTC

svn commit: r1080023 - in /cassandra/trunk/src/java/org/apache/cassandra/cql: CreateColumnFamilyStatement.java QueryProcessor.java SelectStatement.java Term.java UpdateStatement.java

Author: eevans
Date: Wed Mar  9 22:00:25 2011
New Revision: 1080023

URL: http://svn.apache.org/viewvc?rev=1080023&view=rev
Log:
use AbstractType.fromString methods to marshal to BB

Patch by eevans for CASSANDRA-2027

Modified:
    cassandra/trunk/src/java/org/apache/cassandra/cql/CreateColumnFamilyStatement.java
    cassandra/trunk/src/java/org/apache/cassandra/cql/QueryProcessor.java
    cassandra/trunk/src/java/org/apache/cassandra/cql/SelectStatement.java
    cassandra/trunk/src/java/org/apache/cassandra/cql/Term.java
    cassandra/trunk/src/java/org/apache/cassandra/cql/UpdateStatement.java

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=1080023&r1=1080022&r2=1080023&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/CreateColumnFamilyStatement.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/CreateColumnFamilyStatement.java Wed Mar  9 22:00:25 2011
@@ -31,6 +31,7 @@ import org.apache.cassandra.config.Colum
 import org.apache.cassandra.config.ConfigurationException;
 import org.apache.cassandra.config.DatabaseDescriptor;
 import org.apache.cassandra.db.ColumnFamilyType;
+import org.apache.cassandra.db.marshal.AbstractType;
 import org.apache.cassandra.thrift.InvalidRequestException;
 
 /** A <code>CREATE COLUMNFAMILY</code> parsed from a CQL query statement. */
@@ -165,7 +166,7 @@ public class CreateColumnFamilyStatement
     }
     
     // Column definitions
-    private Map<ByteBuffer, ColumnDefinition> getColumns() throws InvalidRequestException
+    private Map<ByteBuffer, ColumnDefinition> getColumns(AbstractType<?> comparator) throws InvalidRequestException
     {
         Map<ByteBuffer, ColumnDefinition> columnDefs = new HashMap<ByteBuffer, ColumnDefinition>();
         
@@ -173,7 +174,7 @@ public class CreateColumnFamilyStatement
         {
             try
             {
-                ByteBuffer columnName = col.getKey().getByteBuffer();
+                ByteBuffer columnName = col.getKey().getByteBuffer(comparator);
                 String validator = comparators.containsKey(col.getValue()) ? comparators.get(col.getValue()) : col.getValue();
                 columnDefs.put(columnName, new ColumnDefinition(columnName, validator, null, null));
             }
@@ -202,10 +203,14 @@ public class CreateColumnFamilyStatement
         
         try
         {
+            // 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, "ascii")));
+            String validator = getPropertyString(KW_DEFAULTVALIDATION, "ascii");
+            
             return new CFMetaData(keyspace,
                                   name,
                                   ColumnFamilyType.create("Standard"),
-                                  DatabaseDescriptor.getComparator(comparators.get(properties.get(KW_COMPARATOR))),
+                                  comparator,
                                   null,
                                   properties.get(KW_COMMENT),
                                   getPropertyDouble(KW_ROWCACHESIZE, CFMetaData.DEFAULT_ROW_CACHE_SIZE),
@@ -213,7 +218,7 @@ public class CreateColumnFamilyStatement
                                   getPropertyDouble(KW_READREPAIRCHANCE, CFMetaData.DEFAULT_READ_REPAIR_CHANCE),
                                   getPropertyBoolean(KW_REPLICATEONWRITE, false),
                                   getPropertyInt(KW_GCGRACESECONDS, CFMetaData.DEFAULT_GC_GRACE_SECONDS),
-                                  DatabaseDescriptor.getComparator(comparators.get(properties.get(KW_DEFAULTVALIDATION))),
+                                  DatabaseDescriptor.getComparator(comparators.get(validator)),
                                   getPropertyInt(KW_MINCOMPACTIONTHRESHOLD, CFMetaData.DEFAULT_MIN_COMPACTION_THRESHOLD),
                                   getPropertyInt(KW_MAXCOMPACTIONTHRESHOLD, CFMetaData.DEFAULT_MAX_COMPACTION_THRESHOLD),
                                   getPropertyInt(KW_ROWCACHESAVEPERIODSECS, CFMetaData.DEFAULT_ROW_CACHE_SAVE_PERIOD_IN_SECONDS),
@@ -221,7 +226,7 @@ public class CreateColumnFamilyStatement
                                   getPropertyInt(KW_MEMTABLEFLUSHINMINS, CFMetaData.DEFAULT_MEMTABLE_LIFETIME_IN_MINS),
                                   getPropertyInt(KW_MEMTABLESIZEINMB, CFMetaData.DEFAULT_MEMTABLE_THROUGHPUT_IN_MB),
                                   getPropertyDouble(KW_MEMTABLEOPSINMILLIONS, CFMetaData.DEFAULT_MEMTABLE_OPERATIONS_IN_MILLIONS),
-                                  getColumns());
+                                  getColumns(comparator));
         }
         catch (ConfigurationException e)
         {
@@ -229,6 +234,12 @@ public class CreateColumnFamilyStatement
         }
     }
     
+    private String getPropertyString(String key, String defaultValue)
+    {
+        String value = properties.get(key);
+        return value != null ? value : defaultValue;
+    }
+    
     // Return a property value, typed as a Boolean
     private Boolean getPropertyBoolean(String key, Boolean defaultValue) throws InvalidRequestException
     {

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=1080023&r1=1080022&r2=1080023&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/QueryProcessor.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/QueryProcessor.java Wed Mar  9 22:00:25 2011
@@ -51,6 +51,7 @@ import org.apache.cassandra.db.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.AsciiType;
 import org.apache.cassandra.db.marshal.MarshalException;
 import org.apache.cassandra.dht.AbstractBounds;
 import org.apache.cassandra.dht.Bounds;
@@ -78,11 +79,12 @@ public class QueryProcessor
     {
         List<org.apache.cassandra.db.Row> rows = null;
         QueryPath queryPath = new QueryPath(select.getColumnFamily());
+        AbstractType<?> comparator = select.getComparator(keyspace);
         List<ReadCommand> commands = new ArrayList<ReadCommand>();
         
         assert select.getKeys().size() == 1;
         
-        ByteBuffer key = select.getKeys().get(0).getByteBuffer();
+        ByteBuffer key = select.getKeys().get(0).getByteBuffer(AsciiType.instance);
         validateKey(key);
         
         // ...of a list of column names
@@ -90,7 +92,7 @@ public class QueryProcessor
         {
             Collection<ByteBuffer> columnNames = new ArrayList<ByteBuffer>();
             for (Term column : select.getColumnNames())
-                columnNames.add(column.getByteBuffer());
+                columnNames.add(column.getByteBuffer(comparator));
             
             validateColumnNames(keyspace, select.getColumnFamily(), columnNames);
             commands.add(new SliceByNamesReadCommand(keyspace, key, queryPath, columnNames));
@@ -100,13 +102,13 @@ public class QueryProcessor
         {
             validateColumnNames(keyspace,
                                 select.getColumnFamily(),
-                                select.getColumnStart().getByteBuffer(),
-                                select.getColumnFinish().getByteBuffer());
+                                select.getColumnStart().getByteBuffer(comparator),
+                                select.getColumnFinish().getByteBuffer(comparator));
             commands.add(new SliceFromReadCommand(keyspace,
                                                   key,
                                                   queryPath,
-                                                  select.getColumnStart().getByteBuffer(),
-                                                  select.getColumnFinish().getByteBuffer(),
+                                                  select.getColumnStart().getByteBuffer(comparator),
+                                                  select.getColumnFinish().getByteBuffer(comparator),
                                                   select.isColumnsReversed(),
                                                   select.getColumnsLimit()));
         }
@@ -132,13 +134,14 @@ public class QueryProcessor
     {
         List<org.apache.cassandra.db.Row> rows = null;
         
-        ByteBuffer startKey = (select.getKeyStart() != null) ? select.getKeyStart().getByteBuffer() : (new Term()).getByteBuffer();
-        ByteBuffer finishKey = (select.getKeyFinish() != null) ? select.getKeyFinish().getByteBuffer() : (new Term()).getByteBuffer();
+        ByteBuffer startKey = (select.getKeyStart() != null) ? select.getKeyStart().getByteBuffer(AsciiType.instance) : (new Term()).getByteBuffer();
+        ByteBuffer finishKey = (select.getKeyFinish() != null) ? select.getKeyFinish().getByteBuffer(AsciiType.instance) : (new Term()).getByteBuffer();
         IPartitioner<?> p = StorageService.getPartitioner();
         AbstractBounds bounds = new Bounds(p.getToken(startKey), p.getToken(finishKey));
         
+        AbstractType<?> comparator = select.getComparator(keyspace);
         // XXX: Our use of Thrift structs internally makes me Sad. :(
-        SlicePredicate thriftSlicePredicate = slicePredicateFromSelect(select);
+        SlicePredicate thriftSlicePredicate = slicePredicateFromSelect(select, comparator);
         validateSlicePredicate(keyspace, select.getColumnFamily(), thriftSlicePredicate);
 
         try
@@ -170,19 +173,25 @@ public class QueryProcessor
     private static List<org.apache.cassandra.db.Row> getIndexedSlices(String keyspace, SelectStatement select)
     throws TimedOutException, UnavailableException, InvalidRequestException
     {
+        AbstractType<?> comparator = select.getComparator(keyspace);
         // XXX: Our use of Thrift structs internally (still) makes me Sad. :~(
-        SlicePredicate thriftSlicePredicate = slicePredicateFromSelect(select);
+        SlicePredicate thriftSlicePredicate = slicePredicateFromSelect(select, comparator);
         validateSlicePredicate(keyspace, select.getColumnFamily(), thriftSlicePredicate);
         
         List<IndexExpression> expressions = new ArrayList<IndexExpression>();
         for (Relation columnRelation : select.getColumnRelations())
         {
-            expressions.add(new IndexExpression(columnRelation.getEntity().getByteBuffer(),
+            // Left and right side of relational expression encoded according to comparator/validator.
+            ByteBuffer entity = columnRelation.getEntity().getByteBuffer(comparator);
+            ByteBuffer value = columnRelation.getValue().getByteBuffer(select.getValueValidator(keyspace, entity));
+            
+            expressions.add(new IndexExpression(entity,
                                                 IndexOperator.valueOf(columnRelation.operator().toString()),
-                                                columnRelation.getValue().getByteBuffer()));
+                                                value));
         }
         
-        ByteBuffer startKey = (!select.isKeyRange()) ? (new Term()).getByteBuffer() : select.getKeyStart().getByteBuffer();
+        // FIXME: keys as ascii is not a Real Solution
+        ByteBuffer startKey = (!select.isKeyRange()) ? (new Term()).getByteBuffer() : select.getKeyStart().getByteBuffer(AsciiType.instance);
         IndexClause thriftIndexClause = new IndexClause(expressions, startKey, select.getNumRecords());
         
         List<org.apache.cassandra.db.Row> rows;
@@ -222,20 +231,20 @@ public class QueryProcessor
                 cfamsSeen.add(update.getColumnFamily());
             }
             
-            ByteBuffer key = update.getKey().getByteBuffer();
+            // FIXME: keys as ascii is not a Real Solution
+            ByteBuffer key = update.getKey().getByteBuffer(AsciiType.instance);
             validateKey(key);
             validateColumnFamily(keyspace, update.getColumnFamily());
+            AbstractType<?> comparator = update.getComparator(keyspace);
             
             RowMutation rm = new RowMutation(keyspace, key);
             for (Map.Entry<Term, Term> column : update.getColumns().entrySet())
             {
-                validateColumn(keyspace,
-                               update.getColumnFamily(),
-                               column.getKey().getByteBuffer(),
-                               column.getValue().getByteBuffer());
-                rm.add(new QueryPath(update.getColumnFamily(), null, column.getKey().getByteBuffer()),
-                       column.getValue().getByteBuffer(),
-                       System.currentTimeMillis());
+                ByteBuffer colName = column.getKey().getByteBuffer(comparator);
+                ByteBuffer colValue = column.getValue().getByteBuffer(update.getValueValidator(keyspace, colName));
+                
+                validateColumn(keyspace, update.getColumnFamily(), colName, colValue);
+                rm.add(new QueryPath(update.getColumnFamily(), null, colName), colValue, System.currentTimeMillis());
             }
             
             rowMutations.add(rm);
@@ -255,15 +264,16 @@ public class QueryProcessor
         }
     }
     
-    private static SlicePredicate slicePredicateFromSelect(SelectStatement select) throws InvalidRequestException
+    private static SlicePredicate slicePredicateFromSelect(SelectStatement select, AbstractType<?> comparator)
+    throws InvalidRequestException
     {
         SlicePredicate thriftSlicePredicate = new SlicePredicate();
         
         if (select.isColumnRange() || select.getColumnNames().size() == 0)
         {
             SliceRange sliceRange = new SliceRange();
-            sliceRange.start = select.getColumnStart().getByteBuffer();
-            sliceRange.finish = select.getColumnFinish().getByteBuffer();
+            sliceRange.start = select.getColumnStart().getByteBuffer(comparator);
+            sliceRange.finish = select.getColumnFinish().getByteBuffer(comparator);
             sliceRange.reversed = select.isColumnsReversed();
             sliceRange.count = select.getColumnsLimit();
             thriftSlicePredicate.slice_range = sliceRange;
@@ -272,7 +282,7 @@ public class QueryProcessor
         {
             List<ByteBuffer> columnNames = new ArrayList<ByteBuffer>();
             for (Term column : select.getColumnNames())
-                columnNames.add(column.getByteBuffer());
+                columnNames.add(column.getByteBuffer(comparator));
             thriftSlicePredicate.column_names = columnNames;
         }
         
@@ -301,12 +311,14 @@ public class QueryProcessor
         if (select.getKeys().size() > 1)
             throw new InvalidRequestException("SELECTs can contain only by by-key clause");
         
+        AbstractType<?> comparator = select.getComparator(keyspace);
+        
         if (select.getColumnRelations().size() > 0)
         {
             Set<ByteBuffer> indexed = Table.open(keyspace).getColumnFamilyStore(select.getColumnFamily()).getIndexedColumns();
             for (Relation relation : select.getColumnRelations())
             {
-                if ((relation.operator().equals(RelationType.EQ)) && indexed.contains(relation.getEntity().getByteBuffer()))
+                if ((relation.operator().equals(RelationType.EQ)) && indexed.contains(relation.getEntity().getByteBuffer(comparator)))
                     return;
             }
             throw new InvalidRequestException("No indexed columns present in by-columns clause with \"equals\" operator");
@@ -354,7 +366,7 @@ public class QueryProcessor
     private static void validateColumnNames(String keyspace, String columnFamily, Iterable<ByteBuffer> columns)
     throws InvalidRequestException
     {
-        AbstractType comparator = ColumnFamily.getComparatorFor(keyspace, columnFamily, null);
+        AbstractType<?> comparator = ColumnFamily.getComparatorFor(keyspace, columnFamily, null);
         for (ByteBuffer name : columns)
         {
             if (name.remaining() > IColumn.MAX_NAME_LENGTH)
@@ -388,7 +400,7 @@ public class QueryProcessor
     throws InvalidRequestException
     {
         validateColumnName(keyspace, columnFamily, name);
-        AbstractType validator = DatabaseDescriptor.getValueValidator(keyspace, columnFamily, name);
+        AbstractType<?> validator = DatabaseDescriptor.getValueValidator(keyspace, columnFamily, name);
         
         try
         {
@@ -562,19 +574,20 @@ public class QueryProcessor
             case DELETE:
                 DeleteStatement delete = (DeleteStatement)statement.statement;
                 clientState.hasColumnFamilyAccess(delete.getColumnFamily(), Permission.WRITE);
+                AbstractType<?> comparator = DatabaseDescriptor.getComparator(keyspace, delete.getColumnFamily());
                 
                 List<RowMutation> rowMutations = new ArrayList<RowMutation>();
                 for (Term key : delete.getKeys())
                 {
-                    RowMutation rm = new RowMutation(keyspace, key.getByteBuffer());
+                    RowMutation rm = new RowMutation(keyspace, key.getByteBuffer(AsciiType.instance));
                     if (delete.getColumns().size() < 1)     // No columns, delete the row
                         rm.delete(new QueryPath(delete.getColumnFamily()), System.currentTimeMillis());
                     else    // Delete specific columns
                     {
                         for (Term column : delete.getColumns())
                         {
-                            validateColumnName(keyspace, delete.getColumnFamily(), column.getByteBuffer());
-                            rm.delete(new QueryPath(delete.getColumnFamily(), null, column.getByteBuffer()),
+                            validateColumnName(keyspace, delete.getColumnFamily(), column.getByteBuffer(comparator));
+                            rm.delete(new QueryPath(delete.getColumnFamily(), null, column.getByteBuffer(comparator)),
                                       System.currentTimeMillis());
                         }
                     }

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=1080023&r1=1080022&r2=1080023&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/SelectStatement.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/SelectStatement.java Wed Mar  9 22:00:25 2011
@@ -20,8 +20,11 @@
  */
 package org.apache.cassandra.cql;
 
+import java.nio.ByteBuffer;
 import java.util.List;
 
+import org.apache.cassandra.config.DatabaseDescriptor;
+import org.apache.cassandra.db.marshal.AbstractType;
 import org.apache.cassandra.thrift.ConsistencyLevel;
 
 /**
@@ -123,4 +126,14 @@ public class SelectStatement
     {
         return isCountOper;
     }
+    
+    public AbstractType getComparator(String keyspace)
+    {
+        return DatabaseDescriptor.getComparator(keyspace, columnFamily);
+    }
+    
+    public AbstractType getValueValidator(String keyspace, ByteBuffer column)
+    {
+        return DatabaseDescriptor.getValueValidator(keyspace, columnFamily, column);
+    }
 }

Modified: cassandra/trunk/src/java/org/apache/cassandra/cql/Term.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cql/Term.java?rev=1080023&r1=1080022&r2=1080023&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/Term.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/Term.java Wed Mar  9 22:00:25 2011
@@ -24,8 +24,13 @@ import java.io.UnsupportedEncodingExcept
 import java.nio.ByteBuffer;
 import java.text.ParseException;
 
+import org.apache.cassandra.db.marshal.AbstractType;
+import org.apache.cassandra.db.marshal.AsciiType;
+import org.apache.cassandra.db.marshal.IntegerType;
 import org.apache.cassandra.db.marshal.LexicalUUIDType;
+import org.apache.cassandra.db.marshal.MarshalException;
 import org.apache.cassandra.db.marshal.TimeUUIDType;
+import org.apache.cassandra.db.marshal.UTF8Type;
 import org.apache.cassandra.thrift.InvalidRequestException;
 import org.apache.cassandra.utils.ByteBufferUtil;
 import org.apache.cassandra.utils.FBUtilities;
@@ -87,6 +92,25 @@ public class Term
     }
     
     /**
+     * Returns the typed value, serialized to a ByteBuffer according to a
+     * comparator/validator.
+     * 
+     * @return a ByteBuffer of the value.
+     * @throws InvalidRequestException if unable to coerce the string to its type.
+     */
+    public ByteBuffer getByteBuffer(AbstractType<?> validator) throws InvalidRequestException
+    {
+        try
+        {
+            return validator.fromString(text);
+        }
+        catch (MarshalException e)
+        {
+            throw new InvalidRequestException(e.getMessage());
+        }
+    }
+    
+    /**
      * Returns the typed value, serialized to a ByteBuffer.
      * 
      * @return a ByteBuffer of the value.
@@ -97,72 +121,15 @@ public class Term
         switch (type)
         {
             case STRING:
-                return ByteBuffer.wrap(text.getBytes());
+                return AsciiType.instance.fromString(text);
             case INTEGER: 
-                try
-                {
-                    return ByteBufferUtil.bytes(Integer.parseInt(text));
-                }
-                catch (NumberFormatException e)
-                {
-                    throw new InvalidRequestException(text + " is not valid for type int");
-                }
+                return IntegerType.instance.fromString(text);
             case UNICODE:
-                try
-                {
-                    return ByteBuffer.wrap(text.getBytes("UTF-8"));
-                }
-                catch (UnsupportedEncodingException e)
-                {
-                   throw new RuntimeException(e);
-                }
+                return UTF8Type.instance.fromString(text);
             case UUID:
-                try
-                {
-                    return LexicalUUIDType.instance.fromString(text);
-                }
-                catch (IllegalArgumentException e)
-                {
-                    throw new InvalidRequestException(text + " is not valid for type uuid");
-                }
+                return LexicalUUIDType.instance.fromString(text);
             case TIMEUUID:
-                if (text.equals("") || text.toLowerCase().equals("now"))
-                {
-                    return ByteBuffer.wrap(UUIDGen.decompose(UUIDGen.makeType1UUIDFromHost(FBUtilities.getLocalAddress())));
-                }
-                
-                // Milliseconds since epoch?
-                if (text.matches("^\\d+$"))
-                {
-                    try
-                    {
-                        return ByteBuffer.wrap(UUIDGen.getTimeUUIDBytes(Long.parseLong(text)));
-                    }
-                    catch (NumberFormatException e)
-                    {
-                        throw new InvalidRequestException(text + " is not valid for type timeuuid");
-                    }
-                }
-                
-                try
-                {
-                    long timestamp = DateUtils.parseDate(text, iso8601Patterns).getTime();
-                    return ByteBuffer.wrap(UUIDGen.getTimeUUIDBytes(timestamp));
-                }
-                catch (ParseException e1)
-                {
-                    // Ignore failures; we'll move onto the Next Thing.
-                }
-                
-                // Last chance, a UUID string (i.e. f79326be-2d7b-11e0-b074-0026c650d722)
-                try
-                {
-                    return TimeUUIDType.instance.fromString(text);
-                }
-                catch (IllegalArgumentException e)
-                {
-                    throw new InvalidRequestException(text + " is not valid for type timeuuid");
-                }
+                return TimeUUIDType.instance.fromString(text);
         }
         
         // FIXME: handle scenario that should never happen

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=1080023&r1=1080022&r2=1080023&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/UpdateStatement.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/UpdateStatement.java Wed Mar  9 22:00:25 2011
@@ -20,8 +20,11 @@
  */
 package org.apache.cassandra.cql;
 
+import java.nio.ByteBuffer;
 import java.util.Map;
 
+import org.apache.cassandra.config.DatabaseDescriptor;
+import org.apache.cassandra.db.marshal.AbstractType;
 import org.apache.cassandra.thrift.ConsistencyLevel;
 
 /**
@@ -110,4 +113,14 @@ public class UpdateStatement
                              columns,
                              cLevel);
     }
+    
+    public AbstractType getComparator(String keyspace)
+    {
+        return DatabaseDescriptor.getComparator(keyspace, columnFamily);
+    }
+    
+    public AbstractType getValueValidator(String keyspace, ByteBuffer column)
+    {
+        return DatabaseDescriptor.getValueValidator(keyspace, columnFamily, column);
+    }
 }