You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by nd...@apache.org on 2014/12/18 01:11:53 UTC

[15/22] phoenix git commit: PHOENIX-1514 Break up PDataType Enum

http://git-wip-us.apache.org/repos/asf/phoenix/blob/04ef859b/phoenix-core/src/main/java/org/apache/phoenix/schema/PDataType.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PDataType.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PDataType.java
deleted file mode 100644
index 59b1417..0000000
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PDataType.java
+++ /dev/null
@@ -1,7452 +0,0 @@
-/*
- * 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.phoenix.schema;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.math.MathContext;
-import java.math.RoundingMode;
-import java.sql.Date;
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.sql.Types;
-import java.text.Format;
-import java.util.Arrays;
-import java.util.Map;
-import java.util.Random;
-
-import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
-import org.apache.hadoop.hbase.util.Base64;
-import org.apache.hadoop.hbase.util.Bytes;
-import org.apache.phoenix.exception.SQLExceptionCode;
-import org.apache.phoenix.exception.SQLExceptionInfo;
-import org.apache.phoenix.exception.ValueTypeIncompatibleException;
-import org.apache.phoenix.query.KeyRange;
-import org.apache.phoenix.query.QueryConstants;
-import org.apache.phoenix.util.ByteUtil;
-import org.apache.phoenix.util.DateUtil;
-import org.apache.phoenix.util.NumberUtil;
-import org.apache.phoenix.util.StringUtil;
-
-import com.google.common.base.Preconditions;
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.math.LongMath;
-import com.google.common.primitives.Booleans;
-import com.google.common.primitives.Doubles;
-import com.google.common.primitives.Longs;
-
-/**
- * The data types of PColumns
- *
- * 
- * 
- * @since 0.1
- *
- * TODO: cleanup implementation to reduce copy/paste duplication
- */
-@SuppressWarnings("rawtypes")
-public enum PDataType {
-	
-    VARCHAR("VARCHAR", Types.VARCHAR, String.class, null) {
-        @Override
-        public byte[] toBytes(Object object) {
-            // TODO: consider using avro UTF8 object instead of String
-            // so that we get get the size easily
-            if (object == null) {
-                return ByteUtil.EMPTY_BYTE_ARRAY;
-            }
-            return Bytes.toBytes((String)object);
-        }
-
-        @Override
-        public int toBytes(Object object, byte[] bytes, int offset) {
-            if (object == null) {
-                return 0;
-            }
-            byte[] b = toBytes(object); // TODO: no byte[] allocation: use CharsetEncoder
-            System.arraycopy(b, 0, bytes, offset, b.length);
-            return b.length;
-        }
-
-        @Override
-        public Object toObject(byte[] bytes, int offset, int length, PDataType actualType, SortOrder sortOrder, Integer maxLength, Integer scale) {
-            if (!actualType.isCoercibleTo(this)) {
-                throwConstraintViolationException(actualType, this);
-            }
-            if (length == 0) {
-                return null;
-            }
-            if (sortOrder == SortOrder.DESC) {
-                bytes = SortOrder.invert(bytes, offset, length);
-                offset = 0;
-            }
-            return Bytes.toString(bytes, offset, length);
-        }
-
-        @Override
-        public Object toObject(Object object, PDataType actualType) {
-            switch (actualType) {
-            case VARCHAR:
-            case CHAR:
-                String s = (String)object;
-                return s == null || s.length() > 0 ? s : null;
-            default:
-                return throwConstraintViolationException(actualType,this);
-            }
-        }
-
-        @Override
-        public boolean isCoercibleTo(PDataType targetType) {
-            return this == targetType || targetType == CHAR || targetType == VARBINARY || targetType == BINARY;
-        }
-
-        @Override
-        public boolean isCoercibleTo(PDataType targetType, Object value) {
-            if (isCoercibleTo(targetType)) {
-                if (targetType == PDataType.CHAR) {
-                    return value != null;
-                }
-                return true;
-            }
-            return false;
-        }
-
-        @Override
-        public boolean isSizeCompatible(ImmutableBytesWritable ptr, Object value, PDataType srcType,
-                Integer maxLength, Integer scale, Integer desiredMaxLength, Integer desiredScale) {
-            if (ptr.getLength() != 0 && maxLength != null && desiredMaxLength != null) {
-                return maxLength <= desiredMaxLength;
-            }
-            return true;
-        }
-
-        @Override
-        public boolean isFixedWidth() {
-            return false;
-        }
-
-        @Override
-        public int estimateByteSize(Object o) {
-            String value = (String) o;
-            return value == null ? 1 : value.length();
-        }
-
-        @Override
-        public Integer getByteSize() {
-            return null;
-        }
-
-        @Override
-        public int compareTo(Object lhs, Object rhs, PDataType rhsType) {
-            return ((String)lhs).compareTo((String)rhs);
-        }
-
-        @Override
-        public Object toObject(String value) {
-            return value;
-        }
-
-        @Override
-        public boolean isBytesComparableWith(PDataType otherType) {
-            return super.isBytesComparableWith(otherType) || this == CHAR;
-        }
-
-        @Override
-        public String toStringLiteral(byte[] b, int offset, int length, Format formatter) {
-            while (b[length-1] == 0) {
-                length--;
-            }
-            if (formatter != null) {
-                Object o = toObject(b,offset,length);
-                return "'" + formatter.format(o) + "'";
-            }
-            return "'" + Bytes.toStringBinary(b, offset, length) + "'";
-        }
-
-        private char[] sampleChars = new char[1];
-        @Override
-        public Object getSampleValue(Integer maxLength, Integer arrayLength) {
-            Preconditions.checkArgument(maxLength == null || maxLength >= 0);
-            int length = maxLength != null ? maxLength : 1;
-            if (length != sampleChars.length) {
-                sampleChars = new char[length];
-            }
-            for (int i = 0; i < length; i++) {
-                sampleChars[i] = (char) RANDOM.get().nextInt(Byte.MAX_VALUE);
-            }
-            return new String(sampleChars);
-        }
-    },
-    /**
-     * Fixed length single byte characters
-     */
-    CHAR("CHAR", Types.CHAR, String.class, null) { // Delegate to VARCHAR
-        @Override
-        public void pad(ImmutableBytesWritable ptr, Integer maxLength) {
-            if (ptr.getLength() >= maxLength) {
-                return;
-            }
-            byte[] newBytes = new byte[maxLength];
-            System.arraycopy(ptr.get(), ptr.getOffset(), newBytes, 0, ptr.getLength());
-            Arrays.fill(newBytes, ptr.getLength(), maxLength, StringUtil.SPACE_UTF8);
-            ptr.set(newBytes);
-        }
-
-        @Override
-        public Object pad(Object object, Integer maxLength) {
-            String s = (String) object;
-            if (s == null) {
-                return s;
-            }
-            if (s.length() == maxLength) {
-                return object;
-            }
-            if (s.length() > maxLength) {
-                throw new ValueTypeIncompatibleException(this,maxLength,null);
-            }
-            return Strings.padEnd(s, maxLength, ' ');
-        }
-        
-        @Override
-        public byte[] toBytes(Object object) {
-            if (object == null) {
-                throw newIllegalDataException(this + " may not be null");
-            }
-            byte[] b = VARCHAR.toBytes(object);
-            if (b.length != ((String) object).length()) {
-                throw newIllegalDataException("CHAR types may only contain single byte characters (" + object + ")");
-            }
-            return b;
-        }
-
-        @Override
-        public int toBytes(Object object, byte[] bytes, int offset) {
-            if (object == null) {
-                throw newIllegalDataException(this + " may not be null");
-            }
-            int len = VARCHAR.toBytes(object, bytes, offset);
-            if (len != ((String) object).length()) {
-                throw newIllegalDataException("CHAR types may only contain single byte characters (" + object + ")");
-            }
-            return len;
-        }
-
-        @Override
-        public Object toObject(byte[] bytes, int offset, int length, PDataType actualType, SortOrder sortOrder, Integer maxLength, Integer scale) {
-            if (!actualType.isCoercibleTo(this)) { // TODO: have isCoercibleTo that takes bytes, offset?
-                throwConstraintViolationException(actualType,this);
-            }
-            if (length == 0) {
-                return null;
-            }
-            length = StringUtil.getUnpaddedCharLength(bytes, offset, length, sortOrder);
-            if (sortOrder == SortOrder.DESC) {
-                bytes = SortOrder.invert(bytes, offset, length);
-                offset = 0;
-            }
-            // TODO: UTF-8 decoder that will invert as it decodes
-            String s = Bytes.toString(bytes, offset, length);
-            if (length != s.length()) {
-               throw newIllegalDataException("CHAR types may only contain single byte characters (" + s + ")");
-            }
-            return s;
-        }
-
-        @Override
-        public Object toObject(Object object, PDataType actualType) {
-            switch (actualType) {
-            case VARCHAR:
-            case CHAR:
-                String s = (String)object;
-                return s == null || s.length() > 0 ? s : null;
-            default:
-                return throwConstraintViolationException(actualType,this);
-            }
-        }
-
-        @Override
-        public boolean isCoercibleTo(PDataType targetType) {
-            return this == targetType || targetType == VARCHAR || targetType == BINARY || targetType == VARBINARY;
-        }
-
-        @Override
-        public void coerceBytes(ImmutableBytesWritable ptr, Object o, PDataType actualType, 
-                Integer actualMaxLength, Integer actualScale, SortOrder actualModifier,
-                Integer desiredMaxLength, Integer desiredScale, SortOrder expectedModifier) {
-            if (o != null && actualType == PDataType.VARCHAR && ((String)o).length() != ptr.getLength()) {
-                throw newIllegalDataException("CHAR types may only contain single byte characters (" + o + ")");
-            }
-            super.coerceBytes(ptr, o, actualType, actualMaxLength, actualScale, actualModifier, desiredMaxLength, desiredScale, expectedModifier);
-        }
-        
-        @Override
-        public boolean isSizeCompatible(ImmutableBytesWritable ptr, Object value, PDataType srcType,
-                Integer maxLength, Integer scale, Integer desiredMaxLength, Integer desiredScale) {
-            return VARCHAR.isSizeCompatible(ptr, value, srcType, maxLength, scale, desiredMaxLength, desiredScale);
-        }
-
-        @Override
-        public boolean isFixedWidth() {
-            return true;
-        }
-
-        @Override
-        public Integer getByteSize() {
-            return null;
-        }
-
-        @Override
-        public Integer getMaxLength(Object o) {
-            if (o == null) {
-                return null;
-            }
-            String value = (String) o;
-            return value.length();
-        }
-
-        @Override
-        public int estimateByteSize(Object o) {
-            String value = (String) o;
-            return value.length();
-        }
-
-        @Override
-        public int compareTo(Object lhs, Object rhs, PDataType rhsType) {
-            return VARCHAR.compareTo(lhs, rhs, rhsType);
-        }
-
-        @Override
-        public Object toObject(String value) {
-            if (value == null || value.length() == 0) {
-                throw newIllegalDataException(this + " may not be null");
-            }
-            if (StringUtil.hasMultiByteChars(value)) {
-                throw newIllegalDataException("CHAR types may only contain single byte characters (" + value + ")");
-            }
-            return value;
-        }
-
-        @Override
-        public Integer estimateByteSizeFromLength(Integer length) {
-            return length;
-        }
-
-        @Override
-        public boolean isBytesComparableWith(PDataType otherType) {
-            return super.isBytesComparableWith(otherType) || this == VARCHAR;
-        }
-        
-        @Override
-        public String toStringLiteral(byte[] b, int offset, int length, Format formatter) {
-            return VARCHAR.toStringLiteral(b, offset, length, formatter);
-        }
-
-        @Override
-        public Object getSampleValue(Integer maxLength, Integer arrayLength) {
-            return VARCHAR.getSampleValue(maxLength, arrayLength);
-        }
-    },
-    LONG("BIGINT", Types.BIGINT, Long.class, new LongCodec()) {
-        @Override
-        public Integer getScale(Object o) {
-            return ZERO;
-        }
-
-        @Override
-        public byte[] toBytes(Object object) {
-            byte[] b = new byte[Bytes.SIZEOF_LONG];
-            toBytes(object, b, 0);
-            return b;
-        }
-
-        @Override
-        public int toBytes(Object object, byte[] b, int o) {
-            if (object == null) {
-                throw newIllegalDataException(this + " may not be null");
-            }
-            return this.getCodec().encodeLong(((Number)object).longValue(), b, o);
-        }
-
-        @Override
-        public Object toObject(Object object, PDataType actualType) {
-            if (object == null) {
-                return null;
-            }
-            switch (actualType) {
-            case LONG:
-            case UNSIGNED_LONG:
-                return object;
-            case UNSIGNED_INT:
-            case INTEGER:
-                long s = (Integer)object;
-                return s;
-            case TINYINT:
-            case UNSIGNED_TINYINT:
-                s = (Byte)object;
-                return s;
-            case SMALLINT:
-            case UNSIGNED_SMALLINT:
-                s = (Short)object;
-                return s;
-            case FLOAT:
-            case UNSIGNED_FLOAT:
-                Float f = (Float)object;
-                if (f > Long.MAX_VALUE || f < Long.MIN_VALUE) {
-                    throw newIllegalDataException(actualType + " value " + f + " cannot be cast to Long without changing its value");
-                }
-                s = f.longValue();
-                return s;
-            case DOUBLE:
-            case UNSIGNED_DOUBLE:
-                Double de = (Double) object;
-                if (de > Long.MAX_VALUE || de < Long.MIN_VALUE) {
-                    throw newIllegalDataException(actualType + " value " + de + " cannot be cast to Long without changing its value");
-                }
-                s = de.longValue();
-                return s;
-            case DECIMAL:
-                BigDecimal d = (BigDecimal)object;
-                return d.longValueExact();
-            case DATE:
-            case UNSIGNED_DATE:
-            case TIME:
-            case UNSIGNED_TIME:
-                java.util.Date date = (java.util.Date)object;
-                return date.getTime();
-            default:
-                return throwConstraintViolationException(actualType,this);
-            }
-        }
-
-        @Override
-        public Long toObject(byte[] b, int o, int l, PDataType actualType, SortOrder sortOrder, Integer maxLength, Integer scale) {
-            if (l == 0) {
-                return null;
-            }
-            switch (actualType) {
-            case LONG:
-            case UNSIGNED_LONG:
-            case INTEGER:
-            case UNSIGNED_INT:
-            case SMALLINT:
-            case UNSIGNED_SMALLINT:
-            case TINYINT:
-            case UNSIGNED_TINYINT:
-            case FLOAT:
-            case UNSIGNED_FLOAT:
-            case DOUBLE:
-            case UNSIGNED_DOUBLE:
-            case DATE:
-            case UNSIGNED_DATE:
-            case TIME:
-            case UNSIGNED_TIME:
-                return actualType.getCodec().decodeLong(b, o, sortOrder);
-            case DECIMAL:
-                BigDecimal bd = (BigDecimal)actualType.toObject(b, o, l, actualType, sortOrder);
-                return bd.longValueExact();
-            }
-            throwConstraintViolationException(actualType,this);
-            return null;
-        }
-
-        @Override
-        public boolean isCoercibleTo(PDataType targetType) {
-            // In general, don't allow conversion of LONG to INTEGER. There are times when
-            // we check isComparableTo for a more relaxed check and then throw a runtime
-            // exception if we overflow
-            return this == targetType || targetType == DECIMAL
-                    || targetType == VARBINARY || targetType == BINARY
-                    || targetType == DOUBLE;
-        }
-
-        @Override
-        public boolean isComparableTo(PDataType targetType) {
-            return DECIMAL.isComparableTo(targetType);
-        }
-
-        @Override
-        public boolean isCoercibleTo(PDataType targetType, Object value) {
-            if (value != null) {
-                long l;
-                switch (targetType) {
-                    case UNSIGNED_DOUBLE:
-                    case UNSIGNED_FLOAT:
-                    case UNSIGNED_LONG:
-                        l = (Long) value;
-                        return l >= 0;
-                    case UNSIGNED_INT:
-                        l = (Long) value;
-                        return (l >= 0 && l <= Integer.MAX_VALUE);
-                    case INTEGER:
-                        l = (Long) value;
-                        return (l >= Integer.MIN_VALUE && l <= Integer.MAX_VALUE);
-                    case UNSIGNED_SMALLINT:
-                        l = (Long) value;
-                        return (l >= 0 && l <= Short.MAX_VALUE);
-                    case SMALLINT:
-                        l = (Long) value;
-                        return (l >=Short.MIN_VALUE && l<=Short.MAX_VALUE);
-                    case TINYINT:
-                        l = (Long)value;
-                        return (l >=Byte.MIN_VALUE && l<Byte.MAX_VALUE);
-                    case UNSIGNED_TINYINT:
-                        l = (Long)value;
-                        return (l >=0 && l<Byte.MAX_VALUE);
-                    default:
-                        break;
-                }
-            }
-            return super.isCoercibleTo(targetType, value);
-        }
-
-        @Override
-        public boolean isCastableTo(PDataType targetType) {
-            return super.isCastableTo(targetType) || targetType.isCoercibleTo(TIMESTAMP);
-        }
-
-        @Override
-        public boolean isFixedWidth() {
-            return true;
-        }
-
-        @Override
-        public Integer getByteSize() {
-            return Bytes.SIZEOF_LONG;
-        }
-
-        @Override
-        public Integer getMaxLength(Object o) {
-            return LONG_PRECISION;
-        }
-
-        @Override
-        public int compareTo(Object lhs, Object rhs, PDataType rhsType) {
-            if (rhsType == DECIMAL) {
-                return -((BigDecimal)rhs).compareTo(BigDecimal.valueOf(((Number)lhs).longValue()));
-            } else if (rhsType == DOUBLE || rhsType == FLOAT || rhsType == UNSIGNED_DOUBLE || rhsType == UNSIGNED_FLOAT) {
-                return Doubles.compare(((Number)lhs).doubleValue(), ((Number)rhs).doubleValue());
-            }
-            return Longs.compare(((Number)lhs).longValue(), ((Number)rhs).longValue());
-        }
-
-        @Override
-        public Object toObject(String value) {
-            if (value == null || value.length() == 0) {
-                return null;
-            }
-            try {
-                return Long.parseLong(value);
-            } catch (NumberFormatException e) {
-                throw newIllegalDataException(e);
-            }
-        }
-
-        @Override
-        public Object getSampleValue(Integer maxLength, Integer arrayLength) {
-            return RANDOM.get().nextLong();
-        }
-    },
-    INTEGER("INTEGER", Types.INTEGER, Integer.class, new IntCodec()) {
-        @Override
-        public Integer getScale(Object o) {
-            return ZERO;
-        }
-    	
-        @Override
-        public byte[] toBytes(Object object) {
-            byte[] b = new byte[Bytes.SIZEOF_INT];
-            toBytes(object, b, 0);
-            return b;
-        }
-
-        @Override
-        public int toBytes(Object object, byte[] b, int o) {
-            if (object == null) {
-                throw newIllegalDataException(this + " may not be null");
-            }
-            return this.getCodec().encodeInt(((Number)object).intValue(), b, o);
-        }
-
-        @Override
-        public Object toObject(Object object, PDataType actualType) {
-            Object o = LONG.toObject(object, actualType);
-            if (!(o instanceof Long) || o == null) {
-                return o;
-            }
-            long l = (Long)o;
-            if (l < Integer.MIN_VALUE || l > Integer.MAX_VALUE) {
-                throw newIllegalDataException(actualType + " value " + l + " cannot be cast to Integer without changing its value");
-            }
-            int v = (int)l;
-            return v;
-        }
-
-        @Override
-        public Integer toObject(byte[] b, int o, int l, PDataType actualType, SortOrder sortOrder, Integer maxLength, Integer scale) {
-            if (l == 0) {
-                return null;
-            }
-            switch (actualType) {
-            case LONG:
-            case UNSIGNED_LONG:
-            case INTEGER:
-            case UNSIGNED_INT:
-            case SMALLINT:
-            case UNSIGNED_SMALLINT:
-            case TINYINT:
-            case UNSIGNED_TINYINT:
-            case FLOAT:
-            case UNSIGNED_FLOAT:
-            case DOUBLE:
-            case UNSIGNED_DOUBLE:
-                return actualType.getCodec().decodeInt(b, o, sortOrder);
-            case DECIMAL:
-                BigDecimal bd = (BigDecimal)actualType.toObject(b, o, l, actualType, sortOrder);
-                return bd.intValueExact();
-            }
-            throwConstraintViolationException(actualType,this);
-            return null;
-        }
-
-        @Override
-        public boolean isCoercibleTo(PDataType targetType, Object value) {
-            if (value != null) {
-                switch (targetType) {
-                    case UNSIGNED_DOUBLE:
-                    case UNSIGNED_FLOAT:
-                    case UNSIGNED_LONG:
-                    case UNSIGNED_INT:
-                        int i = (Integer) value;
-                        return i >= 0;
-                    case UNSIGNED_SMALLINT:
-                        i = (Integer) value;
-                        return (i >= 0 && i <= Short.MAX_VALUE);
-                    case SMALLINT:
-                        i = (Integer) value;
-                        return (i >=Short.MIN_VALUE && i<=Short.MAX_VALUE);
-                    case TINYINT:
-                        i = (Integer)value;
-                        return (i >=Byte.MIN_VALUE && i<=Byte.MAX_VALUE);
-                    case UNSIGNED_TINYINT:
-                        i = (Integer)value;
-                        return (i >=0 && i<Byte.MAX_VALUE);
-                    default:
-                        break;
-                }
-            }
-            return super.isCoercibleTo(targetType, value);
-        }
-
-        @Override
-        public boolean isCoercibleTo(PDataType targetType) {
-            return this == targetType || targetType == FLOAT || LONG.isCoercibleTo(targetType);
-        }
-
-        @Override
-        public boolean isFixedWidth() {
-            return true;
-        }
-
-        @Override
-        public Integer getByteSize() {
-            return Bytes.SIZEOF_INT;
-        }
-
-        @Override
-        public Integer getMaxLength(Object o) {
-            return INT_PRECISION;
-        }
-
-        @Override
-        public int compareTo(Object lhs, Object rhs, PDataType rhsType) {
-            return LONG.compareTo(lhs,rhs,rhsType);
-        }
-
-        @Override
-        public boolean isComparableTo(PDataType targetType) {
-            return DECIMAL.isComparableTo(targetType);
-        }
-
-        @Override
-        public Object toObject(String value) {
-            if (value == null || value.length() == 0) {
-                return null;
-            }
-            try {
-                return Integer.parseInt(value);
-            } catch (NumberFormatException e) {
-                throw newIllegalDataException(e);
-            }
-        }
-
-        @Override
-        public Object getSampleValue(Integer maxLength, Integer arrayLength) {
-            return RANDOM.get().nextInt();
-        }
-    },
-    SMALLINT("SMALLINT", Types.SMALLINT, Short.class, new ShortCodec()){
-        @Override
-        public Integer getScale(Object o) {
-            return ZERO;
-        }
-
-      @Override
-      public int compareTo(Object lhs, Object rhs, PDataType rhsType) {
-        return LONG.compareTo(lhs, rhs, rhsType);
-      }
-      
-      @Override
-      public boolean isComparableTo(PDataType targetType) {
-          return DECIMAL.isComparableTo(targetType);
-      }
-
-      @Override
-      public boolean isFixedWidth() {
-        return true;
-      }
-
-      @Override
-      public Integer getByteSize() {
-        return Bytes.SIZEOF_SHORT;
-      }
-
-      @Override
-      public Integer getMaxLength(Object o) {
-          return SHORT_PRECISION;
-      }
-
-      @Override
-      public byte[] toBytes(Object object) {
-        byte[] b = new byte[Bytes.SIZEOF_SHORT];
-        toBytes(object, b, 0);
-        return b;
-      }
-
-      @Override
-      public int toBytes(Object object, byte[] bytes, int offset) {
-        if (object == null) {
-          throw newIllegalDataException(this + " may not be null");
-        }
-        return this.getCodec().encodeShort(((Number)object).shortValue(), bytes, offset);
-      }
-      
-      @Override
-      public Object toObject(Object object, PDataType actualType) {
-          Object o = LONG.toObject(object, actualType);
-          if (!(o instanceof Long) || o == null) {
-              return o;
-          }
-          long l = (Long)o;
-          if (l < Short.MIN_VALUE || l > Short.MAX_VALUE) {
-              throw newIllegalDataException(actualType + " value " + l + " cannot be cast to Short without changing its value");
-          }
-          short s = (short)l;
-          return s;
-      }
-
-      @Override
-      public Short toObject(byte[] b, int o, int l, PDataType actualType, SortOrder sortOrder, Integer maxLength, Integer scale) {
-          if (l == 0) {
-              return null;
-          }
-          switch (actualType) {
-          case SMALLINT:
-          case UNSIGNED_SMALLINT:
-          case TINYINT:
-          case UNSIGNED_TINYINT:
-          case LONG:
-          case UNSIGNED_LONG:
-          case INTEGER:
-          case UNSIGNED_INT:
-          case FLOAT:
-          case UNSIGNED_FLOAT:
-          case DOUBLE:
-          case UNSIGNED_DOUBLE:
-              return actualType.getCodec().decodeShort(b, o, sortOrder);
-          case DECIMAL:
-              BigDecimal bd = (BigDecimal)actualType.toObject(b, o, l, actualType, sortOrder);
-              return bd.shortValueExact();
-          }
-          throwConstraintViolationException(actualType,this);
-          return null;
-      }
-
-      @Override
-      public Object toObject(String value) {
-        if (value == null || value.length() == 0) {
-          return null;
-        }
-        try {
-            return Short.parseShort(value);
-        } catch (NumberFormatException e) {
-            throw newIllegalDataException(e);
-        }
-      }
-      
-      @Override
-      public boolean isCoercibleTo(PDataType targetType, Object value) {
-          if (value != null) {
-              switch (targetType) {
-                  case UNSIGNED_DOUBLE:
-                  case UNSIGNED_FLOAT:
-                  case UNSIGNED_LONG:
-                  case UNSIGNED_INT:
-                  case UNSIGNED_SMALLINT:
-                      short i = (Short) value;
-                      return i >= 0;
-                  case UNSIGNED_TINYINT:
-                      i = (Short) value;
-                      return (i>=0 && i<= Byte.MAX_VALUE);
-                  case TINYINT:
-                      i = (Short)value;
-                      return (i>=Byte.MIN_VALUE && i<= Byte.MAX_VALUE);
-                  default:
-                      break;
-              }
-          }
-          return super.isCoercibleTo(targetType, value);
-      }
-
-      @Override
-      public boolean isCoercibleTo(PDataType targetType) {
-          return this == targetType || INTEGER.isCoercibleTo(targetType);
-      }
-
-      @Override
-      public Object getSampleValue(Integer maxLength, Integer arrayLength) {
-          return ((Integer) INTEGER.getSampleValue(maxLength, arrayLength)).shortValue();
-      }
-
-    },
-    TINYINT("TINYINT", Types.TINYINT, Byte.class, new ByteCodec()) {
-        @Override
-        public Integer getScale(Object o) {
-            return ZERO;
-        }
-
-      @Override
-      public int compareTo(Object lhs, Object rhs, PDataType rhsType) {
-        return LONG.compareTo(lhs, rhs, rhsType);
-      }
-      
-      @Override
-      public boolean isComparableTo(PDataType targetType) {
-          return DECIMAL.isComparableTo(targetType);
-      }
-
-      @Override
-      public boolean isFixedWidth() {
-        return true;
-      }
-
-      @Override
-      public Integer getByteSize() {
-        return Bytes.SIZEOF_BYTE;
-      }
-      
-      @Override
-      public Integer getMaxLength(Object o) {
-          return BYTE_PRECISION;
-      }
-
-      @Override
-      public byte[] toBytes(Object object) {
-        byte[] b = new byte[Bytes.SIZEOF_BYTE];
-        toBytes(object, b, 0);
-        return b;
-      }
-
-      @Override
-      public int toBytes(Object object, byte[] bytes, int offset) {
-        if (object == null) {
-          throw newIllegalDataException(this + " may not be null");
-        }
-        return this.getCodec().encodeByte(((Number)object).byteValue(), bytes, offset);
-      }
-
-      @Override
-      public Object toObject(String value) {
-        if (value == null || value.length() == 0) {
-          return null;
-        }
-        try {
-          Byte b = Byte.parseByte(value);
-          return b;
-        } catch (NumberFormatException e) {
-          throw newIllegalDataException(e);
-        }
-      }
-      
-      @Override
-      public Object toObject(Object object, PDataType actualType) {
-          Object o = LONG.toObject(object, actualType);
-          if(!(o instanceof Long) || o == null) {
-              return o;
-          }
-          long l = (Long)o;
-          if (l < Byte.MIN_VALUE || l > Byte.MAX_VALUE) {
-              throw newIllegalDataException(actualType + " value " + l + " cannot be cast to Byte without changing its value");
-          }
-          return (byte)l;
-      }
-      
-      @Override
-      public Byte toObject(byte[] b, int o, int l, PDataType actualType, SortOrder sortOrder, Integer maxLength, Integer scale) {
-          if (l == 0) {
-              return null;
-          }
-          switch (actualType) {
-          case UNSIGNED_DOUBLE:
-          case DOUBLE:
-          case UNSIGNED_FLOAT:
-          case FLOAT:
-          case UNSIGNED_LONG:
-          case LONG:
-          case UNSIGNED_INT:
-          case INTEGER:
-          case UNSIGNED_SMALLINT:
-          case SMALLINT:
-          case UNSIGNED_TINYINT:
-          case TINYINT:
-              return actualType.getCodec().decodeByte(b, o, sortOrder);
-          case DECIMAL:
-              BigDecimal bd = (BigDecimal)actualType.toObject(b, o, l, actualType, sortOrder);
-              return bd.byteValueExact();
-          }
-          throwConstraintViolationException(actualType,this);
-          return null;
-      }
-      
-      @Override
-      public boolean isCoercibleTo(PDataType targetType, Object value) {
-          if (value != null) {
-              switch (targetType) {
-                  case UNSIGNED_DOUBLE:
-                  case UNSIGNED_FLOAT:
-                  case UNSIGNED_LONG:
-                  case UNSIGNED_INT:
-                  case UNSIGNED_SMALLINT:
-                  case UNSIGNED_TINYINT:
-                      byte i = (Byte) value;
-                      return i >= 0;
-                  default:
-                      break;
-              }
-          }
-          return super.isCoercibleTo(targetType, value);
-      }
-      
-      @Override
-      public boolean isCoercibleTo(PDataType targetType) {
-          return this == targetType || SMALLINT.isCoercibleTo(targetType);
-      }
-      
-      @Override
-      public Object getSampleValue(Integer maxLength, Integer arrayLength) {
-          return ((Integer) INTEGER.getSampleValue(maxLength, arrayLength)).byteValue();
-      }
-
-    },
-    FLOAT("FLOAT", Types.FLOAT, Float.class, new FloatCodec()) {
-
-        @Override
-        public int compareTo(Object lhs, Object rhs, PDataType rhsType) {
-            return DOUBLE.compareTo(lhs, rhs, rhsType);
-        }
-
-        @Override
-        public boolean isFixedWidth() {
-            return true;
-        }
-
-        @Override
-        public Integer getByteSize() {
-            return Bytes.SIZEOF_FLOAT;
-        }
-        
-        @Override
-        public Integer getScale(Object o) {
-            if (o == null) {
-                return null;
-            }
-            Float v = (Float) o;
-            BigDecimal bd = BigDecimal.valueOf(v);
-            return bd.scale() == 0 ? null : bd.scale();
-        }
-        
-        @Override
-        public Integer getMaxLength(Object o) {
-            if (o == null) {
-                return null;
-            }
-            Float v = (Float) o;
-            BigDecimal bd = BigDecimal.valueOf(v);
-            return bd.precision();
-        }
-
-        @Override
-        public byte[] toBytes(Object object) {
-            byte[] b = new byte[Bytes.SIZEOF_FLOAT];
-            toBytes(object, b, 0);
-            return b;
-        }
-
-        @Override
-        public int toBytes(Object object, byte[] bytes, int offset) {
-            if (object == null) {
-                throw newIllegalDataException(this + " may not be null");
-            }
-            return this.getCodec().encodeFloat(((Number) object).floatValue(),
-                    bytes, offset);
-        }
-
-        @Override
-        public Object toObject(String value) {
-            if (value == null || value.length() == 0) {
-                return null;
-            }
-            try {
-                return Float.parseFloat(value);
-            } catch (NumberFormatException e) {
-                throw newIllegalDataException(e);
-            }
-        }
-        
-        @Override
-        public Object toObject(Object object, PDataType actualType) {
-            if (object == null) {
-                return null;
-            }
-            switch (actualType) {
-            case FLOAT:
-            case UNSIGNED_FLOAT:
-                return object;
-            case DOUBLE:
-            case UNSIGNED_DOUBLE:
-                double d = (Double)object;
-                if (Double.isNaN(d)
-                        || d == Double.POSITIVE_INFINITY
-                        || d == Double.NEGATIVE_INFINITY
-                        || (d >= -Float.MAX_VALUE && d <= Float.MAX_VALUE)) {
-                    return (float) d;
-                } else {
-                    throw newIllegalDataException(actualType + " value " + d + " cannot be cast to Float without changing its value");
-                }
-            case LONG:
-            case UNSIGNED_LONG:
-                float f = (Long)object;
-                return f;
-            case UNSIGNED_INT:
-            case INTEGER:
-                f = (Integer)object;
-                return f;
-            case TINYINT:
-            case UNSIGNED_TINYINT:
-                f = (Byte)object;
-                return f;
-            case SMALLINT:
-            case UNSIGNED_SMALLINT:
-                f = (Short)object;
-                return f;
-            case DECIMAL:
-                BigDecimal dl = (BigDecimal)object;
-                return dl.floatValue();
-            default:
-                return throwConstraintViolationException(actualType,this);
-            }
-        }
-        
-        @Override
-        public Float toObject(byte[] b, int o, int l, PDataType actualType, SortOrder sortOrder, Integer maxLength, Integer scale) {
-            if (l <= 0) {
-                return null;
-            }
-            switch (actualType) {
-            case FLOAT:
-            case UNSIGNED_FLOAT:
-            case DOUBLE:
-            case UNSIGNED_DOUBLE:
-            case UNSIGNED_LONG:
-            case LONG:
-            case UNSIGNED_INT:
-            case INTEGER:
-            case UNSIGNED_SMALLINT:
-            case SMALLINT:
-            case UNSIGNED_TINYINT:
-            case TINYINT:
-                return actualType.getCodec().decodeFloat(b, o, sortOrder);
-            case DECIMAL:
-                BigDecimal bd = (BigDecimal)actualType.toObject(b, o, l, actualType, sortOrder);
-                return bd.floatValue();
-            }
-            
-            throwConstraintViolationException(actualType,this);
-            return null;
-        }
-        
-        @Override
-        public boolean isCoercibleTo(PDataType targetType, Object value) {
-            if (value != null) {
-                float f = (Float)value;
-                switch (targetType) {
-                case UNSIGNED_FLOAT:
-                    return f >= 0;
-                case UNSIGNED_LONG:
-                    return (f >= 0 && f <= Long.MAX_VALUE);
-                case LONG:
-                    return (f >= Long.MIN_VALUE && f <= Long.MAX_VALUE);
-                case UNSIGNED_INT:
-                    return (f >= 0 && f <= Integer.MAX_VALUE);
-                case INTEGER:
-                    return (f >= Integer.MIN_VALUE && f <= Integer.MAX_VALUE);
-                case UNSIGNED_SMALLINT:
-                    return (f >= 0 && f <= Short.MAX_VALUE);
-                case SMALLINT:
-                    return (f >=Short.MIN_VALUE && f<=Short.MAX_VALUE);
-                case TINYINT:
-                    return (f >=Byte.MIN_VALUE && f<Byte.MAX_VALUE);
-                case UNSIGNED_TINYINT:
-                    return (f >=0 && f<Byte.MAX_VALUE);
-                default:
-                    break;
-                }
-            }
-            return super.isCoercibleTo(targetType, value);
-        }
-        
-        @Override
-        public boolean isCoercibleTo(PDataType targetType) {
-            return this == targetType || DOUBLE.isCoercibleTo(targetType);
-        }
-
-        @Override
-        public Object getSampleValue(Integer maxLength, Integer arrayLength) {
-            return RANDOM.get().nextFloat();
-        }
-    },
-    DOUBLE("DOUBLE", Types.DOUBLE, Double.class, new DoubleCodec()) {
-
-        @Override
-        public int compareTo(Object lhs, Object rhs, PDataType rhsType) {
-            if (rhsType == DECIMAL) {
-                return -((BigDecimal)rhs).compareTo(BigDecimal.valueOf(((Number)lhs).doubleValue()));
-            }
-            return Doubles.compare(((Number)lhs).doubleValue(), ((Number)rhs).doubleValue());
-        }
-
-        @Override
-        public boolean isFixedWidth() {
-            return true;
-        }
-
-        @Override
-        public Integer getByteSize() {
-            return Bytes.SIZEOF_DOUBLE;
-        }
-        
-        @Override
-        public Integer getScale(Object o) {
-            if (o == null) {
-                return null;
-            }
-            Double v = (Double) o;
-            BigDecimal bd = BigDecimal.valueOf(v);
-            return bd.scale() == 0 ? null : bd.scale();
-        }
-        
-        @Override
-        public Integer getMaxLength(Object o) {
-            if (o == null) {
-                return null;
-            }
-            Double v = (Double) o;
-            BigDecimal db = BigDecimal.valueOf(v);
-            return db.precision();
-        }
-
-        @Override
-        public byte[] toBytes(Object object) {
-            byte[] b = new byte[Bytes.SIZEOF_DOUBLE];
-            toBytes(object, b, 0);
-            return b;
-        }
-
-        @Override
-        public int toBytes(Object object, byte[] bytes, int offset) {
-            if (object == null) {
-                throw newIllegalDataException(this + " may not be null");
-            } 
-            return this.getCodec().encodeDouble(((Number) object).doubleValue(),
-                    bytes, offset); 
-        }
-
-        @Override
-        public Object toObject(String value) {
-            if (value == null || value.length() == 0) {
-                return null;
-            }
-            try {
-                return Double.parseDouble(value);
-            } catch (NumberFormatException e) {
-                throw newIllegalDataException(e);
-            }
-        }
-        
-        @Override
-        public Object toObject(Object object, PDataType actualType) {
-            if (object == null) {
-                return null;
-            }
-            double de;
-            switch (actualType) {
-            case DOUBLE:
-            case UNSIGNED_DOUBLE:
-                return object; 
-            case FLOAT:
-            case UNSIGNED_FLOAT:
-                de = (Float)object;
-                return de;
-            case LONG:
-            case UNSIGNED_LONG:
-                de = (Long)object;
-                return de;
-            case UNSIGNED_INT:
-            case INTEGER:
-                de = (Integer)object;
-                return de;
-            case TINYINT:
-            case UNSIGNED_TINYINT:
-                de = (Byte)object;
-                return de;
-            case SMALLINT:
-            case UNSIGNED_SMALLINT:
-                de = (Short)object;
-                return de;
-            case DECIMAL:
-                BigDecimal d = (BigDecimal)object;
-                return d.doubleValue();
-            default:
-                return throwConstraintViolationException(actualType,this);
-            }
-        }
-        
-        @Override
-        public Double toObject(byte[] b, int o, int l, PDataType actualType, SortOrder sortOrder, Integer maxLength, Integer scale) {
-            if (l <= 0) {
-                return null;
-            }
-            switch (actualType) {
-            case DOUBLE:
-            case UNSIGNED_DOUBLE:
-            case FLOAT:
-            case UNSIGNED_FLOAT:
-            case UNSIGNED_LONG:
-            case LONG:
-            case UNSIGNED_INT:
-            case INTEGER:
-            case UNSIGNED_SMALLINT:
-            case SMALLINT:
-            case UNSIGNED_TINYINT:
-            case TINYINT:
-                return actualType.getCodec().decodeDouble(b, o, sortOrder);
-            case DECIMAL:
-                BigDecimal bd = (BigDecimal)actualType.toObject(b, o, l, actualType, sortOrder);
-                return bd.doubleValue();
-            }
-            throwConstraintViolationException(actualType,this);
-            return null;
-        }
-        
-        @Override
-        public boolean isCoercibleTo(PDataType targetType, Object value) {
-            if (value != null) {
-                double d = (Double)value;
-                switch (targetType) {
-                case UNSIGNED_DOUBLE:
-                    return d >= 0;
-                case FLOAT:
-                    return Double.isNaN(d)
-                            || d == Double.POSITIVE_INFINITY
-                            || d == Double.NEGATIVE_INFINITY
-                            || (d >= -Float.MAX_VALUE && d <= Float.MAX_VALUE);
-                case UNSIGNED_FLOAT:
-                    return Double.isNaN(d) || d == Double.POSITIVE_INFINITY
-                            || (d >= 0 && d <= Float.MAX_VALUE);
-                case UNSIGNED_LONG:
-                    return (d >= 0 && d <= Long.MAX_VALUE);
-                case LONG:
-                    return (d >= Long.MIN_VALUE && d <= Long.MAX_VALUE);
-                case UNSIGNED_INT:
-                    return (d >= 0 && d <= Integer.MAX_VALUE);
-                case INTEGER:
-                    return (d >= Integer.MIN_VALUE && d <= Integer.MAX_VALUE);
-                case UNSIGNED_SMALLINT:
-                    return (d >= 0 && d <= Short.MAX_VALUE);
-                case SMALLINT:
-                    return (d >=Short.MIN_VALUE && d<=Short.MAX_VALUE);
-                case TINYINT:
-                    return (d >=Byte.MIN_VALUE && d<Byte.MAX_VALUE);
-                case UNSIGNED_TINYINT:
-                    return (d >=0 && d<Byte.MAX_VALUE);
-                default:
-                    break;
-                }
-            }
-            return super.isCoercibleTo(targetType, value);
-        }
-        
-        @Override
-        public boolean isCoercibleTo(PDataType targetType) {
-            return this == targetType || targetType == DECIMAL
-                    || targetType == VARBINARY || targetType == BINARY;
-        }
-        
-        @Override
-        public Object getSampleValue(Integer maxLength, Integer arrayLength) {
-            return RANDOM.get().nextDouble();
-        }
-    },
-    DECIMAL("DECIMAL", Types.DECIMAL, BigDecimal.class, null) {
-        @Override
-        public byte[] toBytes(Object object) {
-            if (object == null) {
-                return ByteUtil.EMPTY_BYTE_ARRAY;
-            }
-            BigDecimal v = (BigDecimal) object;
-            v = NumberUtil.normalize(v);
-            int len = getLength(v);
-            byte[] result = new byte[Math.min(len, MAX_BIG_DECIMAL_BYTES)];
-            PDataType.toBytes(v, result, 0, len);
-            return result;
-        }
-
-        @Override
-        public int toBytes(Object object, byte[] bytes, int offset) {
-            if (object == null) {
-                return 0;
-            }
-            BigDecimal v = (BigDecimal) object;
-            v = NumberUtil.normalize(v);
-            int len = getLength(v);
-            return PDataType.toBytes(v, bytes, offset, len);
-        }
-
-        private int getLength(BigDecimal v) {
-            int signum = v.signum();
-            if (signum == 0) { // Special case for zero
-                return 1;
-            }
-            /*
-             * Size of DECIMAL includes:
-             * 1) one byte for exponent
-             * 2) one byte for terminal byte if negative
-             * 3) one byte for every two digits with the following caveats:
-             *    a) add one to round up in the case when there is an odd number of digits
-             *    b) add one in the case that the scale is odd to account for 10x of lowest significant digit
-             *       (basically done to increase the range of exponents that can be represented)
-             */
-            return (signum < 0 ? 2 : 1) + (v.precision() +  1 + (v.scale() % 2 == 0 ? 0 : 1)) / 2;
-        }
-
-        @Override
-        public int estimateByteSize(Object o) {
-            if (o == null) {
-                return 1;
-            }
-            BigDecimal v = (BigDecimal) o;
-            // TODO: should we strip zeros and round here too?
-            return Math.min(getLength(v),MAX_BIG_DECIMAL_BYTES);
-        }
-
-        @Override
-        public Integer getMaxLength(Object o) {
-            if (o == null) {
-                return MAX_PRECISION;
-            }
-            BigDecimal v = (BigDecimal) o;
-            return v.precision();
-        }
-
-        @Override
-        public Integer getScale(Object o) {
-            return null;
-        }
-
-        @Override
-        public Object toObject(byte[] b, int o, int l, PDataType actualType, SortOrder sortOrder, Integer maxLength, Integer scale) {
-            Preconditions.checkNotNull(sortOrder);        	
-            if (l == 0) {
-                return null;
-            }
-            switch (actualType) {
-            case DECIMAL:
-                if (sortOrder == SortOrder.DESC) {
-                    b = SortOrder.invert(b, o, new byte[l], 0, l);
-                    o = 0;
-                }
-                return toBigDecimal(b, o, l);
-            case DATE:
-            case TIME:
-            case UNSIGNED_DATE:
-            case UNSIGNED_TIME:
-            case LONG:
-            case UNSIGNED_LONG:
-            case INTEGER:
-            case SMALLINT:
-            case TINYINT:
-            case UNSIGNED_INT:
-            case UNSIGNED_SMALLINT:
-            case UNSIGNED_TINYINT:
-                return BigDecimal.valueOf(actualType.getCodec().decodeLong(b, o, sortOrder));
-            case FLOAT:
-            case UNSIGNED_FLOAT:
-                return BigDecimal.valueOf(actualType.getCodec().decodeFloat(b, o, sortOrder));
-            case DOUBLE:
-            case UNSIGNED_DOUBLE:
-                return BigDecimal.valueOf(actualType.getCodec().decodeDouble(b, o, sortOrder));
-            case TIMESTAMP:
-            case UNSIGNED_TIMESTAMP:
-                long millisPart = actualType.getCodec().decodeLong(b, o, sortOrder);
-                int nanoPart = UNSIGNED_INT.getCodec().decodeInt(b, o+Bytes.SIZEOF_LONG, sortOrder);
-                BigDecimal nanosPart = BigDecimal.valueOf((nanoPart % QueryConstants.MILLIS_TO_NANOS_CONVERTOR)/QueryConstants.MILLIS_TO_NANOS_CONVERTOR);
-                BigDecimal value = BigDecimal.valueOf(millisPart).add(nanosPart);
-                return value;
-            case BOOLEAN:
-                return (Boolean)BOOLEAN.toObject(b, o, l, actualType, sortOrder) ? BigDecimal.ONE : BigDecimal.ZERO;
-            default:
-                return throwConstraintViolationException(actualType,this);
-            }
-        }
-
-        @Override
-        public Object toObject(Object object, PDataType actualType) {
-            if (object == null) {
-                return null;
-            }
-            switch (actualType) {
-            case INTEGER:
-            case UNSIGNED_INT:
-                return BigDecimal.valueOf((Integer)object);
-            case LONG:
-            case UNSIGNED_LONG:
-                return BigDecimal.valueOf((Long)object);
-            case SMALLINT:
-            case UNSIGNED_SMALLINT:
-                return BigDecimal.valueOf((Short)object);
-            case TINYINT:
-            case UNSIGNED_TINYINT:
-                return BigDecimal.valueOf((Byte)object);
-            case FLOAT:
-            case UNSIGNED_FLOAT:
-                return BigDecimal.valueOf((Float)object);
-            case DOUBLE:
-            case UNSIGNED_DOUBLE:
-                return BigDecimal.valueOf((Double)object);
-            case DECIMAL:
-                return object;
-            case DATE:
-            case UNSIGNED_DATE:
-            case TIME:
-            case UNSIGNED_TIME:
-                java.util.Date d = (java.util.Date)object;
-                return BigDecimal.valueOf(d.getTime());
-            case TIMESTAMP:
-            case UNSIGNED_TIMESTAMP:
-                Timestamp ts = (Timestamp)object;
-                long millisPart = ts.getTime();
-                BigDecimal nanosPart = BigDecimal.valueOf((ts.getNanos() % QueryConstants.MILLIS_TO_NANOS_CONVERTOR)/QueryConstants.MILLIS_TO_NANOS_CONVERTOR);
-                BigDecimal value = BigDecimal.valueOf(millisPart).add(nanosPart);
-                return value;
-            case BOOLEAN:
-                return ((Boolean)object) ? BigDecimal.ONE : BigDecimal.ZERO;
-            default:
-                return throwConstraintViolationException(actualType,this);
-            }
-        }
-
-        @Override
-        public boolean isFixedWidth() {
-            return false;
-        }
-
-        @Override
-        public Integer getByteSize() {
-            return MAX_BIG_DECIMAL_BYTES;
-        }
-
-        @Override
-        public int compareTo(Object lhs, Object rhs, PDataType rhsType) {
-            if (rhsType == DECIMAL) {
-                return ((BigDecimal)lhs).compareTo((BigDecimal)rhs);
-            }
-            return -rhsType.compareTo(rhs, lhs, this);
-        }
-
-        @Override
-        public boolean isCastableTo(PDataType targetType) {
-            return super.isCastableTo(targetType) || targetType.isCoercibleTo(TIMESTAMP) || targetType == BOOLEAN;
-        }
-
-        @Override
-        public boolean isCoercibleTo(PDataType targetType, Object value) {
-            if (value != null) {
-                BigDecimal bd;
-                switch (targetType) {
-                    case UNSIGNED_LONG:
-                    case UNSIGNED_INT:
-                    case UNSIGNED_SMALLINT:
-                    case UNSIGNED_TINYINT:
-                        bd = (BigDecimal) value;
-                        if (bd.signum() == -1) {
-                            return false;
-                        }
-                    case LONG:
-                        bd = (BigDecimal) value;
-                        try {
-                            bd.longValueExact();
-                            return true;
-                        } catch (ArithmeticException e) {
-                            return false;
-                        }
-                    case INTEGER:
-                        bd = (BigDecimal) value;
-                        try {
-                            bd.intValueExact();
-                            return true;
-                        } catch (ArithmeticException e) {
-                            return false;
-                        }
-                    case SMALLINT:
-                        bd = (BigDecimal) value;
-                        try {
-                            bd.shortValueExact();
-                            return true;
-                        } catch (ArithmeticException e) {
-                            return false;
-                        }
-                    case TINYINT:
-                        bd = (BigDecimal) value;
-                        try {
-                            bd.byteValueExact();
-                            return true;
-                        } catch (ArithmeticException e) {
-                            return false;
-                        }
-                    case UNSIGNED_FLOAT:
-                        bd = (BigDecimal) value;
-                        try {
-                            BigDecimal maxFloat = MAX_FLOAT_AS_BIG_DECIMAL;
-                            boolean isNegtive = (bd.signum() == -1);
-                            return bd.compareTo(maxFloat)<=0 && !isNegtive;
-                        } catch(Exception e) {
-                            return false;
-                        }
-                    case FLOAT:
-                        bd = (BigDecimal) value;
-                        try {
-                            BigDecimal maxFloat = MAX_FLOAT_AS_BIG_DECIMAL;
-                            // Float.MIN_VALUE should not be used here, as this is the
-                            // smallest in terms of closest to zero.
-                            BigDecimal minFloat = MIN_FLOAT_AS_BIG_DECIMAL;
-                            return bd.compareTo(maxFloat)<=0 && bd.compareTo(minFloat)>=0;
-                        } catch(Exception e) {
-                            return false;
-                        }
-                    case UNSIGNED_DOUBLE:
-                        bd = (BigDecimal) value;
-                        try {
-                            BigDecimal maxDouble = MAX_DOUBLE_AS_BIG_DECIMAL;
-                            boolean isNegtive = (bd.signum() == -1);
-                            return bd.compareTo(maxDouble)<=0 && !isNegtive;
-                        } catch(Exception e) {
-                            return false;
-                        }
-                    case DOUBLE:
-                        bd = (BigDecimal) value;
-                        try {
-                            BigDecimal maxDouble = MAX_DOUBLE_AS_BIG_DECIMAL;
-                            BigDecimal minDouble = MIN_DOUBLE_AS_BIG_DECIMAL;
-                            return bd.compareTo(maxDouble)<=0 && bd.compareTo(minDouble)>=0;
-                        } catch(Exception e) {
-                            return false;
-                        }
-                    default:
-                        break;
-                }
-            }
-            return super.isCoercibleTo(targetType, value);
-        }
-
-        @Override
-        public boolean isSizeCompatible(ImmutableBytesWritable ptr, Object value, PDataType srcType, Integer maxLength,
-        		Integer scale, Integer desiredMaxLength, Integer desiredScale) {
-            if (ptr.getLength() == 0) {
-                return true;
-            }
-            // Use the scale from the value if provided, as it prevents a deserialization.
-            // The maxLength and scale for the underlying expression are ignored, because they
-            // are not relevant in this case: for example a DECIMAL(10,2) may be assigned to a
-            // DECIMAL(5,0) as long as the value fits.
-            if (value != null) {
-                BigDecimal v = (BigDecimal) value;
-                maxLength = v.precision();
-                scale = v.scale();
-            } else  {
-                int[] v = getDecimalPrecisionAndScale(ptr.get(), ptr.getOffset(), ptr.getLength());
-                maxLength = v[0];
-                scale = v[1];
-            }
-            if (desiredMaxLength != null && desiredScale != null && maxLength != null && scale != null &&
-            		((desiredScale == null && desiredMaxLength < maxLength) || 
-            				(desiredMaxLength - desiredScale) < (maxLength - scale))) {
-                return false;
-            }
-            return true;
-        }
-
-        @Override
-        public void coerceBytes(ImmutableBytesWritable ptr, Object object, PDataType actualType, 
-                Integer maxLength, Integer scale, SortOrder actualModifier,
-                Integer desiredMaxLength, Integer desiredScale, SortOrder expectedModifier) {
-            if (desiredScale == null) {
-                // deiredScale not available, or we do not have scale requirement, delegate to parents.
-                super.coerceBytes(ptr, object, actualType, maxLength, scale, actualModifier, desiredMaxLength, desiredScale, expectedModifier);
-                return;
-            }
-            if (ptr.getLength() == 0) {
-                return;
-            }
-            if (scale == null) {
-                if (object != null) {
-                    BigDecimal v = (BigDecimal) object;
-                    scale = v.scale();
-                } else {
-                    int[] v = getDecimalPrecisionAndScale(ptr.get(), ptr.getOffset(), ptr.getLength());
-                    scale = v[1];
-                }
-            }
-            if (this == actualType && scale <= desiredScale) {
-                // No coerce and rescale necessary
-                return;
-            } else {
-                BigDecimal decimal;
-                // Rescale is necessary.
-                if (object != null) { // value object is passed in.
-                    decimal = (BigDecimal) toObject(object, actualType);
-                } else { // only value bytes is passed in, need to convert to object first.
-                    decimal = (BigDecimal) toObject(ptr);
-                }
-                decimal = decimal.setScale(desiredScale, BigDecimal.ROUND_DOWN);
-                ptr.set(toBytes(decimal));
-            }
-        }
-
-        @Override
-        public Object toObject(String value) {
-            if (value == null || value.length() == 0) {
-                return null;
-            }
-            try {
-                return new BigDecimal(value);
-            } catch (NumberFormatException e) {
-                throw newIllegalDataException(e);
-            }
-        }
-
-        @Override
-        public Integer estimateByteSizeFromLength(Integer length) {
-            // No association of runtime byte size from decimal precision.
-            return null;
-        }
-        
-        @Override
-        public String toStringLiteral(byte[] b, int offset, int length, Format formatter) {
-            if (formatter == null) {
-                BigDecimal o = (BigDecimal)toObject(b, offset, length);
-                return o.toPlainString();
-            }
-            return super.toStringLiteral(b,offset, length, formatter);
-        }
-
-        @Override
-        public Object getSampleValue(Integer maxLength, Integer arrayLength) {
-            return new BigDecimal((Long) LONG.getSampleValue(maxLength, arrayLength));
-        }
-    },
-    TIMESTAMP("TIMESTAMP", Types.TIMESTAMP, Timestamp.class, new DateCodec()) {
-
-        @Override
-        public byte[] toBytes(Object object) {
-            if (object == null) {
-                throw newIllegalDataException(this + " may not be null");
-            }
-            byte[] bytes = new byte[getByteSize()];
-            toBytes(object, bytes, 0);
-            return bytes;
-        }
-
-        @Override
-        public int toBytes(Object object, byte[] bytes, int offset) {
-            if (object == null) {
-                throw newIllegalDataException(this + " may not be null");
-            }
-            Timestamp value = (Timestamp)object;
-            DATE.getCodec().encodeLong(value.getTime(), bytes, offset);
-            
-            /*
-             * By not getting the stuff that got spilled over from the millis part,
-             * it leaves the timestamp's byte representation saner - 8 bytes of millis | 4 bytes of nanos.
-             * Also, it enables timestamp bytes to be directly compared with date/time bytes.   
-             */
-            Bytes.putInt(bytes, offset + Bytes.SIZEOF_LONG, value.getNanos() % 1000000);  
-            return getByteSize();
-        }
-
-        @Override
-        public Object toObject(Object object, PDataType actualType) {
-            if (object == null) {
-                return null;
-            }
-            switch (actualType) {
-            case DATE:
-            case TIME:
-            case UNSIGNED_DATE:
-            case UNSIGNED_TIME:
-                return new Timestamp(((java.util.Date)object).getTime());
-            case TIMESTAMP:
-            case UNSIGNED_TIMESTAMP:
-                return object;
-            case LONG:
-            case UNSIGNED_LONG:
-                return new Timestamp((Long)object);
-            case DECIMAL:
-                BigDecimal bd = (BigDecimal)object;
-                long ms = bd.longValue();
-                int nanos = (bd.remainder(BigDecimal.ONE).multiply(QueryConstants.BD_MILLIS_NANOS_CONVERSION)).intValue();
-                return DateUtil.getTimestamp(ms, nanos);
-            default:
-                return throwConstraintViolationException(actualType,this);
-            }
-        }
-
-        @Override
-        public Timestamp toObject(byte[] b, int o, int l, PDataType actualType, SortOrder sortOrder, Integer maxLength, Integer scale) {
-            if (actualType == null || l == 0) {
-                return null;
-            }
-            switch (actualType) {
-            case TIMESTAMP:
-            case UNSIGNED_TIMESTAMP:
-                long millisDeserialized = (actualType == TIMESTAMP ? DATE : UNSIGNED_DATE).getCodec().decodeLong(b, o, sortOrder);
-                Timestamp v = new Timestamp(millisDeserialized);
-                int nanosDeserialized = PDataType.UNSIGNED_INT.getCodec().decodeInt(b, o + Bytes.SIZEOF_LONG, sortOrder);
-                /*
-                 * There was a bug in serialization of timestamps which was causing the sub-second millis part
-                 * of time stamp to be present both in the LONG and INT bytes. Having the <100000 check
-                 * makes this serialization fix backward compatible.
-                 */
-                v.setNanos(nanosDeserialized < 1000000 ? v.getNanos() + nanosDeserialized : nanosDeserialized);
-                return v;
-            case DATE:
-            case TIME:
-            case LONG:
-            case UNSIGNED_LONG:
-            case UNSIGNED_DATE:
-            case UNSIGNED_TIME:
-                return new Timestamp(actualType.getCodec().decodeLong(b, o, sortOrder));
-            case DECIMAL:
-                BigDecimal bd = (BigDecimal) actualType.toObject(b, o, l, actualType, sortOrder);
-                long ms = bd.longValue();
-                int nanos = (bd.remainder(BigDecimal.ONE).multiply(QueryConstants.BD_MILLIS_NANOS_CONVERSION)).intValue();
-                v = DateUtil.getTimestamp(ms, nanos);
-                return v;
-            }
-            throwConstraintViolationException(actualType,this);
-            return null;
-        }
-        
-        @Override
-        public boolean isCastableTo(PDataType targetType) {
-            return DATE.isCastableTo(targetType);
-        }
-
-       @Override
-        public boolean isCoercibleTo(PDataType targetType) {
-            return this == targetType || targetType == VARBINARY || targetType == BINARY;
-        }
-
-        @Override
-        public boolean isCoercibleTo(PDataType targetType, Object value) {
-            if (value != null) {
-                switch (targetType) {
-                    case UNSIGNED_TIMESTAMP:
-                        return ((java.util.Date)value).getTime() >= 0;
-                    case UNSIGNED_DATE:
-                    case UNSIGNED_TIME:
-                        return ((java.util.Date)value).getTime() >= 0 && ((Timestamp)value).getNanos() == 0;
-                    case DATE:
-                    case TIME:
-                        return ((Timestamp)value).getNanos() == 0;
-                    default:
-                        break;
-                }
-            }
-            return super.isCoercibleTo(targetType, value);
-        }
-        
-        @Override
-        public boolean isFixedWidth() {
-            return true;
-        }
-
-        @Override
-        public Integer getByteSize() {
-            return MAX_TIMESTAMP_BYTES;
-        }
-
-        @Override
-        public int compareTo(Object lhs, Object rhs, PDataType rhsType) {
-            if (rhsType == TIMESTAMP || rhsType == UNSIGNED_TIMESTAMP) {
-                return ((Timestamp)lhs).compareTo((Timestamp)rhs);
-            }
-            int c = ((Date)rhs).compareTo((Date)lhs);
-            if (c != 0) return c;
-            return ((Timestamp)lhs).getNanos();
-        }
-
-        @Override
-        public Object toObject(String value) {
-            if (value == null || value.length() == 0) {
-                return null;
-            }
-            return DateUtil.parseTimestamp(value);
-        }
-        
-        @Override
-        public String toStringLiteral(byte[] b, int offset, int length, Format formatter) {
-            Timestamp value = (Timestamp)toObject(b,offset,length);
-            if (formatter == null || formatter == DateUtil.DEFAULT_DATE_FORMATTER) {
-                // If default formatter has not been overridden,
-                // use one that displays milliseconds.
-                formatter = DateUtil.DEFAULT_MS_DATE_FORMATTER;
-            }
-            return "'" + super.toStringLiteral(b, offset, length, formatter) + "." + value.getNanos() + "'";
-        }
-        
-        @Override
-        public int getNanos(ImmutableBytesWritable ptr, SortOrder sortOrder) {
-            int nanos = PDataType.UNSIGNED_INT.getCodec().decodeInt(ptr.get(), ptr.getOffset() + PDataType.LONG.getByteSize(), sortOrder);
-            return nanos;
-        }
-        
-        @Override
-        public long getMillis(ImmutableBytesWritable ptr, SortOrder sortOrder) {
-            long millis = PDataType.LONG.getCodec().decodeLong(ptr.get(),ptr.getOffset(), sortOrder);
-            return millis;
-        }
-        
-        @Override
-        public Object getSampleValue(Integer maxLength, Integer arrayLength) {
-            return new Timestamp((Long) LONG.getSampleValue(maxLength, arrayLength));
-        }
-
-    },
-    TIME("TIME", Types.TIME, Time.class, new DateCodec()) {
-
-        @Override
-        public byte[] toBytes(Object object) {
-            return DATE.toBytes(object);
-        }
-
-        @Override
-        public int toBytes(Object object, byte[] bytes, int offset) {
-            return DATE.toBytes(object, bytes, offset);
-        }
-
-        @Override
-        public Time toObject(byte[] b, int o, int l, PDataType actualType, SortOrder sortOrder, Integer maxLength, Integer scale) {
-            if (l == 0) {
-                return null;
-            }
-            switch (actualType) {
-            case TIMESTAMP:
-            case UNSIGNED_TIMESTAMP:
-            case DATE:
-            case TIME:
-            case LONG:
-            case UNSIGNED_LONG:
-            case UNSIGNED_DATE:
-            case UNSIGNED_TIME:
-                return new Time(actualType.getCodec().decodeLong(b, o, sortOrder));
-            case DECIMAL:
-                BigDecimal bd = (BigDecimal)actualType.toObject(b, o, l, actualType, sortOrder);
-                return new Time(bd.longValueExact());
-            }
-            throwConstraintViolationException(actualType,this);
-            return null;
-        }
-
-        @Override
-        public Object toObject(Object object, PDataType actualType) {
-            if (object == null) {
-                return null;
-            }
-            switch (actualType) {
-            case DATE:
-            case UNSIGNED_DATE:
-                return new Time(((Date)object).getTime());
-            case TIMESTAMP:
-            case UNSIGNED_TIMESTAMP:
-                return new Time(((Timestamp)object).getTime());
-            case TIME:
-            case UNSIGNED_TIME:
-                return object;
-            case LONG:
-            case UNSIGNED_LONG:
-                return new Time((Long)object);
-            case DECIMAL:
-                return new Time(((BigDecimal)object).longValueExact());
-            default:
-                return throwConstraintViolationException(actualType,this);
-            }
-        }
-
-        @Override
-        public boolean isCastableTo(PDataType targetType) {
-            return DATE.isCastableTo(targetType);
-        }
-
-        @Override
-        public boolean isCoercibleTo(PDataType targetType) {
-            return DATE.isCoercibleTo(targetType);
-        }
-
-        @Override
-        public boolean isCoercibleTo(PDataType targetType, Object value) {
-            return DATE.isCoercibleTo(targetType, value);
-        }
-        
-        @Override
-        public boolean isFixedWidth() {
-            return true;
-        }
-
-        @Override
-        public Integer getByteSize() {
-            return Bytes.SIZEOF_LONG;
-        }
-
-        @Override
-        public int compareTo(Object lhs, Object rhs, PDataType rhsType) {
-            return DATE.compareTo(lhs, rhs, rhsType);
-        }
-
-        @Override
-        public Object toObject(String value) {
-            if (value == null || value.length() == 0) {
-                return null;
-            }
-            return DateUtil.parseTime(value);
-        }
-
-        @Override
-        public boolean isBytesComparableWith(PDataType otherType) {
-            return super.isBytesComparableWith(otherType) ||  this == DATE;
-        }
-        
-        @Override
-        public String toStringLiteral(byte[] b, int offset, int length, Format formatter) {
-            // TODO: different default formatter for TIME?
-            return DATE.toStringLiteral(b, offset, length, formatter);
-        }
-        
-        @Override
-        public Object getSampleValue(Integer maxLength, Integer arrayLength) {
-            return new Time((Long) LONG.getSampleValue(maxLength, arrayLength));
-        }
-    },
-    DATE("DATE", Types.DATE, Date.class, new DateCodec()) { // After TIMESTAMP and DATE to ensure toLiteral finds those first
-
-        @Override
-        public byte[] toBytes(Object object) {
-            if (object == null) {
-                throw newIllegalDataException(this + " may not be null");
-            }
-            byte[] bytes = new byte[getByteSize()];
-            toBytes(object, bytes, 0);
-            return bytes;
-        }
-
-        @Override
-        public int toBytes(Object object, byte[] bytes, int offset) {
-            if (object == null) {
-                throw newIllegalDataException(this + " may not be null");
-            }
-            getCodec().encodeLong(((java.util.Date)object).getTime(), bytes, offset);
-            return this.getByteSize();
-        }
-
-        @Override
-        public Object toObject(Object object, PDataType actualType) {
-            if (object == null) {
-                return null;
-            }
-            switch (actualType) {
-            case TIME:
-            case UNSIGNED_TIME:
-                return new Date(((Time)object).getTime());
-            case TIMESTAMP:
-            case UNSIGNED_TIMESTAMP:
-                return new Date(((Timestamp)object).getTime());
-            case DATE:
-            case UNSIGNED_DATE:
-                return object;
-            case LONG:
-            case UNSIGNED_LONG:
-                return new Date((Long)object);
-            case DECIMAL:
-                return new Date(((BigDecimal)object).longValueExact());
-            default:
-                return throwConstraintViolationException(actualType,this);
-            }
-        }
-
-        @Override
-        public Date toObject(byte[] b, int o, int l, PDataType actualType, SortOrder sortOrder, Integer maxLength, Integer scale) {
-            if (l == 0) {
-                return null;
-            }
-            switch (actualType) {
-            case TIMESTAMP:
-            case UNSIGNED_TIMESTAMP:
-            case DATE:
-            case TIME:
-            case LONG:
-            case UNSIGNED_LONG:
-            case UNSIGNED_DATE:
-            case UNSIGNED_TIME:
-                return new Date(actualType.getCodec().decodeLong(b, o, sortOrder));
-            case DECIMAL:
-                BigDecimal bd = (BigDecimal)actualType.toObject(b, o, l, actualType, sortOrder);
-                return new Date(bd.longValueExact());
-            }
-            throwConstraintViolationException(actualType,this);
-            return null;
-        }
-
-        @Override
-        public boolean isCastableTo(PDataType targetType) {
-            return super.isCastableTo(targetType) || targetType == DECIMAL || targetType == LONG || targetType == UNSIGNED_LONG;
-        }
-
-        @Override
-        public boolean isCoercibleTo(PDataType targetType) {
-            return targetType == DATE || targetType == TIME || targetType == TIMESTAMP
-                    || targetType == VARBINARY || targetType == BINARY;
-        }
-
-        @Override
-        public boolean isCoercibleTo(PDataType targetType, Object value) {
-            if (value != null) {
-                switch (targetType) {
-                    case UNSIGNED_TIMESTAMP:
-                    case UNSIGNED_DATE:
-                    case UNSIGNED_TIME:
-                        return ((java.util.Date)value).getTime() >= 0;
-                    default:
-                        break;
-                }
-            }
-            return super.isCoercibleTo(targetType, value);
-        }
-
-        @Override
-        public boolean isFixedWidth() {
-            return true;
-        }
-
-        @Override
-        public Integer getByteSize() {
-            return Bytes.SIZEOF_LONG;
-        }
-
-        @Override
-        public int compareTo(Object lhs, Object rhs, PDataType rhsType) {
-            if (rhsType == TIMESTAMP || rhsType == UNSIGNED_TIMESTAMP) {
-                return -rhsType.compareTo(rhs, lhs, TIME);
-            }
-            return ((java.util.Date)rhs).compareTo((java.util.Date)lhs);
-        }
-
-        @Override
-        public Object toObject(String value) {
-            if (value == null || value.length() == 0) {
-                return null;
-            }
-            return DateUtil.parseDate(value);
-        }
-
-        @Override
-        public boolean isBytesComparableWith(PDataType otherType) {
-            return super.isBytesComparableWith(otherType) || this == TIME;
-        }
-        
-        @Override
-        public String toStringLiteral(byte[] b, int offset, int length, Format formatter) {
-            if (formatter == null || formatter == DateUtil.DEFAULT_DATE_FORMATTER) {
-                // If default formatter has not been overridden,
-                // use one that displays milliseconds.
-                formatter = DateUtil.DEFAULT_MS_DATE_FORMATTER;
-            }
-            return "'" + super.toStringLiteral(b, offset, length, formatter) + "'";
-        }
-        
-        @Override
-        public void coerceBytes(ImmutableBytesWritable ptr, Object object, PDataType actualType, 
-                Integer maxLength, Integer scale, SortOrder actualModifier,
-                Integer desiredMaxLength, Integer desiredScale, SortOrder expectedModifier) {
-            if (ptr.getLength() > 0 && actualType  == PDataType.TIMESTAMP && actualModifier == expectedModifier) {
-                ptr.set(ptr.get(), ptr.getOffset(), getByteSize());
-                return;
-            }
-            super.coerceBytes(ptr, object, actualType, maxLength, scale, actualModifier, desiredMaxLength, desiredScale, expectedModifier);
-        }
-
-        @Override
-        public Object getSampleValue(Integer maxLength, Integer arrayLength) {
-            return new Date((Long) LONG.getSampleValue(maxLength, arrayLength));
-        }
-    },
-    UNSIGNED_TIMESTAMP("UNSIGNED_TIMESTAMP", 19, Timestamp.class, null) {
-
-        @Override
-        public byte[] toBytes(Object object) {
-            if (object == null) {
-                throw newIllegalDataException(this + " may not be null");
-            }
-            byte[] bytes = new byte[getByteSize()];
-            toBytes(object, bytes, 0);
-            return bytes;
-        }
-
-        @Override
-        public int toBytes(Object object, byte[] bytes, int offset) {
-            if (object == null) {
-                throw newIllegalDataException(this + " may not be null");
-            }
-            Timestamp value = (Timestamp)object;
-            UNSIGNED_DATE.getCodec().encodeLong(value.getTime(), bytes, offset);
-            
-            /*
-             * By not getting the stuff that got spilled over from the millis part,
-             * it leaves the timestamp's byte representation saner - 8 bytes of millis | 4 bytes of nanos.
-             * Also, it enables timestamp bytes to be directly compared with date/time bytes.   
-             */
-            Bytes.putInt(bytes, offset + Bytes.SIZEOF_LONG, value.getNanos() % 1000000);  
-            return getByteSize();
-        }
-
-        @Override
-        public Object toObject(Object object, PDataType actualType) {
-            Timestamp ts = (Timestamp)TIMESTAMP.toObject(object, actualType);
-            throwIfNonNegativeDate(ts);
-            return ts;
-        }
-
-        @Override
-        public Object toObject(byte[] b, int o, int l, PDataType actualType, SortOrder sortOrder, Integer maxLength, Integer scale) {
-            Timestamp ts = (Timestamp) TIMESTAMP.toObject(b, o, l, actualType, sortOrder);
-            throwIfNonNegativeDate(ts);
-            return ts;
-        }
-        
-        @Override
-        public boolean isCastableTo(PDataType targetType) {
-            return UNSIGNED_DATE.isCastableTo(targetType);
-        }
-
-        @Override
-        public boolean isCoercibleTo(PDataType targetType) {
-            return targetType == this || UNSIGNED_DATE.isCoercibleTo(targetType);
-        }
-
-        @Override
-        public boolean isCoercibleTo(PDataType targetType, Object value) {
-            return super.isCoercibleTo(targetType, value) || TIMESTAMP.isCoercibleTo(targetType, value);
-        }
-
-        @Override
-        public boolean isFixedWidth() {
-            return true;
-        }
-
-        @Override
-        public Integer getByteSize() {
-            return TIMESTAMP.getByteSize();
-        }
-
-        @Override
-        public int compareTo(Object lhs, Object rhs, PDataType rhsType) {
-            return TIMESTAMP.compareTo(lhs, rhs, rhsType);
-        }
-
-        @Override
-        public Object toObject(String value) {
-            return TIMESTAMP.toObject(value);
-        }
-        
-        @Override
-        public String toStringLiteral(byte[] b, int offset, int length, Format formatter) {
-            Timestamp value = (Timestamp)toObject(b,offset,length);
-            if (formatter == null || formatter == DateUtil.DEFAULT_DATE_FORMATTER) {
-                // If default formatter has not been overridden,
-                // use one that displays milliseconds.
-                formatter = DateUtil.DEFAULT_MS_DATE_FORMATTER;
-            }
-            return "'" + super.toStringLiteral(b, offset, length, formatter) + "." + value.getNanos() + "'";
-        }
-        
-        @Override
-        public int getNanos(ImmutableBytesWritable ptr, SortOrder sortOrder) {
-            int nanos = PDataType.UNSIGNED_INT.getCodec().decodeInt(ptr.get(), ptr.getOffset() + PDataType.LONG.getByteSize(), sortOrder);
-            return nanos;
-        }
-        
-        @Override
-        public long getMillis(ImmutableBytesWritable ptr, SortOrder sortOrder) {
-            long millis = PDataType.UNSIGNED_LONG.getCodec().decodeLong(ptr.get(),ptr.getOffset(), sortOrder);
-            return millis;
-        }
-
-        @Override
-        public int getResultSetSqlType() {
-            return Types.TIMESTAMP;
-        }
-
-        @Override
-        public Object getSampleValue(Integer maxLength, Integer arrayLength) {
-            return new Timestamp((Long) UNSIGNED_LONG.getSampleValue(maxLength, arrayLength));
-        }
-    },
-    UNSIGNED_TIME("UNSIGNED_TIME", 18, Time.class, new UnsignedDateCodec()) {
-
-        @Override
-        public byte[] toBytes(Object object) {
-            return UNSIGNED_DATE.toBytes(object);
-        }
-
-        @Override
-        public int toBytes(Object object, byte[] bytes, int offset) {
-            return UNSIGNED_DATE.toBytes(object, bytes, offset);
-        }
-
-        @Override
-        public Object toObject(byte[] b, int o, int l, PDataType actualType, SortOrder sortOrder, Integer maxLength, Integer scale) {
-            Time t = (Time)TIME.toObject(b, o, l, actualType, sortOrder);
-            throwIfNonNegativeDate(t);
-            return t;
-        }
-
-        @Override
-        public Object toObject(Object object, PDataType actualType) {
-            Time t = (Time)TIME.toObject(object, actualType);
-            throwIfNonNegativeDate(t);
-            return t;
-        }
-
-        @Override
-        public boolean isCastableTo(PDataType targetType) {
-            return UNSIGNED_DATE.isCastableTo(targetType);
-        }
-
-        @Override
-        public boolean isCoercibleTo(PDataType targetType) {
-            return UNSIGNED_DATE.isCoercibleTo(targetType);
-        }
-
-        @Override
-        public boolean isCoercibleTo(PDataType targetType, Object value) {
-            return super.isCoercibleTo(targetType, value) || TIME.isCoercibleTo(targetType, value);
-        }
-
-        @Override
-        public boolean isFixedWidth() {
-            return true;
-        }
-
-        @Override
-        public Integer getByteSize() {
-            return Bytes.SIZEOF_LONG;
-        }
-
-        @Override
-        public int compareTo(Object lhs, Object rhs, PDataType rhsType) {
-            return TIME.compareTo(lhs, rhs, rhsType);
-        }
-
-        @Override
-        public Object toObject(String value) {
-            return TIME.toObject(value);
-        }
-
-        @Override
-        public boolean isBytesComparableWith(PDataType otherType) {
-            return super.isBytesComparableWith(otherType) ||  this == UNSIGNED_DATE;
-        }
-        
-        @Override
-        public String toStringLiteral(byte[] b, int offset, int length, Format formatter) {
-            return UNSIGNED_DATE.toStringLiteral(b, offset, length, formatter);
-        }
-
-        @Override
-        public int getResultSetSqlType() {
-            return Types.TIME;
-        }
-
-        @Override
-        public Object getSampleValue(Integer maxLength, Integer arrayLength) {
-            return new Time((Long) UNSIGNED_LONG.getSampleValue(maxLength, arrayLength));
-        }
-    },
-    UNSIGNED_DATE("UNSIGNED_DATE", 19, Date.class, new UnsignedDateCodec()) { // After TIMESTAMP and DATE to ensure toLiteral finds those first
-
-        @Override
-        public byte[] toBytes(Object object) {
-            if (object == null) {
-                throw newIllegalDataException(this + " may not be null");
-            }
-            byte[] bytes = new byte[getByteSize()];
-            toBytes(object, bytes, 0);
-            return bytes;
-        }
-
-        @Override
-        public int toBytes(Object object, byte[] bytes, int offset) {
-            if (object == null) {
-                throw newIllegalDataException(this + " may not be null");
-            }
-            getCodec().encodeLong(((java.util.Date)object).getTime(), bytes, offset);
-            return this.getByteSize();
-        }
-
-        @Override
-        public Object toObject(Object object, PDataType actualType) {
-            Date d = (Date)DATE.toObject(object, actualType);
-            throwIfNonNegativeDate(d);
-            return d;
-        }
-
-        @Override
-        public Object toObject(byte[] b, int o, int l, PDataType actualType, SortOrder sortOrder, Integer maxLength, Integer scale) {
-            Date d = (Date)DATE.toObject(b,o,l,actualType, sortOrder);
-            throwIfNonNegativeDate(d);
-            return d;
-        }
-
-        @Override
-        public boolean isCastableTo(PDataType targetType) {
-            return DATE.isCastableTo(targetType);
-        }
-
-        @Override
-        public boolean isCoercibleTo(PDataType targetType) {
-            return targetType == this || targetType == UNSIGNED_TIME || targetType == UNSIGNED_TIMESTAMP
-                    || DATE.isCoercibleTo(targetType);
-        }
-
-        @Override
-        public boolean isCoercibleTo(PDataType targetType, Object value) {
-            return super.isCoercibleTo(targetType, value) || DATE.isCoercibleTo(targetType, value);
-        }
-
-        @Override
-        public boolean isFixedWidth() {
-            return true;
-        }
-
-        @Override
-        public Integer getByteSize() {
-            return DATE.getByteSize();
-        }
-
-        @Override
-        public int compareTo(Object lhs, Object rhs, PDataType rhsType) {
-            return DATE.compareTo(lhs, rhs, rhsType);
-        }
-
-        @Override
-        public Object toObject(String va

<TRUNCATED>