Author: jbellis
Date: Tue Sep 28 14:21:02 2010
New Revision: 1002173

URL: http://svn.apache.org/viewvc?rev=1002173&view=rev
Log:
make cli comparator-aware and improve quote rules.
patch by Pavel Yaskevich; reviewed by jbellis for CASSANDRA-1523 and 
CASSANDRA-1524

Modified:
    cassandra/trunk/CHANGES.txt
    cassandra/trunk/src/java/org/apache/cassandra/cli/Cli.g
    cassandra/trunk/src/java/org/apache/cassandra/cli/CliClient.java
    cassandra/trunk/src/java/org/apache/cassandra/cli/CliUtils.java

Modified: cassandra/trunk/CHANGES.txt
URL: 
http://svn.apache.org/viewvc/cassandra/trunk/CHANGES.txt?rev=1002173&r1=1002172&r2=1002173&view=diff
==============================================================================
--- cassandra/trunk/CHANGES.txt (original)
+++ cassandra/trunk/CHANGES.txt Tue Sep 28 14:21:02 2010
@@ -8,6 +8,7 @@ dev
  * fix setting gc_grace_seconds via CLI (CASSANDRA-1549)
  * support TTL'd index values (CASSANDRA-1536)
  * make removetoken work like decommission (CASSANDRA-1216)
+ * make cli comparator-aware and improve quote rules (CASSANDRA-1523,-1524)
 
 
 0.7-beta2

Modified: cassandra/trunk/src/java/org/apache/cassandra/cli/Cli.g
URL: 
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cli/Cli.g?rev=1002173&r1=1002172&r2=1002173&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cli/Cli.g (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cli/Cli.g Tue Sep 28 14:21:02 
2010
@@ -74,12 +74,12 @@ package org.apache.cassandra.cli;
 //
 
 // the root node
-root: stmt SEMICOLON? EOF -> stmt;
+root: statement SEMICOLON? EOF -> statement;
 
-stmt
-    : connectStmt
-    | exitStmt
-    | countStmt
+statement
+    : connectStatement
+    | exitStatement
+    | countStatement
     | describeTable
     | addColumnFamily
     | addKeyspace
@@ -88,20 +88,20 @@ stmt
     | renameColumnFamily
     | renameKeyspace
     | useTable
-    | delStmt
-    | getStmt
-    | helpStmt
-    | setStmt
-    | showStmt
+    | delStatement
+    | getStatement
+    | helpStatement
+    | setStatement
+    | showStatement
     | -> ^(NODE_NO_OP)
     ;
 
-connectStmt
+connectStatement
     : K_CONNECT host SLASH port -> ^(NODE_CONNECT host port)
     | K_CONNECT ipaddr SLASH port -> ^(NODE_CONNECT ipaddr port)
     ;
 
-helpStmt
+helpStatement
     : K_HELP K_HELP -> ^(NODE_HELP NODE_HELP)
     | K_HELP K_CONNECT -> ^(NODE_HELP NODE_CONNECT)
     | K_HELP K_USE -> ^(NODE_HELP NODE_USE_TABLE)
@@ -125,28 +125,28 @@ helpStmt
     | '?'    -> ^(NODE_HELP)
     ;
 
-exitStmt
+exitStatement
     : K_QUIT -> ^(NODE_EXIT)
     | K_EXIT -> ^(NODE_EXIT)
     ;
 
-getStmt
+getStatement
     : K_GET columnFamilyExpr -> ^(NODE_THRIFT_GET columnFamilyExpr)
     ;
 
-setStmt
+setStatement
     : K_SET columnFamilyExpr '=' value -> ^(NODE_THRIFT_SET columnFamilyExpr 
value)
     ;
 
-countStmt
+countStatement
     : K_COUNT columnFamilyExpr -> ^(NODE_THRIFT_COUNT columnFamilyExpr)
     ;
 
-delStmt
+delStatement
     : K_DEL columnFamilyExpr -> ^(NODE_THRIFT_DEL columnFamilyExpr)
     ;
 
-showStmt
+showStatement
     : showClusterName
     | showVersion
     | showTables
@@ -216,7 +216,7 @@ columnName: Identifier;
 
 attname: Identifier;
 
-attvaluestring: StringLiteral;
+attvaluestring: (Identifier | StringLiteral);
       
 attvalueint: IntegerLiteral;
   
@@ -242,11 +242,11 @@ password: StringLiteral;
 
 columnFamily: Identifier;
 
-rowKey:   StringLiteral;
+rowKey:   (Identifier | StringLiteral);
 
-value: StringLiteral;
+value: (Identifier | IntegerLiteral | StringLiteral);
 
-columnOrSuperColumn: StringLiteral;
+columnOrSuperColumn: (Identifier | IntegerLiteral | StringLiteral);
 
 host: id+=Identifier (id+=DOT id+=Identifier)* -> ^(NODE_ID_LIST $id+);
 
@@ -321,7 +321,9 @@ StringLiteral
 
 
 IntegerLiteral
-   : Digit+;
+   : Digit+
+   ;
+
 
 //
 // syntactic elements

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=1002173&r1=1002172&r2=1002173&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cli/CliClient.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cli/CliClient.java Tue Sep 28 
14:21:02 2010
@@ -17,21 +17,20 @@
  */
 package org.apache.cassandra.cli;
 
-import org.apache.cassandra.auth.SimpleAuthenticator;
-import org.apache.cassandra.db.marshal.AbstractType;
-import org.apache.cassandra.db.marshal.BytesType;
-import org.apache.cassandra.thrift.*;
-
-import org.apache.cassandra.utils.FBUtilities;
-import org.apache.thrift.*;
-
-import org.antlr.runtime.tree.*;
-
-import java.util.*;
 import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.util.*;
 
 import org.apache.commons.lang.ArrayUtils;
 
+import org.antlr.runtime.tree.CommonTree;
+import org.antlr.runtime.tree.Tree;
+import org.apache.cassandra.auth.SimpleAuthenticator;
+import org.apache.cassandra.db.marshal.*;
+import org.apache.cassandra.thrift.*;
+import org.apache.cassandra.utils.FBUtilities;
+import org.apache.thrift.TException;
+
 // Cli Client Side Library
 public class CliClient 
 {
@@ -67,22 +66,21 @@ public class CliClient 
     private String username = null;
     private Map<String, KsDef> keyspacesMap = new HashMap<String, KsDef>();
 
-    public CliClient(CliSessionState css, Cassandra.Client thriftClient)
+    public CliClient(CliSessionState cliSessionState, Cassandra.Client 
thriftClient)
     {
-        css_ = css;
+        css_ = cliSessionState;
         thriftClient_ = thriftClient;
     }
 
     // Execute a CLI Statement 
     public void executeCLIStmt(String stmt) throws TException, 
NotFoundException, InvalidRequestException, UnavailableException, 
TimedOutException, IllegalAccessException, ClassNotFoundException, 
InstantiationException, NoSuchFieldException
     {
-        CommonTree ast = null;
-
-        ast = CliCompiler.compileQuery(stmt);
+        CommonTree ast = CliCompiler.compileQuery(stmt);
 
         try
         {
-            switch (ast.getType()) {
+            switch (ast.getType())
+            {
                 case CliParser.NODE_EXIT:
                     cleanupAndExit();
                     break;
@@ -155,8 +153,8 @@ public class CliClient 
 
     private void printCmdHelp(CommonTree ast)
     {
-        
-        if(ast.getChildCount() > 0) {
+        if (ast.getChildCount() > 0)
+        {
             int helpType = ast.getChild(0).getType();
                     
             switch(helpType)
@@ -355,7 +353,6 @@ public class CliClient 
             css_.out.println("del <cf>['<key>']['<super>']['<col>']            
             Delete sub column.");
             css_.out.println("count <cf>['<key>']                              
       Count columns in record.");
             css_.out.println("count <cf>['<key>']['<super>']                  
Count columns in a super column.");
-            return;
         } 
     }
 
@@ -487,7 +484,7 @@ public class CliClient 
                     css_.out.printf("\n     (column=%s, value=%s, 
timestamp=%d)", formatSubcolumnName(keyspace, columnFamily, col),
                                     new String(col.value, "UTF-8"), 
col.timestamp);
                 
-                css_.out.println(")"); 
+                css_.out.println(")");
             }
             else
             {
@@ -535,7 +532,7 @@ public class CliClient 
             return;
 
         // This will never happen unless the grammar is broken
-        assert (ast.getChildCount() == 1) : "serious parsing error (this is a 
bug).";
+        assert ast.getChildCount() == 1 : "serious parsing error (this is a 
bug).";
 
         CommonTree columnFamilySpec = (CommonTree)ast.getChild(0);
         assert(columnFamilySpec.getType() == CliParser.NODE_COLUMN_ACCESS);
@@ -545,10 +542,11 @@ public class CliClient 
         int columnSpecCnt = CliCompiler.numColumnSpecifiers(columnFamilySpec);
 
         List<String> cfnames = new ArrayList<String>();
-        for (CfDef cfd : keyspacesMap.get(keySpace).cf_defs) {
+        for (CfDef cfd : keyspacesMap.get(keySpace).cf_defs)
+        {
             cfnames.add(cfd.name);
         }
-
+ 
         int idx = cfnames.indexOf(columnFamily);
         if (idx == -1)
         {
@@ -559,7 +557,7 @@ public class CliClient 
         boolean isSuper = 
keyspacesMap.get(keySpace).cf_defs.get(idx).column_type.equals("Super");
         
         byte[] superColumnName = null;
-        byte[] columnName = null;
+        String columnName;
         
         // table.cf['key'] -- row slice
         if (columnSpecCnt == 0)
@@ -577,16 +575,16 @@ public class CliClient 
                 doSlice(keySpace, key, columnFamily, superColumnName);
                 return;
             }
-            else
+            else 
             {
-                columnName = CliCompiler.getColumn(columnFamilySpec, 
0).getBytes("UTF-8");
+                 columnName = CliCompiler.getColumn(columnFamilySpec, 0);
             }
         }
         // table.cf['key']['column']['column'] -- get of a sub-column
         else if (columnSpecCnt == 2)
         {
             superColumnName = CliCompiler.getColumn(columnFamilySpec, 
0).getBytes("UTF-8");
-            columnName = CliCompiler.getColumn(columnFamilySpec, 
1).getBytes("UTF-8");
+            columnName = CliCompiler.getColumn(columnFamilySpec, 1);
         }
         // The parser groks an arbitrary number of these so it is possible to 
get here.
         else
@@ -594,17 +592,19 @@ public class CliClient 
             css_.out.println("Invalid row, super column, or column 
specification.");
             return;
         }
-        
-        // Perform a get(), print out the results.
-        ColumnPath path = new 
ColumnPath(columnFamily).setSuper_column(superColumnName).setColumn(columnName);
+
+        // Perform a get()
+        ColumnPath path = new 
ColumnPath(columnFamily).setSuper_column(superColumnName).setColumn(columnNameAsByteArray(columnName,
 columnFamily));
         Column column = thriftClient_.get(key.getBytes(), path, 
ConsistencyLevel.ONE).column;
-        css_.out.printf("=> (column=%s, value=%s, timestamp=%d)\n", 
formatColumnName(keySpace, columnFamily, column),
-                        new String(column.value, "UTF-8"), column.timestamp);
+        // print results
+        css_.out.printf("=> (column=%s, value=%s, timestamp=%d)\n",
+                        formatColumnName(keySpace, columnFamily, column), new 
String(column.value, "UTF-8"), column.timestamp);
     }
 
     // Execute SET statement
-    private void executeSet(CommonTree ast) throws TException, 
InvalidRequestException, UnavailableException, TimedOutException, 
UnsupportedEncodingException
-    { 
+    private void executeSet(CommonTree ast)
+    throws TException, InvalidRequestException, UnavailableException, 
TimedOutException, UnsupportedEncodingException, NoSuchFieldException, 
InstantiationException, IllegalAccessException
+    {
         if (!CliMain.isConnected() || !hasKeySpace())
             return;
 
@@ -619,7 +619,7 @@ public class CliClient 
         String value = CliUtils.unescapeSQLString(ast.getChild(1).getText());
 
         byte[] superColumnName = null;
-        byte[] columnName = null;
+        String columnName;
 
         // table.cf['key']
         if (columnSpecCnt == 0)
@@ -631,7 +631,7 @@ public class CliClient 
         else if (columnSpecCnt == 1)
         {
             // get the column name
-            columnName = CliCompiler.getColumn(columnFamilySpec, 
0).getBytes("UTF-8");
+            columnName = CliCompiler.getColumn(columnFamilySpec, 0);
         }
         // table.cf['key']['super_column']['column'] = 'value'
         else
@@ -640,12 +640,12 @@ public class CliClient 
             
             // get the super column and column names
             superColumnName = CliCompiler.getColumn(columnFamilySpec, 
0).getBytes("UTF-8");
-            columnName = CliCompiler.getColumn(columnFamilySpec, 
1).getBytes("UTF-8");
+            columnName = CliCompiler.getColumn(columnFamilySpec, 1);
         }
-        
+
         // do the insert
         thriftClient_.insert(key.getBytes(), new 
ColumnParent(columnFamily).setSuper_column(superColumnName),
-                             new Column(columnName, value.getBytes(), 
FBUtilities.timestampMicros()), ConsistencyLevel.ONE);
+                             new Column(columnNameAsByteArray(columnName, 
columnFamily), value.getBytes(), FBUtilities.timestampMicros()), 
ConsistencyLevel.ONE);
         
         css_.out.println("Value inserted.");
     }
@@ -1080,7 +1080,8 @@ public class CliClient 
         CliMain.connect(css_.hostName, css_.thriftPort);
     }
 
-    private CfDef getCfDef(String ksname, String cfname) {
+    private CfDef getCfDef(String ksname, String cfname)
+    {
         List<String> cfnames = new ArrayList<String>();
         KsDef ksd = keyspacesMap.get(ksname);
         for (CfDef cfd : ksd.cf_defs) {
@@ -1089,4 +1090,39 @@ public class CliClient 
         int idx = cfnames.indexOf(cfname);
         return ksd.cf_defs.get(idx);
     }
+
+    private byte[] columnNameAsByteArray(final String column, final String 
columnFamily) throws NoSuchFieldException, InstantiationException, 
IllegalAccessException, UnsupportedEncodingException
+    {
+        List<String> cfnames = new ArrayList<String>();
+        for (CfDef cfd : keyspacesMap.get(keySpace).cf_defs)
+        {
+            cfnames.add(cfd.name);
+        }
+
+        int idx = cfnames.indexOf(columnFamily);
+        if (idx == -1)
+        {
+            throw new NoSuchFieldException("No such column family: " + 
columnFamily);
+        }
+
+        final String comparatorClass  = 
keyspacesMap.get(keySpace).cf_defs.get(idx).comparator_type;
+        final AbstractType comparator = 
getFormatTypeForColumn(comparatorClass);
+
+        if (comparator instanceof LongType)
+        {
+            return FBUtilities.toByteArray(Long.valueOf(column));
+        }
+        else if (comparator instanceof IntegerType)
+        {
+            return new BigInteger(column).toByteArray();
+        }
+        else if (comparator instanceof AsciiType)
+        {
+            return column.getBytes("US-ASCII");
+        }
+        else
+        {
+            return column.getBytes("UTF-8");
+        }   
+    }
 }

Modified: cassandra/trunk/src/java/org/apache/cassandra/cli/CliUtils.java
URL: 
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cli/CliUtils.java?rev=1002173&r1=1002172&r2=1002173&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cli/CliUtils.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cli/CliUtils.java Tue Sep 28 
14:21:02 2010
@@ -23,43 +23,73 @@ package org.apache.cassandra.cli;
 
 public class CliUtils
 {
-    /*
+    /**
      * Strips leading and trailing "'" characters, and handles
      * and escaped characters such as \n, \r, etc.
-     * [Shameless clone from hive.]
      */
-    public static String unescapeSQLString(String b) 
+    public static String unescapeSQLString(String b)
     {
-        assert(b.charAt(0) == '\'');
-        assert(b.charAt(b.length()-1) == '\'');
+        int j = 1;
+        final char start = b.charAt(0);
+        final char end = b.charAt(b.length() - 1);
+
+        if (start != '\'' && end != '\'')
+        {
+            j = 0;
+        }
+
         StringBuilder sb = new StringBuilder(b.length());
-        
-        for (int i=1; i+1<b.length(); i++)
+
+        for (int i = j; ((j == 0) ? i : i + 1) < b.length(); i++)
         {
-            if (b.charAt(i) == '\\' && i+2<b.length())
+            if (b.charAt(i) == '\\' && i + 2 < b.length())
             {
-                char n=b.charAt(i+1);
-                switch(n)
+                char n = b.charAt(i + 1);
+                switch (n)
                 {
-                case '0': sb.append("\0"); break;
-                case '\'': sb.append("'"); break;
-                case '"': sb.append("\""); break;
-                case 'b': sb.append("\b"); break;
-                case 'n': sb.append("\n"); break;
-                case 'r': sb.append("\r"); break;
-                case 't': sb.append("\t"); break;
-                case 'Z': sb.append("\u001A"); break;
-                case '\\': sb.append("\\"); break;
-                case '%': sb.append("%"); break;
-                case '_': sb.append("_"); break;
-                default: sb.append(n);
+                    case '0':
+                        sb.append("\0");
+                        break;
+                    case '\'':
+                        sb.append("'");
+                        break;
+                    case '"':
+                        sb.append("\"");
+                        break;
+                    case 'b':
+                        sb.append("\b");
+                        break;
+                    case 'n':
+                        sb.append("\n");
+                        break;
+                    case 'r':
+                        sb.append("\r");
+                        break;
+                    case 't':
+                        sb.append("\t");
+                        break;
+                    case 'Z':
+                        sb.append("\u001A");
+                        break;
+                    case '\\':
+                        sb.append("\\");
+                        break;
+                    case '%':
+                        sb.append("%");
+                        break;
+                    case '_':
+                        sb.append("_");
+                        break;
+                    default:
+                        sb.append(n);
                 }
-            } 
+            }
             else
             {
                 sb.append(b.charAt(i));
             }
         }
+
         return sb.toString();
-    } 
+    }
 }


Reply via email to