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 2010/11/11 04:07:12 UTC

svn commit: r1033808 - in /cassandra/branches/cassandra-0.7: ./ src/java/org/apache/cassandra/cli/ test/unit/org/apache/cassandra/cli/

Author: jbellis
Date: Thu Nov 11 03:07:12 2010
New Revision: 1033808

URL: http://svn.apache.org/viewvc?rev=1033808&view=rev
Log:
add ASSUME cli statement
patch by Pavel Yaskevich; reviewed by jbellis for CASSANDRA-1693

Modified:
    cassandra/branches/cassandra-0.7/CHANGES.txt
    cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/cli/Cli.g
    cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/cli/CliClient.java
    cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/cli/CliUserHelp.java
    cassandra/branches/cassandra-0.7/test/unit/org/apache/cassandra/cli/CliTest.java

Modified: cassandra/branches/cassandra-0.7/CHANGES.txt
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/CHANGES.txt?rev=1033808&r1=1033807&r2=1033808&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.7/CHANGES.txt (original)
+++ cassandra/branches/cassandra-0.7/CHANGES.txt Thu Nov 11 03:07:12 2010
@@ -16,7 +16,8 @@ dev
  * add friendlier error for UnknownHostException on startup (CASSANDRA-1697)
  * include jna dependency in RPM package (CASSANDRA-1690)
  * add --skip-keys option to stress.py (CASSANDRA-1696)
- * improve cli handling of non-string column names (CASSANDRA-1701)
+ * improve cli handling of non-string keys and column names 
+   (CASSANDRA-1701, -1693)
  * enable skipping bad rows on LazilyCompacted path (CASSANDRA-1702)
  * r/m extra subcomparator line in cli keyspaces output (CASSANDRA-1712)
  * add read repair chance to cli "show keyspaces"

Modified: cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/cli/Cli.g
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/cli/Cli.g?rev=1033808&r1=1033807&r2=1033808&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/cli/Cli.g (original)
+++ cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/cli/Cli.g Thu Nov 11 03:07:12 2010
@@ -56,6 +56,7 @@ tokens {
     NODE_UPDATE_COLUMN_FAMILY;
     NODE_LIST;
     NODE_TRUNCATE;
+    NODE_ASSUME;
 
     // Internal Nodes.
     NODE_COLUMN_ACCESS;
@@ -151,6 +152,7 @@ statement
     | showStatement
     | listStatement
     | truncateStatement
+    | assumeStatement
     | -> ^(NODE_NO_OP)
     ;
 
@@ -204,6 +206,8 @@ helpStatement
         -> ^(NODE_HELP NODE_LIST)
     | HELP TRUNCATE
         -> ^(NODE_HELP NODE_TRUNCATE)
+    | HELP ASSUME
+        -> ^(NODE_HELP NODE_ASSUME)
     | HELP 
         -> ^(NODE_HELP)
     | '?'    
@@ -266,6 +270,11 @@ truncateStatement
         -> ^(NODE_TRUNCATE columnFamily)
     ;
 
+assumeStatement
+    : ASSUME columnFamily assumptionElement=Identifier 'AS' defaultType=Identifier
+        -> ^(NODE_ASSUME columnFamily $assumptionElement $defaultType)
+    ;
+
 showClusterName
     : SHOW CLUSTER NAME 
         -> ^(NODE_SHOW_CLUSTER_NAME)
@@ -515,6 +524,7 @@ UPDATE:     'UPDATE';
 LIST:       'LIST';
 LIMIT:      'LIMIT';
 TRUNCATE:   'TRUNCATE';
+ASSUME:     'ASSUME';
 
 IP_ADDRESS 
     : IntegerLiteral '.' IntegerLiteral '.' IntegerLiteral '.' IntegerLiteral

Modified: cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/cli/CliClient.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/cli/CliClient.java?rev=1033808&r1=1033807&r2=1033808&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/cli/CliClient.java (original)
+++ cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/cli/CliClient.java Thu Nov 11 03:07:12 2010
@@ -35,7 +35,7 @@ import java.nio.ByteBuffer;
 import java.util.*;
 
 // Cli Client Side Library
-public class CliClient extends CliUserHelp 
+public class CliClient extends CliUserHelp
 {
 
     /**
@@ -94,13 +94,15 @@ public class CliClient extends CliUserHe
     private String keySpace = null;
     private String username = null;
     private Map<String, KsDef> keyspacesMap = new HashMap<String, KsDef>();
-
+    private Map<String, AbstractType> cfKeysComparators;
+    
     private final String DEFAULT_PLACEMENT_STRATEGY = "org.apache.cassandra.locator.SimpleStrategy";
     
     public CliClient(CliSessionState cliSessionState, Cassandra.Client thriftClient)
     {
         this.sessionState = cliSessionState;
         this.thriftClient = thriftClient;
+        this.cfKeysComparators = new HashMap<String, AbstractType>();
     }
 
     // Execute a CLI Statement 
@@ -175,6 +177,9 @@ public class CliClient extends CliUserHe
                 case CliParser.NODE_TRUNCATE:
                     executeTruncate(tree.getChild(0).getText());
                     break;
+                case CliParser.NODE_ASSUME:
+                    executeAssumeStatement(tree);
+                    break;
                 case CliParser.NODE_NO_OP:
                     // comment lines come here; they are treated as no ops.
                     break;
@@ -214,28 +219,28 @@ public class CliClient extends CliUserHe
     private void executeCount(Tree statement)
             throws TException, InvalidRequestException, UnavailableException, TimedOutException
     {
-       if (!CliMain.isConnected() || !hasKeySpace())
-           return;
+        if (!CliMain.isConnected() || !hasKeySpace())
+            return;
 
-       Tree columnFamilySpec = statement.getChild(0);
+        Tree columnFamilySpec = statement.getChild(0);
 
-       String key = CliCompiler.getKey(columnFamilySpec);
-       String columnFamily = CliCompiler.getColumnFamily(columnFamilySpec);
-       int columnSpecCnt = CliCompiler.numColumnSpecifiers(columnFamilySpec);
+        String key = CliCompiler.getKey(columnFamilySpec);
+        String columnFamily = CliCompiler.getColumnFamily(columnFamilySpec);
+        int columnSpecCnt = CliCompiler.numColumnSpecifiers(columnFamilySpec);
        
-       ColumnParent colParent = new ColumnParent(columnFamily).setSuper_column((ByteBuffer) null);
+        ColumnParent colParent = new ColumnParent(columnFamily).setSuper_column((ByteBuffer) null);
        
-       if (columnSpecCnt != 0)
-       {
-           byte[] superColumn = columnNameAsByteArray(CliCompiler.getColumn(columnFamilySpec, 0), columnFamily);
-           colParent = new ColumnParent(columnFamily).setSuper_column(superColumn);
-       }
+        if (columnSpecCnt != 0)
+        {
+            byte[] superColumn = columnNameAsByteArray(CliCompiler.getColumn(columnFamilySpec, 0), columnFamily);
+            colParent = new ColumnParent(columnFamily).setSuper_column(superColumn);
+        }
 
-       SliceRange range = new SliceRange(FBUtilities.EMPTY_BYTE_BUFFER, FBUtilities.EMPTY_BYTE_BUFFER, false, Integer.MAX_VALUE);
-       SlicePredicate predicate = new SlicePredicate().setColumn_names(null).setSlice_range(range);
-       
-       int count = thriftClient.get_count(ByteBuffer.wrap(key.getBytes(Charsets.UTF_8)), colParent, predicate, ConsistencyLevel.ONE);
-       sessionState.out.printf("%d columns\n", count);
+        SliceRange range = new SliceRange(FBUtilities.EMPTY_BYTE_BUFFER, FBUtilities.EMPTY_BYTE_BUFFER, false, Integer.MAX_VALUE);
+        SlicePredicate predicate = new SlicePredicate().setColumn_names(null).setSlice_range(range);
+
+        int count = thriftClient.get_count(ByteBuffer.wrap(key.getBytes(Charsets.UTF_8)), colParent, predicate, ConsistencyLevel.ONE);
+        sessionState.out.printf("%d columns\n", count);
     }
     
     private void executeDelete(Tree statement) 
@@ -607,8 +612,11 @@ public class CliClient extends CliUserHe
             parent.setSuper_column(superColumnName);
         
         // do the insert
-        thriftClient.insert(ByteBuffer.wrap(key.getBytes(Charsets.UTF_8)), parent,
-                             new Column(columnName, columnValueInBytes, FBUtilities.timestampMicros()), ConsistencyLevel.ONE);
+        AbstractType keyComparator = this.cfKeysComparators.get(columnFamily);
+        ByteBuffer keyBytes = keyComparator == null
+                            ? ByteBuffer.wrap(key.getBytes(Charsets.UTF_8))
+                            : getBytesAccordingToType(key, keyComparator);
+        thriftClient.insert(keyBytes, parent, new Column(columnName, columnValueInBytes, FBUtilities.timestampMicros()), ConsistencyLevel.ONE);
         
         sessionState.out.println("Value inserted.");
     }
@@ -979,6 +987,63 @@ public class CliClient extends CliUserHe
         }
     }
 
+    /**
+     * Command: ASSUME <columnFamily> (VALIDATOR | COMPARATOR | KEYS | SUB_COMPARATOR) AS <type>
+     * Tree: ^(NODE_ASSUME <columnFamily> (VALIDATOR | COMPARATOR | KEYS | SUB_COMPARATOR) <type>))
+     * @param statement - tree representing current statement
+     */
+    private void executeAssumeStatement(Tree statement)
+    {
+        if (!CliMain.isConnected() || !hasKeySpace())
+            return;
+
+        CfDef columnFamily = getCfDef(statement.getChild(0).getText());
+
+        // VALIDATOR | COMPARATOR | KEYS | SUB_COMPARATOR
+        String assumptionElement = statement.getChild(1).getText().toUpperCase();
+        // used to store in this.cfKeysComparator
+        AbstractType comparator;
+
+        // Could be UTF8Type, IntegerType, LexicalUUIDType etc.
+        String defaultType = statement.getChild(2).getText();
+
+        try
+        {
+            comparator = Function.valueOf(defaultType.toUpperCase()).getValidator();
+        }
+        catch (Exception e)
+        {
+            String functions = Function.getFunctionNames();
+            sessionState.out.println("Type '" + defaultType + "' was not found. Available: " + functions);
+            return;
+        }
+
+        if (assumptionElement.equals("COMPARATOR"))
+        {
+            columnFamily.setComparator_type(defaultType);
+        }
+        else if (assumptionElement.equals("SUB_COMPARATOR"))
+        {
+            columnFamily.setSubcomparator_type(defaultType);
+        }
+        else if (assumptionElement.equals("VALIDATOR"))
+        {
+            columnFamily.setDefault_validation_class(defaultType);
+        }
+        else if (assumptionElement.equals("KEYS"))
+        {
+            this.cfKeysComparators.put(columnFamily.getName(), comparator);
+        }
+        else
+        {
+            String elements = "VALIDATOR, COMPARATOR, KEYS, SUB_COMPARATOR.";
+            sessionState.out.println(String.format("'%s' is invalid. Available: %s", assumptionElement, elements));
+            return;
+        }
+
+        sessionState.out.println(String.format("Assumption for column family '%s' added successfully.", columnFamily.getName()));
+    }
+
     // SHOW API VERSION
     private void executeShowVersion() throws TException
     {
@@ -1260,7 +1325,7 @@ public class CliClient extends CliUserHe
     
     /**
      * Used to parse meta tree and compile meta attributes into List<ColumnDef>
-     * @param cfDef 
+     * @param cfDef - column family definition 
      * @param meta (Tree representing Array of the hashes with metadata attributes)
      * @return List<ColumnDef> List of the ColumnDef's
      * 
@@ -1444,7 +1509,7 @@ public class CliClient extends CliUserHe
     /**
      * Converts column name into byte[] according to comparator type
      * @param column - column name from parser
-     * @param columnFamilyDef - column family from parser
+     * @param cfDef  - column family from parser
      * @return bytes[] - into which column name was converted according to comparator type
      */
     private byte[] columnNameAsByteArray(String column, CfDef cfDef)
@@ -1710,12 +1775,14 @@ public class CliClient extends CliUserHe
     {
         AbstractType validator;
         String columnFamilyName = columnFamilyDef.getName();
+        AbstractType keyComparator = this.cfKeysComparators.get(columnFamilyName);
 
         for (KeySlice ks : slices)
         {
-            sessionState.out.printf("-------------------\n");
-            sessionState.out.printf("RowKey: %s\n", ByteBufferUtil.string(ks.key, Charsets.UTF_8));
+            String keyName = (keyComparator == null) ? ByteBufferUtil.string(ks.key, Charsets.UTF_8) : keyComparator.getString(ks.key);
 
+            sessionState.out.printf("-------------------\n");
+            sessionState.out.printf("RowKey: %s\n", keyName);
             Iterator<ColumnOrSuperColumn> iterator = ks.getColumnsIterator();
 
             while (iterator.hasNext())

Modified: cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/cli/CliUserHelp.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/cli/CliUserHelp.java?rev=1033808&r1=1033807&r2=1033808&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/cli/CliUserHelp.java (original)
+++ cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/cli/CliUserHelp.java Thu Nov 11 03:07:12 2010
@@ -287,7 +287,18 @@ public class CliUserHelp {
                 state.out.println("example:");
                 state.out.println("truncate Category");
                 break;
-            
+
+            case CliParser.NODE_ASSUME:
+                state.out.println("assume <column_family> comparator as <type>");
+                state.out.println("assume <column_family> sub_comparator as <type>");
+                state.out.println("assume <column_family> validator as <type>");
+                state.out.println("assume <column_family> keys as <type>\n");
+                state.out.println("Assume one of the attributes (comparator, sub_comparator, validator or keys)");
+                state.out.println("of the given column family to match specified type. Available types: " + CliClient.Function.getFunctionNames());
+                state.out.println("example:");
+                state.out.println("assume Users comparator as lexicaluuid");
+                break;
+
             default:
                 state.out.println("?");
                 break;
@@ -331,7 +342,9 @@ public class CliUserHelp {
             state.out.println("del <cf>['<key>']['<super>']['<col>']                         Delete sub column.");
             state.out.println("count <cf>['<key>']                                     Count columns in record.");
             state.out.println("count <cf>['<key>']['<super>']                  Count columns in a super column.");
-            state.out.println("truncate <column_family>                       Truncate specified column family.");            
+            state.out.println("truncate <column_family>                       Truncate specified column family.");
+            state.out.println("assume <column_family> <attribute> as <type>");
+            state.out.println("Assume one of the attributes of the given column family to match specified type.");
             state.out.println("list <cf>                                    List all rows in the column family.");
             state.out.println("list <cf>[<startKey>:]");
             state.out.println("                       List rows in the column family beginning with <startKey>.");

Modified: cassandra/branches/cassandra-0.7/test/unit/org/apache/cassandra/cli/CliTest.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/test/unit/org/apache/cassandra/cli/CliTest.java?rev=1033808&r1=1033807&r2=1033808&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.7/test/unit/org/apache/cassandra/cli/CliTest.java (original)
+++ cassandra/branches/cassandra-0.7/test/unit/org/apache/cassandra/cli/CliTest.java Thu Nov 11 03:07:12 2010
@@ -80,7 +80,11 @@ public class CliTest extends CleanupHelp
         "get SCF1['hello'][1][9999]",
         "truncate CF1",
         "update keyspace TestKeySpace with placement_strategy='org.apache.cassandra.locator.LocalStrategy'",
-        "update keyspace TestKeySpace with replication_factor=1 and strategy_options=[{DC1:3, DC2:4, DC5:1}]"
+        "update keyspace TestKeySpace with replication_factor=1 and strategy_options=[{DC1:3, DC2:4, DC5:1}]",
+        "assume CF1 comparator as utf8",
+        "assume CF1 sub_comparator as integer",
+        "assume CF1 validator as lexicaluuid",
+        "assume CF1 keys as timeuuid"
     };
     
     @Test
@@ -135,6 +139,10 @@ public class CliTest extends CleanupHelp
             {
                 assertTrue(result.contains(" truncated."));
             }
+            else if (statement.startsWith("assume "))
+            {
+                assertTrue(result.contains("successfully."));
+            }
 
             outStream.reset(); // reset stream so we have only output from next statement all the time
             errStream.reset(); // no errors to the end user.