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:54 UTC

[16/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/PArrayDataType.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PArrayDataType.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PArrayDataType.java
deleted file mode 100644
index 8d96b87..0000000
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PArrayDataType.java
+++ /dev/null
@@ -1,660 +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.io.DataOutputStream;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
-import org.apache.hadoop.hbase.util.Bytes;
-import org.apache.hadoop.hbase.util.Pair;
-import org.apache.phoenix.expression.Expression;
-import org.apache.phoenix.query.QueryConstants;
-import org.apache.phoenix.schema.tuple.Tuple;
-import org.apache.phoenix.util.ByteUtil;
-import org.apache.phoenix.util.TrustedByteArrayOutputStream;
-
-import com.google.common.base.Objects;
-import com.google.common.base.Preconditions;
-
-/**
- * The datatype for PColummns that are Arrays. Any variable length array would follow the below order. 
- * Every element would be seperated by a seperator byte '0'. Null elements are counted and once a first 
- * non null element appears we write the count of the nulls prefixed with a seperator byte.
- * Trailing nulls are not taken into account. The last non null element is followed by two seperator bytes. 
- * For eg a, b, null, null, c, null -> 65 0 66 0 0 2 67 0 0 0 
- * a null null null b c null d -> 65 0 0 3 66 0 67 0 0 1 68 0 0 0.
- * The reason we use this serialization format is to allow the
- * byte array of arrays of the same type to be directly comparable against each other. 
- * This prevents a costly deserialization on compare and allows an array column to be used as the last column in a primary key constraint.
- */
-public class PArrayDataType {
-
-    public static final byte ARRAY_SERIALIZATION_VERSION = 1;
-	public PArrayDataType() {
-	}
-
-	public byte[] toBytes(Object object, PDataType baseType, SortOrder sortOrder) {
-		if(object == null) {
-			throw new ConstraintViolationException(this + " may not be null");
-		}
-		PhoenixArray arr = ((PhoenixArray)object);
-        int noOfElements = arr.numElements;
-        if(noOfElements == 0) {
-        	return ByteUtil.EMPTY_BYTE_ARRAY;
-        }
-        TrustedByteArrayOutputStream byteStream = null;
-		if (!baseType.isFixedWidth()) {
-	        Pair<Integer, Integer> nullsVsNullRepeationCounter = new Pair<Integer, Integer>();
-	        int size = estimateByteSize(object, nullsVsNullRepeationCounter,
-	                PDataType.fromTypeId((baseType.getSqlType() + PDataType.ARRAY_TYPE_BASE)));
-		    size += ((2 * Bytes.SIZEOF_BYTE) + (noOfElements - nullsVsNullRepeationCounter.getFirst()) * Bytes.SIZEOF_BYTE)
-		                                + (nullsVsNullRepeationCounter.getSecond() * 2 * Bytes.SIZEOF_BYTE);
-		    // Assume an offset array that fit into Short.MAX_VALUE.  Also not considering nulls that could be > 255
-		    // In both of these cases, finally an array copy would happen
-		    int capacity = noOfElements * Bytes.SIZEOF_SHORT;
-		    // Here the int for noofelements, byte for the version, int for the offsetarray position and 2 bytes for the end seperator
-            byteStream = new TrustedByteArrayOutputStream(size + capacity + Bytes.SIZEOF_INT + Bytes.SIZEOF_BYTE +  Bytes.SIZEOF_INT);
-		} else {
-		    int size = arr.getMaxLength() * noOfElements;
-		    // Here the int for noofelements, byte for the version
-		    byteStream = new TrustedByteArrayOutputStream(size);
-		}
-		DataOutputStream oStream = new DataOutputStream(byteStream);
-		// Handles bit inversion also
-		return createArrayBytes(byteStream, oStream, (PhoenixArray)object, noOfElements, baseType, sortOrder);
-	}
-	
-    public static int serializeNulls(DataOutputStream oStream, int nulls) throws IOException {
-        // We need to handle 3 different cases here
-        // 1) Arrays with repeating nulls in the middle which is less than 255
-        // 2) Arrays with repeating nulls in the middle which is less than 255 but greater than bytes.MAX_VALUE
-        // 3) Arrays with repeating nulls in the middle greaterh than 255
-        // Take a case where we have two arrays that has the following elements
-        // Array 1 - size : 240, elements = abc, bcd, null, null, bcd,null,null......,null, abc
-        // Array 2 - size : 16 : elements = abc, bcd, null, null, bcd, null, null...null, abc
-        // In both case the elements and the value array will be the same but the Array 1 is actually smaller because it has more nulls.
-        // Now we should have mechanism to show that we treat arrays with more nulls as lesser.  Hence in the above case as 
-        // 240 > Bytes.MAX_VALUE, by always inverting the number of nulls we would get a +ve value
-        // For Array 2, by inverting we would get a -ve value.  On comparison Array 2 > Array 1.
-        // Now for cases where the number of nulls is greater than 255, we would write an those many (byte)1, it is bigger than 255.
-        // This would ensure that we don't compare with triple zero which is used as an end  byte
-        if (nulls > 0) {
-            oStream.write(QueryConstants.SEPARATOR_BYTE);
-            int nMultiplesOver255 = nulls / 255;
-            while (nMultiplesOver255-- > 0) {
-                // Don't write a zero byte, as we need to ensure that the only triple zero
-                // byte occurs at the end of the array (i.e. the terminator byte for the
-                // element plus the double zero byte at the end of the array).
-                oStream.write((byte)1); 
-            }
-            int nRemainingNulls = nulls % 255; // From 0 to 254
-            // Write a byte for the remaining null elements
-            if (nRemainingNulls > 0) {
-                // Remaining null elements is from 1 to 254.
-                // Subtract one and invert so that more remaining nulls becomes smaller than less 
-                // remaining nulls and min byte value is always greater than 1, the repeating value  
-                // used for arrays with more than 255 repeating null elements.
-                // The reason we invert is that  an array with less null elements has a non
-                // null element sooner than an array with more null elements. Thus, the more
-                // null elements you have, the smaller the array becomes.
-                byte nNullByte = SortOrder.invert((byte)(nRemainingNulls-1));
-                oStream.write(nNullByte); // Single byte for repeating nulls
-            }
-        }
-        return 0;
-    }
- 
-    public static void writeEndSeperatorForVarLengthArray(DataOutputStream oStream) throws IOException {
-        oStream.write(QueryConstants.SEPARATOR_BYTE);
-        oStream.write(QueryConstants.SEPARATOR_BYTE);
-    }
-
-	public static boolean useShortForOffsetArray(int maxOffset) {
-		// If the max offset is less than Short.MAX_VALUE then offset array can use short
-		if (maxOffset <= (2 * Short.MAX_VALUE)) {
-			return true;
-		}
-		// else offset array can use Int
-		return false;
-	}
-
-	public int toBytes(Object object, byte[] bytes, int offset) {
-	    PhoenixArray array = (PhoenixArray)object;
-        if (array == null || array.baseType == null) {
-            return 0;
-        }
-        return estimateByteSize(object, null, PDataType.fromTypeId((array.baseType.getSqlType() + PDataType.ARRAY_TYPE_BASE)));
-	}
-
-	// Estimates the size of the given array and also calculates the number of nulls and its repetition factor
-    public int estimateByteSize(Object o, Pair<Integer, Integer> nullsVsNullRepeationCounter, PDataType baseType) {
-        if (baseType.isFixedWidth()) { return baseType.getByteSize(); }
-        if (baseType.isArrayType()) {
-            PhoenixArray array = (PhoenixArray)o;
-            int noOfElements = array.numElements;
-            int totalVarSize = 0;
-            int nullsRepeationCounter = 0;
-            int nulls = 0;
-            int totalNulls = 0;
-            for (int i = 0; i < noOfElements; i++) {
-                totalVarSize += array.estimateByteSize(i);
-                if (!PDataType.fromTypeId((baseType.getSqlType() - PDataType.ARRAY_TYPE_BASE)).isFixedWidth()) {
-                    if (array.isNull(i)) {
-                        nulls++;
-                    } else {
-                        if (nulls > 0) {
-                            totalNulls += nulls;
-                            nulls = 0;
-                            nullsRepeationCounter++;
-                        }
-                    }
-                }
-            }
-            if (nullsVsNullRepeationCounter != null) {
-                if (nulls > 0) {
-                    totalNulls += nulls;
-                    // do not increment nullsRepeationCounter to identify trailing nulls
-                }
-                nullsVsNullRepeationCounter.setFirst(totalNulls);
-                nullsVsNullRepeationCounter.setSecond(nullsRepeationCounter);
-            }
-            return totalVarSize;
-        }
-        // Non fixed width types must override this
-        throw new UnsupportedOperationException();
-    }
-    
-	public boolean isCoercibleTo(PDataType targetType, Object value) {
-	    return targetType.isCoercibleTo(targetType, value);
-	}
-	
-	public boolean isCoercibleTo(PDataType targetType, PDataType expectedTargetType) {
-		if(!targetType.isArrayType()) {
-			return false;
-		} else {
-			PDataType targetElementType = PDataType.fromTypeId(targetType.getSqlType()
-					- PDataType.ARRAY_TYPE_BASE);
-			PDataType expectedTargetElementType = PDataType.fromTypeId(expectedTargetType
-					.getSqlType() - PDataType.ARRAY_TYPE_BASE);
-			return expectedTargetElementType.isCoercibleTo(targetElementType);
-		}
-    }
-	
-	public boolean isSizeCompatible(ImmutableBytesWritable ptr, Object value,
-			PDataType srcType, Integer maxLength, Integer scale,
-			Integer desiredMaxLength, Integer desiredScale) {
-        if (value == null) return true;
-		PhoenixArray pArr = (PhoenixArray) value;
-		Object[] arr = (Object[]) pArr.array;
-		PDataType baseType = PDataType.fromTypeId(srcType.getSqlType()
-				- PDataType.ARRAY_TYPE_BASE);
-		for (int i = 0 ; i < arr.length; i++) {
-			if (!baseType.isSizeCompatible(ptr, arr[i], baseType, srcType.getMaxLength(arr[i]),
-					scale, desiredMaxLength, desiredScale)) {
-				return false;
-			}
-		}
-		return true;
-	}
-	
-    public void coerceBytes(ImmutableBytesWritable ptr, Object value, PDataType actualType, Integer maxLength,
-            Integer scale, Integer desiredMaxLength, Integer desiredScale, PDataType desiredType,
-            SortOrder actualModifer, SortOrder expectedModifier) {
-        if (ptr.getLength() == 0) { // a zero length ptr means null which will not be coerced to anything different
-            return;
-        }
-        PDataType baseType = PDataType.fromTypeId(actualType.getSqlType() - PDataType.ARRAY_TYPE_BASE);
-        PDataType desiredBaseType = PDataType.fromTypeId(desiredType.getSqlType() - PDataType.ARRAY_TYPE_BASE);
-        if ((Objects.equal(maxLength, desiredMaxLength) || maxLength == null || desiredMaxLength == null)
-                && actualType.isBytesComparableWith(desiredType)
-                && baseType.isFixedWidth() == desiredBaseType.isFixedWidth() && actualModifer == expectedModifier) { 
-            return; 
-        }
-        if (value == null || actualType != desiredType) {
-            value = toObject(ptr.get(), ptr.getOffset(), ptr.getLength(), baseType, actualModifer, maxLength,
-                    desiredScale, desiredBaseType);
-            PhoenixArray pArr = (PhoenixArray)value;
-            // VARCHAR <=> CHAR
-            if(baseType.isFixedWidth() != desiredBaseType.isFixedWidth()) {
-                if (!pArr.isPrimitiveType()) {
-                    pArr = new PhoenixArray(pArr, desiredMaxLength);
-                }
-            }
-            baseType = desiredBaseType;
-            ptr.set(toBytes(pArr, baseType, expectedModifier));
-        } else {
-            PhoenixArray pArr = (PhoenixArray)value;
-            pArr = new PhoenixArray(pArr, desiredMaxLength);
-            ptr.set(toBytes(pArr, baseType, expectedModifier));
-        }
-    }
-
-
-    public Object toObject(String value) {
-		throw new IllegalArgumentException("This operation is not suppported");
-	}
-
-	public Object toObject(byte[] bytes, int offset, int length, PDataType baseType, 
-			SortOrder sortOrder, Integer maxLength, Integer scale, PDataType desiredDataType) {
-		return createPhoenixArray(bytes, offset, length, sortOrder,
-				baseType, maxLength, desiredDataType);
-	}
-
-    public static boolean positionAtArrayElement(Tuple tuple, ImmutableBytesWritable ptr, int index,
-            Expression arrayExpr, PDataType pDataType, Integer maxLen) {
-        if (!arrayExpr.evaluate(tuple, ptr)) {
-            return false;
-        } else if (ptr.getLength() == 0) { return true; }
-
-        // Given a ptr to the entire array, set ptr to point to a particular element within that array
-        // given the type of an array element (see comments in PDataTypeForArray)
-        positionAtArrayElement(ptr, index - 1, pDataType, maxLen);
-        return true;
-    }
-    public static void positionAtArrayElement(ImmutableBytesWritable ptr, int arrayIndex, PDataType baseDataType,
-            Integer byteSize) {
-        byte[] bytes = ptr.get();
-        int initPos = ptr.getOffset();
-        if (!baseDataType.isFixedWidth()) {
-            int noOfElements = Bytes.toInt(bytes, (ptr.getOffset() + ptr.getLength() - (Bytes.SIZEOF_BYTE + Bytes.SIZEOF_INT)),
-                    Bytes.SIZEOF_INT);
-            boolean useShort = true;
-            if (noOfElements < 0) {
-                noOfElements = -noOfElements;
-                useShort = false;
-            }
-            if (arrayIndex >= noOfElements) {
-                ptr.set(ByteUtil.EMPTY_BYTE_ARRAY);
-                return;
-            }
-
-            int indexOffset = Bytes.toInt(bytes,
-                    (ptr.getOffset() + ptr.getLength() - (Bytes.SIZEOF_BYTE + 2 * Bytes.SIZEOF_INT))) + ptr.getOffset();
-            if(arrayIndex >= noOfElements) {
-                ptr.set(ByteUtil.EMPTY_BYTE_ARRAY);
-            } else {
-                // Skip those many offsets as given in the arrayIndex
-                // If suppose there are 5 elements in the array and the arrayIndex = 3
-                // This means we need to read the 4th element of the array
-                // So inorder to know the length of the 4th element we will read the offset of 4th element and the
-                // offset of 5th element.
-                // Subtracting the offset of 5th element and 4th element will give the length of 4th element
-                // So we could just skip reading the other elements.
-                int currOffset = getOffset(bytes, arrayIndex, useShort, indexOffset);
-                int elementLength = 0;
-                if (arrayIndex == (noOfElements - 1)) {
-                    elementLength = bytes[currOffset + initPos] == QueryConstants.SEPARATOR_BYTE ? 0 : indexOffset
-                            - (currOffset + initPos) - 3;
-                } else {
-                    elementLength = bytes[currOffset + initPos] == QueryConstants.SEPARATOR_BYTE ? 0 : getOffset(bytes,
-                            arrayIndex + 1, useShort, indexOffset) - currOffset - 1;
-                }
-                ptr.set(bytes, currOffset + initPos, elementLength);
-            }
-        } else {
-            int elemByteSize = (byteSize == null ? baseDataType.getByteSize() : byteSize);
-            int offset = arrayIndex * elemByteSize;
-            if (offset >= ptr.getLength()) {
-                ptr.set(ByteUtil.EMPTY_BYTE_ARRAY);
-            } else {
-                ptr.set(bytes, ptr.getOffset() + offset, elemByteSize);
-            }
-        }
-    }
-    
-    public static void positionAtArrayElement(ImmutableBytesWritable ptr, int arrayIndex, PDataType baseDataType,
-            Integer byteSize, int offset, int length, int noOfElements, boolean first) {
-        byte[] bytes = ptr.get();
-        if (!baseDataType.isFixedWidth()) {
-            int indexOffset = Bytes.toInt(bytes, (offset + length - (Bytes.SIZEOF_BYTE + 2 * Bytes.SIZEOF_INT)))
-                    + offset;
-            boolean useShort = true;
-            if (first) {
-                int count = Bytes.toInt(bytes,
-                        (ptr.getOffset() + ptr.getLength() - (Bytes.SIZEOF_BYTE + Bytes.SIZEOF_INT)), Bytes.SIZEOF_INT);
-                if (count < 0) {
-                    count = -count;
-                    useShort = false;
-                }
-            }
-            if (arrayIndex >= noOfElements) {
-                return;
-            } else {
-                // Skip those many offsets as given in the arrayIndex
-                // If suppose there are 5 elements in the array and the arrayIndex = 3
-                // This means we need to read the 4th element of the array
-                // So inorder to know the length of the 4th element we will read the offset of 4th element and the
-                // offset of 5th element.
-                // Subtracting the offset of 5th element and 4th element will give the length of 4th element
-                // So we could just skip reading the other elements.
-                int currOffset = getOffset(bytes, arrayIndex, useShort, indexOffset);
-                int elementLength = 0;
-                if (arrayIndex == (noOfElements - 1)) {
-                    elementLength = bytes[currOffset + offset] == QueryConstants.SEPARATOR_BYTE ? 0 : indexOffset
-                            - (currOffset + offset) - 3;
-                } else {
-                    elementLength = bytes[currOffset + offset] == QueryConstants.SEPARATOR_BYTE ? 0 : getOffset(bytes,
-                            arrayIndex + 1, useShort, indexOffset) - currOffset - 1;
-                }
-                ptr.set(bytes, currOffset + offset, elementLength);
-            }
-        } else {
-            int elemByteSize = (byteSize == null ? baseDataType.getByteSize() : byteSize);
-            offset += arrayIndex * elemByteSize;
-            if (offset >= offset + length) {
-                return;
-            } else {
-                ptr.set(bytes, offset, elemByteSize);
-            }
-        }
-    }
-
-    private static int getOffset(byte[] bytes, int arrayIndex, boolean useShort, int indexOffset) {
-        int offset;
-        if (useShort) {
-            offset = indexOffset + (Bytes.SIZEOF_SHORT * arrayIndex);
-            return Bytes.toShort(bytes, offset, Bytes.SIZEOF_SHORT) + Short.MAX_VALUE;
-        } else {
-            offset = indexOffset + (Bytes.SIZEOF_INT * arrayIndex);
-            return Bytes.toInt(bytes, offset, Bytes.SIZEOF_INT);
-        }
-    }
-    
-    private static int getOffset(ByteBuffer indexBuffer, int arrayIndex, boolean useShort, int indexOffset ) {
-        int offset;
-        if(useShort) {
-            offset = indexBuffer.getShort() + Short.MAX_VALUE;
-        } else {
-            offset = indexBuffer.getInt();
-        }
-        return offset;
-    }
-
-	public Object toObject(Object object, PDataType actualType) {
-		return object;
-	}
-
-	public Object toObject(Object object, PDataType actualType, SortOrder sortOrder) {
-		// How to use the sortOrder ? Just reverse the elements
-		return toObject(object, actualType);
-	}
-	
-	/**
-	 * creates array bytes
-	 * @param byteStream
-	 * @param oStream
-	 * @param array
-	 * @param noOfElements
-	 * @param baseType
-	 * @param sortOrder 
-	 * @param maxLength 
-	 * @param capacity
-	 * @return
-	 */
-    private byte[] createArrayBytes(TrustedByteArrayOutputStream byteStream, DataOutputStream oStream,
-            PhoenixArray array, int noOfElements, PDataType baseType, SortOrder sortOrder) {
-        try {
-            if (!baseType.isFixedWidth()) {
-                int[] offsetPos = new int[noOfElements];
-                int nulls = 0;
-                for (int i = 0; i < noOfElements; i++) {
-                    byte[] bytes = array.toBytes(i);
-                    if (bytes.length == 0) {
-                        offsetPos[i] = byteStream.size();
-                        nulls++;
-                    } else {
-                        nulls = serializeNulls(oStream, nulls);
-                        offsetPos[i] = byteStream.size();
-                        if (sortOrder == SortOrder.DESC) {
-                            SortOrder.invert(bytes, 0, bytes, 0, bytes.length);
-                        }
-                        oStream.write(bytes, 0, bytes.length);
-                        oStream.write(QueryConstants.SEPARATOR_BYTE);
-                    }
-                }
-                // Double seperator byte to show end of the non null array
-                PArrayDataType.writeEndSeperatorForVarLengthArray(oStream);
-                noOfElements = PArrayDataType.serailizeOffsetArrayIntoStream(oStream, byteStream, noOfElements,
-                        offsetPos[offsetPos.length - 1], offsetPos);
-                serializeHeaderInfoIntoStream(oStream, noOfElements);
-            } else {
-                for (int i = 0; i < noOfElements; i++) {
-                    byte[] bytes = array.toBytes(i);
-                    int length = bytes.length;
-                    if (sortOrder == SortOrder.DESC) {
-                        SortOrder.invert(bytes, 0, bytes, 0, bytes.length);
-                    }
-                    oStream.write(bytes, 0, length);
-                }
-            }
-            ImmutableBytesWritable ptr = new ImmutableBytesWritable();
-            ptr.set(byteStream.getBuffer(), 0, byteStream.size());
-            return ByteUtil.copyKeyBytesIfNecessary(ptr);
-        } catch (IOException e) {
-            try {
-                byteStream.close();
-                oStream.close();
-            } catch (IOException ioe) {
-
-            }
-        }
-        // This should not happen
-        return null;
-    }
-
-    public static int serailizeOffsetArrayIntoStream(DataOutputStream oStream, TrustedByteArrayOutputStream byteStream,
-            int noOfElements, int maxOffset, int[] offsetPos) throws IOException {
-        int offsetPosition = (byteStream.size());
-        byte[] offsetArr = null;
-        boolean useInt = true;
-        if (PArrayDataType.useShortForOffsetArray(maxOffset)) {
-            offsetArr = new byte[PArrayDataType.initOffsetArray(noOfElements, Bytes.SIZEOF_SHORT)];
-            useInt = false;
-        } else {
-            offsetArr = new byte[PArrayDataType.initOffsetArray(noOfElements, Bytes.SIZEOF_INT)];
-            noOfElements = -noOfElements;
-        }
-        int off = 0;
-        if(useInt) {
-            for (int pos : offsetPos) {
-                Bytes.putInt(offsetArr, off, pos);
-                off += Bytes.SIZEOF_INT;
-            }
-        } else {
-            for (int pos : offsetPos) {
-                Bytes.putShort(offsetArr, off, (short)(pos - Short.MAX_VALUE));
-                off += Bytes.SIZEOF_SHORT;
-            }
-        }
-        oStream.write(offsetArr);
-        oStream.writeInt(offsetPosition);
-        return noOfElements;
-    }
-
-    public static void serializeHeaderInfoIntoBuffer(ByteBuffer buffer, int noOfElements) {
-        // No of elements
-        buffer.putInt(noOfElements);
-        // Version of the array
-        buffer.put(ARRAY_SERIALIZATION_VERSION);
-    }
-
-    public static void serializeHeaderInfoIntoStream(DataOutputStream oStream, int noOfElements) throws IOException {
-        // No of elements
-        oStream.writeInt(noOfElements);
-        // Version of the array
-        oStream.write(ARRAY_SERIALIZATION_VERSION);
-    }
-
-	public static int initOffsetArray(int noOfElements, int baseSize) {
-		// for now create an offset array equal to the noofelements
-		return noOfElements * baseSize;
-    }
-
-    // Any variable length array would follow the below order
-    // Every element would be seperated by a seperator byte '0'
-    // Null elements are counted and once a first non null element appears we
-    // write the count of the nulls prefixed with a seperator byte
-    // Trailing nulls are not taken into account
-    // The last non null element is followed by two seperator bytes
-    // For eg
-    // a, b, null, null, c, null would be 
-    // 65 0 66 0 0 2 67 0 0 0
-    // a null null null b c null d would be
-    // 65 0 0 3 66 0 67 0 0 1 68 0 0 0
-	// Follow the above example to understand how this works
-    private Object createPhoenixArray(byte[] bytes, int offset, int length, SortOrder sortOrder,
-            PDataType baseDataType, Integer maxLength, PDataType desiredDataType) {
-        if (bytes == null || bytes.length == 0) { return null; }
-        Object[] elements;
-        if (!baseDataType.isFixedWidth()) {
-            ByteBuffer buffer = ByteBuffer.wrap(bytes, offset, length);
-            int initPos = buffer.position();
-            buffer.position((buffer.limit() - (Bytes.SIZEOF_BYTE + Bytes.SIZEOF_INT)));
-            int noOfElements = buffer.getInt();
-            boolean useShort = true;
-            int baseSize = Bytes.SIZEOF_SHORT;
-            if (noOfElements < 0) {
-                noOfElements = -noOfElements;
-                baseSize = Bytes.SIZEOF_INT;
-                useShort = false;
-            }
-            if (baseDataType == desiredDataType) {
-                elements = (Object[])java.lang.reflect.Array.newInstance(baseDataType.getJavaClass(), noOfElements);
-            } else {
-                elements = (Object[])java.lang.reflect.Array.newInstance(desiredDataType.getJavaClass(), noOfElements);
-            }
-            buffer.position(buffer.limit() - (Bytes.SIZEOF_BYTE + (2 * Bytes.SIZEOF_INT)));
-            int indexOffset = buffer.getInt();
-            buffer.position(initPos);
-            buffer.position(indexOffset + initPos);
-            ByteBuffer indexArr = ByteBuffer.allocate(initOffsetArray(noOfElements, baseSize));
-            byte[] array = indexArr.array();
-            buffer.get(array);
-            int countOfElementsRead = 0;
-            int i = 0;
-            int currOffset = -1;
-            int nextOff = -1;
-            boolean foundNull = false;
-            if (noOfElements != 0) {
-                while (countOfElementsRead <= noOfElements) {
-                    if (countOfElementsRead == 0) {
-                        currOffset = getOffset(indexArr, countOfElementsRead, useShort, indexOffset);
-                        countOfElementsRead++;
-                    } else {
-                        currOffset = nextOff;
-                    }
-                    if (countOfElementsRead == noOfElements) {
-                        nextOff = indexOffset - 2;
-                    } else {
-                        nextOff = getOffset(indexArr, countOfElementsRead + 1, useShort, indexOffset);
-                    }
-                    countOfElementsRead++;
-                    if ((bytes[currOffset + initPos] != QueryConstants.SEPARATOR_BYTE) && foundNull) {
-                        // Found a non null element
-                        foundNull = false;
-                    }
-                    if (bytes[currOffset + initPos] == QueryConstants.SEPARATOR_BYTE) {
-                        // Null element
-                        foundNull = true;
-                        i++;
-                        continue;
-                    }
-                    int elementLength = nextOff - currOffset;
-                    buffer.position(currOffset + initPos);
-                    // Subtract the seperator from the element length
-                    byte[] val = new byte[elementLength - 1];
-                    buffer.get(val);
-                    if (baseDataType == desiredDataType) {
-                        elements[i++] = baseDataType.toObject(val, sortOrder);
-                    } else {
-                        elements[i++] = desiredDataType.toObject(val, sortOrder, baseDataType);
-                    }
-                }
-            }
-        } else {
-            int elemLength = (maxLength == null ? baseDataType.getByteSize() : maxLength);
-            int noOfElements = length / elemLength;
-            if (baseDataType == desiredDataType) {
-                elements = (Object[])java.lang.reflect.Array.newInstance(baseDataType.getJavaClass(), noOfElements);
-            } else {
-                elements = (Object[])java.lang.reflect.Array.newInstance(desiredDataType.getJavaClass(), noOfElements);
-            }
-            ImmutableBytesWritable ptr = new ImmutableBytesWritable();
-            for (int i = 0; i < noOfElements; i++) {
-                ptr.set(bytes, offset + i * elemLength, elemLength);
-                if (baseDataType == desiredDataType) {
-                    elements[i] = baseDataType.toObject(ptr, sortOrder);
-                } else {
-                    elements[i] = desiredDataType.toObject(ptr, baseDataType, sortOrder);
-                }
-            }
-        }
-        if(baseDataType == desiredDataType) {
-            return PArrayDataType.instantiatePhoenixArray(baseDataType, elements);
-        } else {
-            return PArrayDataType.instantiatePhoenixArray(desiredDataType, elements);
-        }
-    }
-	
-    public static PhoenixArray instantiatePhoenixArray(PDataType actualType, Object[] elements) {
-        return PDataType.instantiatePhoenixArray(actualType, elements);
-    }
-	
-	public int compareTo(Object lhs, Object rhs) {
-		PhoenixArray lhsArr = (PhoenixArray) lhs;
-		PhoenixArray rhsArr = (PhoenixArray) rhs;
-		if(lhsArr.equals(rhsArr)) {
-			return 0;
-		}
-		return 1;
-	}
-
-	public static int getArrayLength(ImmutableBytesWritable ptr,
-			PDataType baseType, Integer maxLength) {
-		byte[] bytes = ptr.get();
-		if(baseType.isFixedWidth()) {
-		    int elemLength = maxLength == null ? baseType.getByteSize() : maxLength;
-			return (ptr.getLength() / elemLength);
-		}
-		return Bytes.toInt(bytes, (ptr.getOffset() + ptr.getLength() - (Bytes.SIZEOF_BYTE + Bytes.SIZEOF_INT)));
-	}
-
-    public static int estimateSize(int size, PDataType baseType) {
-        if(baseType.isFixedWidth()) {
-            return baseType.getByteSize() * size;
-        } else {
-            return size * ValueSchema.ESTIMATED_VARIABLE_LENGTH_SIZE;
-        }
-        
-    }
-    
-    public Object getSampleValue(PDataType baseType, Integer arrayLength, Integer elemLength) {
-        Preconditions.checkArgument(arrayLength == null || arrayLength >= 0);
-        if (arrayLength == null) {
-            arrayLength = 1;
-        }
-        Object[] array = new Object[arrayLength];
-        for (int i = 0; i < arrayLength; i++) {
-            array[i] = baseType.getSampleValue(elemLength, arrayLength);
-        }
-        return instantiatePhoenixArray(baseType, array);
-    }
-
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/04ef859b/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnImpl.java
index e0143c3..47963c2 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnImpl.java
@@ -19,6 +19,7 @@ package org.apache.phoenix.schema;
 
 import org.apache.phoenix.coprocessor.generated.PTableProtos;
 import org.apache.phoenix.query.QueryConstants;
+import org.apache.phoenix.schema.types.PDataType;
 import org.apache.phoenix.util.SizedUtil;
 
 import com.google.common.base.Preconditions;