cassandra-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From alek...@apache.org
Subject cassandra git commit: Add smallint and tinyint data types
Date Fri, 15 May 2015 14:44:22 GMT
Repository: cassandra
Updated Branches:
  refs/heads/trunk e1e30fc5e -> 35a945e2b


Add smallint and tinyint data types

patch by Benjamin Lerer; reviewed by Aleksey Yeschenko for
CASSANDRA-8951


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

Branch: refs/heads/trunk
Commit: 35a945e2bf04437db0201c942000bdb98ef4ddef
Parents: e1e30fc
Author: Benjamin Lerer <benjamin.lerer@datastax.com>
Authored: Fri May 15 17:43:57 2015 +0300
Committer: Aleksey Yeschenko <aleksey@apache.org>
Committed: Fri May 15 17:43:57 2015 +0300

----------------------------------------------------------------------
 CHANGES.txt                                     |   1 +
 NEWS.txt                                        |   2 +
 doc/native_protocol_v4.spec                     |  49 +++++----
 .../org/apache/cassandra/cql3/CQL3Type.java     |   2 +
 .../org/apache/cassandra/cql3/Constants.java    |   2 +
 src/java/org/apache/cassandra/cql3/Cql.g        |   5 +-
 .../apache/cassandra/cql3/UntypedResultSet.java |  10 ++
 .../apache/cassandra/db/marshal/ByteType.java   | 100 ++++++++++++++++++
 .../apache/cassandra/db/marshal/ShortType.java  | 103 +++++++++++++++++++
 .../cassandra/serializers/ByteSerializer.java   |  54 ++++++++++
 .../cassandra/serializers/ShortSerializer.java  |  54 ++++++++++
 .../apache/cassandra/transport/DataType.java    |   3 +-
 .../apache/cassandra/utils/ByteBufferUtil.java  |  17 +++
 test/unit/org/apache/cassandra/Util.java        |  18 ++++
 .../org/apache/cassandra/cql3/CQLTester.java    |   6 ++
 .../apache/cassandra/cql3/CreateTableTest.java  |  37 +++++++
 .../cassandra/db/marshal/TypeCompareTest.java   |  42 ++++++++
 .../cassandra/db/marshal/TypeParserTest.java    |   6 ++
 .../db/marshal/TypeValidationTest.java          |  26 +++++
 19 files changed, 516 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/35a945e2/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index e71b8c2..87c3c6f 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 2.2
+ * Add `smallint` and `tinyint` data types (CASSANDRA-8951)
  * Avoid thrift schema creation when native driver is used in stress tool (CASSANDRA-9374)
  * Populate TokenMetadata early during startup (CASSANDRA-9317)
  * Make Functions.declared thread-safe

http://git-wip-us.apache.org/repos/asf/cassandra/blob/35a945e2/NEWS.txt
----------------------------------------------------------------------
diff --git a/NEWS.txt b/NEWS.txt
index c16b55a..4d77fa0 100644
--- a/NEWS.txt
+++ b/NEWS.txt
@@ -70,6 +70,8 @@ New features
      In a QUERY request an unset limit is treated as 'unlimited'.
      Unset WHERE clauses with unset partition column, clustering column
      or index column are not allowed.
+   - New `ByteType` (cql tinyint). 1-byte signed integer
+   - New `ShortType` (cql smallint). 2-byte signed integer
 
 
 Upgrading

http://git-wip-us.apache.org/repos/asf/cassandra/blob/35a945e2/doc/native_protocol_v4.spec
----------------------------------------------------------------------
diff --git a/doc/native_protocol_v4.spec b/doc/native_protocol_v4.spec
index 4014594..0f86989 100644
--- a/doc/native_protocol_v4.spec
+++ b/doc/native_protocol_v4.spec
@@ -598,6 +598,8 @@ Table of Contents
             0x0010    Inet
             0x0011    Date
             0x0012    Time
+            0x0013    Smallint
+            0x0014    Tinyint
             0x0020    List: the value is an [option], representing the type
                             of the elements of the list.
             0x0021    Map: the value is two [option], representing the types of the
@@ -888,25 +890,47 @@ Table of Contents
   A [int] n indicating the number of elements in the set, followed by n
   elements.  Each element is [bytes] representing the serialized value.
 
-6.13 text
+6.13 smallint
+
+  A two-byte two's complement integer.
+
+
+6.14 text
 
   A sequence of bytes conforming to the UTF-8 specifications.
 
-6.14 timestamp
+6.15 timestamp
 
   An eight-byte two's complement integer representing a millisecond-precision
   offset from the unix epoch (00:00:00, January 1st, 1970).  Negative values
   represent a negative offset from the epoch.
 
-6.15 uuid
+6.16 timeuuid
+
+  A 16 byte sequence representing a version 1 UUID as defined by RFC 4122.
+
+6.17 tinyint
+
+  A one-byte two's complement integer.
+
+6.18 tuple
+
+  A sequence of [bytes] values representing the items in a tuple.  The encoding
+  of each element depends on the data type for that position in the tuple.
+  Null values may be represented by using length -1 for the [bytes]
+  representation of an element.
+
+  Within a tuple, all data types should use the v3 protocol serialization format.
+
+6.19 uuid
 
   A 16 byte sequence representing any valid UUID as defined by RFC 4122.
 
-6.16 varchar
+6.20 varchar
 
   An alias of the "text" type.
 
-6.17 varint
+6.21 varint
 
   A variable-length two's complement encoding of a signed integer.
 
@@ -928,20 +952,6 @@ Table of Contents
   value.  Implementors should pad positive values that have a MSB >= 0x80
   with a leading 0x00 byte.
 
-6.18 timeuuid
-
-  A 16 byte sequence representing a version 1 UUID as defined by RFC 4122.
-
-6.19 tuple
-
-  A sequence of [bytes] values representing the items in a tuple.  The encoding
-  of each element depends on the data type for that position in the tuple.
-  Null values may be represented by using length -1 for the [bytes]
-  representation of an element.
-
-  Within a tuple, all data types should use the v3 protocol serialization format.
-
-
 7. User Defined Types
 
   This section describes the serialization format for User defined types (UDT),
@@ -1141,3 +1151,4 @@ Table of Contents
   * Add custom payload to frames for custom QueryHandler implementations (ignored by Cassandra's
standard QueryHandler)
   * Add "TRACE_COMPLETE" event (section 4.2.6).
   * Add warnings to frames for responses for which the server generated a warning during
processing, which the client needs to address.
+  * Add the tinyint and smallint data types

http://git-wip-us.apache.org/repos/asf/cassandra/blob/35a945e2/src/java/org/apache/cassandra/cql3/CQL3Type.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/CQL3Type.java b/src/java/org/apache/cassandra/cql3/CQL3Type.java
index 362f1f8..fb2716e 100644
--- a/src/java/org/apache/cassandra/cql3/CQL3Type.java
+++ b/src/java/org/apache/cassandra/cql3/CQL3Type.java
@@ -48,8 +48,10 @@ public interface CQL3Type
         FLOAT       (FloatType.instance),
         INET        (InetAddressType.instance),
         INT         (Int32Type.instance),
+        SMALLINT    (ShortType.instance),
         TEXT        (UTF8Type.instance),
         TIMESTAMP   (TimestampType.instance),
+        TINYINT     (ByteType.instance),
         UUID        (UUIDType.instance),
         VARCHAR     (UTF8Type.instance),
         VARINT      (IntegerType.instance),

http://git-wip-us.apache.org/repos/asf/cassandra/blob/35a945e2/src/java/org/apache/cassandra/cql3/Constants.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/Constants.java b/src/java/org/apache/cassandra/cql3/Constants.java
index a0eff94..07b848c 100644
--- a/src/java/org/apache/cassandra/cql3/Constants.java
+++ b/src/java/org/apache/cassandra/cql3/Constants.java
@@ -198,7 +198,9 @@ public abstract class Constants
                         case DOUBLE:
                         case FLOAT:
                         case INT:
+                        case SMALLINT:
                         case TIMESTAMP:
+                        case TINYINT:
                         case VARINT:
                             return AssignmentTestable.TestResult.WEAKLY_ASSIGNABLE;
                     }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/35a945e2/src/java/org/apache/cassandra/cql3/Cql.g
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/Cql.g b/src/java/org/apache/cassandra/cql3/Cql.g
index bd47825..831b012 100644
--- a/src/java/org/apache/cassandra/cql3/Cql.g
+++ b/src/java/org/apache/cassandra/cql3/Cql.g
@@ -56,7 +56,6 @@ options {
     public static final Set<String> reservedTypeNames = new HashSet<String>()
     {{
         add("byte");
-        add("smallint");
         add("complex");
         add("enum");
         add("date");
@@ -1453,8 +1452,10 @@ native_type returns [CQL3Type t]
     | K_FLOAT     { $t = CQL3Type.Native.FLOAT; }
     | K_INET      { $t = CQL3Type.Native.INET;}
     | K_INT       { $t = CQL3Type.Native.INT; }
+    | K_SMALLINT  { $t = CQL3Type.Native.SMALLINT; }
     | K_TEXT      { $t = CQL3Type.Native.TEXT; }
     | K_TIMESTAMP { $t = CQL3Type.Native.TIMESTAMP; }
+    | K_TINYINT   { $t = CQL3Type.Native.TINYINT; }
     | K_UUID      { $t = CQL3Type.Native.UUID; }
     | K_VARCHAR   { $t = CQL3Type.Native.VARCHAR; }
     | K_VARINT    { $t = CQL3Type.Native.VARINT; }
@@ -1643,6 +1644,8 @@ K_DOUBLE:      D O U B L E;
 K_FLOAT:       F L O A T;
 K_INET:        I N E T;
 K_INT:         I N T;
+K_SMALLINT:    S M A L L I N T;
+K_TINYINT:     T I N Y I N T;
 K_TEXT:        T E X T;
 K_UUID:        U U I D;
 K_VARCHAR:     V A R C H A R;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/35a945e2/src/java/org/apache/cassandra/cql3/UntypedResultSet.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/UntypedResultSet.java b/src/java/org/apache/cassandra/cql3/UntypedResultSet.java
index 072d3b7..bf3cbb5 100644
--- a/src/java/org/apache/cassandra/cql3/UntypedResultSet.java
+++ b/src/java/org/apache/cassandra/cql3/UntypedResultSet.java
@@ -229,6 +229,16 @@ public abstract class UntypedResultSet implements Iterable<UntypedResultSet.Row>
             return BooleanType.instance.compose(data.get(column));
         }
 
+        public byte getByte(String column)
+        {
+            return ByteType.instance.compose(data.get(column));
+        }
+
+        public short getShort(String column)
+        {
+            return ShortType.instance.compose(data.get(column));
+        }
+
         public int getInt(String column)
         {
             return Int32Type.instance.compose(data.get(column));

http://git-wip-us.apache.org/repos/asf/cassandra/blob/35a945e2/src/java/org/apache/cassandra/db/marshal/ByteType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/ByteType.java b/src/java/org/apache/cassandra/db/marshal/ByteType.java
new file mode 100644
index 0000000..b63b92e
--- /dev/null
+++ b/src/java/org/apache/cassandra/db/marshal/ByteType.java
@@ -0,0 +1,100 @@
+/*
+ * 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 java.nio.ByteBuffer;
+
+import org.apache.cassandra.cql3.CQL3Type;
+import org.apache.cassandra.cql3.Constants;
+import org.apache.cassandra.cql3.Term;
+import org.apache.cassandra.serializers.ByteSerializer;
+import org.apache.cassandra.serializers.MarshalException;
+import org.apache.cassandra.serializers.TypeSerializer;
+import org.apache.cassandra.utils.ByteBufferUtil;
+
+public class ByteType extends AbstractType<Byte>
+{
+    public static final ByteType instance = new ByteType();
+
+    ByteType()
+    {
+    } // singleton
+
+    public int compare(ByteBuffer o1, ByteBuffer o2)
+    {
+        return o1.get(o1.position()) - o2.get(o2.position());
+    }
+
+    public ByteBuffer fromString(String source) throws MarshalException
+    {
+        // Return an empty ByteBuffer for an empty string.
+        if (source.isEmpty())
+            return ByteBufferUtil.EMPTY_BYTE_BUFFER;
+
+        byte b;
+
+        try
+        {
+            b = Byte.parseByte(source);
+        }
+        catch (Exception e)
+        {
+            throw new MarshalException(String.format("Unable to make byte from '%s'", source),
e);
+        }
+
+        return decompose(b);
+    }
+
+    public Term fromJSONObject(Object parsed) throws MarshalException
+    {
+        try
+        {
+            if (parsed instanceof String)
+                return new Constants.Value(fromString((String) 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));
+        }
+    }
+
+    @Override
+    public String toJSONString(ByteBuffer buffer, int protocolVersion)
+    {
+        return getSerializer().deserialize(buffer).toString();
+    }
+
+    @Override
+    public CQL3Type asCQL3Type()
+    {
+        return CQL3Type.Native.TINYINT;
+    }
+
+    @Override
+    public TypeSerializer<Byte> getSerializer()
+    {
+        return ByteSerializer.instance;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/35a945e2/src/java/org/apache/cassandra/db/marshal/ShortType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/ShortType.java b/src/java/org/apache/cassandra/db/marshal/ShortType.java
new file mode 100644
index 0000000..43e8f5e
--- /dev/null
+++ b/src/java/org/apache/cassandra/db/marshal/ShortType.java
@@ -0,0 +1,103 @@
+/*
+ * 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 java.nio.ByteBuffer;
+
+import org.apache.cassandra.cql3.CQL3Type;
+import org.apache.cassandra.cql3.Constants;
+import org.apache.cassandra.cql3.Term;
+import org.apache.cassandra.serializers.MarshalException;
+import org.apache.cassandra.serializers.ShortSerializer;
+import org.apache.cassandra.serializers.TypeSerializer;
+import org.apache.cassandra.utils.ByteBufferUtil;
+
+public class ShortType extends AbstractType<Short>
+{
+    public static final ShortType instance = new ShortType();
+
+    ShortType()
+    {
+    } // singleton
+
+    public int compare(ByteBuffer o1, ByteBuffer o2)
+    {
+        int diff = o1.get(o1.position()) - o2.get(o2.position());
+        if (diff != 0)
+            return diff;
+
+        return ByteBufferUtil.compareUnsigned(o1, o2);
+    }
+
+    public ByteBuffer fromString(String source) throws MarshalException
+    {
+        // Return an empty ByteBuffer for an empty string.
+        if (source.isEmpty())
+            return ByteBufferUtil.EMPTY_BYTE_BUFFER;
+
+        short s;
+
+        try
+        {
+            s = Short.parseShort(source);
+        }
+        catch (Exception e)
+        {
+            throw new MarshalException(String.format("Unable to make short from '%s'", source),
e);
+        }
+
+        return decompose(s);
+    }
+
+    public Term fromJSONObject(Object parsed) throws MarshalException
+    {
+        try
+        {
+            if (parsed instanceof String)
+                return new Constants.Value(fromString((String) 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));
+        }
+    }
+
+    @Override
+    public String toJSONString(ByteBuffer buffer, int protocolVersion)
+    {
+        return getSerializer().deserialize(buffer).toString();
+    }
+
+    @Override
+    public CQL3Type asCQL3Type()
+    {
+        return CQL3Type.Native.SMALLINT;
+    }
+
+    public TypeSerializer<Short> getSerializer()
+    {
+        return ShortSerializer.instance;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/35a945e2/src/java/org/apache/cassandra/serializers/ByteSerializer.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/serializers/ByteSerializer.java b/src/java/org/apache/cassandra/serializers/ByteSerializer.java
new file mode 100644
index 0000000..8c736cb
--- /dev/null
+++ b/src/java/org/apache/cassandra/serializers/ByteSerializer.java
@@ -0,0 +1,54 @@
+/*
+ * 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.serializers;
+
+import org.apache.cassandra.utils.ByteBufferUtil;
+
+import java.nio.ByteBuffer;
+
+public class ByteSerializer implements TypeSerializer<Byte>
+{
+    public static final ByteSerializer instance = new ByteSerializer();
+
+    public Byte deserialize(ByteBuffer bytes)
+    {
+        return bytes.remaining() == 0 ? null : bytes.get(bytes.position());
+    }
+
+    public ByteBuffer serialize(Byte value)
+    {
+        return value == null ? ByteBufferUtil.EMPTY_BYTE_BUFFER : ByteBuffer.allocate(1).put(0,
value);
+    }
+
+    public void validate(ByteBuffer bytes) throws MarshalException
+    {
+        if (bytes.remaining() != 1)
+            throw new MarshalException(String.format("Expected 1 byte for a tinyint (%d)",
bytes.remaining()));
+    }
+
+    public String toString(Byte value)
+    {
+        return value == null ? "" : String.valueOf(value);
+    }
+
+    public Class<Byte> getType()
+    {
+        return Byte.class;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/35a945e2/src/java/org/apache/cassandra/serializers/ShortSerializer.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/serializers/ShortSerializer.java b/src/java/org/apache/cassandra/serializers/ShortSerializer.java
new file mode 100644
index 0000000..f12affa
--- /dev/null
+++ b/src/java/org/apache/cassandra/serializers/ShortSerializer.java
@@ -0,0 +1,54 @@
+/*
+ * 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.serializers;
+
+import org.apache.cassandra.utils.ByteBufferUtil;
+
+import java.nio.ByteBuffer;
+
+public class ShortSerializer implements TypeSerializer<Short>
+{
+    public static final ShortSerializer instance = new ShortSerializer();
+
+    public Short deserialize(ByteBuffer bytes)
+    {
+        return bytes.remaining() == 0 ? null : ByteBufferUtil.toShort(bytes);
+    }
+
+    public ByteBuffer serialize(Short value)
+    {
+        return value == null ? ByteBufferUtil.EMPTY_BYTE_BUFFER : ByteBufferUtil.bytes(value.shortValue());
+    }
+
+    public void validate(ByteBuffer bytes) throws MarshalException
+    {
+        if (bytes.remaining() != 2)
+            throw new MarshalException(String.format("Expected 2 bytes for a smallint (%d)",
bytes.remaining()));
+    }
+
+    public String toString(Short value)
+    {
+        return value == null ? "" : String.valueOf(value);
+    }
+
+    public Class<Short> getType()
+    {
+        return Short.class;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/35a945e2/src/java/org/apache/cassandra/transport/DataType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/transport/DataType.java b/src/java/org/apache/cassandra/transport/DataType.java
index a78b740..e3eaf32 100644
--- a/src/java/org/apache/cassandra/transport/DataType.java
+++ b/src/java/org/apache/cassandra/transport/DataType.java
@@ -53,13 +53,14 @@ public enum DataType implements OptionCodec.Codecable<DataType>
     INET     (16, InetAddressType.instance, 1),
     DATE     (17, SimpleDateType.instance, 4),
     TIME     (18, TimeType.instance, 4),
+    SMALLINT (19, ShortType.instance, 4),
+    BYTE     (20, ByteType.instance, 4),
     LIST     (32, null, 1),
     MAP      (33, null, 1),
     SET      (34, null, 1),
     UDT      (48, null, 3),
     TUPLE    (49, null, 3);
 
-
     public static final OptionCodec<DataType> codec = new OptionCodec<DataType>(DataType.class);
 
     private final int id;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/35a945e2/src/java/org/apache/cassandra/utils/ByteBufferUtil.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/utils/ByteBufferUtil.java b/src/java/org/apache/cassandra/utils/ByteBufferUtil.java
index 4fea55e..1831c19 100644
--- a/src/java/org/apache/cassandra/utils/ByteBufferUtil.java
+++ b/src/java/org/apache/cassandra/utils/ByteBufferUtil.java
@@ -383,6 +383,18 @@ public class ByteBufferUtil
         return bytes.getInt(bytes.position());
     }
 
+    /**
+     * Convert a byte buffer to a short.
+     * Does not change the byte buffer position.
+     *
+     * @param bytes byte buffer to convert to short
+     * @return short representation of the byte buffer
+     */
+    public static short toShort(ByteBuffer bytes)
+    {
+        return bytes.getShort(bytes.position());
+    }
+
     public static long toLong(ByteBuffer bytes)
     {
         return bytes.getLong(bytes.position());
@@ -398,6 +410,11 @@ public class ByteBufferUtil
         return bytes.getDouble(bytes.position());
     }
 
+    public static ByteBuffer bytes(short s)
+    {
+        return ByteBuffer.allocate(2).putShort(0, s);
+    }
+
     public static ByteBuffer bytes(int i)
     {
         return ByteBuffer.allocate(4).putInt(0, i);

http://git-wip-us.apache.org/repos/asf/cassandra/blob/35a945e2/test/unit/org/apache/cassandra/Util.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/Util.java b/test/unit/org/apache/cassandra/Util.java
index 4ebd0b5..9b8e5df 100644
--- a/test/unit/org/apache/cassandra/Util.java
+++ b/test/unit/org/apache/cassandra/Util.java
@@ -179,6 +179,24 @@ public class Util
         return bb;
     }
 
+    public static ByteBuffer getBytes(short v)
+    {
+        byte[] bytes = new byte[2];
+        ByteBuffer bb = ByteBuffer.wrap(bytes);
+        bb.putShort(v);
+        bb.rewind();
+        return bb;
+    }
+
+    public static ByteBuffer getBytes(byte v)
+    {
+        byte[] bytes = new byte[1];
+        ByteBuffer bb = ByteBuffer.wrap(bytes);
+        bb.put(v);
+        bb.rewind();
+        return bb;
+    }
+
     public static List<Row> getRangeSlice(ColumnFamilyStore cfs)
     {
         return getRangeSlice(cfs, null);

http://git-wip-us.apache.org/repos/asf/cassandra/blob/35a945e2/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 c318717..c37767c 100644
--- a/test/unit/org/apache/cassandra/cql3/CQLTester.java
+++ b/test/unit/org/apache/cassandra/cql3/CQLTester.java
@@ -1017,6 +1017,12 @@ public abstract class CQLTester
         if (value instanceof ByteBuffer || value instanceof TupleValue || value == null)
             return BytesType.instance;
 
+        if (value instanceof Byte)
+            return ByteType.instance;
+
+        if (value instanceof Short)
+            return ShortType.instance;
+
         if (value instanceof Integer)
             return Int32Type.instance;
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/35a945e2/test/unit/org/apache/cassandra/cql3/CreateTableTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/CreateTableTest.java b/test/unit/org/apache/cassandra/cql3/CreateTableTest.java
index 14d2c2b..d14e87b 100644
--- a/test/unit/org/apache/cassandra/cql3/CreateTableTest.java
+++ b/test/unit/org/apache/cassandra/cql3/CreateTableTest.java
@@ -19,6 +19,8 @@ package org.apache.cassandra.cql3;
 
 import org.junit.Test;
 
+import org.apache.cassandra.utils.ByteBufferUtil;
+
 import static junit.framework.Assert.assertFalse;
 
 public class CreateTableTest extends CQLTester
@@ -29,4 +31,39 @@ public class CreateTableTest extends CQLTester
         createTable("CREATE TABLE %s (id text PRIMARY KEY);");
         assertFalse(currentTableMetadata().isThriftCompatible());
     }
+
+    @Test
+    public void testCreateTableWithSmallintColumns() throws Throwable
+    {
+        createTable("CREATE TABLE %s (a text, b smallint, c smallint, primary key (a, b));");
+        execute("INSERT INTO %s (a, b, c) VALUES ('1', 1, 2)");
+        execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", "2", Short.MAX_VALUE, Short.MIN_VALUE);
+
+        assertRows(execute("SELECT * FROM %s"),
+                   row("1", (short) 1, (short) 2),
+                   row("2", Short.MAX_VALUE, Short.MIN_VALUE));
+
+        assertInvalidMessage("Expected 2 bytes for a smallint (4)",
+                             "INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", "3", 1, 2);
+        assertInvalidMessage("Expected 2 bytes for a smallint (0)",
+                             "INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", "3", (short) 1,
ByteBufferUtil.EMPTY_BYTE_BUFFER);
+     }
+
+    @Test
+    public void testCreateTinyintColumns() throws Throwable
+    {
+        createTable("CREATE TABLE %s (a text, b tinyint, c tinyint, primary key (a, b));");
+        execute("INSERT INTO %s (a, b, c) VALUES ('1', 1, 2)");
+        execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", "2", Byte.MAX_VALUE, Byte.MIN_VALUE);
+
+        assertRows(execute("SELECT * FROM %s"),
+                   row("1", (byte) 1, (byte) 2),
+                   row("2", Byte.MAX_VALUE, Byte.MIN_VALUE));
+
+        assertInvalidMessage("Expected 1 byte for a tinyint (4)",
+                             "INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", "3", 1, 2);
+
+        assertInvalidMessage("Expected 1 byte for a tinyint (0)",
+                             "INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", "3", (byte) 1,
ByteBufferUtil.EMPTY_BYTE_BUFFER);
+     }
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/35a945e2/test/unit/org/apache/cassandra/db/marshal/TypeCompareTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/db/marshal/TypeCompareTest.java b/test/unit/org/apache/cassandra/db/marshal/TypeCompareTest.java
index 04b030e..fae04a2 100644
--- a/test/unit/org/apache/cassandra/db/marshal/TypeCompareTest.java
+++ b/test/unit/org/apache/cassandra/db/marshal/TypeCompareTest.java
@@ -93,6 +93,48 @@ public class TypeCompareTest
     }
 
     @Test
+    public void testByte()
+    {
+        Random rng = new Random();
+        ByteBuffer[] data = new ByteBuffer[Byte.MAX_VALUE];
+        for (int i = 0; i < data.length; i++)
+        {
+            data[i] = ByteBuffer.allocate(1);
+            rng.nextBytes(data[i].array());
+        }
+
+        Arrays.sort(data, ByteType.instance);
+
+        for (int i = 1; i < data.length; i++)
+        {
+            byte b0 = data[i - 1].get(data[i - 1].position());
+            byte b1 = data[i].get(data[i].position());
+            assert b0 <= b1;
+        }
+    }
+
+    @Test
+    public void testShort()
+    {
+        Random rng = new Random();
+        ByteBuffer[] data = new ByteBuffer[1000];
+        for (int i = 0; i < data.length; i++)
+        {
+            data[i] = ByteBuffer.allocate(2);
+            rng.nextBytes(data[i].array());
+        }
+
+        Arrays.sort(data, ShortType.instance);
+
+        for (int i = 1; i < data.length; i++)
+        {
+            short s0 = data[i - 1].getShort(data[i - 1].position());
+            short s1 = data[i].getShort(data[i].position());
+            assert s0 <= s1;
+        }
+    }
+
+    @Test
     public void testInt()
     {
         Random rng = new Random();

http://git-wip-us.apache.org/repos/asf/cassandra/blob/35a945e2/test/unit/org/apache/cassandra/db/marshal/TypeParserTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/db/marshal/TypeParserTest.java b/test/unit/org/apache/cassandra/db/marshal/TypeParserTest.java
index 5a697be..6581fc7 100644
--- a/test/unit/org/apache/cassandra/db/marshal/TypeParserTest.java
+++ b/test/unit/org/apache/cassandra/db/marshal/TypeParserTest.java
@@ -40,6 +40,12 @@ public class TypeParserTest
         type = TypeParser.parse("    ");
         assert type == BytesType.instance;
 
+        type = TypeParser.parse("ByteType");
+        assert type == ByteType.instance;
+
+        type = TypeParser.parse("ShortType");
+        assert type == ShortType.instance;
+
         type = TypeParser.parse("LongType");
         assert type == LongType.instance;
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/35a945e2/test/unit/org/apache/cassandra/db/marshal/TypeValidationTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/db/marshal/TypeValidationTest.java b/test/unit/org/apache/cassandra/db/marshal/TypeValidationTest.java
index ed5e2bf..5ebeb64 100644
--- a/test/unit/org/apache/cassandra/db/marshal/TypeValidationTest.java
+++ b/test/unit/org/apache/cassandra/db/marshal/TypeValidationTest.java
@@ -65,6 +65,32 @@ public class TypeValidationTest
     }
 
     @Test
+    public void testValidShort()
+    {
+        ShortType.instance.validate(Util.getBytes((short) 5));
+        ShortType.instance.validate(Util.getBytes(Short.MAX_VALUE));
+    }
+
+    @Test(expected = MarshalException.class)
+    public void testInvalidShort()
+    {
+        ShortType.instance.validate(Util.getBytes(2057022603));
+    }
+
+    @Test
+    public void testValidByte()
+    {
+        ByteType.instance.validate(Util.getBytes((byte) 5));
+        ByteType.instance.validate(Util.getBytes(Byte.MAX_VALUE));
+    }
+
+    @Test(expected = MarshalException.class)
+    public void testInvalidByte()
+    {
+        ByteType.instance.validate(Util.getBytes(2057022603));
+    }
+
+    @Test
     public void testValidUtf8() throws UnsupportedEncodingException
     {
         assert Character.MAX_CODE_POINT == 0x0010ffff;


Mime
View raw message