PHOENIX-3881 PHOENIX-3882 PHOENIX-3502 Support Arrays in phoenix-calcite (Ankit 
Singhal)


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

Branch: refs/heads/calcite
Commit: b2d7fe01588848fc789b1f670805ccc64b6badba
Parents: e37387d
Author: Ankit Singhal <[email protected]>
Authored: Mon Jul 3 11:06:12 2017 +0530
Committer: Ankit Singhal <[email protected]>
Committed: Mon Jul 3 11:06:12 2017 +0530

----------------------------------------------------------------------
 .../phoenix/end2end/ArrayFillFunctionIT.java    |   5 +-
 .../org/apache/phoenix/end2end/ArrayIT.java     |  32 ++-
 .../phoenix/end2end/ArrayPrependFunctionIT.java |  19 +-
 .../end2end/ArrayToStringFunctionIT.java        |  43 ++--
 .../end2end/StringToArrayFunctionIT.java        |  17 +-
 .../apache/phoenix/calcite/CalciteUtils.java    | 140 +++++++++++--
 .../phoenix/calcite/PhoenixScalarFunction.java  |  23 +-
 .../apache/phoenix/calcite/PhoenixSchema.java   | 209 +++++++++++++++----
 .../expression/BindParameterExpression.java     |  16 +-
 .../function/ArrayAppendFunction.java           |  15 +-
 .../function/ArrayConcatFunction.java           |   3 +-
 .../function/ArrayElemRefExpression.java        |   4 +
 .../expression/function/ArrayFillFunction.java  |  12 +-
 .../expression/function/ArrayIndexFunction.java |  12 +-
 .../function/ArrayLengthFunction.java           |  10 +-
 .../function/ArrayPrependFunction.java          |  12 +-
 .../function/ArrayToStringFunction.java         |  11 +-
 .../apache/phoenix/parse/FunctionParseNode.java |   3 +-
 .../phoenix/schema/types/PArrayDataType.java    |   5 +-
 .../phoenix/schema/types/PBinaryArray.java      |   3 +-
 .../phoenix/schema/types/PBooleanArray.java     |   3 +-
 .../apache/phoenix/schema/types/PCharArray.java |   3 +-
 .../apache/phoenix/schema/types/PDataType.java  |   2 +-
 .../phoenix/schema/types/PDoubleArray.java      |   3 +-
 .../phoenix/schema/types/PIntegerArray.java     |   3 +-
 .../phoenix/schema/types/PVarbinaryArray.java   |   3 +-
 .../phoenix/schema/types/PVarcharArray.java     |   3 +-
 .../phoenix/compile/QueryCompilerTest.java      |  78 +++----
 .../java/org/apache/phoenix/query/BaseTest.java |  37 +++-
 29 files changed, 522 insertions(+), 207 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/b2d7fe01/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayFillFunctionIT.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayFillFunctionIT.java 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayFillFunctionIT.java
index 5133e5d..a94444e 100644
--- 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayFillFunctionIT.java
+++ 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayFillFunctionIT.java
@@ -18,7 +18,6 @@
 
 package org.apache.phoenix.end2end;
 
-import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
@@ -225,7 +224,7 @@ public class ArrayFillFunctionIT extends 
ParallelStatsDisabledIT {
         assertFalse(rs.next());
     }
 
-    @Test(expected = IllegalArgumentException.class)
+    @Test(expected = AssertionError.class)
     public void testArrayFillFunctionInvalidLength1() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
         
@@ -243,7 +242,7 @@ public class ArrayFillFunctionIT extends 
ParallelStatsDisabledIT {
         assertFalse(rs.next());
     }
 
-    @Test(expected = IllegalArgumentException.class)
+    @Test(expected = AssertionError.class)
     public void testArrayFillFunctionInvalidLength2() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
         

http://git-wip-us.apache.org/repos/asf/phoenix/blob/b2d7fe01/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayIT.java 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayIT.java
index 26fba02..32b9825 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayIT.java
@@ -22,7 +22,6 @@ import static org.apache.phoenix.util.TestUtil.B_VALUE;
 import static org.apache.phoenix.util.TestUtil.ROW1;
 import static org.apache.phoenix.util.TestUtil.TABLE_WITH_ARRAY;
 import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES;
-import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
@@ -39,7 +38,6 @@ import java.sql.Types;
 import java.util.Properties;
 
 import org.apache.phoenix.query.BaseTest;
-import org.apache.phoenix.schema.types.PhoenixArray;
 import org.apache.phoenix.util.PhoenixRuntime;
 import org.apache.phoenix.util.PropertiesUtil;
 import org.apache.phoenix.util.SchemaUtil;
@@ -143,7 +141,7 @@ public class ArrayIT extends BaseClientManagedTimeIT {
                props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB,
                        Long.toString(ts + 2)); // Execute at timestamp 2
                Connection conn = DriverManager.getConnection(getUrl(), props);
-        analyzeTable(conn, TABLE_WITH_ARRAY);
+               analyzeTable(conn, TABLE_WITH_ARRAY);
                try {
                    PreparedStatement statement = conn.prepareStatement(query);
                        statement.setString(1, tenantId);
@@ -158,7 +156,7 @@ public class ArrayIT extends BaseClientManagedTimeIT {
             doubleArr[3] = 386.63;
                        Array array = conn.createArrayOf("DOUBLE",
                                        doubleArr);
-                       PhoenixArray resultArray = (PhoenixArray) 
rs.getArray(1);
+                       Array resultArray = rs.getArray(1);
                        assertEquals(resultArray, array);
             assertEquals("[25.343, 36.763, 37.56, 386.63]", rs.getString(1));
                        assertEquals(rs.getString("B_string"), B_VALUE);
@@ -282,9 +280,9 @@ public class ArrayIT extends BaseClientManagedTimeIT {
                        strArr[2] = "XYZWER";
                        strArr[3] = "AB";
                        Array array = conn.createArrayOf("VARCHAR", strArr);
-                       PhoenixArray resultArray = (PhoenixArray) 
rs.getArray(1);
+                       Array resultArray =  rs.getArray(1);
                        assertEquals(resultArray, array);
-            assertEquals("['ABC', 'CEDF', 'XYZWER', 'AB']", rs.getString(1));
+            assertEquals("[ABC, CEDF, XYZWER, AB]", rs.getString(1));
                        assertFalse(rs.next());
                } finally {
                        conn.close();
@@ -692,7 +690,7 @@ public class ArrayIT extends BaseClientManagedTimeIT {
             Array resultArr = conn.createArrayOf("VARCHAR", strArr);
             assertEquals(resultArr, array);
             // since array is var length, last string element is messed up
-            String expectedPrefix = "['abc', 'defgh', 'b";
+            String expectedPrefix = "[abc, defgh, b";
             assertTrue("Expected to start with " + expectedPrefix,
                 rs.getString(2).startsWith(expectedPrefix));
             assertFalse(rs.next());
@@ -835,9 +833,9 @@ public class ArrayIT extends BaseClientManagedTimeIT {
         conn = DriverManager.getConnection(getUrl(), props);
         rs = conn.createStatement().executeQuery("SELECT b_string_array FROM 
t");
         assertTrue(rs.next());
-        PhoenixArray strArr = (PhoenixArray)rs.getArray(1);
+        Array strArr = rs.getArray(1);
         assertEquals(array, strArr);
-        assertEquals("['abc', 'def', 'ghi', 'jkll', null, null, null, 'xxx']", 
rs.getString(1));
+        assertEquals("[abc, def, ghi, jkll, null, null, null, xxx]", 
rs.getString(1));
         conn.close();
     }
 
@@ -1005,7 +1003,7 @@ public class ArrayIT extends BaseClientManagedTimeIT {
         assertArrayGetString(rs, intIndex, intArray, "5555, 6666");
         assertArrayGetString(rs, longIndex, longArray, "7777777, 8888888");
         assertArrayGetString(rs, shortIndex, shortArray, "333, 444");
-        assertArrayGetString(rs, stringIndex, stringArray, "'a', 'b'");
+        assertArrayGetString(rs, stringIndex, stringArray, "a, b");
         conn.close();
     }
 
@@ -1039,11 +1037,11 @@ public class ArrayIT extends BaseClientManagedTimeIT {
         conn.close();
         props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts 
+ 40));
         conn = DriverManager.getConnection(getUrl(), props);
-        rs = conn.createStatement().executeQuery("SELECT CAST(a AS DOUBLE []) 
FROM t");
+        rs = conn.createStatement().executeQuery("SELECT CAST(a AS DOUBLE 
array) FROM t");
         assertTrue(rs.next());
         Double[] d = new Double[] { 1.0, 2.0 };
         array = conn.createArrayOf("DOUBLE", d);
-        PhoenixArray arr = (PhoenixArray)rs.getArray(1);
+        Array arr = rs.getArray(1);
         assertEquals(array, arr);
         assertEquals("[1.0, 2.0]", rs.getString(1));
         conn.close();
@@ -1065,7 +1063,7 @@ public class ArrayIT extends BaseClientManagedTimeIT {
         stmt = conn.prepareStatement("UPSERT INTO t VALUES(?,?)");
         stmt.setString(1, "a");
         String[] s = new String[] { "1", "2" };
-        PhoenixArray array = (PhoenixArray)conn.createArrayOf("VARCHAR", s);
+        Array array = conn.createArrayOf("VARCHAR", s);
         stmt.setArray(2, array);
         stmt.execute();
         conn.commit();
@@ -1075,7 +1073,7 @@ public class ArrayIT extends BaseClientManagedTimeIT {
         conn = DriverManager.getConnection(getUrl(), props);
         rs = conn.createStatement().executeQuery("SELECT CAST(a AS CHAR ARRAY) 
FROM t");
         assertTrue(rs.next());
-        PhoenixArray arr = (PhoenixArray)rs.getArray(1);
+        Array arr = rs.getArray(1);
         String[] array2 = (String[])array.getArray();
         String[] array3 = (String[])arr.getArray();
         assertEquals(array2[0], array3[0]);
@@ -1146,7 +1144,7 @@ public class ArrayIT extends BaseClientManagedTimeIT {
             doubleArr[2] = 37.56;
             doubleArr[3] = 386.63;
                        Array array = conn.createArrayOf("DOUBLE", doubleArr);
-                       PhoenixArray resultArray = (PhoenixArray) 
rs.getArray(1);
+                       Array resultArray = rs.getArray(1);
                        assertEquals(resultArray, array);
             assertEquals("[25.343, 36.763, 37.56, 386.63]", rs.getString(1));
                        assertFalse(rs.next());
@@ -1427,8 +1425,8 @@ public class ArrayIT extends BaseClientManagedTimeIT {
                        PreparedStatement statement = 
conn.prepareStatement(query);
                        ResultSet rs = statement.executeQuery();
                        assertTrue(rs.next());
-                       PhoenixArray resultArray = (PhoenixArray) 
rs.getArray(1);
-                       assertNull(resultArray);
+                       Double result = rs.getDouble(1);
+                       assertTrue(result!=null);
                } finally {
                        conn.close();
                }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/b2d7fe01/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayPrependFunctionIT.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayPrependFunctionIT.java
 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayPrependFunctionIT.java
index 182e664..d9cf7ec 100644
--- 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayPrependFunctionIT.java
+++ 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayPrependFunctionIT.java
@@ -18,13 +18,16 @@
 package org.apache.phoenix.end2end;
 
 import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
-import java.sql.*;
+import java.sql.Array;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
 
 import org.apache.phoenix.schema.TypeMismatchException;
-import org.apache.phoenix.schema.types.PhoenixArray;
 import org.junit.Test;
 
 public class ArrayPrependFunctionIT extends ParallelStatsDisabledIT {
@@ -33,7 +36,7 @@ public class ArrayPrependFunctionIT extends 
ParallelStatsDisabledIT {
         conn.createStatement().execute("CREATE TABLE " + tableName + " ( k 
VARCHAR PRIMARY KEY, a " + type + "[],b " + type + ")");
         conn.commit();
         PreparedStatement stmt = conn.prepareStatement("UPSERT INTO " + 
tableName + " VALUES(?,?," + value + ")");
-        PhoenixArray array = (PhoenixArray) conn.createArrayOf(type, 
objectArray);
+        Array array =  conn.createArrayOf(type, objectArray);
         stmt.setString(1, "a");
         stmt.setArray(2, array);
         stmt.execute();
@@ -120,7 +123,7 @@ public class ArrayPrependFunctionIT extends 
ParallelStatsDisabledIT {
         String tableName = generateUniqueName();
         initTableWithVarArray(conn, tableName, "VARCHAR", s, null);
         String[] s2 = new String[]{null, null, null, "1", "2"};
-        PhoenixArray array2 = (PhoenixArray) conn.createArrayOf("VARCHAR", s2);
+        Array array2 =  conn.createArrayOf("VARCHAR", s2);
         conn = DriverManager.getConnection(getUrl());
         ResultSet rs;
         rs = conn.createStatement().executeQuery("SELECT ARRAY_PREPEND(b,a) 
FROM " + tableName + " WHERE k = 'a'");
@@ -135,7 +138,7 @@ public class ArrayPrependFunctionIT extends 
ParallelStatsDisabledIT {
         String tableName = generateUniqueName();
         initTableWithVarArray(conn, tableName, "VARCHAR", s, null);
         String[] s2 = new String[]{null, "1", "2"};
-        PhoenixArray array2 = (PhoenixArray) conn.createArrayOf("VARCHAR", s2);
+        Array array2 =  conn.createArrayOf("VARCHAR", s2);
         conn = DriverManager.getConnection(getUrl());
         ResultSet rs;
         rs = conn.createStatement().executeQuery("SELECT ARRAY_PREPEND(b,a) 
FROM " + tableName + " WHERE k = 'a'");
@@ -150,7 +153,7 @@ public class ArrayPrependFunctionIT extends 
ParallelStatsDisabledIT {
         String tableName = generateUniqueName();
         initTableWithVarArray(conn, tableName, "VARCHAR", s, null);
         String[] s2 = new String[]{null, "176", null, "212"};
-        PhoenixArray array2 = (PhoenixArray) conn.createArrayOf("VARCHAR", s2);
+        Array array2 =  conn.createArrayOf("VARCHAR", s2);
         conn = DriverManager.getConnection(getUrl());
         ResultSet rs;
         rs = conn.createStatement().executeQuery("SELECT ARRAY_PREPEND(b,a) 
FROM " + tableName + " WHERE k = 'a'");
@@ -165,7 +168,7 @@ public class ArrayPrependFunctionIT extends 
ParallelStatsDisabledIT {
         String tableName = generateUniqueName();
         initTableWithVarArray(conn, tableName, "VARCHAR", s, "'foo'");
         String[] s2 = new String[]{"foo", "176", null, "212"};
-        PhoenixArray array2 = (PhoenixArray) conn.createArrayOf("VARCHAR", s2);
+        Array array2 =  conn.createArrayOf("VARCHAR", s2);
         conn = DriverManager.getConnection(getUrl());
         ResultSet rs;
         rs = conn.createStatement().executeQuery("SELECT ARRAY_PREPEND(b,a) 
FROM " + tableName + " WHERE k = 'a'");

http://git-wip-us.apache.org/repos/asf/phoenix/blob/b2d7fe01/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayToStringFunctionIT.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayToStringFunctionIT.java
 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayToStringFunctionIT.java
index 8a3461c..53e21ea 100644
--- 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayToStringFunctionIT.java
+++ 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayToStringFunctionIT.java
@@ -17,7 +17,6 @@
  */
 package org.apache.phoenix.end2end;
 
-import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
@@ -258,17 +257,17 @@ public class ArrayToStringFunctionIT extends 
ParallelStatsDisabledIT {
     public void testArrayToStringFunctionWithUpsert1() throws Exception {
         String table = generateUniqueName();
         String ddl =
-            "CREATE TABLE " + table + " (region_name VARCHAR PRIMARY 
KEY,varchar VARCHAR)";
+            "CREATE TABLE " + table + " (region_name VARCHAR PRIMARY 
KEY,varchars VARCHAR)";
         conn.createStatement().execute(ddl);
 
         String dml = "UPSERT INTO " + table
-            + "(region_name,varchar) VALUES('SF Bay 
Area',ARRAY_TO_STRING(ARRAY['hello','world'],','))";
+            + "(region_name,varchars) VALUES('SF Bay 
Area',ARRAY_TO_STRING(ARRAY['hello','world'],','))";
         conn.createStatement().execute(dml);
         conn.commit();
 
         ResultSet rs;
         rs = conn.createStatement().executeQuery(
-            "SELECT varchar FROM " + table + " WHERE region_name = 'SF Bay 
Area'");
+            "SELECT varchars FROM " + table + " WHERE region_name = 'SF Bay 
Area'");
         assertTrue(rs.next());
 
         String expected = "hello,world";
@@ -281,17 +280,17 @@ public class ArrayToStringFunctionIT extends 
ParallelStatsDisabledIT {
     public void testArrayToStringFunctionWithUpsert2() throws Exception {
         String tableName = generateUniqueName();
         String ddl =
-            "CREATE TABLE " + tableName + " (region_name VARCHAR PRIMARY 
KEY,varchar VARCHAR)";
+            "CREATE TABLE " + tableName + " (region_name VARCHAR PRIMARY 
KEY,varchars VARCHAR)";
         conn.createStatement().execute(ddl);
 
         String dml = "UPSERT INTO " + tableName
-            + "(region_name,varchar) VALUES('SF Bay 
Area',ARRAY_TO_STRING(ARRAY[3, 4, 5],', '))";
+            + "(region_name,varchars) VALUES('SF Bay 
Area',ARRAY_TO_STRING(ARRAY[3, 4, 5],', '))";
         conn.createStatement().execute(dml);
         conn.commit();
 
         ResultSet rs;
         rs = conn.createStatement().executeQuery(
-            "SELECT varchar FROM " + tableName + " WHERE region_name = 'SF Bay 
Area'");
+            "SELECT varchars FROM " + tableName + " WHERE region_name = 'SF 
Bay Area'");
         assertTrue(rs.next());
 
         String expected = "3, 4, 5";
@@ -304,17 +303,17 @@ public class ArrayToStringFunctionIT extends 
ParallelStatsDisabledIT {
     public void testArrayToStringFunctionWithUpsert3() throws Exception {
         String tableName = generateUniqueName();
         String ddl =
-            "CREATE TABLE " + tableName + " (region_name VARCHAR PRIMARY 
KEY,varchar VARCHAR)";
+            "CREATE TABLE " + tableName + " (region_name VARCHAR PRIMARY 
KEY,varchars VARCHAR)";
         conn.createStatement().execute(ddl);
 
         String dml = "UPSERT INTO " + tableName
-            + "(region_name,varchar) VALUES('SF Bay 
Area',ARRAY_TO_STRING(ARRAY[3.1, 4.2, 5.5],', '))";
+            + "(region_name,varchars) VALUES('SF Bay 
Area',ARRAY_TO_STRING(ARRAY[3.1, 4.2, 5.5],', '))";
         conn.createStatement().execute(dml);
         conn.commit();
 
         ResultSet rs;
         rs = conn.createStatement().executeQuery(
-            "SELECT varchar FROM " + tableName + " WHERE region_name = 'SF Bay 
Area'");
+            "SELECT varchars FROM " + tableName + " WHERE region_name = 'SF 
Bay Area'");
         assertTrue(rs.next());
 
         String expected = "3.1, 4.2, 5.5";
@@ -327,17 +326,17 @@ public class ArrayToStringFunctionIT extends 
ParallelStatsDisabledIT {
     public void testArrayToStringFunctionWithUpsert4() throws Exception {
         String tableName = generateUniqueName();
         String ddl =
-            "CREATE TABLE " + tableName + " (region_name VARCHAR PRIMARY 
KEY,varchar VARCHAR)";
+            "CREATE TABLE " + tableName + " (region_name VARCHAR PRIMARY 
KEY,varchars VARCHAR)";
         conn.createStatement().execute(ddl);
 
         String dml = "UPSERT INTO " + tableName
-            + "(region_name,varchar) VALUES('SF Bay 
Area',ARRAY_TO_STRING(ARRAY[true, false, true],', '))";
+            + "(region_name,varchars) VALUES('SF Bay 
Area',ARRAY_TO_STRING(ARRAY[true, false, true],', '))";
         conn.createStatement().execute(dml);
         conn.commit();
 
         ResultSet rs;
         rs = conn.createStatement().executeQuery(
-            "SELECT varchar FROM " + tableName + " WHERE region_name = 'SF Bay 
Area'");
+            "SELECT varchars FROM " + tableName + " WHERE region_name = 'SF 
Bay Area'");
         assertTrue(rs.next());
 
         String expected = "true, false, true";
@@ -354,7 +353,7 @@ public class ArrayToStringFunctionIT extends 
ParallelStatsDisabledIT {
         conn.createStatement().execute(ddl);
 
         String target = generateUniqueName();
-        ddl = "CREATE TABLE " + target + " (region_name VARCHAR PRIMARY 
KEY,varchar VARCHAR)";
+        ddl = "CREATE TABLE " + target + " (region_name VARCHAR PRIMARY 
KEY,varchars VARCHAR)";
         conn.createStatement().execute(ddl);
 
         String dml = "UPSERT INTO " + source
@@ -368,13 +367,13 @@ public class ArrayToStringFunctionIT extends 
ParallelStatsDisabledIT {
 
         dml =
             "UPSERT INTO " + target
-                + "(region_name, varchar) SELECT region_name, 
ARRAY_TO_STRING(doubles, ', ') FROM "
+                + "(region_name, varchars) SELECT region_name, 
ARRAY_TO_STRING(doubles, ', ') FROM "
                 + source;
         conn.createStatement().execute(dml);
         conn.commit();
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT varchar FROM " + 
target);
+        rs = conn.createStatement().executeQuery("SELECT varchars FROM " + 
target);
         assertTrue(rs.next());
 
         String expected = "5.67, 7.87";
@@ -394,7 +393,7 @@ public class ArrayToStringFunctionIT extends 
ParallelStatsDisabledIT {
         conn.createStatement().execute(ddl);
 
         String target = generateUniqueName();
-        ddl = "CREATE TABLE " + target + " (region_name VARCHAR PRIMARY 
KEY,varchar VARCHAR)";
+        ddl = "CREATE TABLE " + target + " (region_name VARCHAR PRIMARY 
KEY,varchars VARCHAR)";
         conn.createStatement().execute(ddl);
 
         String dml = "UPSERT INTO " + source
@@ -408,13 +407,13 @@ public class ArrayToStringFunctionIT extends 
ParallelStatsDisabledIT {
 
         dml =
             "UPSERT INTO " + target
-                + "(region_name, varchar) SELECT region_name, 
ARRAY_TO_STRING(varchars, ':') FROM "
+                + "(region_name, varchars) SELECT region_name, 
ARRAY_TO_STRING(varchars, ':') FROM "
                 + source;
         conn.createStatement().execute(dml);
         conn.commit();
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT varchar FROM " + 
target);
+        rs = conn.createStatement().executeQuery("SELECT varchars FROM " + 
target);
         assertTrue(rs.next());
 
         String expected = "hello:-)";
@@ -434,7 +433,7 @@ public class ArrayToStringFunctionIT extends 
ParallelStatsDisabledIT {
         conn.createStatement().execute(ddl);
 
         String target = generateUniqueName();
-        ddl = "CREATE TABLE " + target + " (region_name VARCHAR PRIMARY 
KEY,varchar VARCHAR)";
+        ddl = "CREATE TABLE " + target + " (region_name VARCHAR PRIMARY 
KEY,varchars VARCHAR)";
         conn.createStatement().execute(ddl);
 
         String dml = "UPSERT INTO " + source
@@ -448,13 +447,13 @@ public class ArrayToStringFunctionIT extends 
ParallelStatsDisabledIT {
 
         dml =
             "UPSERT INTO " + target
-                + "(region_name, varchar) SELECT region_name, 
ARRAY_TO_STRING(booleans, ', ') FROM "
+                + "(region_name, varchars) SELECT region_name, 
ARRAY_TO_STRING(booleans, ', ') FROM "
                 + source;
         conn.createStatement().execute(dml);
         conn.commit();
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT varchar FROM " + 
target);
+        rs = conn.createStatement().executeQuery("SELECT varchars FROM " + 
target);
         assertTrue(rs.next());
 
         String expected = "true, true";

http://git-wip-us.apache.org/repos/asf/phoenix/blob/b2d7fe01/phoenix-core/src/it/java/org/apache/phoenix/end2end/StringToArrayFunctionIT.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/StringToArrayFunctionIT.java
 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/StringToArrayFunctionIT.java
index 1afe6ef..8a44c71 100644
--- 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/StringToArrayFunctionIT.java
+++ 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/StringToArrayFunctionIT.java
@@ -17,7 +17,6 @@
  */
 package org.apache.phoenix.end2end;
 
-import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
@@ -352,7 +351,7 @@ public class StringToArrayFunctionIT extends 
ParallelStatsDisabledIT {
 
         String table1 = generateUniqueName();
         String ddl =
-            "CREATE TABLE " + table1 + " (region_name VARCHAR PRIMARY KEY, 
varchar VARCHAR)";
+            "CREATE TABLE " + table1 + " (region_name VARCHAR PRIMARY KEY, 
\"varchar\" VARCHAR)";
         conn.createStatement().execute(ddl);
 
         String table2 = generateUniqueName();
@@ -360,16 +359,16 @@ public class StringToArrayFunctionIT extends 
ParallelStatsDisabledIT {
         conn.createStatement().execute(ddl);
 
         String dml =
-            "UPSERT INTO " + table1 + "(region_name, varchar) VALUES('SF Bay 
Area', 'a,b,c,d')";
+            "UPSERT INTO " + table1 + "(region_name, \"varchar\") VALUES('SF 
Bay Area', 'a,b,c,d')";
         conn.createStatement().execute(dml);
 
-        dml = "UPSERT INTO " + table1 + "(region_name, varchar) VALUES('SF Bay 
Area2', '1,2,3,4')";
+        dml = "UPSERT INTO " + table1 + "(region_name, \"varchar\") VALUES('SF 
Bay Area2', '1,2,3,4')";
         conn.createStatement().execute(dml);
         conn.commit();
 
         dml =
             "UPSERT INTO " + table2
-                + "(region_name, varchars) SELECT region_name, 
STRING_TO_ARRAY(varchar, ',') FROM "
+                + "(region_name, varchars) SELECT region_name, 
STRING_TO_ARRAY(\"varchar\", ',') FROM "
                 + table1;
         conn.createStatement().execute(dml);
         conn.commit();
@@ -396,7 +395,7 @@ public class StringToArrayFunctionIT extends 
ParallelStatsDisabledIT {
         String sourceTable = generateUniqueName();
 
         String ddl =
-            "CREATE TABLE " + sourceTable + " (region_name VARCHAR PRIMARY 
KEY, varchar VARCHAR)";
+            "CREATE TABLE " + sourceTable + " (region_name VARCHAR PRIMARY 
KEY, \"varchar\" VARCHAR)";
         conn.createStatement().execute(ddl);
 
         String targetTable = generateUniqueName();
@@ -405,17 +404,17 @@ public class StringToArrayFunctionIT extends 
ParallelStatsDisabledIT {
         conn.createStatement().execute(ddl);
 
         String dml = "UPSERT INTO " + sourceTable
-            + "(region_name, varchar) VALUES('SF Bay Area', 'a,b,-,c,d')";
+            + "(region_name, \"varchar\") VALUES('SF Bay Area', 'a,b,-,c,d')";
         conn.createStatement().execute(dml);
 
         dml = "UPSERT INTO " + sourceTable
-            + "(region_name, varchar) VALUES('SF Bay Area2', '1,2,-,3,4')";
+            + "(region_name, \"varchar\") VALUES('SF Bay Area2', '1,2,-,3,4')";
         conn.createStatement().execute(dml);
         conn.commit();
 
         dml =
             "UPSERT INTO " + targetTable
-                + "(region_name, varchars) SELECT region_name, 
STRING_TO_ARRAY(varchar, ',', '-') FROM "
+                + "(region_name, varchars) SELECT region_name, 
STRING_TO_ARRAY(\"varchar\", ',', '-') FROM "
                 + sourceTable;
         conn.createStatement().execute(dml);
         conn.commit();

http://git-wip-us.apache.org/repos/asf/phoenix/blob/b2d7fe01/phoenix-core/src/main/java/org/apache/phoenix/calcite/CalciteUtils.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/calcite/CalciteUtils.java 
b/phoenix-core/src/main/java/org/apache/phoenix/calcite/CalciteUtils.java
index ecb7f0d..6995694 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/CalciteUtils.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/CalciteUtils.java
@@ -1,13 +1,14 @@
 package org.apache.phoenix.calcite;
 
+import java.lang.reflect.InvocationTargetException;
 import java.sql.SQLException;
 import java.sql.Timestamp;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.GregorianCalendar;
 import java.util.List;
 import java.util.Map;
-import java.util.Collections;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.calcite.avatica.util.ByteString;
@@ -39,11 +40,11 @@ import org.apache.calcite.sql.SemiJoinType;
 import org.apache.calcite.sql.SqlAggFunction;
 import org.apache.calcite.sql.SqlFunction;
 import org.apache.calcite.sql.SqlKind;
-import org.apache.calcite.sql.SqlOperator;
 import org.apache.calcite.sql.SqlLiteral;
-import org.apache.calcite.sql.SqlSelect;
 import org.apache.calcite.sql.SqlNode;
 import org.apache.calcite.sql.SqlNodeList;
+import org.apache.calcite.sql.SqlOperator;
+import org.apache.calcite.sql.SqlSelect;
 import org.apache.calcite.sql.fun.SqlStdOperatorTable;
 import org.apache.calcite.sql.parser.SqlParser;
 import org.apache.calcite.sql.parser.SqlParserPos;
@@ -62,6 +63,7 @@ import org.apache.phoenix.compile.ExpressionCompiler;
 import org.apache.phoenix.compile.ExpressionManager;
 import org.apache.phoenix.compile.StatementContext;
 import org.apache.phoenix.expression.AndExpression;
+import org.apache.phoenix.expression.ArrayConstructorExpression;
 import org.apache.phoenix.expression.CaseExpression;
 import org.apache.phoenix.expression.CoerceExpression;
 import org.apache.phoenix.expression.ComparisonExpression;
@@ -94,6 +96,7 @@ import org.apache.phoenix.expression.TimestampAddExpression;
 import org.apache.phoenix.expression.TimestampSubtractExpression;
 import org.apache.phoenix.expression.function.AbsFunction;
 import org.apache.phoenix.expression.function.AggregateFunction;
+import org.apache.phoenix.expression.function.ArrayElemRefExpression;
 import org.apache.phoenix.expression.function.AvgAggregateFunction;
 import org.apache.phoenix.expression.function.CeilDateExpression;
 import org.apache.phoenix.expression.function.CeilDecimalExpression;
@@ -130,20 +133,21 @@ import 
org.apache.phoenix.expression.function.SumAggregateFunction;
 import org.apache.phoenix.expression.function.TrimFunction;
 import org.apache.phoenix.expression.function.UDFExpression;
 import org.apache.phoenix.expression.function.UpperFunction;
-import org.apache.phoenix.jdbc.PhoenixConnection;
-import org.apache.phoenix.jdbc.PhoenixStatement;
 import org.apache.phoenix.expression.function.WeekFunction;
 import org.apache.phoenix.expression.function.YearFunction;
+import org.apache.phoenix.jdbc.PhoenixConnection;
+import org.apache.phoenix.jdbc.PhoenixStatement;
 import org.apache.phoenix.parse.FunctionParseNode;
-import org.apache.phoenix.parse.ParseNode;
-import org.apache.phoenix.parse.SQLParser;
 import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunctionInfo;
 import org.apache.phoenix.parse.JoinTableNode.JoinType;
+import org.apache.phoenix.parse.ParseNode;
+import org.apache.phoenix.parse.SQLParser;
 import org.apache.phoenix.parse.SequenceValueParseNode;
 import org.apache.phoenix.schema.PColumn;
 import org.apache.phoenix.schema.PTableType;
 import org.apache.phoenix.schema.SortOrder;
 import org.apache.phoenix.schema.TypeMismatchException;
+import org.apache.phoenix.schema.types.PArrayDataType;
 import org.apache.phoenix.schema.types.PBinary;
 import org.apache.phoenix.schema.types.PBinaryArray;
 import org.apache.phoenix.schema.types.PChar;
@@ -156,13 +160,13 @@ import org.apache.phoenix.schema.types.PLong;
 import org.apache.phoenix.schema.types.PTimestamp;
 import org.apache.phoenix.schema.types.PUnsignedTimestamp;
 import org.apache.phoenix.schema.types.PVarchar;
+import org.apache.phoenix.schema.types.PhoenixArray;
+import org.apache.phoenix.util.ExpressionUtil;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 
-import org.apache.phoenix.util.ExpressionUtil;
-
 /**
  * Utilities for interacting with Calcite.
  */
@@ -246,7 +250,9 @@ public class CalciteUtils {
             type = typeFactory.createSqlType(sqlTypeName);
         }
         if (isArrayType) {
-            type = typeFactory.createArrayType(type, arraySize == null ? -1 : 
arraySize);
+            type =
+                    typeFactory.createArrayType(
+                        typeFactory.createTypeWithNullability(type, 
type.isNullable()),-1);
         }
 
         return type;
@@ -782,12 +788,12 @@ public class CalciteUtils {
                 RexDynamicParam param = (RexDynamicParam) node;
                 int index = param.getIndex();
                 PDataType type = relDataTypeToPDataType(node.getType());
-                Integer maxLength =
-                        (type == PChar.INSTANCE
-                            || type == PCharArray.INSTANCE
-                            || type == PBinary.INSTANCE
-                            || type == PBinaryArray.INSTANCE) ?
-                        node.getType().getPrecision() : null;
+                Integer maxLength = (type == PChar.INSTANCE
+
+                        || type == PBinary.INSTANCE) ? 
node.getType().getPrecision() : null;
+                if (type == PCharArray.INSTANCE || type == 
PBinaryArray.INSTANCE) {
+                    maxLength = 
node.getType().getComponentType().getPrecision();
+                }
                 return implementor.newBindParameterExpression(index, type, 
maxLength);
             }
         });
@@ -891,7 +897,7 @@ public class CalciteUtils {
             @Override
             public Expression newExpression(RexNode node,
                     PhoenixRelImplementor implementor) {
-                RexCall call = (RexCall) node;
+                final RexCall call = (RexCall) node;
                 List<Expression> children = convertChildren(call, implementor);
                 SqlOperator op = call.getOperator();
                 try {
@@ -917,10 +923,15 @@ public class CalciteUtils {
                                 try {
                                     try {
                                         return 
info.getFunc().getDeclaredConstructor(List.class).newInstance(children);
-                                    } catch (Exception e) {
+                                    } catch (NoSuchMethodException | 
InstantiationException | IllegalAccessException | IllegalArgumentException | 
SecurityException e) {
                                         return 
info.getFunc().getDeclaredConstructor(List.class, 
StatementContext.class).newInstance(children, 
implementor.getStatementContext());
                                     }
-                                } catch (Exception e) {throw new 
RuntimeException ("Failed to create builtin function " + info.getName(), e);}
+                                }catch(InvocationTargetException e){
+                                    if(e.getTargetException() instanceof 
SQLException){
+                                        throw 
(SQLException)e.getTargetException();
+                                    }
+                                }
+                                catch (NoSuchMethodException | 
InstantiationException | IllegalAccessException | IllegalArgumentException |  
SecurityException  e) {throw new RuntimeException ("Failed to create builtin 
function " + info.getName(), e);}
                             }
                             return new UDFExpression(children, 
scalarFunc.getPFunction());
                         }
@@ -946,7 +957,12 @@ public class CalciteUtils {
                         return new CoalesceFunction(children);
                     } else if (op == SqlStdOperatorTable.MOD) {
                         return new ModulusExpression(children);
-                    };
+                    } else if (op == SqlStdOperatorTable.ITEM){
+                         ArrayElemRefExpression arrayElemRefExpression = new 
ArrayElemRefExpression(children);
+                         return arrayElemRefExpression;
+                    }
+                         
+                                
                 } catch (SQLException e) {
                     throw new RuntimeException(e);
                 }
@@ -1085,6 +1101,66 @@ public class CalciteUtils {
                 return implementor.newSequenceExpression(seq, 
SequenceValueParseNode.Op.NEXT_VALUE);
             }
         });
+        EXPRESSION_MAP.put(SqlKind.ARRAY_VALUE_CONSTRUCTOR, new 
ExpressionFactory() {
+            @Override
+            public Expression newExpression(RexNode node, 
PhoenixRelImplementor implementor) {
+                List<Expression> children = convertChildren((RexCall) node, 
implementor);
+                boolean rowKeyOrderOptimizable =
+                        
implementor.getTableMapping().getPTable().rowKeyOrderOptimizable();
+                PDataType dataType =
+                        
+                            
relDataTypeToPDataType(node.getType().getComponentType());
+                ArrayConstructorExpression arrayExpression =
+                        new ArrayConstructorExpression(children, dataType,
+                                rowKeyOrderOptimizable);
+                ImmutableBytesWritable ptr = new ImmutableBytesWritable();
+                if (ExpressionUtil.isConstant(arrayExpression)) {
+                    boolean hasNullValue=false;
+                    for (RexNode l : ((RexCall) node).getOperands()) {
+                        if(l instanceof RexLiteral && 
((RexLiteral)l).getValue()==null){
+                            hasNullValue=true;
+                            break;
+                        }
+                    }
+                    PDataType arrayElemDataType = 
getArrayElemDataType(hasNullValue,dataType);
+                    Object[] elements =
+                            (Object[]) java.lang.reflect.Array
+                                    
.newInstance(arrayElemDataType.getJavaClass(), children.size());
+                    try {
+                        for (int i = 0; i < children.size(); i++) {
+
+                            Expression child = children.get(i);
+                            child.evaluate(null, ptr);
+                            Object value = null;
+                            if (child.getDataType() == null) {
+                                value =
+                                        arrayElemDataType.toObject(ptr, 
arrayElemDataType,
+                                            child.getSortOrder());
+                            } else {
+                                value =
+                                        arrayElemDataType.toObject(ptr, 
child.getDataType(),
+                                            child.getSortOrder());
+                                
+                            }
+                            elements[i] =
+                                    LiteralExpression.newConstant(value, 
arrayElemDataType,
+                                        child.getDeterminism()).getValue();
+                        }
+                        Object value = 
PArrayDataType.instantiatePhoenixArray(arrayElemDataType,
+                                        elements);
+                        return LiteralExpression.newConstant(value,
+                            PDataType.fromTypeId(
+                                arrayElemDataType.getSqlType() + 
PDataType.ARRAY_TYPE_BASE),
+                            null, null, arrayExpression.getSortOrder(), 
Determinism.ALWAYS,
+                            rowKeyOrderOptimizable);
+                    } catch (SQLException e) {
+                        throw new RuntimeException(e);
+                    }
+                }
+                return arrayExpression;
+            }
+        });
+        
         EXPRESSION_MAP.put(SqlKind.CASE, new ExpressionFactory() {
              @Override
              public Expression newExpression(RexNode node, 
PhoenixRelImplementor implementor) {
@@ -1428,11 +1504,19 @@ public class CalciteUtils {
                   column.getDataType().toObject(key,
                       column.getSortOrder(), defaultExpression.getMaxLength(),
                       column.getScale());
+          //TODO: if we can do something better here
+          if(column.getDataType().isArrayType()){
+              try {
+                object=Arrays.asList(((PhoenixArray)object).getArray());
+            } catch (SQLException e) {
+                throw new RuntimeException(e);
+            }
+          }
           RelDataType pDataTypeToRelDataType =
                   
CalciteUtils.pDataTypeToRelDataType(rexBuilder.getTypeFactory(),
                       column.getDataType(), column.getMaxLength(),
                       column.getScale(), column.getArraySize());
-        return rexBuilder.makeLiteral((Comparable)object, 
pDataTypeToRelDataType,true);
+        return rexBuilder.makeLiteral(object, pDataTypeToRelDataType,true);
     }
 
     private static void throwDistinctNotSupportedException(boolean isDistinct, 
String func) {
@@ -1440,4 +1524,18 @@ public class CalciteUtils {
             throw new UnsupportedOperationException("DISTINCT " + func + " not 
supported.");
         }
     }
+    
+    private static PDataType getArrayElemDataType(boolean hasNullValue, 
PDataType baseType) {
+        // make the return type be the most general number type
+        if (baseType != null) {
+            if (baseType.isCoercibleTo(PVarchar.INSTANCE)) {
+                return PVarchar.INSTANCE;
+            }
+            if(hasNullValue && baseType.isCoercibleTo(PDecimal.INSTANCE)){
+                return PDecimal.INSTANCE;
+            }
+        }
+        return baseType;
+    }
+    
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/b2d7fe01/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixScalarFunction.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixScalarFunction.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixScalarFunction.java
index 2d5978d..320d688 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixScalarFunction.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixScalarFunction.java
@@ -20,8 +20,8 @@ package org.apache.phoenix.calcite;
 import java.util.List;
 
 import org.apache.calcite.adapter.enumerable.CallImplementor;
-import org.apache.calcite.adapter.enumerable.RexToLixTranslator;
 import org.apache.calcite.adapter.enumerable.RexImpTable.NullAs;
+import org.apache.calcite.adapter.enumerable.RexToLixTranslator;
 import org.apache.calcite.linq4j.tree.Expression;
 import org.apache.calcite.linq4j.tree.Expressions;
 import org.apache.calcite.rel.type.RelDataType;
@@ -30,6 +30,7 @@ import org.apache.calcite.rex.RexCall;
 import org.apache.calcite.schema.FunctionParameter;
 import org.apache.calcite.schema.ImplementableFunction;
 import org.apache.calcite.schema.ScalarFunction;
+import org.apache.calcite.sql.type.SqlTypeName;
 import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunctionInfo;
 import org.apache.phoenix.parse.PFunction;
 import org.apache.phoenix.parse.PFunction.FunctionArgument;
@@ -63,11 +64,14 @@ public class PhoenixScalarFunction implements 
ScalarFunction, ImplementableFunct
 
                         @SuppressWarnings("rawtypes")
                         public RelDataType getType(RelDataTypeFactory 
typeFactory) {
-                            PDataType dataType =
-                                    arg.isArrayType() ? 
PDataType.fromTypeId(PDataType.sqlArrayType(SchemaUtil
-                                            
.normalizeIdentifier(SchemaUtil.normalizeIdentifier(arg
-                                                    .getArgumentType())))) : 
PDataType.fromSqlTypeName(SchemaUtil
-                                            
.normalizeIdentifier(arg.getArgumentType()));
+                        PDataType dataType =
+                                PDataType.fromSqlTypeName(
+                                    
SchemaUtil.normalizeIdentifier(arg.getArgumentType()));
+                        if (dataType.isArrayType()) {
+                            return typeFactory.createArrayType(
+                                
typeFactory.createSqlType(SqlTypeName.valueOf(PDataType.arrayBaseType(dataType
+                                    ).getSqlTypeName())), -1);
+                        }
                             return 
typeFactory.createJavaType(dataType.getJavaClass());
                         }
 
@@ -88,6 +92,13 @@ public class PhoenixScalarFunction implements 
ScalarFunction, ImplementableFunct
 
     @Override
     public RelDataType getReturnType(RelDataTypeFactory typeFactory) {
+        if (returnType.isArrayType()) {
+            return typeFactory
+                    .createArrayType(
+                        typeFactory.createSqlType(SqlTypeName
+                                
.valueOf(PDataType.arrayBaseType(returnType).getSqlTypeName())),
+                        -1);
+        }
         return typeFactory.createJavaType(returnType.getJavaClass());
     }
 

http://git-wip-us.apache.org/repos/asf/phoenix/blob/b2d7fe01/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixSchema.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixSchema.java 
b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixSchema.java
index 6d9afdf..4b0ec74 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixSchema.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixSchema.java
@@ -1,71 +1,109 @@
 package org.apache.phoenix.calcite;
 
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.ArrayListMultimap;
+import java.lang.reflect.Constructor;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
 
 import org.apache.calcite.jdbc.CalciteSchema;
 import org.apache.calcite.linq4j.tree.Expression;
 import org.apache.calcite.materialize.MaterializationService;
 import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rel.type.RelDataTypeFactory;
-import org.apache.calcite.schema.*;
+import org.apache.calcite.schema.Function;
+import org.apache.calcite.schema.FunctionParameter;
+import org.apache.calcite.schema.Schema;
+import org.apache.calcite.schema.SchemaFactory;
+import org.apache.calcite.schema.SchemaPlus;
+import org.apache.calcite.schema.Table;
 import org.apache.calcite.schema.impl.TableFunctionImpl;
 import org.apache.calcite.schema.impl.ViewTable;
 import org.apache.calcite.sql.ListJarsTable;
+import org.apache.calcite.sql.type.SqlTypeName;
+import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
+import org.apache.hadoop.hbase.util.Pair;
 import org.apache.phoenix.compile.ColumnResolver;
 import org.apache.phoenix.compile.FromCompiler;
 import org.apache.phoenix.compile.SequenceManager;
-import org.apache.phoenix.expression.function.FunctionExpression;
-import org.apache.phoenix.expression.function.UDFExpression;
+import org.apache.phoenix.expression.BaseExpression;
+import org.apache.phoenix.expression.function.ByteBasedRegexpReplaceFunction;
 import org.apache.phoenix.expression.function.ByteBasedRegexpSplitFunction;
 import org.apache.phoenix.expression.function.ByteBasedRegexpSubstrFunction;
-import org.apache.phoenix.expression.function.ByteBasedRegexpReplaceFunction;
+import org.apache.phoenix.expression.function.FunctionExpression;
+import org.apache.phoenix.expression.function.StringBasedRegexpReplaceFunction;
 import org.apache.phoenix.expression.function.StringBasedRegexpSplitFunction;
 import org.apache.phoenix.expression.function.StringBasedRegexpSubstrFunction;
-import org.apache.phoenix.expression.function.StringBasedRegexpReplaceFunction;
+import org.apache.phoenix.expression.function.UDFExpression;
+import org.apache.phoenix.expression.visitor.ExpressionVisitor;
 import org.apache.phoenix.jdbc.PhoenixConnection;
+import org.apache.phoenix.jdbc.PhoenixStatement;
 import org.apache.phoenix.parse.ColumnDef;
-import org.apache.phoenix.parse.NamedTableNode;
-import org.apache.phoenix.parse.PFunction;
-import org.apache.phoenix.parse.SequenceValueParseNode;
-import org.apache.phoenix.parse.TableName;
 import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
-import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunctionInfo;
 import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunctionArgInfo;
+import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunctionInfo;
 import org.apache.phoenix.parse.FunctionParseNode.FunctionClassType;
-import org.apache.phoenix.parse.ParseNodeFactory;
+import org.apache.phoenix.parse.NamedTableNode;
+import org.apache.phoenix.parse.PFunction;
 import org.apache.phoenix.parse.PFunction.FunctionArgument;
+import org.apache.phoenix.parse.ParseNodeFactory;
+import org.apache.phoenix.parse.SequenceValueParseNode;
+import org.apache.phoenix.parse.TableName;
 import org.apache.phoenix.query.QueryServices;
 import org.apache.phoenix.query.QueryServicesOptions;
 import org.apache.phoenix.schema.MetaDataClient;
 import org.apache.phoenix.schema.PColumn;
 import org.apache.phoenix.schema.PTable;
-import org.apache.phoenix.jdbc.PhoenixStatement;
 import org.apache.phoenix.schema.PTable.ViewType;
 import org.apache.phoenix.schema.PTableImpl;
 import org.apache.phoenix.schema.PTableType;
 import org.apache.phoenix.schema.Sequence;
 import org.apache.phoenix.schema.TableNotFoundException;
 import org.apache.phoenix.schema.TableRef;
+import org.apache.phoenix.schema.tuple.Tuple;
+import org.apache.phoenix.schema.types.PBinary;
+import org.apache.phoenix.schema.types.PBinaryArray;
+import org.apache.phoenix.schema.types.PBoolean;
+import org.apache.phoenix.schema.types.PBooleanArray;
+import org.apache.phoenix.schema.types.PChar;
+import org.apache.phoenix.schema.types.PCharArray;
 import org.apache.phoenix.schema.types.PDataType;
 import org.apache.phoenix.schema.types.PDataTypeFactory;
+import org.apache.phoenix.schema.types.PDate;
+import org.apache.phoenix.schema.types.PDateArray;
+import org.apache.phoenix.schema.types.PDouble;
+import org.apache.phoenix.schema.types.PDoubleArray;
+import org.apache.phoenix.schema.types.PFloat;
+import org.apache.phoenix.schema.types.PFloatArray;
+import org.apache.phoenix.schema.types.PInteger;
+import org.apache.phoenix.schema.types.PIntegerArray;
+import org.apache.phoenix.schema.types.PLong;
+import org.apache.phoenix.schema.types.PLongArray;
+import org.apache.phoenix.schema.types.PTime;
+import org.apache.phoenix.schema.types.PTimeArray;
+import org.apache.phoenix.schema.types.PTimestamp;
+import org.apache.phoenix.schema.types.PTimestampArray;
+import org.apache.phoenix.schema.types.PVarbinary;
+import org.apache.phoenix.schema.types.PVarbinaryArray;
+import org.apache.phoenix.schema.types.PVarchar;
+import org.apache.phoenix.schema.types.PVarcharArray;
 import org.apache.phoenix.util.IndexUtil;
 import org.apache.phoenix.util.SchemaUtil;
 
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Sets;
 
 /**
  * Implementation of Calcite's {@link Schema} SPI for Phoenix.
@@ -95,6 +133,8 @@ public class PhoenixSchema implements Schema {
             .create(ListJarsTable.LIST_JARS_TABLE_METHOD);
     private final Multimap<String, Function> builtinFunctions = 
ArrayListMultimap.create();
     private RelDataTypeFactory typeFactory;
+    Map<Class<? extends PDataType>, List<Class<? extends PDataType>>> 
overalodDataTypesForArrayFunctions =
+            new HashMap<Class<? extends PDataType>, List<Class<? extends 
PDataType>>>();
     
     protected PhoenixSchema(String name, String schemaName,
             SchemaPlus parentSchema, PhoenixConnection pc) {
@@ -114,9 +154,27 @@ public class PhoenixSchema implements Schema {
         } catch (SQLException e){
             throw new RuntimeException(e);
         }
+        initializeOveralodMapForArrayFunctions();
         registerBuiltinFunctions();
     }
 
+    private void initializeOveralodMapForArrayFunctions() {
+        
+        this.overalodDataTypesForArrayFunctions.put(PBinaryArray.class,
+            new ArrayList<Class<? extends 
PDataType>>(Arrays.asList(PIntegerArray.class,
+                PFloatArray.class,PDoubleArray.class, PBooleanArray.class, 
PCharArray.class, PLongArray.class,
+                PTimeArray.class, PTimestampArray.class, PDateArray.class)));
+        this.overalodDataTypesForArrayFunctions.put(PVarbinaryArray.class,
+            new ArrayList<Class<? extends 
PDataType>>(Arrays.asList(PVarcharArray.class)));
+        this.overalodDataTypesForArrayFunctions.put(PBinary.class,
+            new ArrayList<Class<? extends PDataType>>(
+                    Arrays.asList(PInteger.class, PBoolean.class, PChar.class,
+                        PLong.class, PTime.class, PTimestamp.class, 
PDate.class,PFloat.class,PDouble.class)));
+        this.overalodDataTypesForArrayFunctions.put(PVarbinary.class,
+            new ArrayList<Class<? extends 
PDataType>>(Arrays.asList(PVarchar.class)));
+        
+    }
+
     protected PhoenixSchema(String name, String schemaName,
             SchemaPlus parentSchema, PhoenixConnection pc, RelDataTypeFactory 
typeFactory) {
         this(name, schemaName, parentSchema, pc);
@@ -206,8 +264,8 @@ public class PhoenixSchema implements Schema {
     }
 
     // Converts phoenix function information to a list of Calcite function 
signatures
-    private static List<PhoenixScalarFunction> 
convertBuiltinFunction(BuiltInFunctionInfo functionInfo){
-        List<List<FunctionArgument>> overloadedArgs = 
PhoenixSchema.overloadArguments(functionInfo.getArgs());
+    private List<PhoenixScalarFunction> 
convertBuiltinFunction(BuiltInFunctionInfo functionInfo){
+        List<List<FunctionArgument>> overloadedArgs = 
overloadArguments(functionInfo.getArgs(),functionInfo.getClassType()==FunctionClassType.ARRAY);
         List<PhoenixScalarFunction> functionList = 
Lists.newArrayListWithExpectedSize(overloadedArgs.size());
         Class<? extends FunctionExpression> clazz = functionInfo.getFunc();
 
@@ -230,10 +288,15 @@ public class PhoenixSchema implements Schema {
                                 @SuppressWarnings("rawtypes")
                                 public RelDataType getType(RelDataTypeFactory 
typeFactory) {
                                     PDataType dataType =
-                                            arg.isArrayType() ? 
PDataType.fromTypeId(PDataType.sqlArrayType(SchemaUtil
-                                                    
.normalizeIdentifier(SchemaUtil.normalizeIdentifier(arg
-                                                            
.getArgumentType())))) : PDataType.fromSqlTypeName(SchemaUtil
+                                            
PDataType.fromSqlTypeName(SchemaUtil
                                                     
.normalizeIdentifier(arg.getArgumentType()));
+                                    if (dataType.isArrayType()) {
+                                        return typeFactory
+                                        .createArrayType(
+                                            
typeFactory.createSqlType(SqlTypeName
+                                                    
.valueOf(PDataType.arrayBaseType(dataType).getSqlTypeName())),
+                                            -1);
+                                    }
                                     return 
typeFactory.createJavaType(dataType.getJavaClass());
                                 }
 
@@ -254,9 +317,44 @@ public class PhoenixSchema implements Schema {
     private static PDataType evaluateReturnType(Class<? extends 
FunctionExpression> f, List<FunctionArgument> argumentList) {
         BuiltInFunction d = f.getAnnotation(BuiltInFunction.class);
         try {
-            // Direct evaluation of the return type
-            FunctionExpression func = f.newInstance();
-            return func.getDataType();
+            if (argumentList.size() > 0 && d.classType() == 
FunctionClassType.ARRAY) {
+                Constructor constructor =
+                        f.getConstructor(new Class[]{List.class});
+                List<BaseExpression> list=new ArrayList<BaseExpression>();
+                for(final FunctionArgument arg:argumentList){
+                   list.add(new BaseExpression(){
+
+                       @Override
+                       public boolean evaluate(Tuple tuple, 
ImmutableBytesWritable ptr) {
+                           // TODO Auto-generated method stub
+                           return false;
+                       }
+
+                       @Override
+                       public <T> T accept(ExpressionVisitor<T> visitor) {
+                           // TODO Auto-generated method stub
+                           return null;
+                       }
+
+                       @Override
+                       public List<org.apache.phoenix.expression.Expression> 
getChildren() {
+                           // TODO Auto-generated method stub
+                           return null;
+                       }
+
+                       @Override
+                       public PDataType getDataType() {
+                          return 
PDataType.fromSqlTypeName(arg.getArgumentType());
+                       }
+                        
+                    });
+                }
+                FunctionExpression 
func=(FunctionExpression)constructor.newInstance(list);
+                return func.getDataType();
+            } else {
+                FunctionExpression func = f.newInstance();
+                return func.getDataType();
+            }
         } catch (Exception e) {
             if (d.classType() == FunctionClassType.ALIAS || d.classType() == 
FunctionClassType.ABSTRACT) {
                 // should never happen
@@ -269,32 +367,51 @@ public class PhoenixSchema implements Schema {
     }
 
     // Using Phoenix argument information, determine all possible function 
signatures
-    private static List<List<PFunction.FunctionArgument>> 
overloadArguments(BuiltInFunctionArgInfo[] args){
+    private  List<List<PFunction.FunctionArgument>> 
overloadArguments(BuiltInFunctionArgInfo[] args, boolean isArrayOverload){
         List<List<PFunction.FunctionArgument>> overloadedArgs = 
Lists.newArrayList();
         int solutions = 1;
-        for(int i = 0; i < args.length; solutions *= 
args[i].getAllowedTypes().length, i++);
+
+        
+        List<Pair<BuiltInFunctionArgInfo, List<Class<? extends PDataType>>>> 
argsAllowedTypePair =
+                new ArrayList<Pair<BuiltInFunctionArgInfo, List<Class<? 
extends PDataType>>>>();
+        for (int i = 0; i < args.length; i++) {
+            List<Class<? extends PDataType>> argList = new ArrayList<Class<? 
extends PDataType>>(Arrays.asList(args[i].getAllowedTypes()));
+            if (isArrayOverload) {
+                for (Class<? extends PDataType> cls : 
this.overalodDataTypesForArrayFunctions.keySet()) {
+                    if (argList.contains(cls)) {
+                        
argList.addAll(this.overalodDataTypesForArrayFunctions.get(cls));
+                    }
+                }
+            }
+            argsAllowedTypePair
+                    .add(new Pair<BuiltInFunctionArgInfo, List<Class<? extends 
PDataType>>>(args[i],
+                            argList));
+        }
+        for(int i = 0; i < argsAllowedTypePair.size(); solutions *= 
argsAllowedTypePair.get(i).getSecond().size(), i++);
         for(int i = 0; i < solutions; i++) {
             int j = 1;
             short k = 0;
             overloadedArgs.add(new ArrayList<PFunction.FunctionArgument>());
-            for(BuiltInFunctionArgInfo arg : args) {
-                Class<? extends PDataType>[] temp = arg.getAllowedTypes();
-                PDataType dataType = 
PDataTypeFactory.getInstance().instanceFromClass(temp[(i/j)%temp.length]);
+            for(Pair<BuiltInFunctionArgInfo, List<Class<? extends PDataType>>> 
arg : argsAllowedTypePair) {
+                List<Class<? extends PDataType>> temp = arg.getSecond();
+                PDataType dataType = 
PDataTypeFactory.getInstance().instanceFromClass(temp.get((i/j)%temp.size()));
                 overloadedArgs.get(i).add( new PFunction.FunctionArgument(
                         dataType.toString(),
                         dataType.isArrayType(),
-                        arg.isConstant(),
-                        arg.getDefaultValue(),
-                        arg.getMinValue(),
-                        arg.getMaxValue(),
+                        arg.getFirst().isConstant(),
+                        arg.getFirst().getDefaultValue(),
+                        arg.getFirst().getMinValue(),
+                        arg.getFirst().getMaxValue(),
                         k));
                 k++;
-                j *= temp.length;
+                j *= temp.size();
             }
         }
+     
         return overloadedArgs;
     }
 
+
     @Override
     public Table getTable(String name) {
         Table table = tables.get(name);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/b2d7fe01/phoenix-core/src/main/java/org/apache/phoenix/expression/BindParameterExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/BindParameterExpression.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/BindParameterExpression.java
index ce23b30..3c089d3 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/BindParameterExpression.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/BindParameterExpression.java
@@ -1,11 +1,15 @@
 package org.apache.phoenix.expression;
 
+import java.sql.SQLException;
+
+import org.apache.calcite.avatica.util.ArrayImpl;
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.phoenix.execute.RuntimeContext;
 import org.apache.phoenix.expression.visitor.ExpressionVisitor;
 import org.apache.phoenix.schema.SortOrder;
 import org.apache.phoenix.schema.tuple.Tuple;
 import org.apache.phoenix.schema.types.PDataType;
+import org.apache.phoenix.schema.types.PhoenixArray;
 
 public class BindParameterExpression extends VariableExpression {
     @SuppressWarnings("rawtypes")
@@ -26,7 +30,17 @@ public class BindParameterExpression extends 
VariableExpression {
         if (value == null) {
             return false;
         }
-        
+        if(type.isArrayType()){
+            PDataType arrayBaseType = PDataType.arrayBaseType(type);
+            try {
+                value=new 
PhoenixArray(arrayBaseType,(Object[])((ArrayImpl)value).getArray());
+            } catch (SQLException e) {
+                throw new RuntimeException(e);
+            }
+            if(arrayBaseType.isFixedWidth()){
+                value=new PhoenixArray((PhoenixArray)value,maxLength);
+            }
+        }
         ptr.set(type.toBytes(value));
         type.pad(ptr, maxLength, SortOrder.ASC);
         return true;

http://git-wip-us.apache.org/repos/asf/phoenix/blob/b2d7fe01/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayAppendFunction.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayAppendFunction.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayAppendFunction.java
index 8c7fa9f..8d24461 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayAppendFunction.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayAppendFunction.java
@@ -22,12 +22,18 @@ import java.util.List;
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.phoenix.expression.Expression;
 import org.apache.phoenix.parse.FunctionParseNode;
+import org.apache.phoenix.parse.FunctionParseNode.FunctionClassType;
 import org.apache.phoenix.schema.TypeMismatchException;
-import org.apache.phoenix.schema.types.*;
+import org.apache.phoenix.schema.types.PArrayDataType;
+import org.apache.phoenix.schema.types.PBinary;
+import org.apache.phoenix.schema.types.PBinaryArray;
+import org.apache.phoenix.schema.types.PDataType;
+import org.apache.phoenix.schema.types.PVarbinary;
+import org.apache.phoenix.schema.types.PVarbinaryArray;
 
 @FunctionParseNode.BuiltInFunction(name = ArrayAppendFunction.NAME, args = {
         @FunctionParseNode.Argument(allowedTypes = {PBinaryArray.class, 
PVarbinaryArray.class}),
-        @FunctionParseNode.Argument(allowedTypes = {PVarbinary.class}, 
defaultValue = "null")})
+        @FunctionParseNode.Argument(allowedTypes = 
{PBinary.class,PVarbinary.class}, defaultValue = "null")},classType = 
FunctionClassType.ARRAY)
 public class ArrayAppendFunction extends ArrayModifierFunction {
 
     public static final String NAME = "ARRAY_APPEND";
@@ -48,4 +54,9 @@ public class ArrayAppendFunction extends 
ArrayModifierFunction {
     public String getName() {
         return NAME;
     }
+    
+    @Override
+    public PDataType getDataType() {
+        return children.get(0).getDataType();
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/b2d7fe01/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayConcatFunction.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayConcatFunction.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayConcatFunction.java
index 85655c6..537488e 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayConcatFunction.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayConcatFunction.java
@@ -22,6 +22,7 @@ import java.util.List;
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.phoenix.expression.Expression;
 import org.apache.phoenix.parse.FunctionParseNode;
+import org.apache.phoenix.parse.FunctionParseNode.FunctionClassType;
 import org.apache.phoenix.schema.SortOrder;
 import org.apache.phoenix.schema.TypeMismatchException;
 import org.apache.phoenix.schema.tuple.Tuple;
@@ -32,7 +33,7 @@ import org.apache.phoenix.schema.types.PVarbinaryArray;
 
 @FunctionParseNode.BuiltInFunction(name = ArrayConcatFunction.NAME, args = {
         @FunctionParseNode.Argument(allowedTypes = {PBinaryArray.class, 
PVarbinaryArray.class}),
-        @FunctionParseNode.Argument(allowedTypes = {PBinaryArray.class, 
PVarbinaryArray.class})})
+        @FunctionParseNode.Argument(allowedTypes = {PBinaryArray.class, 
PVarbinaryArray.class})},classType=FunctionClassType.ARRAY)
 public class ArrayConcatFunction extends ArrayModifierFunction {
 
     public static final String NAME = "ARRAY_CAT";

http://git-wip-us.apache.org/repos/asf/phoenix/blob/b2d7fe01/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayElemRefExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayElemRefExpression.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayElemRefExpression.java
index 06bbced..cb44d08 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayElemRefExpression.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayElemRefExpression.java
@@ -25,6 +25,7 @@ import java.util.List;
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.phoenix.expression.BaseCompoundExpression;
 import org.apache.phoenix.expression.Expression;
+import org.apache.phoenix.expression.LiteralExpression;
 import org.apache.phoenix.expression.visitor.ExpressionVisitor;
 import org.apache.phoenix.schema.tuple.Tuple;
 import org.apache.phoenix.schema.types.PArrayDataTypeDecoder;
@@ -48,6 +49,9 @@ public class ArrayElemRefExpression extends 
BaseCompoundExpression {
     @Override
     public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) {
         Expression arrayExpr = children.get(0);
+        if (children.size() > 1) {
+            this.index = (Integer) ((LiteralExpression) 
children.get(1)).getValue();
+        }
         return PArrayDataTypeDecoder.positionAtArrayElement(tuple, ptr, index, 
arrayExpr, getDataType(), getMaxLength());
     }
 

http://git-wip-us.apache.org/repos/asf/phoenix/blob/b2d7fe01/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayFillFunction.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayFillFunction.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayFillFunction.java
index c8db7f9..f9a3953 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayFillFunction.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayFillFunction.java
@@ -23,14 +23,20 @@ import java.util.List;
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.phoenix.expression.Expression;
 import org.apache.phoenix.parse.FunctionParseNode;
+import org.apache.phoenix.parse.FunctionParseNode.FunctionClassType;
 import org.apache.phoenix.schema.SortOrder;
 import org.apache.phoenix.schema.TypeMismatchException;
 import org.apache.phoenix.schema.tuple.Tuple;
-import org.apache.phoenix.schema.types.*;
+import org.apache.phoenix.schema.types.PArrayDataType;
+import org.apache.phoenix.schema.types.PBinary;
+import org.apache.phoenix.schema.types.PDataType;
+import org.apache.phoenix.schema.types.PInteger;
+import org.apache.phoenix.schema.types.PVarbinary;
+import org.apache.phoenix.schema.types.PhoenixArray;
 
 @FunctionParseNode.BuiltInFunction(name = ArrayFillFunction.NAME, args = {
-        @FunctionParseNode.Argument(allowedTypes = {PVarbinary.class}),
-        @FunctionParseNode.Argument(allowedTypes = {PInteger.class})})
+        @FunctionParseNode.Argument(allowedTypes = 
{PBinary.class,PVarbinary.class}),
+        @FunctionParseNode.Argument(allowedTypes = {PInteger.class})}, 
classType=FunctionClassType.ARRAY)
 public class ArrayFillFunction extends ScalarFunction {
 
     public static final String NAME = "ARRAY_FILL";

http://git-wip-us.apache.org/repos/asf/phoenix/blob/b2d7fe01/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayIndexFunction.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayIndexFunction.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayIndexFunction.java
index 0f3c40c..223709e 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayIndexFunction.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayIndexFunction.java
@@ -23,19 +23,19 @@ import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.phoenix.expression.Expression;
 import org.apache.phoenix.parse.FunctionParseNode.Argument;
 import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
+import org.apache.phoenix.parse.FunctionParseNode.FunctionClassType;
 import org.apache.phoenix.parse.ParseException;
+import org.apache.phoenix.schema.SortOrder;
+import org.apache.phoenix.schema.tuple.Tuple;
 import org.apache.phoenix.schema.types.PArrayDataTypeDecoder;
 import org.apache.phoenix.schema.types.PBinaryArray;
-import org.apache.phoenix.schema.types.PInteger;
 import org.apache.phoenix.schema.types.PDataType;
+import org.apache.phoenix.schema.types.PInteger;
 import org.apache.phoenix.schema.types.PVarbinaryArray;
-import org.apache.phoenix.schema.SortOrder;
-import org.apache.phoenix.schema.tuple.Tuple;
 
 @BuiltInFunction(name = ArrayIndexFunction.NAME, args = {
-               @Argument(allowedTypes = { PBinaryArray.class,
-        PVarbinaryArray.class }),
-               @Argument(allowedTypes = { PInteger.class }) })
+               @Argument(allowedTypes = { PBinaryArray.class, 
PVarbinaryArray.class}),
+               @Argument(allowedTypes = { PInteger.class }) },classType = 
FunctionClassType.ARRAY)
 public class ArrayIndexFunction extends ScalarFunction {
 
        public static final String NAME = "ARRAY_ELEM";

http://git-wip-us.apache.org/repos/asf/phoenix/blob/b2d7fe01/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayLengthFunction.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayLengthFunction.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayLengthFunction.java
index 3f7fe22..7515623 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayLengthFunction.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayLengthFunction.java
@@ -23,15 +23,15 @@ import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.phoenix.expression.Expression;
 import org.apache.phoenix.parse.FunctionParseNode.Argument;
 import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
-import org.apache.phoenix.schema.types.PBinaryArray;
-import org.apache.phoenix.schema.types.PInteger;
+import org.apache.phoenix.parse.FunctionParseNode.FunctionClassType;
+import org.apache.phoenix.schema.tuple.Tuple;
 import org.apache.phoenix.schema.types.PArrayDataType;
+import org.apache.phoenix.schema.types.PBinaryArray;
 import org.apache.phoenix.schema.types.PDataType;
+import org.apache.phoenix.schema.types.PInteger;
 import org.apache.phoenix.schema.types.PVarbinaryArray;
-import org.apache.phoenix.schema.tuple.Tuple;
 
-@BuiltInFunction(name = ArrayLengthFunction.NAME, args = { 
@Argument(allowedTypes = {
-               PBinaryArray.class, PVarbinaryArray.class }) })
+@BuiltInFunction(name = ArrayLengthFunction.NAME, args = { 
@Argument(allowedTypes = {PBinaryArray.class, PVarbinaryArray.class }) 
},classType=FunctionClassType.ARRAY)
 public class ArrayLengthFunction extends ScalarFunction {
        public static final String NAME = "ARRAY_LENGTH";
 

http://git-wip-us.apache.org/repos/asf/phoenix/blob/b2d7fe01/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayPrependFunction.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayPrependFunction.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayPrependFunction.java
index c2311fb..20ab66c 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayPrependFunction.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayPrependFunction.java
@@ -23,12 +23,18 @@ import java.util.List;
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.phoenix.expression.Expression;
 import org.apache.phoenix.parse.FunctionParseNode;
+import org.apache.phoenix.parse.FunctionParseNode.FunctionClassType;
 import org.apache.phoenix.schema.TypeMismatchException;
-import org.apache.phoenix.schema.types.*;
+import org.apache.phoenix.schema.types.PArrayDataType;
+import org.apache.phoenix.schema.types.PBinary;
+import org.apache.phoenix.schema.types.PBinaryArray;
+import org.apache.phoenix.schema.types.PDataType;
+import org.apache.phoenix.schema.types.PVarbinary;
+import org.apache.phoenix.schema.types.PVarbinaryArray;
 
 @FunctionParseNode.BuiltInFunction(name = ArrayPrependFunction.NAME, args = {
-        @FunctionParseNode.Argument(allowedTypes = {PVarbinary.class}),
-        @FunctionParseNode.Argument(allowedTypes = {PBinaryArray.class, 
PVarbinaryArray.class})})
+        @FunctionParseNode.Argument(allowedTypes = 
{PBinary.class,PVarbinary.class}),
+        @FunctionParseNode.Argument(allowedTypes = {PBinaryArray.class, 
PVarbinaryArray.class})}, classType=FunctionClassType.ARRAY)
 public class ArrayPrependFunction extends ArrayModifierFunction {
 
     public static final String NAME = "ARRAY_PREPEND";

http://git-wip-us.apache.org/repos/asf/phoenix/blob/b2d7fe01/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayToStringFunction.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayToStringFunction.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayToStringFunction.java
index 9102df4..7eda953 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayToStringFunction.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayToStringFunction.java
@@ -22,14 +22,21 @@ import java.util.List;
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.phoenix.expression.Expression;
 import org.apache.phoenix.parse.FunctionParseNode;
+import org.apache.phoenix.parse.FunctionParseNode.FunctionClassType;
 import org.apache.phoenix.schema.SortOrder;
 import org.apache.phoenix.schema.tuple.Tuple;
-import org.apache.phoenix.schema.types.*;
+import org.apache.phoenix.schema.types.PArrayDataType;
+import org.apache.phoenix.schema.types.PBinaryArray;
+import org.apache.phoenix.schema.types.PChar;
+import org.apache.phoenix.schema.types.PDataType;
+import org.apache.phoenix.schema.types.PVarbinaryArray;
+import org.apache.phoenix.schema.types.PVarchar;
+import org.apache.phoenix.schema.types.PhoenixArray;
 
 @FunctionParseNode.BuiltInFunction(name = ArrayToStringFunction.NAME, args = {
         @FunctionParseNode.Argument(allowedTypes = {PBinaryArray.class, 
PVarbinaryArray.class}),
         @FunctionParseNode.Argument(allowedTypes = {PVarchar.class, 
PChar.class}),
-        @FunctionParseNode.Argument(allowedTypes = {PVarchar.class, 
PChar.class}, defaultValue = "null")})
+        @FunctionParseNode.Argument(allowedTypes = {PVarchar.class, 
PChar.class}, defaultValue = "null")},classType=FunctionClassType.ARRAY)
 public class ArrayToStringFunction extends ScalarFunction {
     public static final String NAME = "ARRAY_TO_STRING";
 

http://git-wip-us.apache.org/repos/asf/phoenix/blob/b2d7fe01/phoenix-core/src/main/java/org/apache/phoenix/parse/FunctionParseNode.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/parse/FunctionParseNode.java 
b/phoenix-core/src/main/java/org/apache/phoenix/parse/FunctionParseNode.java
index df9ad86..957e9d4 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/FunctionParseNode.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/FunctionParseNode.java
@@ -304,7 +304,8 @@ public class FunctionParseNode extends CompoundParseNode {
         ABSTRACT,
         DERIVED,
         ALIAS,
-        UDF
+        UDF,
+        ARRAY
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/phoenix/blob/b2d7fe01/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 f31f272..2ce5252 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
@@ -84,7 +84,8 @@ public abstract class PArrayDataType<T> extends PDataType<T> {
     }
 
     public byte[] toBytes(Object object, PDataType baseType, SortOrder 
sortOrder) {
-        return toBytes(object, baseType, sortOrder, true);
+             return toBytes(object, baseType, sortOrder, true);
+        
     }
     
     public byte[] toBytes(Object object, PDataType baseType, SortOrder 
sortOrder, boolean rowKeyOrderOptimizable) {
@@ -1051,7 +1052,7 @@ public abstract class PArrayDataType<T> extends 
PDataType<T> {
     }
 
     public static int estimateSize(int size, PDataType baseType) {
-        if (baseType.isFixedWidth()) {
+        if (baseType.isFixedWidth() && baseType.getByteSize()!=null) {
             return baseType.getByteSize() * size;
         } else {
             return size * ValueSchema.ESTIMATED_VARIABLE_LENGTH_SIZE;

http://git-wip-us.apache.org/repos/asf/phoenix/blob/b2d7fe01/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PBinaryArray.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PBinaryArray.java 
b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PBinaryArray.java
index 523f774..b61c551 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PBinaryArray.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PBinaryArray.java
@@ -17,6 +17,7 @@
  */
 package org.apache.phoenix.schema.types;
 
+import org.apache.calcite.avatica.util.ArrayImpl;
 import org.apache.phoenix.schema.SortOrder;
 
 public class PBinaryArray extends PArrayDataType<byte[][]> {
@@ -24,7 +25,7 @@ public class PBinaryArray extends PArrayDataType<byte[][]> {
     public static final PBinaryArray INSTANCE = new PBinaryArray();
 
     private PBinaryArray() {
-        super("BINARY ARRAY", PDataType.ARRAY_TYPE_BASE + 
PBinary.INSTANCE.getSqlType(), PhoenixArray.class, null, 28);
+        super("BINARY ARRAY", PDataType.ARRAY_TYPE_BASE + 
PBinary.INSTANCE.getSqlType(), ArrayImpl.class, null, 28);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/phoenix/blob/b2d7fe01/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PBooleanArray.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PBooleanArray.java 
b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PBooleanArray.java
index 742b0de..e5b3182 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PBooleanArray.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PBooleanArray.java
@@ -17,6 +17,7 @@
  */
 package org.apache.phoenix.schema.types;
 
+import org.apache.calcite.avatica.util.ArrayImpl;
 import org.apache.phoenix.schema.SortOrder;
 import 
org.apache.phoenix.schema.types.PhoenixArray.PrimitiveBooleanPhoenixArray;
 
@@ -25,7 +26,7 @@ public class PBooleanArray extends PArrayDataType<boolean[]> {
     public static final PBooleanArray INSTANCE = new PBooleanArray();
 
     private PBooleanArray() {
-        super("BOOLEAN ARRAY", PDataType.ARRAY_TYPE_BASE + 
PBoolean.INSTANCE.getSqlType(), PhoenixArray.class, null, 25);
+        super("BOOLEAN ARRAY", PDataType.ARRAY_TYPE_BASE + 
PBoolean.INSTANCE.getSqlType(), ArrayImpl.class, null, 25);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/phoenix/blob/b2d7fe01/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PCharArray.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PCharArray.java 
b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PCharArray.java
index a740c7f..0906a20 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PCharArray.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PCharArray.java
@@ -17,6 +17,7 @@
  */
 package org.apache.phoenix.schema.types;
 
+import org.apache.calcite.avatica.util.ArrayImpl;
 import org.apache.phoenix.schema.SortOrder;
 
 public class PCharArray extends PArrayDataType<String[]> {
@@ -24,7 +25,7 @@ public class PCharArray extends PArrayDataType<String[]> {
     public static final PCharArray INSTANCE = new PCharArray();
 
     private PCharArray() {
-        super("CHAR ARRAY", PDataType.ARRAY_TYPE_BASE + 
PChar.INSTANCE.getSqlType(), PhoenixArray.class,
+        super("CHAR ARRAY", PDataType.ARRAY_TYPE_BASE + 
PChar.INSTANCE.getSqlType(), ArrayImpl.class,
                 null, 29);
     }
 

http://git-wip-us.apache.org/repos/asf/phoenix/blob/b2d7fe01/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDataType.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDataType.java 
b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDataType.java
index de1e63f..1bea92e 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDataType.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDataType.java
@@ -1154,7 +1154,7 @@ public abstract class PDataType<T> implements 
DataType<T>, Comparable<PDataType<
             if (type.isArrayType()) {
                 PhoenixArray arr = (PhoenixArray)value;
                 if ((type.getSqlType() == arr.baseType.sqlType + 
PDataType.ARRAY_TYPE_BASE)
-                        && type.getJavaClass().isInstance(value)) { return 
type; }
+                        ) { return type; }
             } else {
                 if (type.getJavaClass().isInstance(value)) { return type; }
             }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/b2d7fe01/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDoubleArray.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDoubleArray.java 
b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDoubleArray.java
index d585229..b5f928c 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDoubleArray.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDoubleArray.java
@@ -17,6 +17,7 @@
  */
 package org.apache.phoenix.schema.types;
 
+import org.apache.calcite.avatica.util.ArrayImpl;
 import org.apache.phoenix.schema.SortOrder;
 
 public class PDoubleArray extends PArrayDataType<double[]> {
@@ -25,7 +26,7 @@ public class PDoubleArray extends PArrayDataType<double[]> {
 
     private PDoubleArray() {
         super("DOUBLE ARRAY", PDataType.ARRAY_TYPE_BASE + 
PDouble.INSTANCE.getSqlType(),
-                PhoenixArray.class, null, 34);
+                ArrayImpl.class, null, 34);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/phoenix/blob/b2d7fe01/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PIntegerArray.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PIntegerArray.java 
b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PIntegerArray.java
index b317cfe..c59f93a 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PIntegerArray.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PIntegerArray.java
@@ -17,6 +17,7 @@
  */
 package org.apache.phoenix.schema.types;
 
+import org.apache.calcite.avatica.util.ArrayImpl;
 import org.apache.phoenix.schema.SortOrder;
 
 public class PIntegerArray extends PArrayDataType<int[]> {
@@ -25,7 +26,7 @@ public class PIntegerArray extends PArrayDataType<int[]> {
 
     private PIntegerArray() {
         super("INTEGER ARRAY", PDataType.ARRAY_TYPE_BASE + 
PInteger.INSTANCE.getSqlType(),
-                PhoenixArray.class, null, 24);
+            ArrayImpl.class, null, 24);
     }
 
     @Override

Reply via email to