/*******************************************************************************
 * Copyright (c) 2014, Salesforce.com, Inc. All rights reserved. Redistribution and use in source and binary forms, with
 * or without modification, are permitted provided that the following conditions are met: Redistributions of source code
 * must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in
 * binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution. Neither the name of Salesforce.com nor the names
 * of its contributors may be used to endorse or promote products derived from this software without specific prior
 * written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ******************************************************************************/
package com.salesforce.phoenix.expression;

import java.sql.Types;
import java.util.List;

import org.apache.hadoop.hbase.io.ImmutableBytesWritable;

import com.salesforce.phoenix.schema.PArrayDataType;
import com.salesforce.phoenix.schema.PDataType;
import com.salesforce.phoenix.schema.PhoenixArray;
import com.salesforce.phoenix.schema.tuple.Tuple;

/**
 * Creates an expression for Upsert with Values/Select using ARRAY
 */
public class ArrayConstructorExpression extends BaseCompoundExpression {
    private PDataType baseType;
    public ArrayConstructorExpression(List<Expression> children, PDataType baseType) {
        super(children);
        this.baseType = baseType;
    }

    @Override
    public PDataType getDataType() {
        return PDataType.fromTypeId(baseType.getSqlType() + Types.ARRAY);
    }

    @Override
    public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) {
        Object[] elements = new Object[children.size()];
        for (int i = 0; i < children.size(); i++) {
            Expression child = children.get(i);
            if (!child.evaluate(tuple, ptr)) {
                return false;
            } else {
                elements[i] = baseType.toObject(ptr, child.getDataType(), child.getColumnModifier());
            }
        }
        PhoenixArray array = PArrayDataType.instantiatePhoenixArray(baseType, elements);
        // FIXME: Need to see if this creation of an array and again back to byte[] can be avoided
        ptr.set(getDataType().toBytes(array));
        return true;
    }
}

@@ -1709,16 +1709,97 @@
 ssion;%0A%0A
+import java.io.DataInput;%0Aimport java.io.DataOutput;%0Aimport java.io.IOException;%0A
 import j
@@ -1813,16 +1813,16 @@
 .Types;%0A
-
 import j
@@ -1894,16 +1894,59 @@
 ritable;
+%0Aimport org.apache.hadoop.io.WritableUtils;
 %0A%0Aimport
@@ -2892,24 +2892,291 @@
 le, ptr)) %7B%0A
+                // TODO: if we're fixed width, we have no representation for null,%0A                // so for now we'll just return false. Once we do, we should remove that.%0A                if ((tuple != null && !tuple.isImmutable()) %7C%7C baseType.isFixedWidth()) %7B%0A    
             
@@ -3193,16 +3193,34 @@
  false;%0A
+                %7D%0A
         
@@ -3614,16 +3614,430 @@
 n true;%0A
-
     %7D%0A
+    %0A    @Override%0A    public void readFields(DataInput input) throws IOException %7B%0A        super.readFields(input);%0A        int baseTypeOrdinal = WritableUtils.readVInt(input);%0A        baseType = PDataType.values()%5BbaseTypeOrdinal%5D;%0A    %7D%0A%0A    @Override%0A    public void write(DataOutput output) throws IOException %7B%0A        super.write(output);%0A        WritableUtils.writeVInt(output, baseType.ordinal());%0A    %7D%0A%0A
 %7D%0A

Fix array constructor serializer