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 2009/07/01 00:06:56 UTC

svn commit: r789979 - in /incubator/cassandra/trunk: src/java/org/apache/cassandra/db/ src/java/org/apache/cassandra/service/ test/system/

Author: jbellis
Date: Tue Jun 30 22:06:56 2009
New Revision: 789979

URL: http://svn.apache.org/viewvc?rev=789979&view=rev
Log:
more consistent checking of thrift parameters; fixes multiple bugs.
patch by jbellis; reviewed by Evan Weaver for CASSANDRA-266

Added:
    incubator/cassandra/trunk/src/java/org/apache/cassandra/service/ThriftValidation.java
Modified:
    incubator/cassandra/trunk/src/java/org/apache/cassandra/db/ColumnReadCommand.java
    incubator/cassandra/trunk/src/java/org/apache/cassandra/db/SliceByNamesReadCommand.java
    incubator/cassandra/trunk/src/java/org/apache/cassandra/db/SliceByRangeReadCommand.java
    incubator/cassandra/trunk/src/java/org/apache/cassandra/service/CassandraServer.java
    incubator/cassandra/trunk/test/system/test_server.py

Modified: incubator/cassandra/trunk/src/java/org/apache/cassandra/db/ColumnReadCommand.java
URL: http://svn.apache.org/viewvc/incubator/cassandra/trunk/src/java/org/apache/cassandra/db/ColumnReadCommand.java?rev=789979&r1=789978&r2=789979&view=diff
==============================================================================
--- incubator/cassandra/trunk/src/java/org/apache/cassandra/db/ColumnReadCommand.java (original)
+++ incubator/cassandra/trunk/src/java/org/apache/cassandra/db/ColumnReadCommand.java Tue Jun 30 22:06:56 2009
@@ -35,8 +35,7 @@
     @Override
     public String getColumnFamilyName()
     {
-        String[] values = RowMutation.getColumnAndColumnFamily(columnFamilyColumn);
-        return values[0];
+        return RowMutation.getColumnAndColumnFamily(columnFamilyColumn)[0];
     }
 
     @Override

Modified: incubator/cassandra/trunk/src/java/org/apache/cassandra/db/SliceByNamesReadCommand.java
URL: http://svn.apache.org/viewvc/incubator/cassandra/trunk/src/java/org/apache/cassandra/db/SliceByNamesReadCommand.java?rev=789979&r1=789978&r2=789979&view=diff
==============================================================================
--- incubator/cassandra/trunk/src/java/org/apache/cassandra/db/SliceByNamesReadCommand.java (original)
+++ incubator/cassandra/trunk/src/java/org/apache/cassandra/db/SliceByNamesReadCommand.java Tue Jun 30 22:06:56 2009
@@ -41,7 +41,7 @@
     @Override
     public String getColumnFamilyName()
     {
-        return columnFamily;
+        return RowMutation.getColumnAndColumnFamily(columnFamily)[0];
     }
 
     @Override

Modified: incubator/cassandra/trunk/src/java/org/apache/cassandra/db/SliceByRangeReadCommand.java
URL: http://svn.apache.org/viewvc/incubator/cassandra/trunk/src/java/org/apache/cassandra/db/SliceByRangeReadCommand.java?rev=789979&r1=789978&r2=789979&view=diff
==============================================================================
--- incubator/cassandra/trunk/src/java/org/apache/cassandra/db/SliceByRangeReadCommand.java (original)
+++ incubator/cassandra/trunk/src/java/org/apache/cassandra/db/SliceByRangeReadCommand.java Tue Jun 30 22:06:56 2009
@@ -1 +1 @@
-package org.apache.cassandra.db;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

public class SliceByRangeReadCommand extends ReadCommand {

	
	public final String columnFamily;
	public final String startColumn;
	public final String endColumn;
	public final int count;
	
	public SliceByRangeReadCommand(String table, String key, String columnFamily, String startCol, String endCol, int count)
	{
		super(table, key, CMD_TYPE_GET_SLICE_BY_RANGE);
		this.columnFamily = columnFamily;
		this.startColumn = startCol;
		this.endColumn = endCol;
		this.count = count;
	}
	
	@Override
	public ReadCommand copy() 
	{
		ReadCommand readCommand= new SliceByRangeReadCommand(table, key, columnFamily, startColumn, endColumn,count);
		readCommand.setDigestQuery(isDigestQuery());
		return readCommand;
	}

	@Override
	public String getColumnFamilyName() 
	{
		return columnFamily;
	}

	@Override
	public Row getRow(Table table) throws IOException 
	{
		r
 eturn table.getRow(key, columnFamily, startColumn, endColumn, count);
	}
	
	@Override
    public String toString()
    {
        return "SliceByRangeReadCommand(" +
               "table='" + table + '\'' +
               ", key='" + key + '\'' +
               ", columnFamily='" + columnFamily + '\'' +
               ", startColumn=" + startColumn +
               ", endColumn=" + endColumn +
               ')';
    }
}

class SliceByRangeReadCommandSerializer extends ReadCommandSerializer
{
	@Override
	public void serialize(ReadCommand rm, DataOutputStream dos) throws IOException
	{
		SliceByRangeReadCommand realRM = (SliceByRangeReadCommand)rm;
		dos.writeBoolean(realRM.isDigestQuery());
		dos.writeUTF(realRM.table);
		dos.writeUTF(realRM.key);
		dos.writeUTF(realRM.columnFamily);
		dos.writeUTF(realRM.startColumn);
		dos.writeUTF(realRM.endColumn);
		dos.writeInt(realRM.count);
	}

	@Override
	public ReadCommand deserialize(DataInputStream dis) throws IOException
	{
		bo
 olean isDigest = dis.readBoolean();
		String table = dis.readUTF();
		String key = dis.readUTF();
		String columnFamily = dis.readUTF();
		String startColumn = dis.readUTF();
		String endColumn = dis.readUTF();
		int count = dis.readInt();
		SliceByRangeReadCommand rm = new SliceByRangeReadCommand(table, key, columnFamily, startColumn, endColumn, count);
		rm.setDigestQuery(isDigest);
		return rm;
	}
}
\ No newline at end of file
+package org.apache.cassandra.db;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

public class SliceByRangeReadCommand extends ReadCommand {

	
	public final String columnFamily;
	public final String startColumn;
	public final String endColumn;
	public final int count;
	
	public SliceByRangeReadCommand(String table, String key, String columnFamily, String startCol, String endCol, int count)
	{
		super(table, key, CMD_TYPE_GET_SLICE_BY_RANGE);
		this.columnFamily = columnFamily;
		this.startColumn = startCol;
		this.endColumn = endCol;
		this.count = count;
	}
	
	@Override
	public ReadCommand copy() 
	{
		ReadCommand readCommand= new SliceByRangeReadCommand(table, key, columnFamily, startColumn, endColumn,count);
		readCommand.setDigestQuery(isDigestQuery());
		return readCommand;
	}

	@Override
	public String getColumnFamilyName() 
	{
        return RowMutation.getColumnAndColumnFamily(columnFamily)[0];
	}

	@Override
	public Row
  getRow(Table table) throws IOException 
	{
		return table.getRow(key, columnFamily, startColumn, endColumn, count);
	}
	
	@Override
    public String toString()
    {
        return "SliceByRangeReadCommand(" +
               "table='" + table + '\'' +
               ", key='" + key + '\'' +
               ", columnFamily='" + columnFamily + '\'' +
               ", startColumn=" + startColumn +
               ", endColumn=" + endColumn +
               ')';
    }
}

class SliceByRangeReadCommandSerializer extends ReadCommandSerializer
{
	@Override
	public void serialize(ReadCommand rm, DataOutputStream dos) throws IOException
	{
		SliceByRangeReadCommand realRM = (SliceByRangeReadCommand)rm;
		dos.writeBoolean(realRM.isDigestQuery());
		dos.writeUTF(realRM.table);
		dos.writeUTF(realRM.key);
		dos.writeUTF(realRM.columnFamily);
		dos.writeUTF(realRM.startColumn);
		dos.writeUTF(realRM.endColumn);
		dos.writeInt(realRM.count);
	}

	@Override
	public ReadCommand deserialize(
 DataInputStream dis) throws IOException
	{
		boolean isDigest = dis.readBoolean();
		String table = dis.readUTF();
		String key = dis.readUTF();
		String columnFamily = dis.readUTF();
		String startColumn = dis.readUTF();
		String endColumn = dis.readUTF();
		int count = dis.readInt();
		SliceByRangeReadCommand rm = new SliceByRangeReadCommand(table, key, columnFamily, startColumn, endColumn, count);
		rm.setDigestQuery(isDigest);
		return rm;
	}
}
\ No newline at end of file

Modified: incubator/cassandra/trunk/src/java/org/apache/cassandra/service/CassandraServer.java
URL: http://svn.apache.org/viewvc/incubator/cassandra/trunk/src/java/org/apache/cassandra/service/CassandraServer.java?rev=789979&r1=789978&r2=789979&view=diff
==============================================================================
--- incubator/cassandra/trunk/src/java/org/apache/cassandra/service/CassandraServer.java (original)
+++ incubator/cassandra/trunk/src/java/org/apache/cassandra/service/CassandraServer.java Tue Jun 30 22:06:56 2009
@@ -68,35 +68,11 @@
 		// Start the storage service
 		storageService.start();
 	}
-	
-	private void validateKeyCommand(String key, String tablename, String... columnFamilyNames) throws InvalidRequestException
-	{
-        if (key.isEmpty())
-        {
-            throw new InvalidRequestException("Key may not be empty");
-        }
-        validateCommand(tablename, columnFamilyNames);
-	}
-
-    private void validateCommand(String tablename, String... columnFamilyNames) throws TableNotDefinedException, ColumnFamilyNotDefinedException
-    {
-        if (!DatabaseDescriptor.getTables().contains(tablename))
-        {
-            throw new TableNotDefinedException("Table " + tablename + " does not exist in this schema.");
-        }
-        for (String cfName : columnFamilyNames)
-        {
-            if (DatabaseDescriptor.getColumnType(tablename, cfName) == null)
-            {
-                throw new ColumnFamilyNotDefinedException("Column Family " + cfName + " is invalid.");
-            }
-        }
-    }
 
     protected ColumnFamily readColumnFamily(ReadCommand command) throws InvalidRequestException
     {
         String cfName = command.getColumnFamilyName();
-        validateKeyCommand(command.key, command.table, cfName);
+        ThriftValidation.validateKey(command.key);
 
         Row row;
         try
@@ -143,8 +119,9 @@
     public List<column_t> get_columns_since(String tablename, String key, String columnParent, long timeStamp) throws InvalidRequestException
     {
         logger.debug("get_columns_since");
+        String[] values = ThriftValidation.validateColumnParent(tablename, columnParent);
+
         ColumnFamily cfamily = readColumnFamily(new ColumnsSinceReadCommand(tablename, key, columnParent, timeStamp));
-        String[] values = RowMutation.getColumnAndColumnFamily(columnParent);
         if (cfamily == null)
         {
             return EMPTY_COLUMNS;
@@ -168,12 +145,26 @@
     public List<column_t> get_slice_by_names(String tablename, String key, String columnParent, List<String> columnNames) throws InvalidRequestException
     {
         logger.debug("get_slice_by_names");
+        String[] values = ThriftValidation.validateColumnParent(tablename, columnParent);
+
         ColumnFamily cfamily = readColumnFamily(new SliceByNamesReadCommand(tablename, key, columnParent, columnNames));
         if (cfamily == null)
         {
             return EMPTY_COLUMNS;
         }
-        return thriftifyColumns(cfamily.getAllColumns());
+        if (DatabaseDescriptor.getColumnFamilyType(tablename, values[0]).equals("Standard"))
+        {
+            return thriftifyColumns(cfamily.getAllColumns());
+        }
+        else
+        {
+            IColumn superColumn = cfamily.getColumn(values[1]);
+            if (superColumn == null)
+            {
+                return EMPTY_COLUMNS;
+            }
+            return thriftifyColumns(superColumn.getSubColumns());
+        }
     }
 
     public List<column_t> get_slice(String tablename, String key, String columnParent, boolean isAscending, int count) throws InvalidRequestException
@@ -186,6 +177,7 @@
             throw new InvalidRequestException("get_slice_from requires positive count");
         if ("Name".compareTo(DatabaseDescriptor.getCFMetaData(tablename, values[0]).indexProperty_) != 0)
             throw new InvalidRequestException("get_slice_from requires CF indexed by name");
+
         ColumnFamily cfamily = readColumnFamily(new SliceFromReadCommand(tablename, key, columnParent, isAscending, count));
         if (cfamily == null)
         {
@@ -198,28 +190,9 @@
     public column_t get_column(String tablename, String key, String columnPath) throws NotFoundException, InvalidRequestException
     {
         logger.debug("get_column");
-        String[] values = RowMutation.getColumnAndColumnFamily(columnPath);
-        if (values.length < 1)
-        {
-            throw new InvalidRequestException("get_column requires non-empty columnfamily");
-        }
-        if (DatabaseDescriptor.getColumnFamilyType(tablename, values[0]).equals("Standard"))
-        {
-            if (values.length != 2)
-            {
-                throw new InvalidRequestException("get_column requires both parts of columnfamily:column for standard CF " + values[0]);
-            }
-        }
-        else
-        {
-            if (values.length != 3)
-            {
-                throw new InvalidRequestException("get_column requires all parts of columnfamily:supercolumn:subcolumn for super CF " + values[0]);
-            }
-        }
+        String[] values = ThriftValidation.validateColumnPath(tablename, columnPath);
 
-        ColumnReadCommand readCommand = new ColumnReadCommand(tablename, key, columnPath);
-        ColumnFamily cfamily = readColumnFamily(readCommand);
+        ColumnFamily cfamily = readColumnFamily(new ColumnReadCommand(tablename, key, columnPath));
         if (cfamily == null)
         {
             throw new NotFoundException();
@@ -250,14 +223,13 @@
 
         return new column_t(column.name(), column.value(), column.timestamp());
     }
-    
 
     public int get_column_count(String tablename, String key, String columnParent) throws InvalidRequestException
     {
         logger.debug("get_column_count");
-        String[] values = RowMutation.getColumnAndColumnFamily(columnParent);
-        ColumnFamily cfamily;
+        String[] values = ThriftValidation.validateColumnParent(tablename, columnParent);
 
+        ColumnFamily cfamily;
         if (DatabaseDescriptor.isNameSortingEnabled(tablename, values[0]))
         {
             cfamily = readColumnFamily(new SliceFromReadCommand(tablename, key, columnParent + ":", true, Integer.MAX_VALUE));
@@ -293,11 +265,11 @@
     throws InvalidRequestException, UnavailableException
     {
         logger.debug("insert");
+        ThriftValidation.validateKey(key);
+        ThriftValidation.validateColumnPath(tablename, columnPath);
+
         RowMutation rm = new RowMutation(tablename, key.trim());
         rm.add(columnPath, cellData, timestamp);
-        Set<String> cfNames = rm.columnFamilyNames();
-        validateKeyCommand(rm.key(), rm.table(), cfNames.toArray(new String[cfNames.size()]));
-
         doInsert(block, rm);
     }
 
@@ -306,7 +278,7 @@
         logger.debug("batch_insert");
         RowMutation rm = RowMutation.getRowMutation(batchMutation);
         Set<String> cfNames = rm.columnFamilyNames();
-        validateKeyCommand(rm.key(), rm.table(), cfNames.toArray(new String[cfNames.size()]));
+        ThriftValidation.validateKeyCommand(rm.key(), rm.table(), cfNames.toArray(new String[cfNames.size()]));
 
         doInsert(block, rm);
     }
@@ -315,17 +287,17 @@
     throws InvalidRequestException, UnavailableException
     {
         logger.debug("remove");
+        ThriftValidation.validateColumnPathOrParent(tablename, columnPathOrParent);
+        
         RowMutation rm = new RowMutation(tablename, key.trim());
         rm.delete(columnPathOrParent, timestamp);
-        Set<String> cfNames = rm.columnFamilyNames();
-        validateKeyCommand(rm.key(), rm.table(), cfNames.toArray(new String[cfNames.size()]));
+
         doInsert(block, rm);
 	}
 
-    private void doInsert(int block, RowMutation rm)
-            throws UnavailableException
+    private void doInsert(int block, RowMutation rm) throws UnavailableException
     {
-        if (block>0)
+        if (block > 0)
         {
             StorageProxy.insertBlocking(rm,block);
         }
@@ -338,6 +310,8 @@
     public List<superColumn_t> get_slice_super_by_names(String tablename, String key, String columnFamily, List<String> superColumnNames) throws InvalidRequestException
     {
         logger.debug("get_slice_super_by_names");
+        ThriftValidation.validateColumnFamily(tablename, columnFamily);
+
         ColumnFamily cfamily = readColumnFamily(new SliceByNamesReadCommand(tablename, key, columnFamily, superColumnNames));
         if (cfamily == null)
         {
@@ -375,6 +349,7 @@
             throw new InvalidRequestException("get_slice_super requires a super CF name and a starting column name");
         if (count <= 0)
             throw new InvalidRequestException("get_slice_super requires positive count");
+
         ColumnFamily cfamily = readColumnFamily(new SliceFromReadCommand(tablename, key, columnFamily, isAscending, count));
         if (cfamily == null)
         {
@@ -387,6 +362,8 @@
     public superColumn_t get_superColumn(String tablename, String key, String superColumnPath) throws InvalidRequestException, NotFoundException
     {
         logger.debug("get_superColumn");
+        ThriftValidation.validateSuperColumnPath(tablename, superColumnPath);
+
         ColumnFamily cfamily = readColumnFamily(new ColumnReadCommand(tablename, key, superColumnPath));
         if (cfamily == null)
         {
@@ -413,7 +390,8 @@
         logger.debug("batch_insert_SuperColumn");
         RowMutation rm = RowMutation.getRowMutation(batchMutationSuper);
         Set<String> cfNames = rm.columnFamilyNames();
-        validateKeyCommand(rm.key(), rm.table(), cfNames.toArray(new String[cfNames.size()]));
+        ThriftValidation.validateKeyCommand(rm.key(), rm.table(), cfNames.toArray(new String[cfNames.size()]));
+
         doInsert(block, rm);
     }
 
@@ -525,7 +503,7 @@
     public List<String> get_key_range(String tablename, List<String> columnFamilies, String startWith, String stopAt, int maxResults) throws InvalidRequestException
     {
         logger.debug("get_key_range");
-        validateCommand(tablename, columnFamilies.toArray(new String[columnFamilies.size()]));
+        ThriftValidation.validateCommand(tablename, columnFamilies.toArray(new String[columnFamilies.size()]));
         if (!(StorageService.getPartitioner() instanceof OrderPreservingPartitioner))
         {
             throw new InvalidRequestException("range queries may only be performed against an order-preserving partitioner");
@@ -541,13 +519,27 @@
 	public List<column_t> get_slice_by_name_range(String tablename, String key, String columnParent, String start, String finish, int count)
     throws InvalidRequestException, NotFoundException, TException
     {
-		logger.debug("get_slice_by_range");
+		logger.debug("get_slice_by_name_range");
+        String[] values = ThriftValidation.validateColumnParent(tablename, columnParent);
+
         ColumnFamily cfamily = readColumnFamily(new SliceByRangeReadCommand(tablename, key, columnParent, start, finish, count));
         if (cfamily == null)
         {
             return EMPTY_COLUMNS;
         }
-        return thriftifyColumns(cfamily.getAllColumns());
+        if (DatabaseDescriptor.getColumnFamilyType(tablename, values[0]).equals("Standard"))
+        {
+            return thriftifyColumns(cfamily.getAllColumns());
+        }
+        else
+        {
+            IColumn superColumn = cfamily.getColumn(values[1]);
+            if (superColumn == null)
+            {
+                return EMPTY_COLUMNS;
+            }
+            return thriftifyColumns(superColumn.getSubColumns());
+        }
 	}
 
     // main method moved to CassandraDaemon

Added: incubator/cassandra/trunk/src/java/org/apache/cassandra/service/ThriftValidation.java
URL: http://svn.apache.org/viewvc/incubator/cassandra/trunk/src/java/org/apache/cassandra/service/ThriftValidation.java?rev=789979&view=auto
==============================================================================
--- incubator/cassandra/trunk/src/java/org/apache/cassandra/service/ThriftValidation.java (added)
+++ incubator/cassandra/trunk/src/java/org/apache/cassandra/service/ThriftValidation.java Tue Jun 30 22:06:56 2009
@@ -0,0 +1,135 @@
+package org.apache.cassandra.service;
+
+import org.apache.cassandra.db.TableNotDefinedException;
+import org.apache.cassandra.db.ColumnFamilyNotDefinedException;
+import org.apache.cassandra.db.RowMutation;
+import org.apache.cassandra.config.DatabaseDescriptor;
+
+public class ThriftValidation
+{
+    static void validateKeyCommand(String key, String tablename, String... columnFamilyNames) throws InvalidRequestException
+    {
+        validateKey(key);
+        validateCommand(tablename, columnFamilyNames);
+    }
+
+    static void validateKey(String key) throws InvalidRequestException
+    {
+        if (key.isEmpty())
+        {
+            throw new InvalidRequestException("Key may not be empty");
+        }
+    }
+
+    static void validateCommand(String tablename, String... columnFamilyNames) throws TableNotDefinedException, ColumnFamilyNotDefinedException
+    {
+        validateTable(tablename);
+        for (String cfName : columnFamilyNames)
+        {
+            if (DatabaseDescriptor.getColumnType(tablename, cfName) == null)
+            {
+                throw new ColumnFamilyNotDefinedException("Column Family " + cfName + " is invalid.");
+            }
+        }
+    }
+
+    private static void validateTable(String tablename) throws TableNotDefinedException
+    {
+        if (!DatabaseDescriptor.getTables().contains(tablename))
+        {
+            throw new TableNotDefinedException("Table " + tablename + " does not exist in this schema.");
+        }
+    }
+
+    private static String validateColumnFamily(String tablename, String[] values) throws InvalidRequestException
+    {
+        if (values.length < 1)
+        {
+            throw new InvalidRequestException("non-empty columnfamily is required");
+        }
+        String cfType = DatabaseDescriptor.getColumnType(tablename, values[0]);
+        if (cfType == null)
+        {
+            throw new InvalidRequestException("unconfigured columnfamily " + values[0]);
+        }
+        return cfType;
+    }
+
+    static String[] validateColumnPath(String tablename, String columnPath) throws InvalidRequestException
+    {
+        validateTable(tablename);
+        String[] values = RowMutation.getColumnAndColumnFamily(columnPath);
+        String cfType = validateColumnFamily(tablename, values);
+        if (cfType.equals("Standard"))
+        {
+            if (values.length != 2)
+            {
+                throw new InvalidRequestException("both parts of columnfamily:column are required for standard CF " + values[0]);
+            }
+        }
+        else if (values.length != 3)
+        {
+            throw new InvalidRequestException("all parts of columnfamily:supercolumn:subcolumn are required for super CF " + values[0]);
+        }
+        return values;
+    }
+
+    static String[] validateColumnParent(String tablename, String columnParent) throws InvalidRequestException
+    {
+        validateTable(tablename);
+        String[] values = RowMutation.getColumnAndColumnFamily(columnParent);
+        String cfType = validateColumnFamily(tablename, values);
+        if (cfType.equals("Standard"))
+        {
+            if (values.length != 1)
+            {
+                throw new InvalidRequestException("columnfamily alone is required for standard CF " + values[0]);
+            }
+        }
+        else if (values.length != 2)
+        {
+            throw new InvalidRequestException("columnfamily:supercolumn is required for super CF " + values[0]);
+        }
+        return values;
+    }
+
+    static String[] validateSuperColumnPath(String tablename, String columnPath) throws InvalidRequestException
+    {
+        validateTable(tablename);
+        String[] values = RowMutation.getColumnAndColumnFamily(columnPath);
+        String cfType = validateColumnFamily(tablename, values);
+        if (cfType.equals("Standard"))
+        {
+            throw new InvalidRequestException(values[0] + " is a standard columnfamily; only super columnfamilies are valid here");
+        }
+        else if (values.length != 1)
+        {
+            throw new InvalidRequestException("columnfamily alone is required for super CF " + values[0]);
+        }
+        return values;
+    }
+
+    static String[] validateColumnPathOrParent(String tablename, String columnPath) throws InvalidRequestException
+    {
+        validateTable(tablename);
+        String[] values = RowMutation.getColumnAndColumnFamily(columnPath);
+        String cfType = validateColumnFamily(tablename, values);
+        if (cfType.equals("Standard"))
+        {
+            if (values.length > 2)
+            {
+                throw new InvalidRequestException("columnfamily:column is the most path components possible for standard CF " + values[0]);
+            }
+        }
+        else if (values.length > 3)
+        {
+            throw new InvalidRequestException("columnfamily:supercolumn:column is the most path components possible for super CF " + values[0]);
+        }
+        return values;
+    }
+
+    public static String validateColumnFamily(String tablename, String columnFamily) throws InvalidRequestException
+    {
+        return validateColumnFamily(tablename, RowMutation.getColumnAndColumnFamily(columnFamily)); 
+    }
+}
\ No newline at end of file

Modified: incubator/cassandra/trunk/test/system/test_server.py
URL: http://svn.apache.org/viewvc/incubator/cassandra/trunk/test/system/test_server.py?rev=789979&r1=789978&r2=789979&view=diff
==============================================================================
--- incubator/cassandra/trunk/test/system/test_server.py (original)
+++ incubator/cassandra/trunk/test/system/test_server.py Tue Jun 30 22:06:56 2009
@@ -71,10 +71,10 @@
     assert result[1].columnName == 'c2'
 
     result = client.get_slice_by_name_range('Table1','key1', 'Standard1', 'a', 'z' , -1)
-    assert len(result) == 3
+    assert len(result) == 3, result
     
     result = client.get_slice_by_name_range('Table1','key1', 'Standard1', 'a', 'z' , 2)
-    assert len(result) == 2
+    assert len(result) == 2, result
 
 	 	
 def _verify_super(supercolumn='Super1'):
@@ -130,6 +130,8 @@
         _verify_batch()
 
     def test_bad_calls(self):
+        _expect_exception(lambda: client.insert('Table1', 'key1', 'Standard1:x:y', 'value', 0, True), InvalidRequestException)
+
         _expect_exception(lambda: client.get_column('Table1', 'key1', 'Standard1'), InvalidRequestException)
         _expect_exception(lambda: client.get_column('Table1', 'key1', 'Standard1:x:y'), InvalidRequestException)
         _expect_exception(lambda: client.get_column('Table1', 'key1', 'Super1'), InvalidRequestException)
@@ -312,4 +314,20 @@
     def test_get_slice_by_name_range(self):
 	_insert_range()
 	_verify_range()
- 
+
+        _insert_super()
+        result = client.get_slice_by_name_range('Table1','key1', 'Super1:sc1', 'a', 'z', -1)
+        assert len(result) == 1, result
+        assert result[0].columnName == 'c4'
+        
+    def test_get_slice_by_names(self):
+        _insert_range()
+        result = client.get_slice_by_names('Table1','key1', 'Standard1', ['c1', 'c2']) 
+        assert len(result) == 2
+        assert result[0].columnName == 'c1'
+        assert result[1].columnName == 'c2'
+
+        _insert_super()
+        result = client.get_slice_by_names('Table1','key1', 'Super1:sc1', ['c4']) 
+        assert len(result) == 1
+        assert result[0].columnName == 'c4'