You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by ra...@apache.org on 2015/06/30 19:23:30 UTC
phoenix git commit: PHOENIX-2060 - ARRAY_FILL Push the new files
Repository: phoenix
Updated Branches:
refs/heads/master c0ad8cf67 -> fb8c9413f
PHOENIX-2060 - ARRAY_FILL Push the new files
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/fb8c9413
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/fb8c9413
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/fb8c9413
Branch: refs/heads/master
Commit: fb8c9413f6583798059741fb7c03c8c04a2c3336
Parents: c0ad8cf
Author: ramkrishna <ra...@gmail.com>
Authored: Tue Jun 30 22:52:40 2015 +0530
Committer: ramkrishna <ra...@gmail.com>
Committed: Tue Jun 30 22:52:40 2015 +0530
----------------------------------------------------------------------
.../phoenix/end2end/ArrayFillFunctionIT.java | 531 +++++++++++++++++++
.../expression/function/ArrayFillFunction.java | 79 +++
.../expression/ArrayFillFunctionTest.java | 221 ++++++++
3 files changed, 831 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/phoenix/blob/fb8c9413/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
new file mode 100644
index 0000000..f9ce88d
--- /dev/null
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayFillFunctionIT.java
@@ -0,0 +1,531 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.phoenix.end2end;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.math.BigDecimal;
+import java.sql.*;
+
+import org.junit.Test;
+
+public class ArrayFillFunctionIT extends BaseHBaseManagedTimeIT {
+
+ private void initTables(Connection conn) throws Exception {
+ String ddl = "CREATE TABLE regions (region_name VARCHAR PRIMARY KEY,length1 INTEGER, length2 INTEGER,date DATE,time TIME,timestamp TIMESTAMP,varchar VARCHAR,integer INTEGER,double DOUBLE,bigint BIGINT,char CHAR(15),double1 DOUBLE,char1 CHAR(17),nullcheck INTEGER,chars2 CHAR(15)[], varchars2 VARCHAR[])";
+ conn.createStatement().execute(ddl);
+ String dml = "UPSERT INTO regions(region_name,length1,length2,date,time,timestamp,varchar,integer,double,bigint,char,double1,char1,nullcheck,chars2,varchars2) VALUES('SF Bay Area'," +
+ "0," +
+ "-3," +
+ "to_date('2015-05-20 06:12:14.184')," +
+ "to_time('2015-05-20 06:12:14.184')," +
+ "to_timestamp('2015-05-20 06:12:14.184')," +
+ "'foo'," +
+ "34," +
+ "23.45," +
+ "34567," +
+ "'foo'," +
+ "23.45," +
+ "'wert'," +
+ "NULL," +
+ "ARRAY['hello','hello','hello']," +
+ "ARRAY['hello','hello','hello']" +
+ ")";
+ PreparedStatement stmt = conn.prepareStatement(dml);
+ stmt.execute();
+ conn.commit();
+ }
+
+ @Test
+ public void testArrayFillFunctionVarchar() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ initTables(conn);
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT ARRAY_FILL(varchar,5) FROM regions WHERE region_name = 'SF Bay Area'");
+ assertTrue(rs.next());
+
+ String[] strings = new String[]{"foo", "foo", "foo", "foo", "foo"};
+
+ Array array = conn.createArrayOf("VARCHAR", strings);
+
+ assertEquals(array, rs.getArray(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testArrayFillFunctionInteger() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ initTables(conn);
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT ARRAY_FILL(integer,4) FROM regions WHERE region_name = 'SF Bay Area'");
+ assertTrue(rs.next());
+
+ Object[] objects = new Object[]{34, 34, 34, 34};
+
+ Array array = conn.createArrayOf("INTEGER", objects);
+
+ assertEquals(array, rs.getArray(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testArrayFillFunctionDouble() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ initTables(conn);
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT ARRAY_FILL(double,4) FROM regions WHERE region_name = 'SF Bay Area'");
+ assertTrue(rs.next());
+
+ Object[] objects = new Object[]{23.45, 23.45, 23.45, 23.45};
+
+ Array array = conn.createArrayOf("DOUBLE", objects);
+
+ assertEquals(array, rs.getArray(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testArrayFillFunctionBigint() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ initTables(conn);
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT ARRAY_FILL(bigint,4) FROM regions WHERE region_name = 'SF Bay Area'");
+ assertTrue(rs.next());
+
+ Object[] objects = new Object[]{34567l, 34567l, 34567l, 34567l};
+
+ Array array = conn.createArrayOf("BIGINT", objects);
+
+ assertEquals(array, rs.getArray(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testArrayFillFunctionChar() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ initTables(conn);
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT ARRAY_FILL(char,4) FROM regions WHERE region_name = 'SF Bay Area'");
+ assertTrue(rs.next());
+
+ Object[] objects = new Object[]{"foo", "foo", "foo", "foo"};
+
+ Array array = conn.createArrayOf("CHAR", objects);
+ assertEquals(array, rs.getArray(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testArrayFillFunctionVarChar() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ initTables(conn);
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT ARRAY_FILL(varchar,4) FROM regions WHERE region_name = 'SF Bay Area'");
+ assertTrue(rs.next());
+
+ Object[] objects = new Object[]{"foo", "foo", "foo", "foo"};
+
+ Array array = conn.createArrayOf("VARCHAR", objects);
+ assertEquals(array, rs.getArray(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testArrayFillFunctionDate() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ initTables(conn);
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT ARRAY_FILL(date,3) FROM regions WHERE region_name = 'SF Bay Area'");
+ assertTrue(rs.next());
+
+ Object[] objects = new Object[]{new Date(1432102334184l), new Date(1432102334184l), new Date(1432102334184l)};
+
+ Array array = conn.createArrayOf("DATE", objects);
+ assertEquals(array, rs.getArray(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testArrayFillFunctionTime() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ initTables(conn);
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT ARRAY_FILL(time,3) FROM regions WHERE region_name = 'SF Bay Area'");
+ assertTrue(rs.next());
+
+ Object[] objects = new Object[]{new Time(1432102334184l), new Time(1432102334184l), new Time(1432102334184l)};
+
+ Array array = conn.createArrayOf("TIME", objects);
+ assertEquals(array, rs.getArray(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testArrayFillFunctionTimestamp() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ initTables(conn);
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT ARRAY_FILL(timestamp,3) FROM regions WHERE region_name = 'SF Bay Area'");
+ assertTrue(rs.next());
+
+ Object[] objects = new Object[]{new Timestamp(1432102334184l), new Timestamp(1432102334184l), new Timestamp(1432102334184l)};
+
+ Array array = conn.createArrayOf("TIMESTAMP", objects);
+ assertEquals(array, rs.getArray(1));
+ assertFalse(rs.next());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testArrayFillFunctionInvalidLength1() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ initTables(conn);
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT ARRAY_FILL(timestamp,length2) FROM regions WHERE region_name = 'SF Bay Area'");
+ assertTrue(rs.next());
+
+ Object[] objects = new Object[]{new Timestamp(1432102334184l), new Timestamp(1432102334184l), new Timestamp(1432102334184l)};
+
+ Array array = conn.createArrayOf("TIMESTAMP", objects);
+ assertEquals(array, rs.getArray(1));
+ assertFalse(rs.next());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testArrayFillFunctionInvalidLength2() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ initTables(conn);
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT ARRAY_FILL(timestamp,length1) FROM regions WHERE region_name = 'SF Bay Area'");
+ assertTrue(rs.next());
+
+ Object[] objects = new Object[]{new Timestamp(1432102334184l), new Timestamp(1432102334184l), new Timestamp(1432102334184l)};
+
+ Array array = conn.createArrayOf("TIMESTAMP", objects);
+ assertEquals(array, rs.getArray(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testArrayFillFunctionWithNestedFunctions1() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ initTables(conn);
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT ARRAY_FILL(ARRAY_ELEM(ARRAY[23,45],1),3) FROM regions WHERE region_name = 'SF Bay Area'");
+ assertTrue(rs.next());
+
+ Integer[] integers = new Integer[]{23, 23, 23};
+
+ Array array = conn.createArrayOf("INTEGER", integers);
+
+ assertEquals(array, rs.getArray(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testArrayFillFunctionWithNestedFunctions2() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ initTables(conn);
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT ARRAY_FILL('hello', ARRAY_LENGTH(ARRAY[34, 45])) FROM regions WHERE region_name = 'SF Bay Area'");
+ assertTrue(rs.next());
+
+ Object[] objects = new Object[]{"hello", "hello"};
+
+ Array array = conn.createArrayOf("VARCHAR", objects);
+
+ assertEquals(array, rs.getArray(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testArrayFillFunctionWithNestedFunctions3() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ initTables(conn);
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT ARRAY_FILL(3.4, ARRAY_LENGTH(ARRAY[34, 45])) FROM regions WHERE region_name = 'SF Bay Area'");
+ assertTrue(rs.next());
+
+ Object[] objects = new Object[]{BigDecimal.valueOf(3.4), BigDecimal.valueOf(3.4)};
+
+ Array array = conn.createArrayOf("DECIMAL", objects);
+
+ assertEquals(array, rs.getArray(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testArrayFillFunctionWithUpsert1() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+
+ String ddl = "CREATE TABLE regions (region_name VARCHAR PRIMARY KEY,varchars VARCHAR[])";
+ conn.createStatement().execute(ddl);
+
+ String dml = "UPSERT INTO regions(region_name,varchars) VALUES('SF Bay Area',ARRAY_FILL('hello',3))";
+ conn.createStatement().execute(dml);
+ conn.commit();
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT varchars FROM regions WHERE region_name = 'SF Bay Area'");
+ assertTrue(rs.next());
+
+ String[] strings = new String[]{"hello", "hello", "hello"};
+
+ Array array = conn.createArrayOf("VARCHAR", strings);
+
+ assertEquals(array, rs.getArray(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testArrayFillFunctionWithUpsert2() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+
+ String ddl = "CREATE TABLE regions (region_name VARCHAR PRIMARY KEY,integers INTEGER[])";
+ conn.createStatement().execute(ddl);
+
+ String dml = "UPSERT INTO regions(region_name,integers) VALUES('SF Bay Area',ARRAY_FILL(3456,3))";
+ conn.createStatement().execute(dml);
+ conn.commit();
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT integers FROM regions WHERE region_name = 'SF Bay Area'");
+ assertTrue(rs.next());
+
+ Integer[] integers = new Integer[]{3456, 3456, 3456};
+
+ Array array = conn.createArrayOf("INTEGER", integers);
+
+ assertEquals(array, rs.getArray(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testArrayFillFunctionWithUpsert3() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+
+ String ddl = "CREATE TABLE regions (region_name VARCHAR PRIMARY KEY,doubles DOUBLE[])";
+ conn.createStatement().execute(ddl);
+
+ String dml = "UPSERT INTO regions(region_name,doubles) VALUES('SF Bay Area',ARRAY_FILL(2.5,3))";
+ conn.createStatement().execute(dml);
+ conn.commit();
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT doubles FROM regions WHERE region_name = 'SF Bay Area'");
+ assertTrue(rs.next());
+
+ Double[] doubles = new Double[]{2.5, 2.5, 2.5};
+
+ Array array = conn.createArrayOf("DOUBLE", doubles);
+
+ assertEquals(array, rs.getArray(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testArrayFillFunctionWithUpsertSelect1() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+
+ String ddl = "CREATE TABLE source (region_name VARCHAR PRIMARY KEY,doubles DOUBLE[])";
+ conn.createStatement().execute(ddl);
+
+ ddl = "CREATE TABLE target (region_name VARCHAR PRIMARY KEY,doubles DOUBLE[],doubles2 DOUBLE[])";
+ conn.createStatement().execute(ddl);
+
+ String dml = "UPSERT INTO source(region_name,doubles) VALUES('SF Bay Area',ARRAY_FILL(3.4,3))";
+ conn.createStatement().execute(dml);
+
+ dml = "UPSERT INTO source(region_name,doubles) VALUES('SF Bay Area2',ARRAY_FILL(2.3,3))";
+ conn.createStatement().execute(dml);
+ conn.commit();
+
+ dml = "UPSERT INTO target(region_name, doubles, doubles2) SELECT region_name, doubles,ARRAY_FILL(4.5,5) FROM source";
+ conn.createStatement().execute(dml);
+ conn.commit();
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT doubles, doubles2 FROM target");
+ assertTrue(rs.next());
+
+ Double[] doubles = new Double[]{3.4, 3.4, 3.4};
+ Double[] doubles2 = new Double[]{4.5, 4.5, 4.5, 4.5, 4.5};
+ Array array = conn.createArrayOf("DOUBLE", doubles);
+ Array array2 = conn.createArrayOf("DOUBLE", doubles2);
+
+ assertEquals(array, rs.getArray(1));
+ assertEquals(array2, rs.getArray(2));
+ assertTrue(rs.next());
+
+ doubles = new Double[]{2.3, 2.3, 2.3};
+ array = conn.createArrayOf("DOUBLE", doubles);
+
+ assertEquals(array, rs.getArray(1));
+ assertEquals(array2, rs.getArray(2));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testArrayFillFunctionWithUpsertSelect2() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+
+ String ddl = "CREATE TABLE source (region_name VARCHAR PRIMARY KEY,varchars VARCHAR[])";
+ conn.createStatement().execute(ddl);
+
+ ddl = "CREATE TABLE target (region_name VARCHAR PRIMARY KEY,varchars VARCHAR[],varchars2 VARCHAR[])";
+ conn.createStatement().execute(ddl);
+
+ String dml = "UPSERT INTO source(region_name,varchars) VALUES('SF Bay Area',ARRAY_FILL('foo',3))";
+ conn.createStatement().execute(dml);
+
+ dml = "UPSERT INTO source(region_name,varchars) VALUES('SF Bay Area2',ARRAY_FILL('hello',3))";
+ conn.createStatement().execute(dml);
+ conn.commit();
+
+ dml = "UPSERT INTO target(region_name, varchars, varchars2) SELECT region_name, varchars,ARRAY_FILL(':-)',5) FROM source";
+ conn.createStatement().execute(dml);
+ conn.commit();
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT varchars, varchars2 FROM target");
+ assertTrue(rs.next());
+
+ String[] strings = new String[]{"foo", "foo", "foo"};
+ String[] strings2 = new String[]{":-)", ":-)", ":-)", ":-)", ":-)"};
+ Array array = conn.createArrayOf("VARCHAR", strings);
+ Array array2 = conn.createArrayOf("VARCHAR", strings2);
+
+ assertEquals(array, rs.getArray(1));
+ assertEquals(array2, rs.getArray(2));
+ assertTrue(rs.next());
+
+ strings = new String[]{"hello", "hello", "hello"};
+ array = conn.createArrayOf("VARCHAR", strings);
+
+ assertEquals(array, rs.getArray(1));
+ assertEquals(array2, rs.getArray(2));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testArrayFillFunctionInWhere1() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ initTables(conn);
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT region_name FROM regions WHERE ARRAY[12, 12, 12, 12]=ARRAY_FILL(12,4)");
+ assertTrue(rs.next());
+
+ assertEquals("SF Bay Area", rs.getString(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testArrayFillFunctionInWhere2() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ initTables(conn);
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT region_name FROM regions WHERE varchar=ANY(ARRAY_FILL('foo',3))");
+ assertTrue(rs.next());
+
+ assertEquals("SF Bay Area", rs.getString(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testArrayFillFunctionInWhere3() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ initTables(conn);
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT region_name FROM regions WHERE ARRAY['2345', '2345', '2345', '2345']=ARRAY_FILL('2345', 4)");
+ assertTrue(rs.next());
+
+ assertEquals("SF Bay Area", rs.getString(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testArrayFillFunctionInWhere4() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ initTables(conn);
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT region_name FROM regions WHERE ARRAY[23.45, 23.45, 23.45]=ARRAY_FILL(23.45, 3)");
+ assertTrue(rs.next());
+
+ assertEquals("SF Bay Area", rs.getString(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testArrayFillFunctionInWhere5() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ initTables(conn);
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT region_name FROM regions WHERE ARRAY['foo','foo','foo','foo','foo']=ARRAY_FILL(varchar,5)");
+ assertTrue(rs.next());
+
+ assertEquals("SF Bay Area", rs.getString(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testArrayFillFunctionInWhere6() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ initTables(conn);
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT region_name FROM regions WHERE varchars2=ARRAY_FILL('hello',3)");
+ assertTrue(rs.next());
+
+ assertEquals("SF Bay Area", rs.getString(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testArrayFillFunctionInWhere7() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ initTables(conn);
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT region_name FROM regions WHERE ARRAY[2,2,2,2]=ARRAY_FILL(2,4)");
+ assertTrue(rs.next());
+
+ assertEquals("SF Bay Area", rs.getString(1));
+ assertFalse(rs.next());
+ }
+}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/fb8c9413/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
new file mode 100644
index 0000000..5c3a2e5
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ArrayFillFunction.java
@@ -0,0 +1,79 @@
+package org.apache.phoenix.expression.function;
+
+import java.util.Arrays;
+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.schema.SortOrder;
+import org.apache.phoenix.schema.TypeMismatchException;
+import org.apache.phoenix.schema.tuple.Tuple;
+import org.apache.phoenix.schema.types.*;
+
+@FunctionParseNode.BuiltInFunction(name = ArrayFillFunction.NAME, args = {
+ @FunctionParseNode.Argument(allowedTypes = {PVarbinary.class}),
+ @FunctionParseNode.Argument(allowedTypes = {PInteger.class})})
+public class ArrayFillFunction extends ScalarFunction {
+
+ public static final String NAME = "ARRAY_FILL";
+
+ public ArrayFillFunction() {
+ }
+
+ public ArrayFillFunction(List<Expression> children) throws TypeMismatchException {
+ super(children);
+ }
+
+ @Override
+ public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) {
+ if (!getElementExpr().evaluate(tuple, ptr)) {
+ return false;
+ }
+ Object element = getElementExpr().getDataType().toObject(ptr, getElementExpr().getSortOrder(), getElementExpr().getMaxLength(), getElementExpr().getScale());
+ if (!getLengthExpr().evaluate(tuple, ptr) || ptr.getLength() == 0) {
+ return false;
+ }
+ int length = (Integer) getLengthExpr().getDataType().toObject(ptr, getLengthExpr().getSortOrder(), getLengthExpr().getMaxLength(), getLengthExpr().getScale());
+ if (length <= 0) {
+ throw new IllegalArgumentException("Array length should be greater than 0");
+ }
+ Object[] elements = new Object[length];
+ Arrays.fill(elements, element);
+ PhoenixArray array = PDataType.instantiatePhoenixArray(getElementExpr().getDataType(), elements);
+ //When max length of a char array is not the max length of the element passed in
+ if (getElementExpr().getDataType().isFixedWidth() && getMaxLength() != null && getMaxLength() != array.getMaxLength()) {
+ array = new PhoenixArray(array, getMaxLength());
+ }
+ ptr.set(((PArrayDataType) getDataType()).toBytes(array, getElementExpr().getDataType(), getElementExpr().getSortOrder()));
+ return true;
+ }
+
+ @Override
+ public String getName() {
+ return NAME;
+ }
+
+ @Override
+ public PDataType getDataType() {
+ return PArrayDataType.fromTypeId(PDataType.ARRAY_TYPE_BASE + getElementExpr().getDataType().getSqlType());
+ }
+
+ @Override
+ public Integer getMaxLength() {
+ return getElementExpr().getDataType().getByteSize() == null ? getElementExpr().getMaxLength() : null;
+ }
+
+ @Override
+ public SortOrder getSortOrder() {
+ return children.get(0).getSortOrder();
+ }
+
+ public Expression getElementExpr() {
+ return children.get(0);
+ }
+
+ public Expression getLengthExpr() {
+ return children.get(1);
+ }
+}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/fb8c9413/phoenix-core/src/test/java/org/apache/phoenix/expression/ArrayFillFunctionTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/expression/ArrayFillFunctionTest.java b/phoenix-core/src/test/java/org/apache/phoenix/expression/ArrayFillFunctionTest.java
new file mode 100644
index 0000000..be8cc6f
--- /dev/null
+++ b/phoenix-core/src/test/java/org/apache/phoenix/expression/ArrayFillFunctionTest.java
@@ -0,0 +1,221 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.phoenix.expression;
+
+import static org.junit.Assert.assertEquals;
+
+import java.math.BigDecimal;
+import java.sql.Date;
+import java.sql.SQLException;
+import java.sql.Time;
+import java.util.List;
+
+import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
+import org.apache.phoenix.expression.function.ArrayFillFunction;
+import org.apache.phoenix.schema.SortOrder;
+import org.apache.phoenix.schema.types.*;
+import org.junit.Test;
+
+import com.google.common.collect.Lists;
+
+public class ArrayFillFunctionTest {
+
+ private static void testExpression(LiteralExpression element, LiteralExpression length, PhoenixArray expected)
+ throws SQLException {
+ List<Expression> expressions = Lists.newArrayList((Expression) element);
+ expressions.add(length);
+
+ Expression arrayFillFunction = new ArrayFillFunction(expressions);
+ ImmutableBytesWritable ptr = new ImmutableBytesWritable();
+ arrayFillFunction.evaluate(null, ptr);
+ PhoenixArray result = (PhoenixArray) arrayFillFunction.getDataType().toObject(ptr, arrayFillFunction.getSortOrder(), arrayFillFunction.getMaxLength(), arrayFillFunction.getScale());
+ assertEquals(expected, result);
+ }
+
+ private static void test(Object element, Object length, PDataType elementDataType, Integer elementMaxLen, Integer elementScale, PDataType lengthDataType, Integer lengthMaxlen, Integer lengthScale, PhoenixArray expected, SortOrder elementSortOrder, SortOrder lengthSortOrder) throws SQLException {
+ LiteralExpression elementLiteral, lengthLiteral;
+ elementLiteral = LiteralExpression.newConstant(element, elementDataType, elementMaxLen, elementScale, elementSortOrder, Determinism.ALWAYS);
+ lengthLiteral = LiteralExpression.newConstant(length, lengthDataType, lengthMaxlen, lengthScale, lengthSortOrder, Determinism.ALWAYS);
+ testExpression(elementLiteral, lengthLiteral, expected);
+ }
+
+ @Test
+ public void testForInt() throws SQLException {
+ Object element = 5;
+ Object length = 3;
+ PDataType baseType = PInteger.INSTANCE;
+ PhoenixArray e = new PhoenixArray.PrimitiveIntPhoenixArray(baseType, new Object[]{5, 5, 5});
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.ASC, SortOrder.ASC);
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.ASC, SortOrder.DESC);
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.DESC, SortOrder.DESC);
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.DESC, SortOrder.ASC);
+ }
+
+ @Test
+ public void testForBoolean() throws SQLException {
+ Object element = false;
+ Object length = 3;
+ PDataType baseType = PBoolean.INSTANCE;
+ PhoenixArray e = new PhoenixArray.PrimitiveBooleanPhoenixArray(baseType, new Object[]{false, false, false});
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.ASC, SortOrder.ASC);
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.ASC, SortOrder.DESC);
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.DESC, SortOrder.DESC);
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.DESC, SortOrder.ASC);
+ }
+
+ @Test
+ public void testForVarchar() throws SQLException {
+ Object element = "foo";
+ Object length = 3;
+ PDataType baseType = PVarchar.INSTANCE;
+ PhoenixArray e = new PhoenixArray(baseType, new Object[]{"foo", "foo", "foo"});
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.ASC, SortOrder.ASC);
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.ASC, SortOrder.DESC);
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.DESC, SortOrder.DESC);
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.DESC, SortOrder.ASC);
+ }
+
+ @Test
+ public void testForChar() throws SQLException {
+ Object element = "foo";
+ Object length = 3;
+ PDataType baseType = PChar.INSTANCE;
+ PhoenixArray e = new PhoenixArray(baseType, new Object[]{"foo", "foo", "foo"});
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.ASC, SortOrder.ASC);
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.ASC, SortOrder.DESC);
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.DESC, SortOrder.DESC);
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.DESC, SortOrder.ASC);
+ }
+
+ @Test
+ public void testForDouble() throws SQLException {
+ Object element = 34.67;
+ Object length = 3;
+ PDataType baseType = PDouble.INSTANCE;
+ PhoenixArray e = new PhoenixArray.PrimitiveDoublePhoenixArray(baseType, new Object[]{34.67, 34.67, 34.67});
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.ASC, SortOrder.ASC);
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.ASC, SortOrder.DESC);
+ }
+
+ @Test
+ public void testForFloat() throws SQLException {
+ Object element = 5.6;
+ Object length = 3;
+ PDataType baseType = PFloat.INSTANCE;
+ PhoenixArray e = new PhoenixArray.PrimitiveFloatPhoenixArray(baseType, new Object[]{(float) 5.6, (float) 5.6, (float) 5.6});
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.ASC, SortOrder.ASC);
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.ASC, SortOrder.DESC);
+ }
+
+ @Test
+ public void testForSmallint() throws SQLException {
+ Object element = 5;
+ Object length = 3;
+ PDataType baseType = PSmallint.INSTANCE;
+ PhoenixArray e = new PhoenixArray.PrimitiveShortPhoenixArray(baseType, new Object[]{(short) 5, (short) 5, (short) 5});
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.ASC, SortOrder.ASC);
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.ASC, SortOrder.DESC);
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.DESC, SortOrder.DESC);
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.DESC, SortOrder.ASC);
+ }
+
+ @Test
+ public void testForTinyint() throws SQLException {
+ Object element = 6;
+ Object length = 3;
+ PDataType baseType = PTinyint.INSTANCE;
+ PhoenixArray e = new PhoenixArray.PrimitiveBytePhoenixArray(baseType, new Object[]{(byte) 6, (byte) 6, (byte) 6});
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.ASC, SortOrder.ASC);
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.ASC, SortOrder.DESC);
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.DESC, SortOrder.DESC);
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.DESC, SortOrder.ASC);
+ }
+
+ @Test
+ public void testForLong() throws SQLException {
+ Object element = 34567l;
+ Object length = 3;
+ PDataType baseType = PLong.INSTANCE;
+ PhoenixArray e = new PhoenixArray.PrimitiveLongPhoenixArray(baseType, new Object[]{34567l, 34567l, 34567l});
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.ASC, SortOrder.ASC);
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.ASC, SortOrder.DESC);
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.DESC, SortOrder.DESC);
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.DESC, SortOrder.ASC);
+ }
+
+ @Test
+ public void testForDecimal() throws SQLException {
+ Object element = BigDecimal.valueOf(345.67);
+ Object length = 3;
+ PDataType baseType = PDecimal.INSTANCE;
+ PhoenixArray e = new PhoenixArray(baseType, new Object[]{BigDecimal.valueOf(345.67), BigDecimal.valueOf(345.67), BigDecimal.valueOf(345.67)});
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.ASC, SortOrder.ASC);
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.ASC, SortOrder.DESC);
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.DESC, SortOrder.DESC);
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.DESC, SortOrder.ASC);
+ }
+
+ @Test
+ public void testForDate() throws SQLException {
+ Object element = new Date(23);
+ Object length = 3;
+ PDataType baseType = PDate.INSTANCE;
+ PhoenixArray e = new PhoenixArray(baseType, new Object[]{new Date(23), new Date(23), new Date(23)});
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.ASC, SortOrder.ASC);
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.ASC, SortOrder.DESC);
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.DESC, SortOrder.DESC);
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.DESC, SortOrder.ASC);
+ }
+
+ @Test
+ public void testForTime() throws SQLException {
+ Object element = new Time(23);
+ Object length = 3;
+ PDataType baseType = PTime.INSTANCE;
+ PhoenixArray e = new PhoenixArray(baseType, new Object[]{new Time(23), new Time(23), new Time(23)});
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.ASC, SortOrder.ASC);
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.ASC, SortOrder.DESC);
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.DESC, SortOrder.DESC);
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.DESC, SortOrder.ASC);
+ }
+
+ @Test
+ public void testForNulls1() throws SQLException {
+ Object element = null;
+ Object length = 3;
+ PDataType baseType = PInteger.INSTANCE;
+ PhoenixArray e = new PhoenixArray.PrimitiveIntPhoenixArray(baseType, new Object[]{0, 0, 0});
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.ASC, SortOrder.ASC);
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.ASC, SortOrder.DESC);
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.DESC, SortOrder.DESC);
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.DESC, SortOrder.ASC);
+ }
+
+ @Test
+ public void testForNulls2() throws SQLException {
+ Object element = null;
+ Object length = 3;
+ PDataType baseType = PVarchar.INSTANCE;
+ PhoenixArray e = new PhoenixArray(baseType, new Object[]{null, null, null});
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.ASC, SortOrder.ASC);
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.ASC, SortOrder.DESC);
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.DESC, SortOrder.DESC);
+ test(element, length, baseType, null, null, PInteger.INSTANCE, null, null, e, SortOrder.DESC, SortOrder.ASC);
+ }
+}