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 2011/07/19 23:29:40 UTC
svn commit: r1148547 - in /cassandra/branches/cassandra-0.8: CHANGES.txt
src/java/org/apache/cassandra/cql/Cql.g
src/java/org/apache/cassandra/cql/DeleteStatement.java
test/system/test_cql.py
Author: jbellis
Date: Tue Jul 19 21:29:39 2011
New Revision: 1148547
URL: http://svn.apache.org/viewvc?rev=1148547&view=rev
Log:
respect client timestamp on full row deletions
patch by slebresne; reviewed by pyaskevich for CASSANDRA-2912
Modified:
cassandra/branches/cassandra-0.8/CHANGES.txt
cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cql/Cql.g
cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cql/DeleteStatement.java
cassandra/branches/cassandra-0.8/test/system/test_cql.py
Modified: cassandra/branches/cassandra-0.8/CHANGES.txt
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.8/CHANGES.txt?rev=1148547&r1=1148546&r2=1148547&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.8/CHANGES.txt (original)
+++ cassandra/branches/cassandra-0.8/CHANGES.txt Tue Jul 19 21:29:39 2011
@@ -1,4 +1,7 @@
0.8.2
+ * CQL:
+ - include only one row per unique key for IN queries (CASSANDRA-2717)
+ - respect client timestamp on full row deletions (CASSANDRA-2912)
* improve thread-safety in StreamOutSession (CASSANDRA-2792)
* allow deleting a row and updating indexed columns in it in the
same mutation (CASSANDRA-2773)
@@ -32,8 +35,6 @@
* fix updating KS with durable_writes=false (CASSANDRA-2907)
* add simplified facade to SSTableWriter for bulk loading use
(CASSANDRA-2911)
- * CQL: include only one row per unique key for IN queries
- (CASSANDRA-2717)
* fix re-using index CF sstable names after drop/recreate (CASSANDRA-2872)
Modified: cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cql/Cql.g
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cql/Cql.g?rev=1148547&r1=1148546&r2=1148547&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cql/Cql.g (original)
+++ cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cql/Cql.g Tue Jul 19 21:29:39 2011
@@ -226,9 +226,17 @@ usingClause[Attributes attrs]
: K_USING usingClauseObjective[attrs] ( K_AND? usingClauseObjective[attrs] )*
;
-usingClauseObjective[Attributes attrs]
+usingClauseDelete[Attributes attrs]
+ : K_USING usingClauseDeleteObjective[attrs] ( K_AND? usingClauseDeleteObjective[attrs] )*
+ ;
+
+usingClauseDeleteObjective[Attributes attrs]
: K_CONSISTENCY K_LEVEL { attrs.setConsistencyLevel(ConsistencyLevel.valueOf($K_LEVEL.text)); }
| K_TIMESTAMP ts=INTEGER { attrs.setTimestamp(Long.valueOf($ts.text)); }
+ ;
+
+usingClauseObjective[Attributes attrs]
+ : usingClauseDeleteObjective[attrs]
| K_TTL t=INTEGER { attrs.setTimeToLive(Integer.parseInt($t.text)); }
;
@@ -319,22 +327,24 @@ updateStatement returns [UpdateStatement
*/
deleteStatement returns [DeleteStatement expr]
: {
- ConsistencyLevel cLevel = null;
+ Attributes attrs = new Attributes();
List<Term> keyList = null;
List<Term> columnsList = Collections.emptyList();
}
K_DELETE
( cols=termList { columnsList = $cols.items; })?
K_FROM columnFamily=( IDENT | STRING_LITERAL | INTEGER )
- ( K_USING K_CONSISTENCY K_LEVEL { cLevel = ConsistencyLevel.valueOf($K_LEVEL.text); } )?
+ ( usingClauseDelete[attrs] )?
K_WHERE ( key_alias=term ('=' key=term { keyList = Collections.singletonList(key); }
| K_IN '(' keys=termList { keyList = $keys.items; } ')')
)?
{
- return new DeleteStatement(columnsList, $columnFamily.text, key_alias.getText(), cLevel, keyList);
+ return new DeleteStatement(columnsList, $columnFamily.text, key_alias.getText(), keyList, attrs);
}
;
+
+
/** CREATE KEYSPACE <KEYSPACE> WITH attr1 = value1 AND attr2 = value2; */
createKeyspaceStatement returns [CreateKeyspaceStatement expr]
: {
Modified: cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cql/DeleteStatement.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cql/DeleteStatement.java?rev=1148547&r1=1148546&r2=1148547&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cql/DeleteStatement.java (original)
+++ cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cql/DeleteStatement.java Tue Jul 19 21:29:39 2011
@@ -47,9 +47,9 @@ public class DeleteStatement extends Abs
private List<Term> columns;
private List<Term> keys;
- public DeleteStatement(List<Term> columns, String columnFamily, String keyName, ConsistencyLevel cLevel, List<Term> keys)
+ public DeleteStatement(List<Term> columns, String columnFamily, String keyName, List<Term> keys, Attributes attrs)
{
- super(columnFamily, keyName, cLevel, null, 0);
+ super(columnFamily, keyName, attrs);
this.columns = columns;
this.keys = keys;
@@ -107,7 +107,7 @@ public class DeleteStatement extends Abs
AbstractType comparator = metadata.getComparatorFor(null);
if (columns.size() < 1) // No columns, delete the row
- mutation.delete(new QueryPath(columnFamily), System.currentTimeMillis());
+ mutation.delete(new QueryPath(columnFamily), (timestamp == null) ? getTimestamp() : timestamp);
else // Delete specific columns
{
for (Term column : columns)
Modified: cassandra/branches/cassandra-0.8/test/system/test_cql.py
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.8/test/system/test_cql.py?rev=1148547&r1=1148546&r2=1148547&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.8/test/system/test_cql.py (original)
+++ cassandra/branches/cassandra-0.8/test/system/test_cql.py Tue Jul 19 21:29:39 2011
@@ -1050,6 +1050,68 @@ class TestCql(ThriftTester):
r = cursor.fetchone()
assert len(r) == 1, "expected 0 results, got %d" % len(r)
+ def test_delete_with_timestamp(self):
+ "delete statement should support setting timestamp"
+ cursor = init()
+ cursor.compression = 'NONE'
+
+ # insert to the StandardString1
+ cursor.execute("UPDATE StandardString1 USING TIMESTAMP 10 SET name = 'name here' WHERE KEY = 'TimestampedUser3'")
+
+ # try to read it
+ cursor.execute("SELECT * FROM StandardString1 WHERE KEY = 'TimestampedUser3'")
+ assert cursor.rowcount == 1, "expected 1 results, got %d" % cursor.rowcount
+ colnames = [col_d[0] for col_d in cursor.description]
+
+ assert colnames[1] == "name", \
+ "unrecognized name '%s'" % colnames[1]
+
+ r = cursor.fetchone()
+ assert r[1] == "name here", \
+ "unrecognized value '%s'" % r[1]
+
+ # DELETE with a lower TIMESTAMP
+ cursor.execute("DELETE 'name here' FROM StandardString1 USING TIMESTAMP 3 WHERE KEY = 'TimestampedUser3'")
+
+ # try to read it
+ cursor.execute("SELECT * FROM StandardString1 WHERE KEY = 'TimestampedUser3'")
+ assert cursor.rowcount == 1, "expected 1 results, got %d" % cursor.rowcount
+ colnames = [col_d[0] for col_d in cursor.description]
+
+ assert len(colnames) == 2, "expected 2 columns, got %d" % len(colnames)
+ assert colnames[1] == "name", \
+ "unrecognized name '%s'" % colnames[1]
+
+ r = cursor.fetchone()
+ assert r[1] == "name here", \
+ "unrecognized value '%s'" % r[1]
+
+ # now DELETE the whole row with a lower TIMESTAMP
+ cursor.execute("DELETE FROM StandardString1 USING TIMESTAMP 3 WHERE KEY = 'TimestampedUser3'")
+
+ # try to read it
+ cursor.execute("SELECT * FROM StandardString1 WHERE KEY = 'TimestampedUser3'")
+ assert cursor.rowcount == 1, "expected 1 results, got %d" % cursor.rowcount
+ colnames = [col_d[0] for col_d in cursor.description]
+
+ assert len(colnames) == 2, "expected 2 columns, got %d" % len(colnames)
+ assert colnames[1] == "name", \
+ "unrecognized name '%s'" % colnames[1]
+
+ r = cursor.fetchone()
+ assert r[1] == "name here", \
+ "unrecognized value '%s'" % r[1]
+
+ # now DELETE the row with a greater TIMESTAMP
+ cursor.execute("DELETE FROM StandardString1 USING TIMESTAMP 15 WHERE KEY = 'TimestampedUser3'")
+ # try to read it
+ cursor.execute("SELECT * FROM StandardString1 WHERE KEY = 'TimestampedUser3'")
+ assert cursor.rowcount == 1, "expected 1 results, got %d" % cursor.rowcount
+ colnames = [col_d[0] for col_d in cursor.description]
+
+ assert len(colnames) == 1, "expected only the KEY column, got %d" % len(colnames)
+ assert colnames[0] == "KEY", "unrecognized name '%s'" % colnames[0]
+
def test_alter_table_statement(self):
"test ALTER statement"
cursor = init()