From dc8a017c7909abc4086ecbb0540c75c88991ab73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Rychlik?= Date: Thu, 4 Aug 2016 12:22:24 -0500 Subject: [PATCH] JSON support for smallint, tinyint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Patch by Paweł Rychlik; reviewed by Tyler Hobbs for CASSANDRA-12371 --- CHANGES.txt | 1 + .../apache/cassandra/db/marshal/ByteType.java | 19 +---- .../cassandra/db/marshal/ShortType.java | 19 +---- .../cql3/validation/entities/JsonTest.java | 76 +++++++++++++++++++ 4 files changed, 85 insertions(+), 30 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 67c79de8c7..5ac79cf399 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 2.2.8 + * Fix INSERT JSON, fromJson() support of smallint, tinyint types (CASSANDRA-12371) * Restore JVM metric export for metric reporters (CASSANDRA-12312) * Release sstables of failed stream sessions only when outgoing transfers are finished (CASSANDRA-11345) * Revert CASSANDRA-11427 (CASSANDRA-12351) diff --git a/src/java/org/apache/cassandra/db/marshal/ByteType.java b/src/java/org/apache/cassandra/db/marshal/ByteType.java index b63b92eda1..e1cacc3287 100644 --- a/src/java/org/apache/cassandra/db/marshal/ByteType.java +++ b/src/java/org/apache/cassandra/db/marshal/ByteType.java @@ -62,22 +62,11 @@ public class ByteType extends AbstractType public Term fromJSONObject(Object parsed) throws MarshalException { - try - { - if (parsed instanceof String) - return new Constants.Value(fromString((String) parsed)); + if (parsed instanceof String || parsed instanceof Number) + return new Constants.Value(fromString(String.valueOf(parsed))); - Number parsedNumber = (Number) parsed; - if (!(parsedNumber instanceof Byte)) - throw new MarshalException(String.format("Expected a byte value, but got a %s: %s", parsed.getClass().getSimpleName(), parsed)); - - return new Constants.Value(getSerializer().serialize(parsedNumber.byteValue())); - } - catch (ClassCastException exc) - { - throw new MarshalException(String.format( - "Expected a byte value, but got a %s: %s", parsed.getClass().getSimpleName(), parsed)); - } + throw new MarshalException(String.format( + "Expected a byte value, but got a %s: %s", parsed.getClass().getSimpleName(), parsed)); } @Override diff --git a/src/java/org/apache/cassandra/db/marshal/ShortType.java b/src/java/org/apache/cassandra/db/marshal/ShortType.java index 43e8f5ebce..2f9ec57845 100644 --- a/src/java/org/apache/cassandra/db/marshal/ShortType.java +++ b/src/java/org/apache/cassandra/db/marshal/ShortType.java @@ -66,22 +66,11 @@ public class ShortType extends AbstractType public Term fromJSONObject(Object parsed) throws MarshalException { - try - { - if (parsed instanceof String) - return new Constants.Value(fromString((String) parsed)); + if (parsed instanceof String || parsed instanceof Number) + return new Constants.Value(fromString(String.valueOf(parsed))); - Number parsedNumber = (Number) parsed; - if (!(parsedNumber instanceof Short)) - throw new MarshalException(String.format("Expected a short value, but got a %s: %s", parsed.getClass().getSimpleName(), parsed)); - - return new Constants.Value(getSerializer().serialize(parsedNumber.shortValue())); - } - catch (ClassCastException exc) - { - throw new MarshalException(String.format( - "Expected a short value, but got a %s: %s", parsed.getClass().getSimpleName(), parsed)); - } + throw new MarshalException(String.format( + "Expected a short value, but got a %s: %s", parsed.getClass().getSimpleName(), parsed)); } @Override 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 4f49c3bdde..6892e79400 100644 --- a/test/unit/org/apache/cassandra/cql3/validation/entities/JsonTest.java +++ b/test/unit/org/apache/cassandra/cql3/validation/entities/JsonTest.java @@ -65,10 +65,12 @@ public class JsonTest extends CQLTester "floatval float, " + "inetval inet, " + "intval int, " + + "smallintval smallint, " + "textval text, " + "timeval time, " + "timestampval timestamp, " + "timeuuidval timeuuid, " + + "tinyintval tinyint, " + "uuidval uuid," + "varcharval varchar, " + "varintval varint, " + @@ -268,6 +270,48 @@ public class JsonTest extends CQLTester assertInvalidMessage("Expected an int value, but got a", "INSERT INTO %s (k, intval) VALUES (?, fromJson(?))", 0, "true"); + // ================ smallint ================ + execute("INSERT INTO %s (k, smallintval) VALUES (?, fromJson(?))", 0, "32767"); + assertRows(execute("SELECT k, smallintval FROM %s WHERE k = ?", 0), row(0, (short) 32767)); + + // strings are also accepted + execute("INSERT INTO %s (k, smallintval) VALUES (?, fromJson(?))", 0, "\"32767\""); + assertRows(execute("SELECT k, smallintval FROM %s WHERE k = ?", 0), row(0, (short) 32767)); + + // smallint overflow (Short.MAX_VALUE + 1) + assertInvalidMessage("Unable to make short from", + "INSERT INTO %s (k, smallintval) VALUES (?, fromJson(?))", 0, "32768"); + + assertInvalidMessage("Unable to make short from", + "INSERT INTO %s (k, smallintval) VALUES (?, fromJson(?))", 0, "123.456"); + + assertInvalidMessage("Unable to make short from", + "INSERT INTO %s (k, smallintval) VALUES (?, fromJson(?))", 0, "\"xyzz\""); + + assertInvalidMessage("Expected a short value, but got a Boolean", + "INSERT INTO %s (k, smallintval) VALUES (?, fromJson(?))", 0, "true"); + + // ================ tinyint ================ + execute("INSERT INTO %s (k, tinyintval) VALUES (?, fromJson(?))", 0, "127"); + assertRows(execute("SELECT k, tinyintval FROM %s WHERE k = ?", 0), row(0, (byte) 127)); + + // strings are also accepted + execute("INSERT INTO %s (k, tinyintval) VALUES (?, fromJson(?))", 0, "\"127\""); + assertRows(execute("SELECT k, tinyintval FROM %s WHERE k = ?", 0), row(0, (byte) 127)); + + // tinyint overflow (Byte.MAX_VALUE + 1) + assertInvalidMessage("Unable to make byte from", + "INSERT INTO %s (k, tinyintval) VALUES (?, fromJson(?))", 0, "128"); + + assertInvalidMessage("Unable to make byte from", + "INSERT INTO %s (k, tinyintval) VALUES (?, fromJson(?))", 0, "123.456"); + + assertInvalidMessage("Unable to make byte from", + "INSERT INTO %s (k, tinyintval) VALUES (?, fromJson(?))", 0, "\"xyzz\""); + + assertInvalidMessage("Expected a byte value, but got a Boolean", + "INSERT INTO %s (k, tinyintval) VALUES (?, fromJson(?))", 0, "true"); + // ================ text (varchar) ================ execute("INSERT INTO %s (k, textval) VALUES (?, fromJson(?))", 0, "\"\""); assertRows(execute("SELECT k, textval FROM %s WHERE k = ?", 0), row(0, "")); @@ -503,10 +547,12 @@ public class JsonTest extends CQLTester "floatval float, " + "inetval inet, " + "intval int, " + + "smallintval smallint, " + "textval text, " + "timeval time, " + "timestampval timestamp, " + "timeuuidval timeuuid, " + + "tinyintval tinyint, " + "uuidval uuid," + "varcharval varchar, " + "varintval varint, " + @@ -600,6 +646,26 @@ public class JsonTest extends CQLTester execute("INSERT INTO %s (k, intval) VALUES (?, ?)", 0, -123123); assertRows(execute("SELECT k, toJson(intval) FROM %s WHERE k = ?", 0), row(0, "-123123")); + // ================ smallint ================ + execute("INSERT INTO %s (k, smallintval) VALUES (?, ?)", 0, (short) 32767); + assertRows(execute("SELECT k, toJson(smallintval) FROM %s WHERE k = ?", 0), row(0, "32767")); + + execute("INSERT INTO %s (k, smallintval) VALUES (?, ?)", 0, (short) 0); + assertRows(execute("SELECT k, toJson(smallintval) FROM %s WHERE k = ?", 0), row(0, "0")); + + execute("INSERT INTO %s (k, smallintval) VALUES (?, ?)", 0, (short) -32768); + assertRows(execute("SELECT k, toJson(smallintval) FROM %s WHERE k = ?", 0), row(0, "-32768")); + + // ================ tinyint ================ + execute("INSERT INTO %s (k, tinyintval) VALUES (?, ?)", 0, (byte) 127); + assertRows(execute("SELECT k, toJson(tinyintval) FROM %s WHERE k = ?", 0), row(0, "127")); + + execute("INSERT INTO %s (k, tinyintval) VALUES (?, ?)", 0, (byte) 0); + assertRows(execute("SELECT k, toJson(tinyintval) FROM %s WHERE k = ?", 0), row(0, "0")); + + execute("INSERT INTO %s (k, tinyintval) VALUES (?, ?)", 0, (byte) -128); + assertRows(execute("SELECT k, toJson(tinyintval) FROM %s WHERE k = ?", 0), row(0, "-128")); + // ================ text (varchar) ================ execute("INSERT INTO %s (k, textval) VALUES (?, ?)", 0, ""); assertRows(execute("SELECT k, toJson(textval) FROM %s WHERE k = ?", 0), row(0, "\"\"")); @@ -869,6 +935,8 @@ public class JsonTest extends CQLTester "intmap map, " + "bigintmap map, " + "varintmap map, " + + "smallintmap map, " + + "tinyintmap map, " + "booleanmap map, " + "floatmap map, " + "doublemap map, " + @@ -893,6 +961,14 @@ public class JsonTest extends CQLTester execute("INSERT INTO %s JSON ?", "{\"k\": 0, \"varintmap\": {\"0\": true, \"1\": false}}"); assertRows(execute("SELECT JSON k, varintmap FROM %s"), row("{\"k\": 0, \"varintmap\": {\"0\": true, \"1\": false}}")); + // smallint keys + execute("INSERT INTO %s JSON ?", "{\"k\": 0, \"smallintmap\": {\"0\": true, \"1\": false}}"); + assertRows(execute("SELECT JSON k, smallintmap FROM %s"), row("{\"k\": 0, \"smallintmap\": {\"0\": true, \"1\": false}}")); + + // tinyint keys + execute("INSERT INTO %s JSON ?", "{\"k\": 0, \"tinyintmap\": {\"0\": true, \"1\": false}}"); + assertRows(execute("SELECT JSON k, tinyintmap FROM %s"), row("{\"k\": 0, \"tinyintmap\": {\"0\": true, \"1\": false}}")); + // boolean keys execute("INSERT INTO %s JSON ?", "{\"k\": 0, \"booleanmap\": {\"true\": true, \"false\": false}}"); assertRows(execute("SELECT JSON k, booleanmap FROM %s"), row("{\"k\": 0, \"booleanmap\": {\"false\": false, \"true\": true}}"));