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/04/04 22:05:20 UTC
svn commit: r1088766 - in /cassandra/trunk:
src/java/org/apache/cassandra/cql/ test/system/
Author: eevans
Date: Mon Apr 4 20:05:19 2011
New Revision: 1088766
URL: http://svn.apache.org/viewvc?rev=1088766&view=rev
Log:
CQL INSERT implementation
Patch by Pavel Yaskevich and eevans for CASSANDRA-2409
Modified:
cassandra/trunk/src/java/org/apache/cassandra/cql/Cql.g
cassandra/trunk/src/java/org/apache/cassandra/cql/QueryProcessor.java
cassandra/trunk/src/java/org/apache/cassandra/cql/StatementType.java
cassandra/trunk/src/java/org/apache/cassandra/cql/UpdateStatement.java
cassandra/trunk/test/system/test_cql.py
Modified: cassandra/trunk/src/java/org/apache/cassandra/cql/Cql.g
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cql/Cql.g?rev=1088766&r1=1088765&r2=1088766&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/Cql.g (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/Cql.g Mon Apr 4 20:05:19 2011
@@ -31,6 +31,8 @@ options {
import java.util.Map;
import java.util.HashMap;
import java.util.Collections;
+ import java.util.List;
+ import java.util.ArrayList;
import org.apache.cassandra.thrift.ConsistencyLevel;
import org.apache.cassandra.thrift.InvalidRequestException;
}
@@ -100,6 +102,7 @@ options {
query returns [CQLStatement stmnt]
: selectStatement { $stmnt = new CQLStatement(StatementType.SELECT, $selectStatement.expr); }
+ | insertStatement { $stmnt = new CQLStatement(StatementType.INSERT, $insertStatement.expr); }
| updateStatement endStmnt { $stmnt = new CQLStatement(StatementType.UPDATE, $updateStatement.expr); }
| batchUpdateStatement { $stmnt = new CQLStatement(StatementType.BATCH_UPDATE, $batchUpdateStatement.expr); }
| useStatement { $stmnt = new CQLStatement(StatementType.USE, $useStatement.keyspace); }
@@ -176,6 +179,36 @@ whereClause returns [WhereClause clause]
;
/**
+ * INSERT INTO
+ * <CF>
+ * (KEY, <column>, <column>, ...)
+ * VALUES
+ * (<key>, <value>, <value>, ...)
+ * (USING
+ * CONSISTENCY <level>)?;
+ *
+ * Consistency level is set to ONE by default
+ */
+insertStatement returns [UpdateStatement expr]
+ : {
+ ConsistencyLevel cLevel = ConsistencyLevel.ONE;
+ Map<Term, Term> columns = new HashMap<Term, Term>();
+
+ List<Term> columnNames = new ArrayList<Term>();
+ List<Term> columnValues = new ArrayList<Term>();
+ }
+ K_INSERT K_INTO columnFamily=( IDENT | STRING_LITERAL | INTEGER )
+ '(' K_KEY ( ',' column_name=term { columnNames.add($column_name.item); } )+ ')'
+ K_VALUES
+ '(' key=term ( ',' column_value=term { columnValues.add($column_value.item); })+ ')'
+ ( K_USING K_CONSISTENCY K_LEVEL { cLevel = ConsistencyLevel.valueOf($K_LEVEL.text); } )?
+ endStmnt
+ {
+ return new UpdateStatement($columnFamily.text, cLevel, columnNames, columnValues, key);
+ }
+ ;
+
+/**
* BEGIN BATCH [USING CONSISTENCY.<LVL>]
* UPDATE <CF> SET name1 = value1 WHERE KEY = keyname1;
* UPDATE <CF> SET name2 = value2 WHERE KEY = keyname2;
@@ -350,6 +383,7 @@ K_WHERE: W H E R E;
K_AND: A N D;
K_KEY: K E Y;
K_COLUMN: C O L (U M N)?;
+K_INSERT: I N S E R T;
K_UPDATE: U P D A T E;
K_WITH: W I T H;
K_ROW: R O W;
@@ -381,6 +415,8 @@ K_INDEX: I N D E X;
K_ON: O N;
K_DROP: D R O P;
K_PRIMARY: P R I M A R Y;
+K_INTO: I N T O;
+K_VALUES: V A L U E S;
// Case-insensitive alpha characters
fragment A: ('a'|'A');
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=1088766&r1=1088765&r2=1088766&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/QueryProcessor.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/QueryProcessor.java Mon Apr 4 20:05:19 2011
@@ -545,7 +545,8 @@ public class QueryProcessor
avroResult.rows = avroRows;
return avroResult;
-
+
+ case INSERT: // insert uses UpdateStatement
case UPDATE:
UpdateStatement update = (UpdateStatement)statement.statement;
batchUpdate(clientState, Collections.singletonList(update), update.getConsistencyLevel());
Modified: cassandra/trunk/src/java/org/apache/cassandra/cql/StatementType.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cql/StatementType.java?rev=1088766&r1=1088765&r2=1088766&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/StatementType.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/StatementType.java Mon Apr 4 20:05:19 2011
@@ -24,7 +24,7 @@ import java.util.EnumSet;
public enum StatementType
{
- SELECT, UPDATE, BATCH_UPDATE, USE, TRUNCATE, DELETE, CREATE_KEYSPACE, CREATE_COLUMNFAMILY, CREATE_INDEX,
+ SELECT, INSERT, UPDATE, BATCH_UPDATE, USE, TRUNCATE, DELETE, CREATE_KEYSPACE, CREATE_COLUMNFAMILY, CREATE_INDEX,
DROP_KEYSPACE, DROP_COLUMNFAMILY;
// Statement types that don't require a keyspace to be set.
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=1088766&r1=1088765&r2=1088766&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/UpdateStatement.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/UpdateStatement.java Mon Apr 4 20:05:19 2011
@@ -21,11 +21,14 @@
package org.apache.cassandra.cql;
import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.db.marshal.AbstractType;
import org.apache.cassandra.thrift.ConsistencyLevel;
+import org.apache.cassandra.thrift.InvalidRequestException;
/**
* An <code>UPDATE</code> statement parsed from a CQL query statement.
@@ -37,6 +40,7 @@ public class UpdateStatement
private String columnFamily;
private ConsistencyLevel cLevel = null;
private Map<Term, Term> columns;
+ private List<Term> columnNames, columnValues;
private Term key;
/**
@@ -68,6 +72,26 @@ public class UpdateStatement
{
this(columnFamily, null, columns, key);
}
+
+ /**
+ * Creates a new UpdateStatement from a column family name, a consistency level,
+ * key, and lists of column names and values. It is intended for use with the
+ * alternate update format, <code>INSERT</code>.
+ *
+ * @param columnFamily column family name
+ * @param cLevel the thrift consistency level
+ * @param columnNames list of column names
+ * @param columnValues list of column values (corresponds to names)
+ * @param key the key name
+ */
+ public UpdateStatement(String columnFamily, ConsistencyLevel cLevel, List<Term> columnNames, List<Term> columnValues, Term key)
+ {
+ this.columnFamily = columnFamily;
+ this.cLevel = cLevel;
+ this.columnNames = columnNames;
+ this.columnValues = columnValues;
+ this.key = key;
+ }
/**
* Returns the consistency level of this <code>UPDATE</code> statement, either
@@ -100,8 +124,25 @@ public class UpdateStatement
return key;
}
- public Map<Term, Term> getColumns()
+ public Map<Term, Term> getColumns() throws InvalidRequestException
{
+ // Created from an UPDATE
+ if (columns != null)
+ return columns;
+
+ // Created from an INSERT
+
+ // Don't hate, validate.
+ if (columnNames.size() != columnValues.size())
+ throw new InvalidRequestException("unmatched column names/values");
+ if (columnNames.size() < 1)
+ throw new InvalidRequestException("no columns specified for INSERT");
+
+ columns = new HashMap<Term, Term>();
+
+ for (int i = 0; i < columnNames.size(); i++)
+ columns.put(columnNames.get(i), columnValues.get(i));
+
return columns;
}
Modified: cassandra/trunk/test/system/test_cql.py
URL: http://svn.apache.org/viewvc/cassandra/trunk/test/system/test_cql.py?rev=1088766&r1=1088765&r2=1088766&view=diff
==============================================================================
--- cassandra/trunk/test/system/test_cql.py (original)
+++ cassandra/trunk/test/system/test_cql.py Mon Apr 4 20:05:19 2011
@@ -602,3 +602,39 @@ class TestCql(ThriftTester):
# FIXME: The above is woefully inadequate, but the test config uses
# CollatingOrderPreservingPartitioner which only supports UTF8.
+
+ def test_write_using_insert(self):
+ "peforming writes using \"insert\""
+ conn = init()
+ conn.execute("INSERT INTO StandardUtf82 (KEY, ?, ?) VALUES (?, ?, ?)",
+ "pork",
+ "beef",
+ "meat",
+ "bacon",
+ "brisket")
+
+ r = conn.execute("SELECT * FROM StandardUtf82 WHERE KEY = ?", "meat")
+ assert r[0][0].name == "beef"
+ assert r[0][0].value == "brisket"
+ assert r[0][1].name == "pork"
+ assert r[0][1].value == "bacon"
+
+ # Bad writes.
+
+ # Too many column values
+ assert_raises(CQLException,
+ conn.execute,
+ "INSERT INTO StandardUtf82 (KEY, ?) VALUES (?, ?, ?)",
+ "name1",
+ "key0",
+ "value1",
+ "value2")
+
+ # Too many column names, (not enough column values)
+ assert_raises(CQLException,
+ conn.execute,
+ "INSERT INTO StandardUtf82 (KEY, ?, ?) VALUES (?, ?)",
+ "name1",
+ "name2",
+ "key0",
+ "value1")