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/07/28 07:00:39 UTC
phoenix git commit: PHOENIX-2147 Implement STRING_TO_ARRAY built in
function (Dumindu Buddhika)
Repository: phoenix
Updated Branches:
refs/heads/master 28a8e9774 -> 265b6dee7
PHOENIX-2147 Implement STRING_TO_ARRAY built in function (Dumindu
Buddhika)
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/265b6dee
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/265b6dee
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/265b6dee
Branch: refs/heads/master
Commit: 265b6dee75891c1d4a35cb73d4baaf86cbae1482
Parents: 28a8e97
Author: ramkrishna <ra...@gmail.com>
Authored: Tue Jul 28 10:30:00 2015 +0530
Committer: ramkrishna <ra...@gmail.com>
Committed: Tue Jul 28 10:30:00 2015 +0530
----------------------------------------------------------------------
.../end2end/StringToArrayFunctionIT.java | 423 +++++++++++++++++++
.../phoenix/expression/ExpressionType.java | 4 +-
.../function/StringToArrayFunction.java | 91 ++++
.../phoenix/schema/types/PArrayDataType.java | 21 +
.../expression/StringToArrayFunctionTest.java | 275 ++++++++++++
5 files changed, 813 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/phoenix/blob/265b6dee/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
new file mode 100644
index 0000000..6e6ac9f
--- /dev/null
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/StringToArrayFunctionIT.java
@@ -0,0 +1,423 @@
+/*
+ * 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.sql.*;
+
+import org.apache.phoenix.schema.types.PVarchar;
+import org.apache.phoenix.schema.types.PhoenixArray;
+import org.junit.Test;
+
+public class StringToArrayFunctionIT extends BaseHBaseManagedTimeIT {
+
+ private void initTables(Connection conn) throws Exception {
+ String ddl = "CREATE TABLE regions (region_name VARCHAR PRIMARY KEY, string1 VARCHAR, string2 CHAR(50), delimiter1 VARCHAR, delimiter2 CHAR(20), nullstring1 VARCHAR, nullstring2 CHAR(20))";
+ conn.createStatement().execute(ddl);
+ String dml = "UPSERT INTO regions(region_name, string1, string2, delimiter1, delimiter2, nullstring1, nullstring2) VALUES('SF Bay Area'," +
+ "'a,b,c,d'," +
+ "'1.2.3.4'," +
+ "','," +
+ "'.'," +
+ "'c'," +
+ "'3'" +
+ ")";
+ PreparedStatement stmt = conn.prepareStatement(dml);
+ stmt.execute();
+ conn.commit();
+ }
+
+ @Test
+ public void testStringToArrayFunction1() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ initTables(conn);
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT STRING_TO_ARRAY(string1, delimiter1) FROM regions WHERE region_name = 'SF Bay Area'");
+ assertTrue(rs.next());
+
+ PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, new Object[]{"a", "b", "c", "d"});
+
+ assertEquals(expected, rs.getArray(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testStringToArrayFunction2() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ initTables(conn);
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT STRING_TO_ARRAY(string1, delimiter1, nullstring1) FROM regions WHERE region_name = 'SF Bay Area'");
+ assertTrue(rs.next());
+
+ PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, new Object[]{"a", "b", null, "d"});
+
+ assertEquals(expected, rs.getArray(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testStringToArrayFunction3() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ initTables(conn);
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT STRING_TO_ARRAY(string1, delimiter1, 'a') FROM regions WHERE region_name = 'SF Bay Area'");
+ assertTrue(rs.next());
+
+ PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, new Object[]{null, "b", "c", "d"});
+
+ assertEquals(expected, rs.getArray(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testStringToArrayFunction4() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ initTables(conn);
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT STRING_TO_ARRAY(string1, delimiter1, 'd') FROM regions WHERE region_name = 'SF Bay Area'");
+ assertTrue(rs.next());
+
+ PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, new Object[]{"a", "b", "c", null});
+
+ assertEquals(expected, rs.getArray(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testStringToArrayFunction5() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ initTables(conn);
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT STRING_TO_ARRAY(string2, delimiter2) FROM regions WHERE region_name = 'SF Bay Area'");
+ assertTrue(rs.next());
+
+ PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, new Object[]{"1", "2", "3", "4"});
+
+ assertEquals(expected, rs.getArray(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testStringToArrayFunction6() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ initTables(conn);
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT STRING_TO_ARRAY(string2, delimiter2, nullstring2) FROM regions WHERE region_name = 'SF Bay Area'");
+ assertTrue(rs.next());
+
+ PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, new Object[]{"1", "2", null, "4"});
+
+ assertEquals(expected, rs.getArray(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testStringToArrayFunction7() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ initTables(conn);
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT STRING_TO_ARRAY(string2, delimiter2, '1') FROM regions WHERE region_name = 'SF Bay Area'");
+ assertTrue(rs.next());
+
+ PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, new Object[]{null, "2", "3", "4"});
+
+ assertEquals(expected, rs.getArray(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testStringToArrayFunction8() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ initTables(conn);
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT STRING_TO_ARRAY(string2, delimiter2, '4') FROM regions WHERE region_name = 'SF Bay Area'");
+ assertTrue(rs.next());
+
+ PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, new Object[]{"1", "2", "3", null});
+
+ assertEquals(expected, rs.getArray(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testStringToArrayFunction9() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ initTables(conn);
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT STRING_TO_ARRAY(region_name, ' ', '4') FROM regions WHERE region_name = 'SF Bay Area'");
+ assertTrue(rs.next());
+
+ PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, new Object[]{"SF", "Bay", "Area"});
+
+ assertEquals(expected, rs.getArray(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testStringToArrayFunction10() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ initTables(conn);
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT STRING_TO_ARRAY('hello,hello,hello', delimiter1) FROM regions WHERE region_name = 'SF Bay Area'");
+ assertTrue(rs.next());
+
+ PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, new Object[]{"hello", "hello", "hello"});
+
+ assertEquals(expected, rs.getArray(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testStringToArrayFunction11() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ initTables(conn);
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT STRING_TO_ARRAY('a,hello,hello,hello,b', ',', 'hello') FROM regions WHERE region_name = 'SF Bay Area'");
+ assertTrue(rs.next());
+
+ PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, new Object[]{"a", null, null, null, "b"});
+
+ assertEquals(expected, rs.getArray(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testStringToArrayFunction12() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ initTables(conn);
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT STRING_TO_ARRAY('b.a.b', delimiter2, 'b') FROM regions WHERE region_name = 'SF Bay Area'");
+ assertTrue(rs.next());
+
+ PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, new Object[]{null, "a", null});
+
+ assertEquals(expected, rs.getArray(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testStringToArrayFunctionWithNestedFunctions1() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ initTables(conn);
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT ARRAY_LENGTH(STRING_TO_ARRAY('a, b, c', ', ')) FROM regions WHERE region_name = 'SF Bay Area'");
+ assertTrue(rs.next());
+
+ assertEquals(3, rs.getInt(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testStringToArrayFunctionWithNestedFunctions2() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ initTables(conn);
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT STRING_TO_ARRAY(ARRAY_TO_STRING(ARRAY['a', 'b', 'c'], delimiter2), delimiter2, 'b') FROM regions WHERE region_name = 'SF Bay Area'");
+ assertTrue(rs.next());
+
+ PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, new Object[]{"a", null, "c"});
+
+ assertEquals(expected, rs.getArray(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testStringToArrayFunctionWithNestedFunctions3() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ initTables(conn);
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT STRING_TO_ARRAY(ARRAY_TO_STRING(ARRAY['a', 'b', 'c'], delimiter2), ARRAY_ELEM(ARRAY[',', '.'], 2), 'b') FROM regions WHERE region_name = 'SF Bay Area'");
+ assertTrue(rs.next());
+
+ PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, new Object[]{"a", null, "c"});
+
+ assertEquals(expected, rs.getArray(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testStringToArrayFunctionWithUpsert1() 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', STRING_TO_ARRAY('hello, world, :-)', ', '))";
+ 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());
+
+ PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, new Object[]{"hello", "world", ":-)"});
+
+ assertEquals(expected, rs.getArray(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testStringToArrayFunctionWithUpsert2() 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', STRING_TO_ARRAY('a, b, -, c', ', ', '-'))";
+ 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());
+
+ PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, new Object[]{"a", "b", null, "c"});
+
+ assertEquals(expected, rs.getArray(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testStringToArrayFunctionWithUpsertSelect1() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+
+ String ddl = "CREATE TABLE source (region_name VARCHAR PRIMARY KEY, varchar VARCHAR)";
+ conn.createStatement().execute(ddl);
+
+ ddl = "CREATE TABLE target (region_name VARCHAR PRIMARY KEY, varchars VARCHAR[])";
+ conn.createStatement().execute(ddl);
+
+ String dml = "UPSERT INTO source(region_name, varchar) VALUES('SF Bay Area', 'a,b,c,d')";
+ conn.createStatement().execute(dml);
+
+ dml = "UPSERT INTO source(region_name, varchar) VALUES('SF Bay Area2', '1,2,3,4')";
+ conn.createStatement().execute(dml);
+ conn.commit();
+
+ dml = "UPSERT INTO target(region_name, varchars) SELECT region_name, STRING_TO_ARRAY(varchar, ',') FROM source";
+ conn.createStatement().execute(dml);
+ conn.commit();
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT varchars FROM target");
+ assertTrue(rs.next());
+
+ PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, new Object[]{"a", "b", "c", "d"});
+
+ assertEquals(expected, rs.getArray(1));
+ assertTrue(rs.next());
+
+ expected = new PhoenixArray(PVarchar.INSTANCE, new Object[]{"1", "2", "3", "4"});
+
+ assertEquals(expected, rs.getArray(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testStringToArrayFunctionWithUpsertSelect2() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+
+ String ddl = "CREATE TABLE source (region_name VARCHAR PRIMARY KEY, varchar VARCHAR)";
+ conn.createStatement().execute(ddl);
+
+ ddl = "CREATE TABLE target (region_name VARCHAR PRIMARY KEY, varchars VARCHAR[])";
+ conn.createStatement().execute(ddl);
+
+ String dml = "UPSERT INTO source(region_name, varchar) VALUES('SF Bay Area', 'a,b,-,c,d')";
+ conn.createStatement().execute(dml);
+
+ dml = "UPSERT INTO source(region_name, varchar) VALUES('SF Bay Area2', '1,2,-,3,4')";
+ conn.createStatement().execute(dml);
+ conn.commit();
+
+ dml = "UPSERT INTO target(region_name, varchars) SELECT region_name, STRING_TO_ARRAY(varchar, ',', '-') FROM source";
+ conn.createStatement().execute(dml);
+ conn.commit();
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT varchars FROM target");
+ assertTrue(rs.next());
+
+ PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, new Object[]{"a", "b", null, "c", "d"});
+
+ assertEquals(expected, rs.getArray(1));
+ assertTrue(rs.next());
+
+ expected = new PhoenixArray(PVarchar.INSTANCE, new Object[]{"1", "2", null, "3", "4"});
+
+ assertEquals(expected, rs.getArray(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testStringToArrayFunctionInWhere1() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ initTables(conn);
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT region_name FROM regions WHERE ARRAY['a', 'b', 'c', 'd']=STRING_TO_ARRAY(string1, delimiter1)");
+ assertTrue(rs.next());
+
+ assertEquals("SF Bay Area", rs.getString(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testStringToArrayFunctionInWhere2() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ initTables(conn);
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT region_name FROM regions WHERE 'a'=ANY(STRING_TO_ARRAY(string1, delimiter1))");
+ assertTrue(rs.next());
+
+ assertEquals("SF Bay Area", rs.getString(1));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testStringToArrayFunctionInWhere3() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ initTables(conn);
+
+ ResultSet rs;
+ rs = conn.createStatement().executeQuery("SELECT region_name FROM regions WHERE 'a'=ALL(STRING_TO_ARRAY('a,a,a,', delimiter1))");
+ assertTrue(rs.next());
+
+ assertEquals("SF Bay Area", rs.getString(1));
+ assertFalse(rs.next());
+ }
+}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/265b6dee/phoenix-core/src/main/java/org/apache/phoenix/expression/ExpressionType.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/ExpressionType.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/ExpressionType.java
index 3c364c0..9e9cb45 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/ExpressionType.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/ExpressionType.java
@@ -96,6 +96,7 @@ import org.apache.phoenix.expression.function.StddevSampFunction;
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.StringToArrayFunction;
import org.apache.phoenix.expression.function.SubstrFunction;
import org.apache.phoenix.expression.function.SumAggregateFunction;
import org.apache.phoenix.expression.function.TimezoneOffsetFunction;
@@ -251,7 +252,8 @@ public enum ExpressionType {
PowerFunction(PowerFunction.class),
ArrayConcatFunction(ArrayConcatFunction.class),
ArrayFillFunction(ArrayFillFunction.class),
- ArrayToStringFunction(ArrayToStringFunction.class)
+ ArrayToStringFunction(ArrayToStringFunction.class),
+ StringToArrayFunction(StringToArrayFunction.class)
;
ExpressionType(Class<? extends Expression> clazz) {
http://git-wip-us.apache.org/repos/asf/phoenix/blob/265b6dee/phoenix-core/src/main/java/org/apache/phoenix/expression/function/StringToArrayFunction.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/StringToArrayFunction.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/StringToArrayFunction.java
new file mode 100644
index 0000000..ffbda01
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/StringToArrayFunction.java
@@ -0,0 +1,91 @@
+/*
+ * 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.function;
+
+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.tuple.Tuple;
+import org.apache.phoenix.schema.types.*;
+
+@FunctionParseNode.BuiltInFunction(name = StringToArrayFunction.NAME, args = {
+ @FunctionParseNode.Argument(allowedTypes = {PVarchar.class, PChar.class}),
+ @FunctionParseNode.Argument(allowedTypes = {PVarchar.class, PChar.class}),
+ @FunctionParseNode.Argument(allowedTypes = {PVarchar.class, PChar.class}, defaultValue = "null")})
+public class StringToArrayFunction extends ScalarFunction {
+ public static final String NAME = "STRING_TO_ARRAY";
+
+ public StringToArrayFunction() {
+ }
+
+ public StringToArrayFunction(List<Expression> children) {
+ super(children);
+ }
+
+ @Override
+ public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) {
+ Expression delimiterExpr = children.get(1);
+ String delimiter;
+ if (!delimiterExpr.evaluate(tuple, ptr)) {
+ return false;
+ } else if (ptr.getLength() == 0) {
+ delimiter = "";
+ } else {
+ delimiter = (String) delimiterExpr.getDataType().toObject(ptr, delimiterExpr.getSortOrder(), delimiterExpr.getMaxLength(), delimiterExpr.getScale());
+ }
+
+ Expression stringExpr = children.get(0);
+ if (!stringExpr.evaluate(tuple, ptr)) {
+ return false;
+ } else if (ptr.getLength() == 0) {
+ return true;
+ }
+ String string = (String) stringExpr.getDataType().toObject(ptr, stringExpr.getSortOrder(), stringExpr.getMaxLength(), stringExpr.getScale());
+
+ Expression nullExpr = children.get(2);
+ String nullString = null;
+ if (nullExpr.evaluate(tuple, ptr) && ptr.getLength() != 0) {
+ nullString = (String) nullExpr.getDataType().toObject(ptr, nullExpr.getSortOrder(), nullExpr.getMaxLength(), nullExpr.getScale());
+ }
+
+ return PArrayDataType.stringToArray(ptr, string, delimiter, nullString, getSortOrder());
+ }
+
+ @Override
+ public String getName() {
+ return NAME;
+ }
+
+ @Override
+ public Integer getMaxLength() {
+ return null;
+ }
+
+ @Override
+ public PDataType getDataType() {
+ return PVarcharArray.INSTANCE;
+ }
+
+ @Override
+ public SortOrder getSortOrder() {
+ return children.get(0).getSortOrder();
+ }
+}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/265b6dee/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 28144fd..a1759a4 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
@@ -24,6 +24,7 @@ import java.sql.Types;
import java.text.Format;
import java.util.LinkedList;
import java.util.List;
+import java.util.regex.Pattern;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.apache.hadoop.hbase.util.Bytes;
@@ -990,6 +991,26 @@ public abstract class PArrayDataType<T> extends PDataType<T> {
return true;
}
+ public static boolean stringToArray(ImmutableBytesWritable ptr, String string, String delimiter, String nullString, SortOrder sortOrder) {
+ Pattern pattern = Pattern.compile(Pattern.quote(delimiter));
+ String[] array;
+ if (delimiter.length() != 0) {
+ array = pattern.split(string);
+ if (nullString != null) {
+ for (int i = 0; i < array.length; i++) {
+ if (array[i].equals(nullString)) {
+ array[i] = null;
+ }
+ }
+ }
+ } else {
+ array = string.split("(?!^)");
+ }
+ PhoenixArray phoenixArray = new PhoenixArray(PVarchar.INSTANCE, array);
+ ptr.set(PVarcharArray.INSTANCE.toBytes(phoenixArray, PVarchar.INSTANCE, sortOrder));
+ return true;
+ }
+
public static int serailizeOffsetArrayIntoStream(DataOutputStream oStream, TrustedByteArrayOutputStream byteStream,
int noOfElements, int maxOffset, int[] offsetPos) throws IOException {
int offsetPosition = (byteStream.size());
http://git-wip-us.apache.org/repos/asf/phoenix/blob/265b6dee/phoenix-core/src/test/java/org/apache/phoenix/expression/StringToArrayFunctionTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/expression/StringToArrayFunctionTest.java b/phoenix-core/src/test/java/org/apache/phoenix/expression/StringToArrayFunctionTest.java
new file mode 100644
index 0000000..6e8e532
--- /dev/null
+++ b/phoenix-core/src/test/java/org/apache/phoenix/expression/StringToArrayFunctionTest.java
@@ -0,0 +1,275 @@
+/*
+ * 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.sql.SQLException;
+import java.util.List;
+
+import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
+import org.apache.phoenix.expression.function.StringToArrayFunction;
+import org.apache.phoenix.schema.SortOrder;
+import org.apache.phoenix.schema.types.*;
+import org.junit.Test;
+
+import com.google.common.collect.Lists;
+
+public class StringToArrayFunctionTest {
+
+ private static void testExpression(LiteralExpression array, LiteralExpression delimiter, LiteralExpression nullString, PhoenixArray expected)
+ throws SQLException {
+ List<Expression> expressions = Lists.newArrayList((Expression) array);
+ expressions.add(delimiter);
+ expressions.add(nullString);
+
+ Expression stringToArrayFunction = new StringToArrayFunction(expressions);
+ ImmutableBytesWritable ptr = new ImmutableBytesWritable();
+ stringToArrayFunction.evaluate(null, ptr);
+ PhoenixArray result = (PhoenixArray) stringToArrayFunction.getDataType().toObject(ptr, stringToArrayFunction.getSortOrder(), stringToArrayFunction.getMaxLength(), stringToArrayFunction.getScale());
+ assertEquals(expected, result);
+ }
+
+ private static void test(String string, String delimiter, String nullString, PhoenixArray expected, SortOrder stringSortOrder, SortOrder delimiterSortOrder, SortOrder nullStringSortOrder, PDataType stringType, PDataType delimiterType, PDataType nullStringType) throws SQLException {
+ LiteralExpression arrayLiteral, delimiterLiteral, nullStringLiteral;
+ arrayLiteral = LiteralExpression.newConstant(string, stringType, null, null, stringSortOrder, Determinism.ALWAYS);
+ delimiterLiteral = LiteralExpression.newConstant(delimiter, delimiterType, null, null, delimiterSortOrder, Determinism.ALWAYS);
+ nullStringLiteral = LiteralExpression.newConstant(nullString, nullStringType, null, null, nullStringSortOrder, Determinism.ALWAYS);
+ testExpression(arrayLiteral, delimiterLiteral, nullStringLiteral, expected);
+ }
+
+ @Test
+ public void testStringToArrayFunction1() throws SQLException {
+ String string = "1,2,3,4,5";
+ Object[] o1 = new Object[]{"1", "2", "3", "4", "5"};
+ PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, o1);
+ String delimiter = ",";
+ String nullString = "*";
+ test(string, delimiter, nullString, expected, SortOrder.ASC, SortOrder.ASC, SortOrder.ASC, PVarchar.INSTANCE, PVarchar.INSTANCE, PVarchar.INSTANCE);
+ test(string, delimiter, nullString, expected, SortOrder.DESC, SortOrder.ASC, SortOrder.ASC, PVarchar.INSTANCE, PVarchar.INSTANCE, PVarchar.INSTANCE);
+ }
+
+ @Test
+ public void testStringToArrayFunction2() throws SQLException {
+ String string = "1,2,3,4,5";
+ Object[] o1 = new Object[]{"1", "2", "3", "4", "5"};
+ PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, o1);
+ String delimiter = ",";
+ String nullString = "";
+ test(string, delimiter, nullString, expected, SortOrder.ASC, SortOrder.ASC, SortOrder.ASC, PVarchar.INSTANCE, PVarchar.INSTANCE, PVarchar.INSTANCE);
+ test(string, delimiter, nullString, expected, SortOrder.DESC, SortOrder.ASC, SortOrder.ASC, PVarchar.INSTANCE, PVarchar.INSTANCE, PVarchar.INSTANCE);
+ }
+
+ @Test
+ public void testStringToArrayFunction3() throws SQLException {
+ String string = "1234";
+ Object[] o1 = new Object[]{"1", "2", "3", "4"};
+ PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, o1);
+ String delimiter = null;
+ String nullString = "";
+ test(string, delimiter, nullString, expected, SortOrder.ASC, SortOrder.ASC, SortOrder.ASC, PVarchar.INSTANCE, PVarchar.INSTANCE, PVarchar.INSTANCE);
+ test(string, delimiter, nullString, expected, SortOrder.DESC, SortOrder.ASC, SortOrder.ASC, PVarchar.INSTANCE, PVarchar.INSTANCE, PVarchar.INSTANCE);
+ }
+
+ @Test
+ public void testStringToArrayFunction4() throws SQLException {
+ String string = "1";
+ Object[] o1 = new Object[]{"1"};
+ PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, o1);
+ String delimiter = ",";
+ String nullString = "";
+ test(string, delimiter, nullString, expected, SortOrder.ASC, SortOrder.ASC, SortOrder.ASC, PVarchar.INSTANCE, PVarchar.INSTANCE, PVarchar.INSTANCE);
+ test(string, delimiter, nullString, expected, SortOrder.DESC, SortOrder.ASC, SortOrder.ASC, PVarchar.INSTANCE, PVarchar.INSTANCE, PVarchar.INSTANCE);
+ }
+
+ @Test
+ public void testStringToArrayFunction5() throws SQLException {
+ String string = "hello, hello, hello";
+ Object[] o1 = new Object[]{"hello", "hello", "hello"};
+ PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, o1);
+ String delimiter = ", ";
+ String nullString = "";
+ test(string, delimiter, nullString, expected, SortOrder.ASC, SortOrder.ASC, SortOrder.ASC, PVarchar.INSTANCE, PVarchar.INSTANCE, PVarchar.INSTANCE);
+ test(string, delimiter, nullString, expected, SortOrder.DESC, SortOrder.ASC, SortOrder.ASC, PVarchar.INSTANCE, PVarchar.INSTANCE, PVarchar.INSTANCE);
+ }
+
+ @Test
+ public void testStringToArrayFunction6() throws SQLException {
+ String string = "1.2...2.3...5.6";
+ Object[] o1 = new Object[]{"1.2", "2.3", "5.6"};
+ PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, o1);
+ String delimiter = "...";
+ String nullString = "";
+ test(string, delimiter, nullString, expected, SortOrder.ASC, SortOrder.ASC, SortOrder.ASC, PVarchar.INSTANCE, PVarchar.INSTANCE, PVarchar.INSTANCE);
+ test(string, delimiter, nullString, expected, SortOrder.DESC, SortOrder.ASC, SortOrder.ASC, PVarchar.INSTANCE, PVarchar.INSTANCE, PVarchar.INSTANCE);
+ }
+
+ @Test
+ public void testStringToArrayFunction7() throws SQLException {
+ String string = "a\\b\\c\\d\\e\\f";
+ Object[] o1 = new Object[]{"a", "b", "c", "d", "e", "f"};
+ PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, o1);
+ String delimiter = "\\";
+ String nullString = "";
+ test(string, delimiter, nullString, expected, SortOrder.ASC, SortOrder.ASC, SortOrder.ASC, PVarchar.INSTANCE, PVarchar.INSTANCE, PVarchar.INSTANCE);
+ test(string, delimiter, nullString, expected, SortOrder.DESC, SortOrder.ASC, SortOrder.ASC, PVarchar.INSTANCE, PVarchar.INSTANCE, PVarchar.INSTANCE);
+ }
+
+ @Test
+ public void testStringToArrayFunction8() throws SQLException {
+ String string = "a-b-c-d-e-f-";
+ Object[] o1 = new Object[]{"a", "b", "c", "d", "e", "f"};
+ PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, o1);
+ String delimiter = "-";
+ String nullString = "";
+ test(string, delimiter, nullString, expected, SortOrder.ASC, SortOrder.ASC, SortOrder.ASC, PVarchar.INSTANCE, PVarchar.INSTANCE, PVarchar.INSTANCE);
+ test(string, delimiter, nullString, expected, SortOrder.DESC, SortOrder.ASC, SortOrder.ASC, PVarchar.INSTANCE, PVarchar.INSTANCE, PVarchar.INSTANCE);
+ }
+
+ @Test
+ public void testStringToArrayFunction9() throws SQLException {
+ String string = "a b c d e f";
+ Object[] o1 = new Object[]{"a", "b", "c", "d", "e", "f"};
+ PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, o1);
+ String delimiter = " ";
+ String nullString = "";
+ test(string, delimiter, nullString, expected, SortOrder.ASC, SortOrder.ASC, SortOrder.ASC, PVarchar.INSTANCE, PVarchar.INSTANCE, PVarchar.INSTANCE);
+ test(string, delimiter, nullString, expected, SortOrder.DESC, SortOrder.ASC, SortOrder.ASC, PVarchar.INSTANCE, PVarchar.INSTANCE, PVarchar.INSTANCE);
+ }
+
+ @Test
+ public void testStringToArrayFunction10() throws SQLException {
+ String string = "axbxcxdxexf";
+ Object[] o1 = new Object[]{"a", "b", "c", "d", "e", "f"};
+ PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, o1);
+ String delimiter = "x";
+ String nullString = "";
+ test(string, delimiter, nullString, expected, SortOrder.ASC, SortOrder.ASC, SortOrder.ASC, PVarchar.INSTANCE, PVarchar.INSTANCE, PVarchar.INSTANCE);
+ test(string, delimiter, nullString, expected, SortOrder.DESC, SortOrder.ASC, SortOrder.ASC, PVarchar.INSTANCE, PVarchar.INSTANCE, PVarchar.INSTANCE);
+ }
+
+ @Test
+ public void testStringToArrayFunction11() throws SQLException {
+ String string = "axbxcxdxexfx*";
+ Object[] o1 = new Object[]{"a", "b", "c", "d", "e", "f", null};
+ PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, o1);
+ String delimiter = "x";
+ String nullString = "*";
+ test(string, delimiter, nullString, expected, SortOrder.ASC, SortOrder.ASC, SortOrder.ASC, PVarchar.INSTANCE, PVarchar.INSTANCE, PVarchar.INSTANCE);
+ test(string, delimiter, nullString, expected, SortOrder.DESC, SortOrder.ASC, SortOrder.ASC, PVarchar.INSTANCE, PVarchar.INSTANCE, PVarchar.INSTANCE);
+ }
+
+ @Test
+ public void testStringToArrayFunction12() throws SQLException {
+ String string = "* a b c d e f";
+ Object[] o1 = new Object[]{null, "a", "b", "c", "d", "e", "f"};
+ PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, o1);
+ String delimiter = " ";
+ String nullString = "*";
+ test(string, delimiter, nullString, expected, SortOrder.ASC, SortOrder.ASC, SortOrder.ASC, PVarchar.INSTANCE, PVarchar.INSTANCE, PVarchar.INSTANCE);
+ test(string, delimiter, nullString, expected, SortOrder.DESC, SortOrder.ASC, SortOrder.ASC, PVarchar.INSTANCE, PVarchar.INSTANCE, PVarchar.INSTANCE);
+ }
+
+ @Test
+ public void testStringToArrayFunction13() throws SQLException {
+ String string = "a * b * c d e f";
+ Object[] o1 = new Object[]{"a", null, "b", null, "c", "d", "e", "f"};
+ PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, o1);
+ String delimiter = " ";
+ String nullString = "*";
+ test(string, delimiter, nullString, expected, SortOrder.ASC, SortOrder.ASC, SortOrder.ASC, PVarchar.INSTANCE, PVarchar.INSTANCE, PVarchar.INSTANCE);
+ test(string, delimiter, nullString, expected, SortOrder.DESC, SortOrder.ASC, SortOrder.ASC, PVarchar.INSTANCE, PVarchar.INSTANCE, PVarchar.INSTANCE);
+ }
+
+ @Test
+ public void testStringToArrayFunction14() throws SQLException {
+ String string = "null a null";
+ Object[] o1 = new Object[]{null, "a", null};
+ PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, o1);
+ String delimiter = " ";
+ String nullString = "null";
+ test(string, delimiter, nullString, expected, SortOrder.ASC, SortOrder.ASC, SortOrder.ASC, PVarchar.INSTANCE, PVarchar.INSTANCE, PVarchar.INSTANCE);
+ test(string, delimiter, nullString, expected, SortOrder.DESC, SortOrder.ASC, SortOrder.ASC, PVarchar.INSTANCE, PVarchar.INSTANCE, PVarchar.INSTANCE);
+ }
+
+ @Test
+ public void testStringToArrayFunction16() throws SQLException {
+ String string = "null a null";
+ Object[] o1 = new Object[]{null, "a", null};
+ PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, o1);
+ String delimiter = " ";
+ String nullString = "null";
+ test(string, delimiter, nullString, expected, SortOrder.ASC, SortOrder.ASC, SortOrder.ASC, PVarchar.INSTANCE, PVarchar.INSTANCE, PVarchar.INSTANCE);
+ test(string, delimiter, nullString, expected, SortOrder.DESC, SortOrder.ASC, SortOrder.ASC, PVarchar.INSTANCE, PVarchar.INSTANCE, PVarchar.INSTANCE);
+ }
+
+ @Test
+ public void testStringToArrayFunction17() throws SQLException {
+ String string = "null a null";
+ Object[] o1 = new Object[]{null, "a", null};
+ PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, o1);
+ String delimiter = " ";
+ String nullString = "null";
+ test(string, delimiter, nullString, expected, SortOrder.ASC, SortOrder.ASC, SortOrder.ASC, PChar.INSTANCE, PVarchar.INSTANCE, PVarchar.INSTANCE);
+ test(string, delimiter, nullString, expected, SortOrder.DESC, SortOrder.ASC, SortOrder.ASC, PChar.INSTANCE, PVarchar.INSTANCE, PVarchar.INSTANCE);
+ }
+
+ @Test
+ public void testStringToArrayFunction18() throws SQLException {
+ String string = "null,a,null";
+ Object[] o1 = new Object[]{null, "a", null};
+ PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, o1);
+ String delimiter = ",";
+ String nullString = "null";
+ test(string, delimiter, nullString, expected, SortOrder.ASC, SortOrder.ASC, SortOrder.ASC, PChar.INSTANCE, PChar.INSTANCE, PVarchar.INSTANCE);
+ test(string, delimiter, nullString, expected, SortOrder.DESC, SortOrder.ASC, SortOrder.ASC, PChar.INSTANCE, PChar.INSTANCE, PVarchar.INSTANCE);
+ }
+
+ @Test
+ public void testStringToArrayFunction19() throws SQLException {
+ String string = "null,a,null";
+ Object[] o1 = new Object[]{null, "a", null};
+ PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, o1);
+ String delimiter = ",";
+ String nullString = "null";
+ test(string, delimiter, nullString, expected, SortOrder.ASC, SortOrder.ASC, SortOrder.ASC, PChar.INSTANCE, PChar.INSTANCE, PChar.INSTANCE);
+ test(string, delimiter, nullString, expected, SortOrder.DESC, SortOrder.ASC, SortOrder.ASC, PChar.INSTANCE, PChar.INSTANCE, PChar.INSTANCE);
+ }
+
+ @Test
+ public void testStringToArrayFunction20() throws SQLException {
+ String string = "abc";
+ Object[] o1 = new Object[]{"a", "b", "c"};
+ PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, o1);
+ String delimiter = null;
+ String nullString = "null";
+ test(string, delimiter, nullString, expected, SortOrder.ASC, SortOrder.ASC, SortOrder.ASC, PChar.INSTANCE, PChar.INSTANCE, PChar.INSTANCE);
+ test(string, delimiter, nullString, expected, SortOrder.DESC, SortOrder.ASC, SortOrder.ASC, PChar.INSTANCE, PChar.INSTANCE, PChar.INSTANCE);
+ }
+
+ @Test
+ public void testStringToArrayFunction21() throws SQLException {
+ String string = "(?!^)";
+ Object[] o1 = new Object[]{"(", "?", "!", "^", ")"};
+ PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, o1);
+ String delimiter = null;
+ String nullString = null;
+ test(string, delimiter, nullString, expected, SortOrder.ASC, SortOrder.ASC, SortOrder.ASC, PVarchar.INSTANCE, PVarchar.INSTANCE, PVarchar.INSTANCE);
+ test(string, delimiter, nullString, expected, SortOrder.DESC, SortOrder.ASC, SortOrder.ASC, PVarchar.INSTANCE, PVarchar.INSTANCE, PVarchar.INSTANCE);
+ }
+}