Repository: cassandra
Updated Branches:
  refs/heads/cassandra-2.2 b77e11cfd -> cb6fad3ef
  refs/heads/cassandra-3.0 e51c85f2e -> 97fb4d102
  refs/heads/cassandra-3.11 b5df3b4c3 -> 48ffad89c
  refs/heads/trunk 10b397e2a -> 4d6af1752


Fix toJSONString for the UDT, tuple and collection types

patch by ZhaoYang; reviewed by Benjamin Lerer for CASSANDRA-13592


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

Branch: refs/heads/cassandra-2.2
Commit: cb6fad3efcd7cd3dc87d02ca7e8e97eb277a66ab
Parents: b77e11c
Author: ZhaoYang <zhaoyangsingap...@gmail.com>
Authored: Fri Jul 7 16:09:15 2017 +0200
Committer: Benjamin Lerer <b.le...@gmail.com>
Committed: Fri Jul 7 16:12:27 2017 +0200

----------------------------------------------------------------------
 CHANGES.txt                                     |   1 +
 .../cassandra/db/marshal/AbstractType.java      |  11 +-
 .../apache/cassandra/db/marshal/EmptyType.java  |   6 +
 .../apache/cassandra/db/marshal/ListType.java   |   5 +-
 .../apache/cassandra/db/marshal/MapType.java    |   7 +-
 .../apache/cassandra/db/marshal/TupleType.java  |   3 +-
 .../org/apache/cassandra/cql3/CQLTester.java    |  19 +-
 .../cql3/validation/entities/JsonTest.java      | 167 +++++++++-
 .../db/marshal/JsonConversionTest.java          | 320 +++++++++++++++++++
 9 files changed, 518 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/cb6fad3e/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 08c6e48..6740c9e 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 2.2.11
+ * Fix toJSONString for the UDT, tuple and collection types (CASSANDRA-13592)
  * Fix nested Tuples/UDTs validation (CASSANDRA-13646)
  * Remove unused max_value_size_in_mb config setting from yaml (CASSANDRA-13625
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/cb6fad3e/src/java/org/apache/cassandra/db/marshal/AbstractType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/AbstractType.java 
b/src/java/org/apache/cassandra/db/marshal/AbstractType.java
index b90e127..799d636 100644
--- a/src/java/org/apache/cassandra/db/marshal/AbstractType.java
+++ b/src/java/org/apache/cassandra/db/marshal/AbstractType.java
@@ -101,7 +101,16 @@ public abstract class AbstractType<T> implements 
Comparator<ByteBuffer>
      **/
     public abstract Term fromJSONObject(Object parsed) throws MarshalException;
 
-    /** Converts a value to a JSON string. */
+    /**
+     * Converts the specified value into its JSON representation.
+     * <p>
+     * The buffer position will stay the same.
+     * </p>
+     *
+     * @param buffer the value to convert
+     * @param protocolVersion the protocol version to use for the conversion
+     * @return a JSON string representing the specified value
+     */
     public String toJSONString(ByteBuffer buffer, int protocolVersion)
     {
         return '"' + getSerializer().deserialize(buffer).toString() + '"';

http://git-wip-us.apache.org/repos/asf/cassandra/blob/cb6fad3e/src/java/org/apache/cassandra/db/marshal/EmptyType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/EmptyType.java 
b/src/java/org/apache/cassandra/db/marshal/EmptyType.java
index f82d767..e5abe5b 100644
--- a/src/java/org/apache/cassandra/db/marshal/EmptyType.java
+++ b/src/java/org/apache/cassandra/db/marshal/EmptyType.java
@@ -65,6 +65,12 @@ public class EmptyType extends AbstractType<Void>
         return new Constants.Value(ByteBufferUtil.EMPTY_BYTE_BUFFER);
     }
 
+    @Override
+    public String toJSONString(ByteBuffer buffer, int protocolVersion)
+    {
+        return "\"\"";
+    }
+
     public TypeSerializer<Void> getSerializer()
     {
         return EmptySerializer.instance;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/cb6fad3e/src/java/org/apache/cassandra/db/marshal/ListType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/ListType.java 
b/src/java/org/apache/cassandra/db/marshal/ListType.java
index 9334ad0..ed44616 100644
--- a/src/java/org/apache/cassandra/db/marshal/ListType.java
+++ b/src/java/org/apache/cassandra/db/marshal/ListType.java
@@ -208,13 +208,14 @@ public class ListType<T> extends CollectionType<List<T>>
 
     public static String setOrListToJsonString(ByteBuffer buffer, AbstractType 
elementsType, int protocolVersion)
     {
+        ByteBuffer value = buffer.duplicate();
         StringBuilder sb = new StringBuilder("[");
-        int size = CollectionSerializer.readCollectionSize(buffer, 
protocolVersion);
+        int size = CollectionSerializer.readCollectionSize(value, 
protocolVersion);
         for (int i = 0; i < size; i++)
         {
             if (i > 0)
                 sb.append(", ");
-            
sb.append(elementsType.toJSONString(CollectionSerializer.readValue(buffer, 
protocolVersion), protocolVersion));
+            
sb.append(elementsType.toJSONString(CollectionSerializer.readValue(value, 
protocolVersion), protocolVersion));
         }
         return sb.append("]").toString();
     }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/cb6fad3e/src/java/org/apache/cassandra/db/marshal/MapType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/MapType.java 
b/src/java/org/apache/cassandra/db/marshal/MapType.java
index 434702a..c7267cf 100644
--- a/src/java/org/apache/cassandra/db/marshal/MapType.java
+++ b/src/java/org/apache/cassandra/db/marshal/MapType.java
@@ -232,22 +232,23 @@ public class MapType<K, V> extends CollectionType<Map<K, 
V>>
     @Override
     public String toJSONString(ByteBuffer buffer, int protocolVersion)
     {
+        ByteBuffer value = buffer.duplicate();
         StringBuilder sb = new StringBuilder("{");
-        int size = CollectionSerializer.readCollectionSize(buffer, 
protocolVersion);
+        int size = CollectionSerializer.readCollectionSize(value, 
protocolVersion);
         for (int i = 0; i < size; i++)
         {
             if (i > 0)
                 sb.append(", ");
 
             // map keys must be JSON strings, so convert non-string keys to 
strings
-            String key = 
keys.toJSONString(CollectionSerializer.readValue(buffer, protocolVersion), 
protocolVersion);
+            String key = 
keys.toJSONString(CollectionSerializer.readValue(value, protocolVersion), 
protocolVersion);
             if (key.startsWith("\""))
                 sb.append(key);
             else
                 sb.append('"').append(Json.quoteAsJsonString(key)).append('"');
 
             sb.append(": ");
-            
sb.append(values.toJSONString(CollectionSerializer.readValue(buffer, 
protocolVersion), protocolVersion));
+            
sb.append(values.toJSONString(CollectionSerializer.readValue(value, 
protocolVersion), protocolVersion));
         }
         return sb.append("}").toString();
     }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/cb6fad3e/src/java/org/apache/cassandra/db/marshal/TupleType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/TupleType.java 
b/src/java/org/apache/cassandra/db/marshal/TupleType.java
index bf7eae4..f3600ef 100644
--- a/src/java/org/apache/cassandra/db/marshal/TupleType.java
+++ b/src/java/org/apache/cassandra/db/marshal/TupleType.java
@@ -261,13 +261,14 @@ public class TupleType extends AbstractType<ByteBuffer>
     @Override
     public String toJSONString(ByteBuffer buffer, int protocolVersion)
     {
+        ByteBuffer duplicated = buffer.duplicate();
         StringBuilder sb = new StringBuilder("[");
         for (int i = 0; i < types.size(); i++)
         {
             if (i > 0)
                 sb.append(", ");
 
-            ByteBuffer value = CollectionSerializer.readValue(buffer, 
protocolVersion);
+            ByteBuffer value = CollectionSerializer.readValue(duplicated, 
protocolVersion);
             if (value == null)
                 sb.append("null");
             else

http://git-wip-us.apache.org/repos/asf/cassandra/blob/cb6fad3e/test/unit/org/apache/cassandra/cql3/CQLTester.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/CQLTester.java 
b/test/unit/org/apache/cassandra/cql3/CQLTester.java
index 98b8e23..416a4b2 100644
--- a/test/unit/org/apache/cassandra/cql3/CQLTester.java
+++ b/test/unit/org/apache/cassandra/cql3/CQLTester.java
@@ -36,13 +36,10 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import static junit.framework.Assert.assertNotNull;
-import com.datastax.driver.core.Cluster;
-import com.datastax.driver.core.ColumnDefinitions;
-import com.datastax.driver.core.DataType;
-import com.datastax.driver.core.ProtocolVersion;
+
+import com.datastax.driver.core.*;
 import com.datastax.driver.core.ResultSet;
-import com.datastax.driver.core.Row;
-import com.datastax.driver.core.Session;
+
 import org.apache.cassandra.SchemaLoader;
 import org.apache.cassandra.concurrent.ScheduledExecutors;
 import org.apache.cassandra.config.CFMetaData;
@@ -557,6 +554,11 @@ public abstract class CQLTester
         return session[protocolVersion-1].execute(formatQuery(query), values);
     }
 
+    protected com.datastax.driver.core.ResultSet executeNetWithPaging(String 
query, int pageSize) throws Throwable
+    {
+        return sessionNet(maxProtocolVersion).execute(new 
SimpleStatement(formatQuery(query)).setFetchSize(pageSize));
+    }
+
     protected Session sessionNet(int protocolVersion)
     {
         requireNetwork();
@@ -663,6 +665,11 @@ public abstract class CQLTester
                                         rows.length>i ? "less" : "more", 
rows.length, i, protocolVersion), i == rows.length);
     }
 
+    protected void assertRowsNet(ResultSet result, Object[]... rows)
+    {
+        assertRowsNet(maxProtocolVersion, result, rows);
+    }
+
     protected void assertRows(UntypedResultSet result, Object[]... rows)
     {
         if (result == null)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/cb6fad3e/test/unit/org/apache/cassandra/cql3/validation/entities/JsonTest.java
----------------------------------------------------------------------
diff --git 
a/test/unit/org/apache/cassandra/cql3/validation/entities/JsonTest.java 
b/test/unit/org/apache/cassandra/cql3/validation/entities/JsonTest.java
index 6892e79..0f29928 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/entities/JsonTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/entities/JsonTest.java
@@ -17,10 +17,11 @@
  */
 package org.apache.cassandra.cql3.validation.entities;
 
-import org.apache.cassandra.config.DatabaseDescriptor;
 import org.apache.cassandra.cql3.Json;
-import org.apache.cassandra.cql3.CQLTester;
 import org.apache.cassandra.dht.ByteOrderedPartitioner;
+import org.apache.cassandra.config.DatabaseDescriptor;
+import org.apache.cassandra.cql3.CQLTester;
+
 import org.apache.cassandra.serializers.SimpleDateSerializer;
 import org.apache.cassandra.serializers.TimeSerializer;
 import org.apache.cassandra.utils.ByteBufferUtil;
@@ -34,11 +35,7 @@ import java.math.BigInteger;
 import java.net.InetAddress;
 import java.text.SimpleDateFormat;
 import java.util.*;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-
+import java.util.concurrent.*;
 import static org.junit.Assert.fail;
 
 public class JsonTest extends CQLTester
@@ -50,6 +47,157 @@ public class JsonTest extends CQLTester
     }
 
     @Test
+    public void testSelectJsonWithPagingWithFrozenTuple() throws Throwable
+    {
+        final UUID uuid = 
UUID.fromString("2dd2cd62-6af3-4cf6-96fc-91b9ab62eedc");
+        final Object partitionKey = tuple(uuid, 2);
+
+        createTable("CREATE TABLE %s (k1 FROZEN<TUPLE<uuid, int>>, c1 
frozen<tuple<uuid, int>>, value int, PRIMARY KEY (k1, c1))");
+
+        // prepare data
+        for (int i = 1; i < 5; i++)
+            execute("INSERT INTO %s (k1, c1, value) VALUES (?, ?, ?)", 
partitionKey, tuple(uuid, i), i);
+
+        for (int pageSize = 1; pageSize < 6; pageSize++)
+        {
+            // SELECT JSON
+            assertRowsNet(executeNetWithPaging("SELECT JSON * FROM %s", 
pageSize),
+                           row("{\"k1\": [\"" + uuid + "\", 2], \"c1\": [\"" + 
uuid + "\", 1], \"value\": 1}"),
+                           row("{\"k1\": [\"" + uuid + "\", 2], \"c1\": [\"" + 
uuid + "\", 2], \"value\": 2}"),
+                           row("{\"k1\": [\"" + uuid + "\", 2], \"c1\": [\"" + 
uuid + "\", 3], \"value\": 3}"),
+                           row("{\"k1\": [\"" + uuid + "\", 2], \"c1\": [\"" + 
uuid + "\", 4], \"value\": 4}"));
+
+            // SELECT toJson(column)
+            assertRowsNet(executeNetWithPaging("SELECT toJson(k1), toJson(c1), 
toJson(value) FROM %s", pageSize),
+                          row("[\"" + uuid + "\", 2]", "[\"" + uuid + "\", 
1]", "1"),
+                          row("[\"" + uuid + "\", 2]", "[\"" + uuid + "\", 
2]", "2"),
+                          row("[\"" + uuid + "\", 2]", "[\"" + uuid + "\", 
3]", "3"),
+                          row("[\"" + uuid + "\", 2]", "[\"" + uuid + "\", 
4]", "4"));
+        }
+    }
+
+    @Test
+    public void testSelectJsonWithPagingWithFrozenMap() throws Throwable
+    {
+        final UUID uuid = 
UUID.fromString("2dd2cd62-6af3-4cf6-96fc-91b9ab62eedc");
+        final Object partitionKey = map(1, tuple(uuid, 1), 2, tuple(uuid, 2));
+
+        createTable("CREATE TABLE %s (k1 FROZEN<map<int, tuple<uuid, int>>>, 
c1 frozen<tuple<uuid, int>>, value int, PRIMARY KEY (k1, c1))");
+
+        // prepare data
+        for (int i = 1; i < 5; i++)
+            execute("INSERT INTO %s (k1, c1, value) VALUES (?, ?, ?)", 
partitionKey, tuple(uuid, i), i);
+
+        for (int pageSize = 1; pageSize < 6; pageSize++)
+        {
+            // SELECT JSON
+            assertRowsNet(executeNetWithPaging("SELECT JSON * FROM %s", 
pageSize),
+                          row("{\"k1\": {\"1\": [\"" + uuid + "\", 1], \"2\": 
[\"" + uuid + "\", 2]}, \"c1\": [\"" + uuid + "\", 1], \"value\": 1}"),
+                          row("{\"k1\": {\"1\": [\"" + uuid + "\", 1], \"2\": 
[\"" + uuid + "\", 2]}, \"c1\": [\"" + uuid + "\", 2], \"value\": 2}"),
+                          row("{\"k1\": {\"1\": [\"" + uuid + "\", 1], \"2\": 
[\"" + uuid + "\", 2]}, \"c1\": [\"" + uuid + "\", 3], \"value\": 3}"),
+                          row("{\"k1\": {\"1\": [\"" + uuid + "\", 1], \"2\": 
[\"" + uuid + "\", 2]}, \"c1\": [\"" + uuid + "\", 4], \"value\": 4}"));
+
+            // SELECT toJson(column)
+            assertRowsNet(executeNetWithPaging("SELECT toJson(k1), toJson(c1), 
toJson(value) FROM %s", pageSize),
+                          row("{\"1\": [\"" + uuid + "\", 1], \"2\": [\"" + 
uuid + "\", 2]}", "[\"" + uuid + "\", 1]", "1"),
+                          row("{\"1\": [\"" + uuid + "\", 1], \"2\": [\"" + 
uuid + "\", 2]}", "[\"" + uuid + "\", 2]", "2"),
+                          row("{\"1\": [\"" + uuid + "\", 1], \"2\": [\"" + 
uuid + "\", 2]}", "[\"" + uuid + "\", 3]", "3"),
+                          row("{\"1\": [\"" + uuid + "\", 1], \"2\": [\"" + 
uuid + "\", 2]}", "[\"" + uuid + "\", 4]", "4"));
+        }
+    }
+
+    @Test
+    public void testSelectJsonWithPagingWithFrozenSet() throws Throwable
+    {
+        final UUID uuid = 
UUID.fromString("2dd2cd62-6af3-4cf6-96fc-91b9ab62eedc");
+        final Object partitionKey = set(tuple(list(1, 2), 1), tuple(list(2, 
3), 2));
+
+        createTable("CREATE TABLE %s (k1 frozen<set<tuple<list<int>, int>>>, 
c1 frozen<tuple<uuid, int>>, value int, PRIMARY KEY (k1, c1))");
+
+        // prepare data
+        for (int i = 1; i < 5; i++)
+            execute("INSERT INTO %s (k1, c1, value) VALUES (?, ?, ?)", 
partitionKey, tuple(uuid, i), i);
+
+        for (int pageSize = 1; pageSize < 6; pageSize++)
+        {
+            // SELECT JSON
+            assertRowsNet(executeNetWithPaging("SELECT JSON * FROM %s", 
pageSize),
+                          row("{\"k1\": [[[1, 2], 1], [[2, 3], 2]], \"c1\": 
[\"" + uuid + "\", 1], \"value\": 1}"),
+                          row("{\"k1\": [[[1, 2], 1], [[2, 3], 2]], \"c1\": 
[\"" + uuid + "\", 2], \"value\": 2}"),
+                          row("{\"k1\": [[[1, 2], 1], [[2, 3], 2]], \"c1\": 
[\"" + uuid + "\", 3], \"value\": 3}"),
+                          row("{\"k1\": [[[1, 2], 1], [[2, 3], 2]], \"c1\": 
[\"" + uuid + "\", 4], \"value\": 4}"));
+
+            // SELECT toJson(column)
+            assertRowsNet(executeNetWithPaging("SELECT toJson(k1), toJson(c1), 
toJson(value) FROM %s", pageSize),
+                          row("[[[1, 2], 1], [[2, 3], 2]]", "[\"" + uuid + 
"\", 1]", "1"),
+                          row("[[[1, 2], 1], [[2, 3], 2]]", "[\"" + uuid + 
"\", 2]", "2"),
+                          row("[[[1, 2], 1], [[2, 3], 2]]", "[\"" + uuid + 
"\", 3]", "3"),
+                          row("[[[1, 2], 1], [[2, 3], 2]]", "[\"" + uuid + 
"\", 4]", "4"));
+        }
+    }
+
+    @Test
+    public void testSelectJsonWithPagingWithFrozenList() throws Throwable
+    {
+        final UUID uuid = 
UUID.fromString("2dd2cd62-6af3-4cf6-96fc-91b9ab62eedc");
+        final Object partitionKey = list(tuple(uuid, 2), tuple(uuid, 3));
+
+        createTable("CREATE TABLE %s (k1 frozen<list<tuple<uuid, int>>>, c1 
frozen<tuple<uuid, int>>, value int, PRIMARY KEY (k1, c1))");
+
+        // prepare data
+        for (int i = 1; i < 5; i++)
+            execute("INSERT INTO %s (k1, c1, value) VALUES (?, ?, ?)", 
partitionKey, tuple(uuid, i), i);
+
+        for (int pageSize = 1; pageSize < 6; pageSize++)
+        {
+        // SELECT JSON
+        assertRowsNet(executeNetWithPaging("SELECT JSON * FROM %s", pageSize),
+                      row("{\"k1\": [[\"" + uuid + "\", 2], [\"" + uuid + "\", 
3]], \"c1\": [\"" + uuid + "\", 1], \"value\": 1}"),
+                      row("{\"k1\": [[\"" + uuid + "\", 2], [\"" + uuid + "\", 
3]], \"c1\": [\"" + uuid + "\", 2], \"value\": 2}"),
+                      row("{\"k1\": [[\"" + uuid + "\", 2], [\"" + uuid + "\", 
3]], \"c1\": [\"" + uuid + "\", 3], \"value\": 3}"),
+                      row("{\"k1\": [[\"" + uuid + "\", 2], [\"" + uuid + "\", 
3]], \"c1\": [\"" + uuid + "\", 4], \"value\": 4}"));
+
+        // SELECT toJson(column)
+        assertRowsNet(executeNetWithPaging("SELECT toJson(k1), toJson(c1), 
toJson(value) FROM %s", pageSize),
+                      row("[[\"" + uuid + "\", 2], [\"" + uuid + "\", 3]]", 
"[\"" + uuid + "\", 1]", "1"),
+                      row("[[\"" + uuid + "\", 2], [\"" + uuid + "\", 3]]", 
"[\"" + uuid + "\", 2]", "2"),
+                      row("[[\"" + uuid + "\", 2], [\"" + uuid + "\", 3]]", 
"[\"" + uuid + "\", 3]", "3"),
+                      row("[[\"" + uuid + "\", 2], [\"" + uuid + "\", 3]]", 
"[\"" + uuid + "\", 4]", "4"));
+        }
+    }
+
+    @Test
+    public void testSelectJsonWithPagingWithFrozenUDT() throws Throwable
+    {
+        final UUID uuid = 
UUID.fromString("2dd2cd62-6af3-4cf6-96fc-91b9ab62eedc");
+        final Object partitionKey = userType(1, 2, list("1", "2"));
+
+        String typeName = createType("CREATE TYPE %s (a int, b int, c 
list<text>)");
+        createTable("CREATE TABLE %s (k1 frozen<" + typeName + ">, c1 
frozen<tuple<uuid, int>>, value int, PRIMARY KEY (k1, c1))");
+
+        // prepare data
+        for (int i = 1; i < 5; i++)
+        execute("INSERT INTO %s (k1, c1, value) VALUES (?, ?, ?)", 
partitionKey, tuple(uuid, i), i);
+
+        for (int pageSize = 1; pageSize < 6; pageSize++)
+        {
+            // SELECT JSON
+            assertRowsNet(executeNetWithPaging("SELECT JSON * FROM %s", 
pageSize),
+                          row("{\"k1\": {\"a\": 1, \"b\": 2, \"c\": [\"1\", 
\"2\"]}, \"c1\": [\"" + uuid + "\", 1], \"value\": 1}"),
+                          row("{\"k1\": {\"a\": 1, \"b\": 2, \"c\": [\"1\", 
\"2\"]}, \"c1\": [\"" + uuid + "\", 2], \"value\": 2}"),
+                          row("{\"k1\": {\"a\": 1, \"b\": 2, \"c\": [\"1\", 
\"2\"]}, \"c1\": [\"" + uuid + "\", 3], \"value\": 3}"),
+                          row("{\"k1\": {\"a\": 1, \"b\": 2, \"c\": [\"1\", 
\"2\"]}, \"c1\": [\"" + uuid + "\", 4], \"value\": 4}"));
+
+            // SELECT toJson(column)
+            assertRowsNet(executeNetWithPaging("SELECT toJson(k1), toJson(c1), 
toJson(value) FROM %s", pageSize),
+                          row("{\"a\": 1, \"b\": 2, \"c\": [\"1\", \"2\"]}", 
"[\"" + uuid + "\", 1]", "1"),
+                          row("{\"a\": 1, \"b\": 2, \"c\": [\"1\", \"2\"]}", 
"[\"" + uuid + "\", 2]", "2"),
+                          row("{\"a\": 1, \"b\": 2, \"c\": [\"1\", \"2\"]}", 
"[\"" + uuid + "\", 3]", "3"),
+                          row("{\"a\": 1, \"b\": 2, \"c\": [\"1\", \"2\"]}", 
"[\"" + uuid + "\", 4]", "4"));
+        }
+    }
+
+    @Test
     public void testFromJsonFct() throws Throwable
     {
         String typeName = createType("CREATE TYPE %s (a int, b uuid, c 
set<text>)");
@@ -679,10 +827,13 @@ public class JsonTest extends CQLTester
         execute("INSERT INTO %s (k, textval) VALUES (?, ?)", 0, "\u0000");
         assertRows(execute("SELECT k, toJson(textval) FROM %s WHERE k = ?", 
0), row(0, "\"\\u0000\""));
 
-        // ================ timestamp ================
+        // ================ time ================
         execute("INSERT INTO %s (k, timeval) VALUES (?, ?)", 0, 123L);
         assertRows(execute("SELECT k, toJson(timeval) FROM %s WHERE k = ?", 
0), row(0, "\"00:00:00.000000123\""));
 
+        execute("INSERT INTO %s (k, timeval) VALUES (?, fromJson(?))", 0, 
"\"07:35:07.000111222\"");
+        assertRows(execute("SELECT k, toJson(timeval) FROM %s WHERE k = ?", 
0), row(0, "\"07:35:07.000111222\""));
+
         // ================ timestamp ================
         SimpleDateFormat sdf = new SimpleDateFormat("y-M-d");
         sdf.setTimeZone(TimeZone.getTimeZone("UDT"));

http://git-wip-us.apache.org/repos/asf/cassandra/blob/cb6fad3e/test/unit/org/apache/cassandra/db/marshal/JsonConversionTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/db/marshal/JsonConversionTest.java 
b/test/unit/org/apache/cassandra/db/marshal/JsonConversionTest.java
new file mode 100644
index 0000000..f7795c7
--- /dev/null
+++ b/test/unit/org/apache/cassandra/db/marshal/JsonConversionTest.java
@@ -0,0 +1,320 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements.  See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership.  The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License.  You may obtain a copy of the License at
+*
+*    http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied.  See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+package org.apache.cassandra.db.marshal;
+
+import static org.junit.Assert.assertEquals;
+
+import java.nio.ByteBuffer;
+import org.apache.cassandra.cql3.QueryOptions;
+import org.apache.cassandra.transport.Server;
+import org.apache.cassandra.utils.UUIDGen;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.junit.Test;
+
+public class JsonConversionTest
+{
+    private static final ObjectMapper JSON_OBJECT_MAPPER = new ObjectMapper();
+
+    @Test
+    public void testMap() throws Exception
+    {
+        String type = "FrozenType(MapType(TupleType(ListType(Int32Type), 
ListType(Int32Type)), ListType(Int32Type)))";
+        String json = "{"
+                + "\"[[1, 2, 3], [1, 2, 3]]\": [1, 2, 3], "
+                + "\"[[1, 2, 3, 4], [1, 2, 3, 4]]\": [1, 2, 3, 4], "
+                + "\"[[1, 2, 3, 4, 5], [1, 2, 3, 4, 5]]\": [1, 2, 3, 4, 5]"
+                + "}";
+        assertBytebufferPositionAndOutput(json, type);
+    }
+
+    @Test
+    public void testUDT() throws Exception
+    {
+        // 6161-> aa
+        // 78 -> x
+        String type = "UserType(ks,6161,78:TupleType(ListType(Int32Type), 
ListType(Int32Type)))";
+        String json = "{"
+                + "\"x\": [[1, 2, 3], [1, 2, 3]]"
+                + "}";
+        assertBytebufferPositionAndOutput(json, type);
+    }
+
+    @Test
+    public void testSimpleDate() throws Exception
+    {
+        String type = "SimpleDateType";
+        String json = "\"1991-06-20\"";
+        assertBytebufferPositionAndOutput(json, type);
+    }
+
+    @Test
+    public void testDate() throws Exception
+    {
+        String type = "DateType";
+        String json = "\"1991-06-20 18:00:00.000Z\"";
+        assertBytebufferPositionAndOutput(json, type);
+    }
+
+    @Test
+    public void testCounterColumn() throws Exception
+    {
+        Long value = 1L;
+        String json = "1";
+        assertBytebufferPositionAndOutput(json, value, 
CounterColumnType.instance);
+    }
+
+    @Test
+    public void testTimestamp() throws Exception
+    {
+        String type = "TimestampType";
+        String json = "\"1991-06-20 18:00:00.000Z\"";
+        assertBytebufferPositionAndOutput(json, type);
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testDynamicCompositeType() throws Exception
+    {
+        String type = "DynamicCompositeType(a=>Int32Type, b=>Int32Type)";
+        // not supported
+        String json = "{"
+                + "\"a\":1,"
+                + "\"b\":2"
+                + "}";
+        assertBytebufferPositionAndOutput(json, type);
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testCompositeType() throws Exception
+    {
+        String type = "CompositeType(Int32Type, Int32Type)";
+        // not supported
+        String json = "{"
+                + "\"a\":1,"
+                + "\"b\":2"
+                + "}";
+        assertBytebufferPositionAndOutput(json, type);
+    }
+
+    @Test
+    public void testList() throws Exception
+    {
+        String type = "FrozenType(ListType(TupleType(ListType(Int32Type), 
ListType(Int32Type))))";
+        String json = "["
+                + "[[1, 2, 3], [1, 2, 3]], "
+                + "[[1, 2, 3, 4], [1, 2, 3, 4]], "
+                + "[[1, 2, 3, 4, 5], [1, 2, 3, 4, 5]]"
+                + "]";
+        assertBytebufferPositionAndOutput(json, type);
+    }
+
+    @Test
+    public void testSet() throws Exception
+    {
+        String type = "FrozenType(SetType(TupleType(Int32Type, Int32Type)))";
+        String json = "[[1, 2], [1, 3], [2, 3]]";
+        assertBytebufferPositionAndOutput(json, type);
+    }
+
+    @Test
+    public void testTuple() throws Exception
+    {
+        String type = "FrozenType(TupleType(TupleType(ListType(Int32Type), 
ListType(Int32Type))))";
+        String json = "["
+                + "[[1, 2, 3], [1, 2, 3]]"
+                + "]";
+        assertBytebufferPositionAndOutput(json, type);
+    }
+
+    @Test
+    public void testInt32() throws Exception
+    {
+        String type = "Int32Type";
+        String json = "10000000";
+        assertBytebufferPositionAndOutput(json, type);
+    }
+
+    @Test
+    public void testReversed() throws Exception
+    {
+        String type = "ReversedType(Int32Type)";
+        String json = "10000000";
+        assertBytebufferPositionAndOutput(json, type);
+    }
+
+    @Test
+    public void testInteger() throws Exception
+    {
+        String type = "IntegerType";
+        String json = "10000000";
+        assertBytebufferPositionAndOutput(json, type);
+    }
+
+    @Test
+    public void testDecimal() throws Exception
+    {
+        String type = "DecimalType";
+        String json = "100000.01";
+        assertBytebufferPositionAndOutput(json, type);
+    }
+
+    @Test
+    public void testEmpty() throws Exception
+    {
+        String type = "EmptyType";
+        String json = "\"\"";
+        assertBytebufferPositionAndOutput(json, type);
+    }
+
+    @Test
+    public void testDouble() throws Exception
+    {
+        String type = "DoubleType";
+        String json = "100000.01";
+        assertBytebufferPositionAndOutput(json, type);
+    }
+
+    @Test
+    public void testFloat() throws Exception
+    {
+        String type = "FloatType";
+        String json = "100000.01";
+        assertBytebufferPositionAndOutput(json, type);
+    }
+
+    @Test
+    public void testShort() throws Exception
+    {
+        String type = "ShortType";
+        String json = "100";
+        assertBytebufferPositionAndOutput(json, type);
+    }
+
+    @Test
+    public void testByte() throws Exception
+    {
+        String type = "ByteType";
+        String json = "0";
+        assertBytebufferPositionAndOutput(json, type);
+    }
+
+    @Test
+    public void testTime() throws Exception
+    {
+        String type = "TimeType";
+        String json = "\"00:00:00.000001991\"";
+        assertBytebufferPositionAndOutput(json, type);
+    }
+
+    @Test
+    public void testInetAddress() throws Exception
+    {
+        String type = "InetAddressType";
+        String json = "\"127.0.0.1\"";
+        assertBytebufferPositionAndOutput(json, type);
+    }
+
+    @Test
+    public void testBoolean() throws Exception
+    {
+        String type = "BooleanType";
+        String json = "false";
+        assertBytebufferPositionAndOutput(json, type);
+    }
+
+    @Test
+    public void testLong() throws Exception
+    {
+        String type = "LongType";
+        String json = "10000000000";
+        assertBytebufferPositionAndOutput(json, type);
+    }
+
+    @Test
+    public void testAscii() throws Exception
+    {
+        String type = "AsciiType";
+        String json = "\"aaa\"";
+        assertBytebufferPositionAndOutput(json, type);
+    }
+
+    @Test
+    public void testBytes() throws Exception
+    {
+        String type = "BytesType";
+        String json = "\"0x00000001\"";
+        assertBytebufferPositionAndOutput(json, type);
+    }
+
+    @Test
+    public void testUUID() throws Exception
+    {
+        String type = "UUIDType";
+        String json = "\"6bddc89a-5644-11e4-97fc-56847afe9799\"";
+        assertBytebufferPositionAndOutput(json, type);
+    }
+
+    @Test
+    public void testLexicalUUID() throws Exception
+    {
+        String type = "LexicalUUIDType";
+        String json = "\"6bddc89a-5644-11e4-97fc-56847afe9799\"";
+        assertBytebufferPositionAndOutput(json, type);
+    }
+
+    @Test
+    public void testTimeUUID() throws Exception
+    {
+        String type = "TimeUUIDType";
+        String json = "\"" + UUIDGen.getTimeUUID() + "\"";
+        assertBytebufferPositionAndOutput(json, type);
+    }
+
+    @Test
+    public void testUtf8() throws Exception
+    {
+        String type = "UTF8Type";
+        String json = "\"abc\"";
+        assertBytebufferPositionAndOutput(json, type);
+    }
+
+    // for those only supports toJson, eg. Counter
+    private static <T> void assertBytebufferPositionAndOutput(String json, T 
value, AbstractType<T> type)
+            throws Exception
+    {
+        ByteBuffer bb = type.getSerializer().serialize(value);
+        int position = bb.position();
+
+        String output = type.toJSONString(bb, Server.CURRENT_VERSION);
+        assertEquals(position, bb.position());
+        assertEquals(json, output);
+    }
+
+    // test fromJSONObject and toJSONString
+    private static void assertBytebufferPositionAndOutput(String json, String 
typeString) throws Exception
+    {
+        AbstractType<?> type = TypeParser.parse(typeString);
+        Object jsonObject = JSON_OBJECT_MAPPER.readValue(json, Object.class);
+        ByteBuffer bb = 
type.fromJSONObject(jsonObject).bindAndGet(QueryOptions.DEFAULT);
+        int position = bb.position();
+
+        String output = type.toJSONString(bb, Server.CURRENT_VERSION);
+        assertEquals(position, bb.position());
+        assertEquals(json, output);
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org
For additional commands, e-mail: commits-h...@cassandra.apache.org

Reply via email to