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();
- }
+ }
}