You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by bl...@apache.org on 2016/08/16 14:38:20 UTC

cassandra git commit: Allow TTL with null value on insert and update

Repository: cassandra
Updated Branches:
  refs/heads/trunk d1bd71c4e -> e83f9e69e


Allow TTL with null value on insert and update

patch by Russell Spitzer; reviewed by Benjamin Lerer for CASSANDRA-12216


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/e83f9e69
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/e83f9e69
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/e83f9e69

Branch: refs/heads/trunk
Commit: e83f9e69e2c4abd295645eaf0289772a15eb4a85
Parents: d1bd71c
Author: Russell Spitzer <ru...@gmail.com>
Authored: Tue Aug 16 16:36:13 2016 +0200
Committer: Benjamin Lerer <b....@gmail.com>
Committed: Tue Aug 16 16:36:13 2016 +0200

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 NEWS.txt                                        |  1 +
 doc/source/cql/changes.rst                      |  2 ++
 doc/source/cql/dml.rst                          |  3 +-
 .../org/apache/cassandra/cql3/Attributes.java   |  2 +-
 .../apache/cassandra/cql3/QueryProcessor.java   |  2 +-
 .../cql3/validation/operations/InsertTest.java  | 27 ++++++++++++++----
 .../cql3/validation/operations/UpdateTest.java  | 30 ++++++++++++++++++++
 8 files changed, 59 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/e83f9e69/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 7b29394..700dd48 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 3.10
+ * Allow TTL with null value on insert and update (CASSANDRA-12216)
  * Make decommission operation resumable (CASSANDRA-12008)
  * Add support to one-way targeted repair (CASSANDRA-9876)
  * Remove clientutil jar (CASSANDRA-11635)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e83f9e69/NEWS.txt
----------------------------------------------------------------------
diff --git a/NEWS.txt b/NEWS.txt
index 9bdeec1..9cfc58b 100644
--- a/NEWS.txt
+++ b/NEWS.txt
@@ -58,6 +58,7 @@ New features
      and org.apache.cassandra.metrics:type=Client,name=AuthFailure respectively.
    - Add support to "unset" JSON fields in prepared statements by specifying DEFAULT UNSET.
      See CASSANDRA-11424 for details
+   - Allow TTL with null value on insert and update. It will be treated as equivalent to inserting a 0.
 
 Upgrading
 ---------

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e83f9e69/doc/source/cql/changes.rst
----------------------------------------------------------------------
diff --git a/doc/source/cql/changes.rst b/doc/source/cql/changes.rst
index 7d7c2b9..4f71748 100644
--- a/doc/source/cql/changes.rst
+++ b/doc/source/cql/changes.rst
@@ -26,6 +26,8 @@ The following describes the changes in each version of CQL.
 
 - Support for ``GROUP BY`` (:jira:`10707`).
 - Adds a ``DEFAULT UNSET`` option for ``INSERT JSON`` to ignore omitted columns (:jira:`11424`).
+- Allows ``null`` as a legal value for TTL on insert and update. It will be treated as equivalent to
+inserting a 0 (:jira:`12216`).
 
 3.4.2
 ^^^^^

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e83f9e69/doc/source/cql/dml.rst
----------------------------------------------------------------------
diff --git a/doc/source/cql/dml.rst b/doc/source/cql/dml.rst
index ad878a9..1b0f80b 100644
--- a/doc/source/cql/dml.rst
+++ b/doc/source/cql/dml.rst
@@ -420,7 +420,8 @@ parameters:
   automatically removed from the database after the specified time. Note that the TTL concerns the inserted values, not
   the columns themselves. This means that any subsequent update of the column will also reset the TTL (to whatever TTL
   is specified in that update). By default, values never expire. A TTL of 0 is equivalent to no TTL. If the table has a
-  default_time_to_live, a TTL of 0 will remove the TTL for the inserted or updated values.
+  default_time_to_live, a TTL of 0 will remove the TTL for the inserted or updated values. A TTL of ``null`` is equivalent
+  to inserting with a TTL of 0.
 
 .. _delete_statement:
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e83f9e69/src/java/org/apache/cassandra/cql3/Attributes.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/Attributes.java b/src/java/org/apache/cassandra/cql3/Attributes.java
index 534a2a0..60671a1 100644
--- a/src/java/org/apache/cassandra/cql3/Attributes.java
+++ b/src/java/org/apache/cassandra/cql3/Attributes.java
@@ -99,7 +99,7 @@ public class Attributes
 
         ByteBuffer tval = timeToLive.bindAndGet(options);
         if (tval == null)
-            throw new InvalidRequestException("Invalid null value of TTL");
+            return 0;
 
         if (tval == ByteBufferUtil.UNSET_BYTE_BUFFER)
             return defaultTimeToLive;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e83f9e69/src/java/org/apache/cassandra/cql3/QueryProcessor.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/QueryProcessor.java b/src/java/org/apache/cassandra/cql3/QueryProcessor.java
index 4e7323e..899b36d 100644
--- a/src/java/org/apache/cassandra/cql3/QueryProcessor.java
+++ b/src/java/org/apache/cassandra/cql3/QueryProcessor.java
@@ -57,7 +57,7 @@ import org.apache.cassandra.utils.*;
 
 public class QueryProcessor implements QueryHandler
 {
-    public static final CassandraVersion CQL_VERSION = new CassandraVersion("3.4.2");
+    public static final CassandraVersion CQL_VERSION = new CassandraVersion("3.4.3");
 
     public static final QueryProcessor instance = new QueryProcessor();
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e83f9e69/test/unit/org/apache/cassandra/cql3/validation/operations/InsertTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/validation/operations/InsertTest.java b/test/unit/org/apache/cassandra/cql3/validation/operations/InsertTest.java
index 9adcb62..488e1c7 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/operations/InsertTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/operations/InsertTest.java
@@ -21,6 +21,7 @@ package org.apache.cassandra.cql3.validation.operations;
 import org.junit.Assert;
 import org.junit.Test;
 
+import org.apache.cassandra.cql3.Attributes;
 import org.apache.cassandra.cql3.CQLTester;
 import org.apache.cassandra.cql3.UntypedResultSet;
 import org.apache.cassandra.cql3.UntypedResultSet.Row;
@@ -52,13 +53,24 @@ public class InsertTest extends CQLTester
     }
 
     @Test
-    public void testInsertTtlWithUnset() throws Throwable
+    public void testInsertWithTtl() throws Throwable
     {
-        createTable("CREATE TABLE %s (k int PRIMARY KEY, i int)");
-        execute("INSERT INTO %s (k, i) VALUES (1, 1) USING TTL ?", unset()); // treat as 'unlimited'
-        assertRows(execute("SELECT ttl(i) FROM %s"),
-                   row(new Object[]{ null })
-        );
+        createTable("CREATE TABLE %s (k int PRIMARY KEY, v int)");
+
+        // test with unset
+        execute("INSERT INTO %s (k, v) VALUES (1, 1) USING TTL ?", unset()); // treat as 'unlimited'
+        assertRows(execute("SELECT ttl(v) FROM %s"), row(new Object[]{ null }));
+
+        // test with null
+        execute("INSERT INTO %s (k, v) VALUES (?, ?) USING TTL ?", 1, 1, null);
+        assertRows(execute("SELECT k, v, TTL(v) FROM %s"), row(1, 1, null));
+
+        // test error handling
+        assertInvalidMessage("A TTL must be greater or equal to 0, but was -5",
+                             "INSERT INTO %s (k, v) VALUES (?, ?) USING TTL ?", 1, 1, -5);
+
+        assertInvalidMessage("ttl is too large.",
+                             "INSERT INTO %s (k, v) VALUES (?, ?) USING TTL ?", 1, 1, Attributes.MAX_TTL + 1);
     }
 
     @Test
@@ -314,6 +326,9 @@ public class InsertTest extends CQLTester
         Assert.assertEquals(1, resultSet.size());
         row = resultSet.one();
         Assert.assertTrue(row.getInt("ttl(b)") >= (9 * secondsPerMinute));
+
+        execute("INSERT INTO %s (a, b) VALUES (?, ?) USING TTL ?", 4, 4, null);
+        assertRows(execute("SELECT ttl(b) FROM %s WHERE a = 4"), row(new Object[]{null}));
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e83f9e69/test/unit/org/apache/cassandra/cql3/validation/operations/UpdateTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/validation/operations/UpdateTest.java b/test/unit/org/apache/cassandra/cql3/validation/operations/UpdateTest.java
index 9c42fc2..494abaa 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/operations/UpdateTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/operations/UpdateTest.java
@@ -24,6 +24,8 @@ import org.junit.Assert;
 import org.junit.Test;
 
 import static org.apache.commons.lang3.StringUtils.isEmpty;
+
+import org.apache.cassandra.cql3.Attributes;
 import org.apache.cassandra.cql3.CQLTester;
 import org.apache.cassandra.cql3.UntypedResultSet;
 import org.apache.cassandra.cql3.UntypedResultSet.Row;
@@ -550,5 +552,33 @@ public class UpdateTest extends CQLTester
         Assert.assertEquals(1, resultSet.size());
         row = resultSet.one();
         Assert.assertTrue(row.getInt("ttl(b)") >= (9 * secondsPerMinute));
+
+        execute("UPDATE %s USING TTL ? SET b = ? WHERE a = ?", null, 3, 3);
+        assertRows(execute("SELECT ttl(b) FROM %s WHERE a = 3"), row(new Object[] { null }));
+    }
+
+    @Test
+    public void testUpdateWithTtl() throws Throwable
+    {
+        createTable("CREATE TABLE %s (k int PRIMARY KEY, v int)");
+
+        execute("INSERT INTO %s (k, v) VALUES (1, 1) USING TTL ?", 3600);
+        execute("INSERT INTO %s (k, v) VALUES (2, 2) USING TTL ?", 3600);
+
+        // test with unset
+        execute("UPDATE %s USING TTL ? SET v = ? WHERE k = ?", unset(), 1, 1); // treat as 'unlimited'
+        assertRows(execute("SELECT ttl(v) FROM %s WHERE k = 1"), row(new Object[] { null }));
+
+        // test with null
+        execute("UPDATE %s USING TTL ? SET v = ? WHERE k = ?", unset(), 2, 2);
+        assertRows(execute("SELECT k, v, TTL(v) FROM %s WHERE k = 2"), row(2, 2, null));
+
+        // test error handling
+        assertInvalidMessage("A TTL must be greater or equal to 0, but was -5",
+                             "UPDATE %s USING TTL ? SET v = ? WHERE k = ?", -5, 1, 1);
+
+        assertInvalidMessage("ttl is too large.",
+                             "UPDATE %s USING TTL ? SET v = ? WHERE k = ?",
+                             Attributes.MAX_TTL + 1, 1, 1);
     }
 }