Require AbstractType.isByteOrderComparable declaration on construction

Force users with custom implementations of AbstractType to
update their code on upgrade, to warn them of the impending
possibility of future deprecation of non-byte-order comparability

patch by benedict; reviewed by sylvain and ariel for CASSANDRA-9901


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

Branch: refs/heads/trunk
Commit: 07594ee05e038bdd582b97985f4116227bb416d5
Parents: 704bf1e
Author: Benedict Elliott Smith <[email protected]>
Authored: Wed Aug 5 10:56:19 2015 +0100
Committer: Benedict Elliott Smith <[email protected]>
Committed: Tue Sep 1 11:56:04 2015 +0100

----------------------------------------------------------------------
 CHANGES.txt                                     |   1 +
 .../org/apache/cassandra/config/CFMetaData.java |   3 +
 .../cassandra/db/ClusteringComparator.java      |  23 ++---
 .../db/marshal/AbstractCompositeType.java       |   7 +-
 .../cassandra/db/marshal/AbstractType.java      | 102 ++++++++++++++-----
 .../apache/cassandra/db/marshal/AsciiType.java  |  12 +--
 .../cassandra/db/marshal/BooleanType.java       |   4 +-
 .../apache/cassandra/db/marshal/ByteType.java   |   3 +-
 .../apache/cassandra/db/marshal/BytesType.java  |  12 +--
 .../cassandra/db/marshal/CollectionType.java    |   3 +-
 .../db/marshal/ColumnToCollectionType.java      |   3 +-
 .../cassandra/db/marshal/CounterColumnType.java |  12 +--
 .../apache/cassandra/db/marshal/DateType.java   |  15 +--
 .../cassandra/db/marshal/DecimalType.java       |   4 +-
 .../apache/cassandra/db/marshal/DoubleType.java |   4 +-
 .../db/marshal/DynamicCompositeType.java        |   8 +-
 .../apache/cassandra/db/marshal/EmptyType.java  |   4 +-
 .../apache/cassandra/db/marshal/FloatType.java  |   4 +-
 .../apache/cassandra/db/marshal/FrozenType.java |  10 +-
 .../cassandra/db/marshal/InetAddressType.java   |  12 +--
 .../apache/cassandra/db/marshal/Int32Type.java  |   3 +-
 .../cassandra/db/marshal/IntegerType.java       |   4 +-
 .../cassandra/db/marshal/LexicalUUIDType.java   |   3 +-
 .../apache/cassandra/db/marshal/ListType.java   |   4 +-
 .../apache/cassandra/db/marshal/LongType.java   |   4 +-
 .../apache/cassandra/db/marshal/MapType.java    |   9 +-
 .../db/marshal/PartitionerDefinedOrder.java     |   3 +-
 .../cassandra/db/marshal/ReversedType.java      |   3 +-
 .../apache/cassandra/db/marshal/SetType.java    |   9 +-
 .../apache/cassandra/db/marshal/ShortType.java  |   3 +-
 .../cassandra/db/marshal/SimpleDateType.java    |  14 +--
 .../apache/cassandra/db/marshal/TimeType.java   |  13 +--
 .../cassandra/db/marshal/TimeUUIDType.java      |   3 +-
 .../cassandra/db/marshal/TimestampType.java     |   4 +-
 .../apache/cassandra/db/marshal/TupleType.java  |   3 +-
 .../apache/cassandra/db/marshal/UTF8Type.java   |  12 +--
 .../apache/cassandra/db/marshal/UUIDType.java   |   3 +-
 .../org/apache/cassandra/cql3/UDHelperTest.java |   6 +-
 38 files changed, 158 insertions(+), 191 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/07594ee0/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 390255c..6a0b0b6 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 3.0.0-beta2
+ * Require AbstractType.isByteOrderComparable declaration in constructor 
(CASSANDRA-9901)
  * Avoid digest mismatch on upgrade to 3.0 (CASSANDRA-9554)
  * Fix Materialized View builder when adding multiple MVs (CASSANDRA-10156)
  * Choose better poolingOptions for protocol v4 in cassandra-stress 
(CASSANDRA-10182)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/07594ee0/src/java/org/apache/cassandra/config/CFMetaData.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/config/CFMetaData.java 
b/src/java/org/apache/cassandra/config/CFMetaData.java
index be3093d..bcc65b5 100644
--- a/src/java/org/apache/cassandra/config/CFMetaData.java
+++ b/src/java/org/apache/cassandra/config/CFMetaData.java
@@ -293,7 +293,10 @@ public final class CFMetaData
         for (ColumnDefinition def : partitionKeyColumns)
             this.columnMetadata.put(def.name.bytes, def);
         for (ColumnDefinition def : clusteringColumns)
+        {
             this.columnMetadata.put(def.name.bytes, def);
+            def.type.checkComparable();
+        }
         for (ColumnDefinition def : partitionColumns)
             this.columnMetadata.put(def.name.bytes, def);
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/07594ee0/src/java/org/apache/cassandra/db/ClusteringComparator.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/ClusteringComparator.java 
b/src/java/org/apache/cassandra/db/ClusteringComparator.java
index a5401f0..f3411cf 100644
--- a/src/java/org/apache/cassandra/db/ClusteringComparator.java
+++ b/src/java/org/apache/cassandra/db/ClusteringComparator.java
@@ -24,11 +24,13 @@ import java.util.List;
 import java.util.Objects;
 
 import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableList;
 
 import org.apache.cassandra.db.rows.Row;
 import org.apache.cassandra.db.marshal.AbstractType;
 import org.apache.cassandra.serializers.MarshalException;
 import org.apache.cassandra.utils.ByteBufferUtil;
+import org.apache.cassandra.utils.FastByteOperations;
 
 import static org.apache.cassandra.io.sstable.IndexHelper.IndexInfo;
 
@@ -42,7 +44,6 @@ import static 
org.apache.cassandra.io.sstable.IndexHelper.IndexInfo;
 public class ClusteringComparator implements Comparator<Clusterable>
 {
     private final List<AbstractType<?>> clusteringTypes;
-    private final boolean isByteOrderComparable;
 
     private final Comparator<IndexInfo> indexComparator;
     private final Comparator<IndexInfo> indexReverseComparator;
@@ -52,25 +53,19 @@ public class ClusteringComparator implements 
Comparator<Clusterable>
 
     public ClusteringComparator(AbstractType<?>... clusteringTypes)
     {
-        this(Arrays.asList(clusteringTypes));
+        this(ImmutableList.copyOf(clusteringTypes));
     }
 
     public ClusteringComparator(List<AbstractType<?>> clusteringTypes)
     {
-        this.clusteringTypes = clusteringTypes;
-        this.isByteOrderComparable = isByteOrderComparable(clusteringTypes);
+        // copy the list to ensure despatch is monomorphic
+        this.clusteringTypes = ImmutableList.copyOf(clusteringTypes);
 
         this.indexComparator = (o1, o2) -> 
ClusteringComparator.this.compare(o1.lastName, o2.lastName);
         this.indexReverseComparator = (o1, o2) -> 
ClusteringComparator.this.compare(o1.firstName, o2.firstName);
         this.reverseComparator = (c1, c2) -> 
ClusteringComparator.this.compare(c2, c1);
-    }
-
-    private static boolean isByteOrderComparable(Iterable<AbstractType<?>> 
types)
-    {
-        boolean isByteOrderComparable = true;
-        for (AbstractType<?> type : types)
-            isByteOrderComparable &= type.isByteOrderComparable();
-        return isByteOrderComparable;
+        for (AbstractType<?> type : clusteringTypes)
+            type.checkComparable(); // this should already be enforced by 
CFMetaData.rebuild, but we check again for other constructors
     }
 
     /**
@@ -168,9 +163,7 @@ public class ClusteringComparator implements 
Comparator<Clusterable>
         if (v2 == null)
             return 1;
 
-        return isByteOrderComparable
-             ? ByteBufferUtil.compareUnsigned(v1, v2)
-             : clusteringTypes.get(i).compare(v1, v2);
+        return clusteringTypes.get(i).compare(v1, v2);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/cassandra/blob/07594ee0/src/java/org/apache/cassandra/db/marshal/AbstractCompositeType.java
----------------------------------------------------------------------
diff --git 
a/src/java/org/apache/cassandra/db/marshal/AbstractCompositeType.java 
b/src/java/org/apache/cassandra/db/marshal/AbstractCompositeType.java
index bb2fbf1..ad4050d 100644
--- a/src/java/org/apache/cassandra/db/marshal/AbstractCompositeType.java
+++ b/src/java/org/apache/cassandra/db/marshal/AbstractCompositeType.java
@@ -36,7 +36,12 @@ import org.apache.cassandra.utils.ByteBufferUtil;
  */
 public abstract class AbstractCompositeType extends AbstractType<ByteBuffer>
 {
-    public int compare(ByteBuffer o1, ByteBuffer o2)
+    protected AbstractCompositeType()
+    {
+        super(ComparisonType.CUSTOM);
+    }
+
+    public int compareCustom(ByteBuffer o1, ByteBuffer o2)
     {
         if (!o1.hasRemaining() || !o2.hasRemaining())
             return o1.hasRemaining() ? 1 : o2.hasRemaining() ? -1 : 0;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/07594ee0/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 258a8a5..30d9ae9 100644
--- a/src/java/org/apache/cassandra/db/marshal/AbstractType.java
+++ b/src/java/org/apache/cassandra/db/marshal/AbstractType.java
@@ -18,6 +18,7 @@
 package org.apache.cassandra.db.marshal;
 
 import java.io.IOException;
+import java.lang.reflect.Method;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -26,6 +27,9 @@ import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 import org.apache.cassandra.cql3.CQL3Type;
 import org.apache.cassandra.cql3.Term;
 import org.apache.cassandra.db.TypeSizes;
@@ -33,12 +37,16 @@ import org.apache.cassandra.exceptions.SyntaxException;
 import org.apache.cassandra.serializers.TypeSerializer;
 import org.apache.cassandra.serializers.MarshalException;
 
+import org.apache.cassandra.utils.FastByteOperations;
 import org.github.jamm.Unmetered;
 import org.apache.cassandra.io.util.DataOutputPlus;
 import org.apache.cassandra.io.util.DataInputPlus;
 import org.apache.cassandra.io.util.FileUtils;
 import org.apache.cassandra.utils.ByteBufferUtil;
 
+import static 
org.apache.cassandra.db.marshal.AbstractType.ComparisonType.CUSTOM;
+import static 
org.apache.cassandra.db.marshal.AbstractType.ComparisonType.NOT_COMPARABLE;
+
 /**
  * Specifies a Comparator for a specific type of ByteBuffer.
  *
@@ -50,26 +58,47 @@ import org.apache.cassandra.utils.ByteBufferUtil;
 @Unmetered
 public abstract class AbstractType<T> implements Comparator<ByteBuffer>
 {
+    private static final Logger logger = 
LoggerFactory.getLogger(AbstractType.class);
+
     public final Comparator<ByteBuffer> reverseComparator;
 
-    protected AbstractType()
-    {
-        reverseComparator = new Comparator<ByteBuffer>()
+    public static enum ComparisonType
+    {
+        /**
+         * This type should never be compared
+         */
+        NOT_COMPARABLE,
+        /**
+         * This type is always compared by its sequence of unsigned bytes
+         */
+        BYTE_ORDER,
+        /**
+         * This type can only be compared by calling the type's 
compareCustom() method, which may be expensive.
+         * Support for this may be removed in a major release of Cassandra, 
however upgrade facilities will be
+         * provided if and when this happens.
+         */
+        CUSTOM
+    }
+
+    public final ComparisonType comparisonType;
+    public final boolean isByteOrderComparable;
+    protected AbstractType(ComparisonType comparisonType)
+    {
+        this.comparisonType = comparisonType;
+        this.isByteOrderComparable = comparisonType == 
ComparisonType.BYTE_ORDER;
+        reverseComparator = (o1, o2) -> AbstractType.this.compare(o2, o1);
+        try
         {
-            public int compare(ByteBuffer o1, ByteBuffer o2)
-            {
-                if (o1.remaining() == 0)
-                {
-                    return o2.remaining() == 0 ? 0 : -1;
-                }
-                if (o2.remaining() == 0)
-                {
-                    return 1;
-                }
-
-                return AbstractType.this.compare(o2, o1);
-            }
-        };
+            Method custom = getClass().getMethod("compareCustom", 
ByteBuffer.class, ByteBuffer.class);
+            if ((custom.getDeclaringClass() == AbstractType.class) == 
(comparisonType == CUSTOM))
+                throw new IllegalStateException((comparisonType == CUSTOM ? 
"compareCustom must be overridden if ComparisonType is CUSTOM"
+                                                                         : 
"compareCustom should not be overridden if ComparisonType is not CUSTOM")
+                                                + " (" + 
getClass().getSimpleName() + ")");
+        }
+        catch (NoSuchMethodException e)
+        {
+            throw new IllegalStateException();
+        }
     }
 
     public static List<String> asCQLTypeStringList(List<AbstractType<?>> 
abstractTypes)
@@ -122,6 +151,27 @@ public abstract class AbstractType<T> implements 
Comparator<ByteBuffer>
         getSerializer().validate(bytes);
     }
 
+    public final int compare(ByteBuffer left, ByteBuffer right)
+    {
+        return isByteOrderComparable
+               ? FastByteOperations.compareUnsigned(left, right)
+               : compareCustom(left, right);
+    }
+
+    /**
+     * Implement IFF ComparisonType is CUSTOM
+     *
+     * Compares the ByteBuffer representation of two instances of this class,
+     * for types where this cannot be done by simple in-order comparison of the
+     * unsigned bytes
+     *
+     * Standard Java compare semantics
+     */
+    public int compareCustom(ByteBuffer left, ByteBuffer right)
+    {
+        throw new UnsupportedOperationException();
+    }
+
     /**
      * Validate cell value. Unlike {@linkplain #validate(java.nio.ByteBuffer)},
      * cell value is passed to validate its content.
@@ -230,15 +280,6 @@ public abstract class AbstractType<T> implements 
Comparator<ByteBuffer>
     }
 
     /**
-     * @return true IFF the byte representation of this type can be compared 
unsigned
-     * and always return the same result as calling this object's compare or 
compareCollectionMembers methods
-     */
-    public boolean isByteOrderComparable()
-    {
-        return false;
-    }
-
-    /**
      * An alternative comparison function used by CollectionsType in 
conjunction with CompositeType.
      *
      * This comparator is only called to compare components of a 
CompositeType. It gets the value of the
@@ -366,4 +407,13 @@ public abstract class AbstractType<T> implements 
Comparator<ByteBuffer>
     {
         return getClass().getName();
     }
+
+    public void checkComparable()
+    {
+        switch (comparisonType)
+        {
+            case NOT_COMPARABLE:
+                throw new IllegalArgumentException(this + " cannot be used in 
comparisons, so cannot be used as a clustering column");
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/07594ee0/src/java/org/apache/cassandra/db/marshal/AsciiType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/AsciiType.java 
b/src/java/org/apache/cassandra/db/marshal/AsciiType.java
index 953fc09..d03fc30 100644
--- a/src/java/org/apache/cassandra/db/marshal/AsciiType.java
+++ b/src/java/org/apache/cassandra/db/marshal/AsciiType.java
@@ -37,7 +37,7 @@ public class AsciiType extends AbstractType<String>
 {
     public static final AsciiType instance = new AsciiType();
 
-    AsciiType() {} // singleton
+    AsciiType() {super(ComparisonType.BYTE_ORDER);} // singleton
 
     private final ThreadLocal<CharsetEncoder> encoder = new 
ThreadLocal<CharsetEncoder>()
     {
@@ -48,11 +48,6 @@ public class AsciiType extends AbstractType<String>
         }
     };
 
-    public int compare(ByteBuffer o1, ByteBuffer o2)
-    {
-        return ByteBufferUtil.compareUnsigned(o1, o2);
-    }
-
     public ByteBuffer fromString(String source)
     {
         // the encoder must be reset each time it's used, hence the 
thread-local storage
@@ -105,9 +100,4 @@ public class AsciiType extends AbstractType<String>
     {
         return AsciiSerializer.instance;
     }
-
-    public boolean isByteOrderComparable()
-    {
-        return true;
-    }
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/07594ee0/src/java/org/apache/cassandra/db/marshal/BooleanType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/BooleanType.java 
b/src/java/org/apache/cassandra/db/marshal/BooleanType.java
index f87eb12..24d0632 100644
--- a/src/java/org/apache/cassandra/db/marshal/BooleanType.java
+++ b/src/java/org/apache/cassandra/db/marshal/BooleanType.java
@@ -35,14 +35,14 @@ public class BooleanType extends AbstractType<Boolean>
 
     public static final BooleanType instance = new BooleanType();
 
-    BooleanType() {} // singleton
+    BooleanType() {super(ComparisonType.CUSTOM);} // singleton
 
     public boolean isEmptyValueMeaningless()
     {
         return true;
     }
 
-    public int compare(ByteBuffer o1, ByteBuffer o2)
+    public int compareCustom(ByteBuffer o1, ByteBuffer o2)
     {
         if (!o1.hasRemaining() || !o2.hasRemaining())
             return o1.hasRemaining() ? 1 : o2.hasRemaining() ? -1 : 0;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/07594ee0/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
index b63b92e..14699cd 100644
--- a/src/java/org/apache/cassandra/db/marshal/ByteType.java
+++ b/src/java/org/apache/cassandra/db/marshal/ByteType.java
@@ -33,9 +33,10 @@ public class ByteType extends AbstractType<Byte>
 
     ByteType()
     {
+        super(ComparisonType.CUSTOM);
     } // singleton
 
-    public int compare(ByteBuffer o1, ByteBuffer o2)
+    public int compareCustom(ByteBuffer o1, ByteBuffer o2)
     {
         return o1.get(o1.position()) - o2.get(o2.position());
     }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/07594ee0/src/java/org/apache/cassandra/db/marshal/BytesType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/BytesType.java 
b/src/java/org/apache/cassandra/db/marshal/BytesType.java
index eed3872..cec20f4 100644
--- a/src/java/org/apache/cassandra/db/marshal/BytesType.java
+++ b/src/java/org/apache/cassandra/db/marshal/BytesType.java
@@ -32,12 +32,7 @@ public class BytesType extends AbstractType<ByteBuffer>
 {
     public static final BytesType instance = new BytesType();
 
-    BytesType() {} // singleton
-
-    public int compare(ByteBuffer o1, ByteBuffer o2)
-    {
-        return ByteBufferUtil.compareUnsigned(o1, o2);
-    }
+    BytesType() {super(ComparisonType.BYTE_ORDER);} // singleton
 
     public ByteBuffer fromString(String source)
     {
@@ -89,11 +84,6 @@ public class BytesType extends AbstractType<ByteBuffer>
         return true;
     }
 
-    public boolean isByteOrderComparable()
-    {
-        return true;
-    }
-
     public CQL3Type asCQL3Type()
     {
         return CQL3Type.Native.BLOB;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/07594ee0/src/java/org/apache/cassandra/db/marshal/CollectionType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/CollectionType.java 
b/src/java/org/apache/cassandra/db/marshal/CollectionType.java
index cc424b9..8992aed 100644
--- a/src/java/org/apache/cassandra/db/marshal/CollectionType.java
+++ b/src/java/org/apache/cassandra/db/marshal/CollectionType.java
@@ -83,8 +83,9 @@ public abstract class CollectionType<T> extends 
AbstractType<T>
 
     public final Kind kind;
 
-    protected CollectionType(Kind kind)
+    protected CollectionType(ComparisonType comparisonType, Kind kind)
     {
+        super(comparisonType);
         this.kind = kind;
     }
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/07594ee0/src/java/org/apache/cassandra/db/marshal/ColumnToCollectionType.java
----------------------------------------------------------------------
diff --git 
a/src/java/org/apache/cassandra/db/marshal/ColumnToCollectionType.java 
b/src/java/org/apache/cassandra/db/marshal/ColumnToCollectionType.java
index a81d3f8..96efa24 100644
--- a/src/java/org/apache/cassandra/db/marshal/ColumnToCollectionType.java
+++ b/src/java/org/apache/cassandra/db/marshal/ColumnToCollectionType.java
@@ -61,10 +61,11 @@ public class ColumnToCollectionType extends 
AbstractType<ByteBuffer>
 
     private ColumnToCollectionType(Map<ByteBuffer, CollectionType> defined)
     {
+        super(ComparisonType.CUSTOM);
         this.defined = ImmutableMap.copyOf(defined);
     }
 
-    public int compare(ByteBuffer o1, ByteBuffer o2)
+    public int compareCustom(ByteBuffer o1, ByteBuffer o2)
     {
         throw new UnsupportedOperationException("ColumnToCollectionType should 
only be used in composite types, never alone");
     }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/07594ee0/src/java/org/apache/cassandra/db/marshal/CounterColumnType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/CounterColumnType.java 
b/src/java/org/apache/cassandra/db/marshal/CounterColumnType.java
index 687e525..18ff256 100644
--- a/src/java/org/apache/cassandra/db/marshal/CounterColumnType.java
+++ b/src/java/org/apache/cassandra/db/marshal/CounterColumnType.java
@@ -31,7 +31,7 @@ public class CounterColumnType extends AbstractType<Long>
 {
     public static final CounterColumnType instance = new CounterColumnType();
 
-    CounterColumnType() {} // singleton
+    CounterColumnType() {super(ComparisonType.NOT_COMPARABLE);} // singleton
 
     public boolean isEmptyValueMeaningless()
     {
@@ -43,11 +43,6 @@ public class CounterColumnType extends AbstractType<Long>
         return true;
     }
 
-    public boolean isByteOrderComparable()
-    {
-        throw new AssertionError();
-    }
-
     @Override
     public Long compose(ByteBuffer bytes)
     {
@@ -66,11 +61,6 @@ public class CounterColumnType extends AbstractType<Long>
         CounterContext.instance().validateContext(cellValue);
     }
 
-    public int compare(ByteBuffer o1, ByteBuffer o2)
-    {
-        return ByteBufferUtil.compareUnsigned(o1, o2);
-    }
-
     public String getString(ByteBuffer bytes)
     {
         return ByteBufferUtil.bytesToHex(bytes);

http://git-wip-us.apache.org/repos/asf/cassandra/blob/07594ee0/src/java/org/apache/cassandra/db/marshal/DateType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/DateType.java 
b/src/java/org/apache/cassandra/db/marshal/DateType.java
index 66da443..6643da4 100644
--- a/src/java/org/apache/cassandra/db/marshal/DateType.java
+++ b/src/java/org/apache/cassandra/db/marshal/DateType.java
@@ -37,21 +37,13 @@ public class DateType extends AbstractType<Date>
 
     public static final DateType instance = new DateType();
 
-    DateType() {} // singleton
+    DateType() {super(ComparisonType.BYTE_ORDER);} // singleton
 
     public boolean isEmptyValueMeaningless()
     {
         return true;
     }
 
-    public int compare(ByteBuffer o1, ByteBuffer o2)
-    {
-        if (!o1.hasRemaining() || !o2.hasRemaining())
-            return o1.hasRemaining() ? 1 : o2.hasRemaining() ? -1 : 0;
-
-        return ByteBufferUtil.compareUnsigned(o1, o2);
-    }
-
     public ByteBuffer fromString(String source) throws MarshalException
     {
       // Return an empty ByteBuffer for an empty string.
@@ -103,11 +95,6 @@ public class DateType extends AbstractType<Date>
         return false;
     }
 
-    public boolean isByteOrderComparable()
-    {
-        return true;
-    }
-
     @Override
     public boolean isValueCompatibleWithInternal(AbstractType<?> otherType)
     {

http://git-wip-us.apache.org/repos/asf/cassandra/blob/07594ee0/src/java/org/apache/cassandra/db/marshal/DecimalType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/DecimalType.java 
b/src/java/org/apache/cassandra/db/marshal/DecimalType.java
index 4052d70..17d91d3 100644
--- a/src/java/org/apache/cassandra/db/marshal/DecimalType.java
+++ b/src/java/org/apache/cassandra/db/marshal/DecimalType.java
@@ -32,14 +32,14 @@ public class DecimalType extends AbstractType<BigDecimal>
 {
     public static final DecimalType instance = new DecimalType();
 
-    DecimalType() {} // singleton
+    DecimalType() {super(ComparisonType.CUSTOM);} // singleton
 
     public boolean isEmptyValueMeaningless()
     {
         return true;
     }
 
-    public int compare(ByteBuffer o1, ByteBuffer o2)
+    public int compareCustom(ByteBuffer o1, ByteBuffer o2)
     {
         if (!o1.hasRemaining() || !o2.hasRemaining())
             return o1.hasRemaining() ? 1 : o2.hasRemaining() ? -1 : 0;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/07594ee0/src/java/org/apache/cassandra/db/marshal/DoubleType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/DoubleType.java 
b/src/java/org/apache/cassandra/db/marshal/DoubleType.java
index bc160d5..a84bdec 100644
--- a/src/java/org/apache/cassandra/db/marshal/DoubleType.java
+++ b/src/java/org/apache/cassandra/db/marshal/DoubleType.java
@@ -31,14 +31,14 @@ public class DoubleType extends AbstractType<Double>
 {
     public static final DoubleType instance = new DoubleType();
 
-    DoubleType() {} // singleton
+    DoubleType() {super(ComparisonType.CUSTOM);} // singleton
 
     public boolean isEmptyValueMeaningless()
     {
         return true;
     }
 
-    public int compare(ByteBuffer o1, ByteBuffer o2)
+    public int compareCustom(ByteBuffer o1, ByteBuffer o2)
     {
         if (!o1.hasRemaining() || !o2.hasRemaining())
             return o1.hasRemaining() ? 1 : o2.hasRemaining() ? -1 : 0;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/07594ee0/src/java/org/apache/cassandra/db/marshal/DynamicCompositeType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/DynamicCompositeType.java 
b/src/java/org/apache/cassandra/db/marshal/DynamicCompositeType.java
index 97d145d..657f126 100644
--- a/src/java/org/apache/cassandra/db/marshal/DynamicCompositeType.java
+++ b/src/java/org/apache/cassandra/db/marshal/DynamicCompositeType.java
@@ -343,10 +343,11 @@ public class DynamicCompositeType extends 
AbstractCompositeType
 
         public FixedValueComparator(int cmp)
         {
+            super(ComparisonType.CUSTOM);
             this.cmp = cmp;
         }
 
-        public int compare(ByteBuffer v1, ByteBuffer v2)
+        public int compareCustom(ByteBuffer v1, ByteBuffer v2)
         {
             return cmp;
         }
@@ -395,10 +396,5 @@ public class DynamicCompositeType extends 
AbstractCompositeType
         {
             throw new UnsupportedOperationException();
         }
-
-        public boolean isByteOrderComparable()
-        {
-            return false;
-        }
     }
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/07594ee0/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 448376f..9cd7226 100644
--- a/src/java/org/apache/cassandra/db/marshal/EmptyType.java
+++ b/src/java/org/apache/cassandra/db/marshal/EmptyType.java
@@ -34,9 +34,9 @@ public class EmptyType extends AbstractType<Void>
 {
     public static final EmptyType instance = new EmptyType();
 
-    private EmptyType() {} // singleton
+    private EmptyType() {super(ComparisonType.CUSTOM);} // singleton
 
-    public int compare(ByteBuffer o1, ByteBuffer o2)
+    public int compareCustom(ByteBuffer o1, ByteBuffer o2)
     {
         return 0;
     }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/07594ee0/src/java/org/apache/cassandra/db/marshal/FloatType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/FloatType.java 
b/src/java/org/apache/cassandra/db/marshal/FloatType.java
index ceedce4..86164b0 100644
--- a/src/java/org/apache/cassandra/db/marshal/FloatType.java
+++ b/src/java/org/apache/cassandra/db/marshal/FloatType.java
@@ -32,14 +32,14 @@ public class FloatType extends AbstractType<Float>
 {
     public static final FloatType instance = new FloatType();
 
-    FloatType() {} // singleton
+    FloatType() {super(ComparisonType.CUSTOM);} // singleton
 
     public boolean isEmptyValueMeaningless()
     {
         return true;
     }
 
-    public int compare(ByteBuffer o1, ByteBuffer o2)
+    public int compareCustom(ByteBuffer o1, ByteBuffer o2)
     {
         if (!o1.hasRemaining() || !o2.hasRemaining())
             return o1.hasRemaining() ? 1 : o2.hasRemaining() ? -1 : 0;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/07594ee0/src/java/org/apache/cassandra/db/marshal/FrozenType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/FrozenType.java 
b/src/java/org/apache/cassandra/db/marshal/FrozenType.java
index 7713028..261e789 100644
--- a/src/java/org/apache/cassandra/db/marshal/FrozenType.java
+++ b/src/java/org/apache/cassandra/db/marshal/FrozenType.java
@@ -31,6 +31,11 @@ import org.apache.cassandra.serializers.MarshalException;
  */
 public class FrozenType extends AbstractType<Void>
 {
+    protected FrozenType()
+    {
+        super(ComparisonType.NOT_COMPARABLE);
+    }
+
     public static AbstractType<?> getInstance(TypeParser parser) throws 
ConfigurationException, SyntaxException
     {
         List<AbstractType<?>> innerTypes = parser.getTypeParameters();
@@ -41,11 +46,6 @@ public class FrozenType extends AbstractType<Void>
         return innerType.freeze();
     }
 
-    public int compare(ByteBuffer o1, ByteBuffer o2)
-    {
-        throw new UnsupportedOperationException();
-    }
-
     public String getString(ByteBuffer bytes)
     {
         throw new UnsupportedOperationException();

http://git-wip-us.apache.org/repos/asf/cassandra/blob/07594ee0/src/java/org/apache/cassandra/db/marshal/InetAddressType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/InetAddressType.java 
b/src/java/org/apache/cassandra/db/marshal/InetAddressType.java
index 4901c74..7ffb9c7 100644
--- a/src/java/org/apache/cassandra/db/marshal/InetAddressType.java
+++ b/src/java/org/apache/cassandra/db/marshal/InetAddressType.java
@@ -32,18 +32,13 @@ public class InetAddressType extends 
AbstractType<InetAddress>
 {
     public static final InetAddressType instance = new InetAddressType();
 
-    InetAddressType() {} // singleton
+    InetAddressType() {super(ComparisonType.BYTE_ORDER);} // singleton
 
     public boolean isEmptyValueMeaningless()
     {
         return true;
     }
 
-    public int compare(ByteBuffer o1, ByteBuffer o2)
-    {
-        return ByteBufferUtil.compareUnsigned(o1, o2);
-    }
-
     public ByteBuffer fromString(String source) throws MarshalException
     {
         // Return an empty ByteBuffer for an empty string.
@@ -93,9 +88,4 @@ public class InetAddressType extends AbstractType<InetAddress>
     {
         return InetAddressSerializer.instance;
     }
-
-    public boolean isByteOrderComparable()
-    {
-        return true;
-    }
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/07594ee0/src/java/org/apache/cassandra/db/marshal/Int32Type.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/Int32Type.java 
b/src/java/org/apache/cassandra/db/marshal/Int32Type.java
index cb0c584..770a76d 100644
--- a/src/java/org/apache/cassandra/db/marshal/Int32Type.java
+++ b/src/java/org/apache/cassandra/db/marshal/Int32Type.java
@@ -33,6 +33,7 @@ public class Int32Type extends AbstractType<Integer>
 
     Int32Type()
     {
+        super(ComparisonType.CUSTOM);
     } // singleton
 
     public boolean isEmptyValueMeaningless()
@@ -40,7 +41,7 @@ public class Int32Type extends AbstractType<Integer>
         return true;
     }
 
-    public int compare(ByteBuffer o1, ByteBuffer o2)
+    public int compareCustom(ByteBuffer o1, ByteBuffer o2)
     {
         if (!o1.hasRemaining() || !o2.hasRemaining())
             return o1.hasRemaining() ? 1 : o2.hasRemaining() ? -1 : 0;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/07594ee0/src/java/org/apache/cassandra/db/marshal/IntegerType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/IntegerType.java 
b/src/java/org/apache/cassandra/db/marshal/IntegerType.java
index a3741d4..8f4ba44 100644
--- a/src/java/org/apache/cassandra/db/marshal/IntegerType.java
+++ b/src/java/org/apache/cassandra/db/marshal/IntegerType.java
@@ -58,14 +58,14 @@ public final class IntegerType extends 
AbstractType<BigInteger>
         return i;
     }
 
-    IntegerType() {/* singleton */}
+    IntegerType() {super(ComparisonType.CUSTOM);}/* singleton */
 
     public boolean isEmptyValueMeaningless()
     {
         return true;
     }
 
-    public int compare(ByteBuffer lhs, ByteBuffer rhs)
+    public int compareCustom(ByteBuffer lhs, ByteBuffer rhs)
     {
         return IntegerType.compareIntegers(lhs, rhs);
     }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/07594ee0/src/java/org/apache/cassandra/db/marshal/LexicalUUIDType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/LexicalUUIDType.java 
b/src/java/org/apache/cassandra/db/marshal/LexicalUUIDType.java
index 174ce3a..70767d4 100644
--- a/src/java/org/apache/cassandra/db/marshal/LexicalUUIDType.java
+++ b/src/java/org/apache/cassandra/db/marshal/LexicalUUIDType.java
@@ -34,6 +34,7 @@ public class LexicalUUIDType extends AbstractType<UUID>
 
     LexicalUUIDType()
     {
+        super(ComparisonType.CUSTOM);
     } // singleton
 
     public boolean isEmptyValueMeaningless()
@@ -41,7 +42,7 @@ public class LexicalUUIDType extends AbstractType<UUID>
         return true;
     }
 
-    public int compare(ByteBuffer o1, ByteBuffer o2)
+    public int compareCustom(ByteBuffer o1, ByteBuffer o2)
     {
         if (!o1.hasRemaining() || !o2.hasRemaining())
             return o1.hasRemaining() ? 1 : o2.hasRemaining() ? -1 : 0;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/07594ee0/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 73af808..4b1158e 100644
--- a/src/java/org/apache/cassandra/db/marshal/ListType.java
+++ b/src/java/org/apache/cassandra/db/marshal/ListType.java
@@ -68,7 +68,7 @@ public class ListType<T> extends CollectionType<List<T>>
 
     private ListType(AbstractType<T> elements, boolean isMultiCell)
     {
-        super(Kind.LIST);
+        super(ComparisonType.CUSTOM, Kind.LIST);
         this.elements = elements;
         this.serializer = ListSerializer.getInstance(elements.getSerializer());
         this.isMultiCell = isMultiCell;
@@ -124,7 +124,7 @@ public class ListType<T> extends CollectionType<List<T>>
     }
 
     @Override
-    public int compare(ByteBuffer o1, ByteBuffer o2)
+    public int compareCustom(ByteBuffer o1, ByteBuffer o2)
     {
         return compareListOrSet(elements, o1, o2);
     }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/07594ee0/src/java/org/apache/cassandra/db/marshal/LongType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/LongType.java 
b/src/java/org/apache/cassandra/db/marshal/LongType.java
index 9d41f4f..8a1528a 100644
--- a/src/java/org/apache/cassandra/db/marshal/LongType.java
+++ b/src/java/org/apache/cassandra/db/marshal/LongType.java
@@ -31,14 +31,14 @@ public class LongType extends AbstractType<Long>
 {
     public static final LongType instance = new LongType();
 
-    LongType() {} // singleton
+    LongType() {super(ComparisonType.CUSTOM);} // singleton
 
     public boolean isEmptyValueMeaningless()
     {
         return true;
     }
 
-    public int compare(ByteBuffer o1, ByteBuffer o2)
+    public int compareCustom(ByteBuffer o1, ByteBuffer o2)
     {
         return compareLongs(o1, o2);
     }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/07594ee0/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 b1440a5..3d6bf22 100644
--- a/src/java/org/apache/cassandra/db/marshal/MapType.java
+++ b/src/java/org/apache/cassandra/db/marshal/MapType.java
@@ -67,7 +67,7 @@ public class MapType<K, V> extends CollectionType<Map<K, V>>
 
     private MapType(AbstractType<K> keys, AbstractType<V> values, boolean 
isMultiCell)
     {
-        super(Kind.MAP);
+        super(ComparisonType.CUSTOM, Kind.MAP);
         this.keys = keys;
         this.values = values;
         this.serializer = MapSerializer.getInstance(keys.getSerializer(), 
values.getSerializer(), keys);
@@ -126,7 +126,7 @@ public class MapType<K, V> extends CollectionType<Map<K, V>>
     }
 
     @Override
-    public int compare(ByteBuffer o1, ByteBuffer o2)
+    public int compareCustom(ByteBuffer o1, ByteBuffer o2)
     {
         return compareMaps(keys, values, o1, o2);
     }
@@ -167,11 +167,6 @@ public class MapType<K, V> extends CollectionType<Map<K, 
V>>
         return serializer;
     }
 
-    public boolean isByteOrderComparable()
-    {
-        return keys.isByteOrderComparable();
-    }
-
     @Override
     protected int collectionSize(List<ByteBuffer> values)
     {

http://git-wip-us.apache.org/repos/asf/cassandra/blob/07594ee0/src/java/org/apache/cassandra/db/marshal/PartitionerDefinedOrder.java
----------------------------------------------------------------------
diff --git 
a/src/java/org/apache/cassandra/db/marshal/PartitionerDefinedOrder.java 
b/src/java/org/apache/cassandra/db/marshal/PartitionerDefinedOrder.java
index 88f9906..02f01ae 100644
--- a/src/java/org/apache/cassandra/db/marshal/PartitionerDefinedOrder.java
+++ b/src/java/org/apache/cassandra/db/marshal/PartitionerDefinedOrder.java
@@ -37,6 +37,7 @@ public class PartitionerDefinedOrder extends 
AbstractType<ByteBuffer>
 
     public PartitionerDefinedOrder(IPartitioner partitioner)
     {
+        super(ComparisonType.CUSTOM);
         this.partitioner = partitioner;
     }
 
@@ -86,7 +87,7 @@ public class PartitionerDefinedOrder extends 
AbstractType<ByteBuffer>
         throw new UnsupportedOperationException();
     }
 
-    public int compare(ByteBuffer o1, ByteBuffer o2)
+    public int compareCustom(ByteBuffer o1, ByteBuffer o2)
     {
         // o1 and o2 can be empty so we need to use PartitionPosition, not 
DecoratedKey
         return PartitionPosition.ForKey.get(o1, 
partitioner).compareTo(PartitionPosition.ForKey.get(o2, partitioner));

http://git-wip-us.apache.org/repos/asf/cassandra/blob/07594ee0/src/java/org/apache/cassandra/db/marshal/ReversedType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/ReversedType.java 
b/src/java/org/apache/cassandra/db/marshal/ReversedType.java
index cf357a8..2e01d9b 100644
--- a/src/java/org/apache/cassandra/db/marshal/ReversedType.java
+++ b/src/java/org/apache/cassandra/db/marshal/ReversedType.java
@@ -57,6 +57,7 @@ public class ReversedType<T> extends AbstractType<T>
 
     private ReversedType(AbstractType<T> baseType)
     {
+        super(ComparisonType.CUSTOM);
         this.baseType = baseType;
     }
 
@@ -65,7 +66,7 @@ public class ReversedType<T> extends AbstractType<T>
         return baseType.isEmptyValueMeaningless();
     }
 
-    public int compare(ByteBuffer o1, ByteBuffer o2)
+    public int compareCustom(ByteBuffer o1, ByteBuffer o2)
     {
         // An empty byte buffer is always smaller
         if (o1.remaining() == 0)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/07594ee0/src/java/org/apache/cassandra/db/marshal/SetType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/SetType.java 
b/src/java/org/apache/cassandra/db/marshal/SetType.java
index 7e94fcb..2fd4960 100644
--- a/src/java/org/apache/cassandra/db/marshal/SetType.java
+++ b/src/java/org/apache/cassandra/db/marshal/SetType.java
@@ -62,7 +62,7 @@ public class SetType<T> extends CollectionType<Set<T>>
 
     public SetType(AbstractType<T> elements, boolean isMultiCell)
     {
-        super(Kind.SET);
+        super(ComparisonType.CUSTOM, Kind.SET);
         this.elements = elements;
         this.serializer = SetSerializer.getInstance(elements.getSerializer(), 
elements);
         this.isMultiCell = isMultiCell;
@@ -113,7 +113,7 @@ public class SetType<T> extends CollectionType<Set<T>>
     }
 
     @Override
-    public int compare(ByteBuffer o1, ByteBuffer o2)
+    public int compareCustom(ByteBuffer o1, ByteBuffer o2)
     {
         return ListType.compareListOrSet(elements, o1, o2);
     }
@@ -123,11 +123,6 @@ public class SetType<T> extends CollectionType<Set<T>>
         return serializer;
     }
 
-    public boolean isByteOrderComparable()
-    {
-        return elements.isByteOrderComparable();
-    }
-
     @Override
     public String toString(boolean ignoreFreezing)
     {

http://git-wip-us.apache.org/repos/asf/cassandra/blob/07594ee0/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
index 43e8f5e..15618b8 100644
--- a/src/java/org/apache/cassandra/db/marshal/ShortType.java
+++ b/src/java/org/apache/cassandra/db/marshal/ShortType.java
@@ -33,9 +33,10 @@ public class ShortType extends AbstractType<Short>
 
     ShortType()
     {
+        super(ComparisonType.CUSTOM);
     } // singleton
 
-    public int compare(ByteBuffer o1, ByteBuffer o2)
+    public int compareCustom(ByteBuffer o1, ByteBuffer o2)
     {
         int diff = o1.get(o1.position()) - o2.get(o2.position());
         if (diff != 0)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/07594ee0/src/java/org/apache/cassandra/db/marshal/SimpleDateType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/SimpleDateType.java 
b/src/java/org/apache/cassandra/db/marshal/SimpleDateType.java
index 747709e..dbfac9e 100644
--- a/src/java/org/apache/cassandra/db/marshal/SimpleDateType.java
+++ b/src/java/org/apache/cassandra/db/marshal/SimpleDateType.java
@@ -31,19 +31,7 @@ public class SimpleDateType extends AbstractType<Integer>
 {
     public static final SimpleDateType instance = new SimpleDateType();
 
-    SimpleDateType() {} // singleton
-
-    public int compare(ByteBuffer o1, ByteBuffer o2)
-    {
-        // We add Integer.MIN_VALUE to overflow to allow unsigned comparison
-        return ByteBufferUtil.compareUnsigned(o1, o2);
-    }
-
-    @Override
-    public boolean isByteOrderComparable()
-    {
-        return true;
-    }
+    SimpleDateType() {super(ComparisonType.BYTE_ORDER);} // singleton
 
     public ByteBuffer fromString(String source) throws MarshalException
     {

http://git-wip-us.apache.org/repos/asf/cassandra/blob/07594ee0/src/java/org/apache/cassandra/db/marshal/TimeType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/TimeType.java 
b/src/java/org/apache/cassandra/db/marshal/TimeType.java
index c241a38..780b020 100644
--- a/src/java/org/apache/cassandra/db/marshal/TimeType.java
+++ b/src/java/org/apache/cassandra/db/marshal/TimeType.java
@@ -33,12 +33,7 @@ import org.apache.cassandra.utils.ByteBufferUtil;
 public class TimeType extends AbstractType<Long>
 {
     public static final TimeType instance = new TimeType();
-    private TimeType() {} // singleton
-
-    public int compare(ByteBuffer o1, ByteBuffer o2)
-    {
-        return ByteBufferUtil.compareUnsigned(o1, o2);
-    }
+    private TimeType() {super(ComparisonType.BYTE_ORDER);} // singleton
 
     public ByteBuffer fromString(String source) throws MarshalException
     {
@@ -46,12 +41,6 @@ public class TimeType extends AbstractType<Long>
     }
 
     @Override
-    public boolean isByteOrderComparable()
-    {
-        return true;
-    }
-
-    @Override
     public boolean isCompatibleWith(AbstractType<?> previous)
     {
         return super.isCompatibleWith(previous);

http://git-wip-us.apache.org/repos/asf/cassandra/blob/07594ee0/src/java/org/apache/cassandra/db/marshal/TimeUUIDType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/TimeUUIDType.java 
b/src/java/org/apache/cassandra/db/marshal/TimeUUIDType.java
index 64fa750..36305a3 100644
--- a/src/java/org/apache/cassandra/db/marshal/TimeUUIDType.java
+++ b/src/java/org/apache/cassandra/db/marshal/TimeUUIDType.java
@@ -33,6 +33,7 @@ public class TimeUUIDType extends AbstractType<UUID>
 
     TimeUUIDType()
     {
+        super(ComparisonType.CUSTOM);
     } // singleton
 
     public boolean isEmptyValueMeaningless()
@@ -40,7 +41,7 @@ public class TimeUUIDType extends AbstractType<UUID>
         return true;
     }
 
-    public int compare(ByteBuffer b1, ByteBuffer b2)
+    public int compareCustom(ByteBuffer b1, ByteBuffer b2)
     {
         // Compare for length
         int s1 = b1.position(), s2 = b2.position();

http://git-wip-us.apache.org/repos/asf/cassandra/blob/07594ee0/src/java/org/apache/cassandra/db/marshal/TimestampType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/TimestampType.java 
b/src/java/org/apache/cassandra/db/marshal/TimestampType.java
index 288f8fd..ebaff42 100644
--- a/src/java/org/apache/cassandra/db/marshal/TimestampType.java
+++ b/src/java/org/apache/cassandra/db/marshal/TimestampType.java
@@ -43,14 +43,14 @@ public class TimestampType extends AbstractType<Date>
 
     public static final TimestampType instance = new TimestampType();
 
-    private TimestampType() {} // singleton
+    private TimestampType() {super(ComparisonType.CUSTOM);} // singleton
 
     public boolean isEmptyValueMeaningless()
     {
         return true;
     }
 
-    public int compare(ByteBuffer o1, ByteBuffer o2)
+    public int compareCustom(ByteBuffer o1, ByteBuffer o2)
     {
         return LongType.compareLongs(o1, o2);
     }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/07594ee0/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 688e173..7a98074 100644
--- a/src/java/org/apache/cassandra/db/marshal/TupleType.java
+++ b/src/java/org/apache/cassandra/db/marshal/TupleType.java
@@ -41,6 +41,7 @@ public class TupleType extends AbstractType<ByteBuffer>
 
     public TupleType(List<AbstractType<?>> types)
     {
+        super(ComparisonType.CUSTOM);
         for (int i = 0; i < types.size(); i++)
             types.set(i, types.get(i).freeze());
         this.types = types;
@@ -69,7 +70,7 @@ public class TupleType extends AbstractType<ByteBuffer>
         return types;
     }
 
-    public int compare(ByteBuffer o1, ByteBuffer o2)
+    public int compareCustom(ByteBuffer o1, ByteBuffer o2)
     {
         if (!o1.hasRemaining() || !o2.hasRemaining())
             return o1.hasRemaining() ? 1 : o2.hasRemaining() ? -1 : 0;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/07594ee0/src/java/org/apache/cassandra/db/marshal/UTF8Type.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/UTF8Type.java 
b/src/java/org/apache/cassandra/db/marshal/UTF8Type.java
index 3fd175c..0778b04 100644
--- a/src/java/org/apache/cassandra/db/marshal/UTF8Type.java
+++ b/src/java/org/apache/cassandra/db/marshal/UTF8Type.java
@@ -35,12 +35,7 @@ public class UTF8Type extends AbstractType<String>
 {
     public static final UTF8Type instance = new UTF8Type();
 
-    UTF8Type() {} // singleton
-
-    public int compare(ByteBuffer o1, ByteBuffer o2)
-    {
-        return ByteBufferUtil.compareUnsigned(o1, o2);
-    }
+    UTF8Type() {super(ComparisonType.BYTE_ORDER);} // singleton
 
     public ByteBuffer fromString(String source)
     {
@@ -83,11 +78,6 @@ public class UTF8Type extends AbstractType<String>
         return this == previous || previous == AsciiType.instance;
     }
 
-    public boolean isByteOrderComparable()
-    {
-        return true;
-    }
-
     public CQL3Type asCQL3Type()
     {
         return CQL3Type.Native.TEXT;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/07594ee0/src/java/org/apache/cassandra/db/marshal/UUIDType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/UUIDType.java 
b/src/java/org/apache/cassandra/db/marshal/UUIDType.java
index 14c9f48..acaf27c 100644
--- a/src/java/org/apache/cassandra/db/marshal/UUIDType.java
+++ b/src/java/org/apache/cassandra/db/marshal/UUIDType.java
@@ -48,6 +48,7 @@ public class UUIDType extends AbstractType<UUID>
 
     UUIDType()
     {
+        super(ComparisonType.CUSTOM);
     }
 
     public boolean isEmptyValueMeaningless()
@@ -55,7 +56,7 @@ public class UUIDType extends AbstractType<UUID>
         return true;
     }
 
-    public int compare(ByteBuffer b1, ByteBuffer b2)
+    public int compareCustom(ByteBuffer b1, ByteBuffer b2)
     {
         // Compare for length
         int s1 = b1.position(), s2 = b2.position();

http://git-wip-us.apache.org/repos/asf/cassandra/blob/07594ee0/test/unit/org/apache/cassandra/cql3/UDHelperTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/UDHelperTest.java 
b/test/unit/org/apache/cassandra/cql3/UDHelperTest.java
index 4a5e78e..288cd86 100644
--- a/test/unit/org/apache/cassandra/cql3/UDHelperTest.java
+++ b/test/unit/org/apache/cassandra/cql3/UDHelperTest.java
@@ -54,6 +54,10 @@ public class UDHelperTest
 {
     static class UFTestCustomType extends AbstractType<String>
     {
+        protected UFTestCustomType()
+        {
+            super(ComparisonType.CUSTOM);
+        }
 
         public ByteBuffer fromString(String source) throws MarshalException
         {
@@ -70,7 +74,7 @@ public class UDHelperTest
             return UTF8Type.instance.getSerializer();
         }
 
-        public int compare(ByteBuffer o1, ByteBuffer o2)
+        public int compareCustom(ByteBuffer o1, ByteBuffer o2)
         {
             return o1.compareTo(o2);
         }

Reply via email to