You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by ma...@apache.org on 2015/04/16 16:32:21 UTC

[40/50] [abbrv] phoenix git commit: PHOENIX-1705 implement ARRAY_APPEND built in function (Dumindu Buddhika)

PHOENIX-1705 implement ARRAY_APPEND built in function (Dumindu Buddhika)


Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/986080f3
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/986080f3
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/986080f3

Branch: refs/heads/calcite
Commit: 986080f3fb939252c01b8c79d0bcdb602e0ddd64
Parents: 1b45110
Author: ramkrishna <ra...@gmail.com>
Authored: Tue Apr 14 23:26:22 2015 +0530
Committer: ramkrishna <ra...@gmail.com>
Committed: Tue Apr 14 23:26:22 2015 +0530

----------------------------------------------------------------------
 .../phoenix/expression/ExpressionType.java      |  4 +-
 .../phoenix/schema/types/PArrayDataType.java    | 85 ++++++++++++++++++++
 2 files changed, 88 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/986080f3/phoenix-core/src/main/java/org/apache/phoenix/expression/ExpressionType.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/ExpressionType.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/ExpressionType.java
index d562d6a..22778ce 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/ExpressionType.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/ExpressionType.java
@@ -21,6 +21,7 @@ import java.util.Map;
 
 import org.apache.phoenix.expression.function.ArrayAllComparisonExpression;
 import org.apache.phoenix.expression.function.ArrayAnyComparisonExpression;
+import org.apache.phoenix.expression.function.ArrayAppendFunction;
 import org.apache.phoenix.expression.function.ArrayElemRefExpression;
 import org.apache.phoenix.expression.function.ArrayIndexFunction;
 import org.apache.phoenix.expression.function.ArrayLengthFunction;
@@ -211,7 +212,8 @@ public enum ExpressionType {
     NowFunction(NowFunction.class),
     InstrFunction(InstrFunction.class),
     MinuteFunction(MinuteFunction.class),
-    DayOfMonthFunction(DayOfMonthFunction.class)
+    DayOfMonthFunction(DayOfMonthFunction.class),
+    ArrayAppendFunction(ArrayAppendFunction.class)
     ;
 
     ExpressionType(Class<? extends Expression> clazz) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/986080f3/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PArrayDataType.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PArrayDataType.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PArrayDataType.java
index c183b7a..b6dce34 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PArrayDataType.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PArrayDataType.java
@@ -456,6 +456,91 @@ public abstract class PArrayDataType<T> extends PDataType<T> {
         return null;
     }
 
+    public static boolean appendItemToArray(ImmutableBytesWritable ptr, int length, int offset, byte[] arrayBytes, PDataType baseType, int arrayLength, Integer maxLength, SortOrder sortOrder) {
+        int elementLength = maxLength == null ? ptr.getLength() : maxLength;
+
+        //padding
+        if (elementLength > ptr.getLength()) {
+            baseType.pad(ptr, elementLength, sortOrder);
+        }
+
+        int elementOffset = ptr.getOffset();
+        byte[] elementBytes = ptr.get();
+
+        byte[] newArray;
+        if (!baseType.isFixedWidth()) {
+
+            int offsetArrayPosition = Bytes.toInt(arrayBytes, offset + length - Bytes.SIZEOF_INT - Bytes.SIZEOF_INT - Bytes.SIZEOF_BYTE, Bytes.SIZEOF_INT);
+            int offsetArrayLength = length - offsetArrayPosition - Bytes.SIZEOF_INT - Bytes.SIZEOF_INT - Bytes.SIZEOF_BYTE;
+
+            //checks whether offset array consists of shorts or integers
+            boolean useInt = offsetArrayLength / Math.abs(arrayLength) == Bytes.SIZEOF_INT;
+            boolean convertToInt = false;
+
+            int newElementPosition = offsetArrayPosition - 2 * Bytes.SIZEOF_BYTE;
+
+            if (!useInt) {
+                if (PArrayDataType.useShortForOffsetArray(newElementPosition)) {
+                    newArray = new byte[length + elementLength + Bytes.SIZEOF_SHORT + Bytes.SIZEOF_BYTE];
+                } else {
+                    newArray = new byte[length + elementLength + arrayLength * Bytes.SIZEOF_SHORT + Bytes.SIZEOF_INT + Bytes.SIZEOF_BYTE];
+                    convertToInt = true;
+                }
+            } else {
+                newArray = new byte[length + elementLength + Bytes.SIZEOF_INT + Bytes.SIZEOF_BYTE];
+            }
+
+            int newOffsetArrayPosition = newElementPosition + elementLength + 3 * Bytes.SIZEOF_BYTE;
+
+            System.arraycopy(arrayBytes, offset, newArray, 0, newElementPosition);
+            System.arraycopy(elementBytes, elementOffset, newArray, newElementPosition, elementLength);
+
+            arrayLength = (Math.abs(arrayLength) + 1) * (int) Math.signum(arrayLength);
+            if (useInt) {
+                System.arraycopy(arrayBytes, offset + offsetArrayPosition, newArray, newOffsetArrayPosition, offsetArrayLength);
+                Bytes.putInt(newArray, newOffsetArrayPosition + offsetArrayLength, newElementPosition);
+
+                writeEndBytes(newArray, newOffsetArrayPosition, offsetArrayLength, arrayLength, arrayBytes[offset + length - 1], true);
+            } else {
+                if (!convertToInt) {
+                    System.arraycopy(arrayBytes, offset + offsetArrayPosition, newArray, newOffsetArrayPosition, offsetArrayLength);
+                    Bytes.putShort(newArray, newOffsetArrayPosition + offsetArrayLength, (short) (newElementPosition - Short.MAX_VALUE));
+
+                    writeEndBytes(newArray, newOffsetArrayPosition, offsetArrayLength, arrayLength, arrayBytes[offset + length - 1], false);
+                } else {
+                    int off = newOffsetArrayPosition;
+                    for (int arrayIndex = 0; arrayIndex < Math.abs(arrayLength) - 1; arrayIndex++) {
+                        Bytes.putInt(newArray, off, getOffset(arrayBytes, arrayIndex, true, offsetArrayPosition));
+                        off += Bytes.SIZEOF_INT;
+                    }
+
+                    Bytes.putInt(newArray, off, newElementPosition);
+                    Bytes.putInt(newArray, off + Bytes.SIZEOF_INT, newOffsetArrayPosition);
+                    Bytes.putInt(newArray, off + 2 * Bytes.SIZEOF_INT, -arrayLength);
+                    Bytes.putByte(newArray, off + 3 * Bytes.SIZEOF_INT, arrayBytes[offset + length - 1]);
+
+                }
+            }
+        } else {
+            newArray = new byte[length + elementLength];
+
+            System.arraycopy(arrayBytes, offset, newArray, 0, length);
+            System.arraycopy(elementBytes, elementOffset, newArray, length, elementLength);
+        }
+
+        ptr.set(newArray);
+
+        return true;
+    }
+
+    private static void writeEndBytes(byte[] array, int newOffsetArrayPosition, int offsetArrayLength, int arrayLength, byte header, boolean useInt) {
+        int byteSize = useInt ? Bytes.SIZEOF_INT : Bytes.SIZEOF_SHORT;
+
+        Bytes.putInt(array, newOffsetArrayPosition + offsetArrayLength + byteSize, newOffsetArrayPosition);
+        Bytes.putInt(array, newOffsetArrayPosition + offsetArrayLength + byteSize + Bytes.SIZEOF_INT, arrayLength);
+        Bytes.putByte(array, newOffsetArrayPosition + offsetArrayLength + byteSize + 2 * Bytes.SIZEOF_INT, header);
+    }
+
     public static int serailizeOffsetArrayIntoStream(DataOutputStream oStream, TrustedByteArrayOutputStream byteStream,
             int noOfElements, int maxOffset, int[] offsetPos) throws IOException {
         int offsetPosition = (byteStream.size());