PHOENIX-777 - Support null value for fixed length ARRAY (Dumindu Buddhika)
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/6f890ade Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/6f890ade Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/6f890ade Branch: refs/heads/4.x-HBase-1.1 Commit: 6f890ade0691d03469ff8fce81c2fa9edd6941af Parents: 9c5f111 Author: ramkrishna <ramkrishna.s.vasude...@gmail.com> Authored: Tue Jun 2 11:18:51 2015 +0530 Committer: ramkrishna <ramkrishna.s.vasude...@gmail.com> Committed: Tue Jun 2 11:18:51 2015 +0530 ---------------------------------------------------------------------- .../phoenix/end2end/ArraysWithNullsIT.java | 300 +++++++++++++++++++ .../phoenix/compile/ExpressionCompiler.java | 9 +- .../apache/phoenix/schema/types/PBinary.java | 2 +- .../org/apache/phoenix/schema/types/PChar.java | 5 +- .../org/apache/phoenix/schema/types/PDate.java | 6 +- .../apache/phoenix/schema/types/PDecimal.java | 3 + .../apache/phoenix/schema/types/PTimestamp.java | 17 +- .../phoenix/schema/types/PhoenixArray.java | 51 ++-- 8 files changed, 358 insertions(+), 35 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/6f890ade/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArraysWithNullsIT.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArraysWithNullsIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArraysWithNullsIT.java new file mode 100644 index 0000000..b034193 --- /dev/null +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArraysWithNullsIT.java @@ -0,0 +1,300 @@ +/* + * 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 java.sql.*; + +import org.apache.phoenix.schema.types.PTimestamp; +import org.apache.phoenix.schema.types.PhoenixArray; +import org.junit.Test; + +public class ArraysWithNullsIT extends BaseClientManagedTimeIT { + + @Test + public void testArrayUpsertIntWithNulls() throws Exception { + Connection conn = DriverManager.getConnection(getUrl()); + conn.createStatement().execute("CREATE TABLE t1 ( k VARCHAR PRIMARY KEY, a INTEGER[])"); + + PreparedStatement stmt = conn.prepareStatement("UPSERT INTO t1 VALUES('a',ARRAY[null,3,null])"); + stmt.execute(); + conn.commit(); + + ResultSet rs = conn.createStatement().executeQuery("Select a from t1 where k = 'a'"); + rs.next(); + Array array = conn.createArrayOf("INTEGER",new Object[]{null,3,null}); + + assertEquals(rs.getArray(1),array); + conn.close(); + + } + + + + @Test + public void testArrayUpsertVarcharWithNulls() throws Exception { + Connection conn = DriverManager.getConnection(getUrl()); + conn.createStatement().execute("CREATE TABLE t2 ( k VARCHAR PRIMARY KEY, a VARCHAR[])"); + + PreparedStatement stmt = conn.prepareStatement("UPSERT INTO t2 VALUES('a',ARRAY['10',null])"); + stmt.execute(); + conn.commit(); + + ResultSet rs = conn.createStatement().executeQuery("Select a from t2 where k = 'a'"); + rs.next(); + Array array = conn.createArrayOf("VARCHAR",new Object[]{"10",null}); + + assertEquals(rs.getArray(1),array); + conn.close(); + + } + + @Test + public void testArrayUpsertBigIntWithNulls() throws Exception { + Connection conn = DriverManager.getConnection(getUrl()); + conn.createStatement().execute("CREATE TABLE t3 ( k VARCHAR PRIMARY KEY, a BIGINT[])"); + + PreparedStatement stmt = conn.prepareStatement("UPSERT INTO t3 VALUES('a',ARRAY[2,null,32335,4])"); + stmt.execute(); + conn.commit(); + + ResultSet rs = conn.createStatement().executeQuery("Select a from t3 where k = 'a'"); + rs.next(); + Array array = conn.createArrayOf("BIGINT",new Object[]{(long)2,null,(long)32335,(long)4}); + + assertEquals(rs.getArray(1),array); + conn.close(); + + } + + @Test + public void testArrayUpsertFloatWithNulls() throws Exception { + Connection conn = DriverManager.getConnection(getUrl()); + conn.createStatement().execute("CREATE TABLE t4 ( k VARCHAR PRIMARY KEY, a FLOAT[])"); + + PreparedStatement stmt = conn.prepareStatement("UPSERT INTO t4 VALUES('a',ARRAY[1.1,2.2,null,3.4])"); + stmt.execute(); + conn.commit(); + + ResultSet rs = conn.createStatement().executeQuery("Select a from t4 where k = 'a'"); + rs.next(); + Array array = conn.createArrayOf("FLOAT",new Object[]{(float)1.1,(float)2.2,null,(float)3.4}); + + assertEquals(rs.getArray(1),array); + conn.close(); + + } + + @Test + public void testArrayUpsertSmallIntWithNulls() throws Exception { + Connection conn = DriverManager.getConnection(getUrl()); + conn.createStatement().execute("CREATE TABLE t5 ( k VARCHAR PRIMARY KEY, a SMALLINT[])"); + + PreparedStatement stmt = conn.prepareStatement("UPSERT INTO t5 VALUES('a',ARRAY[123,456,null,456])"); + stmt.execute(); + conn.commit(); + + ResultSet rs = conn.createStatement().executeQuery("Select a from t5 where k = 'a'"); + rs.next(); + Array array = conn.createArrayOf("SMALLINT",new Object[]{(short)123,(short)456,null,(short)456}); + + assertEquals(rs.getArray(1),array); + conn.close(); + + } + + @Test + public void testArrayUpsertTinyIntWithNulls() throws Exception { + Connection conn = DriverManager.getConnection(getUrl()); + conn.createStatement().execute("CREATE TABLE t6 ( k VARCHAR PRIMARY KEY, a TINYINT[])"); + + PreparedStatement stmt = conn.prepareStatement("UPSERT INTO t6 VALUES('a',ARRAY[123,45,null,45])"); + stmt.execute(); + conn.commit(); + + ResultSet rs = conn.createStatement().executeQuery("Select a from t6 where k = 'a'"); + rs.next(); + Array array = conn.createArrayOf("TINYINT",new Object[]{(byte)123,(byte)45,null,(byte)45}); + + assertEquals(rs.getArray(1),array); + conn.close(); + + } + + @Test + public void testArrayUpsertBooleanWithNulls() throws Exception { + Connection conn = DriverManager.getConnection(getUrl()); + conn.createStatement().execute("CREATE TABLE t7 ( k VARCHAR PRIMARY KEY, a BOOLEAN[])"); + + PreparedStatement stmt = conn.prepareStatement("UPSERT INTO t7 VALUES('a',ARRAY[true,false,null,true])"); + stmt.execute(); + conn.commit(); + + ResultSet rs = conn.createStatement().executeQuery("Select a from t7 where k = 'a'"); + rs.next(); + Array array = conn.createArrayOf("BOOLEAN",new Object[]{true,false,null,true}); + + assertEquals(rs.getArray(1),array); + conn.close(); + + } + + @Test + public void testArrayUpsertDoubleWithNulls() throws Exception { + Connection conn = DriverManager.getConnection(getUrl()); + conn.createStatement().execute("CREATE TABLE t8 ( k VARCHAR PRIMARY KEY, a DOUBLE[])"); + + PreparedStatement stmt = conn.prepareStatement("UPSERT INTO t8 VALUES('a',ARRAY[1.2,2.3,null,3.4])"); + stmt.execute(); + conn.commit(); + + ResultSet rs = conn.createStatement().executeQuery("Select a from t8 where k = 'a'"); + rs.next(); + Array array = conn.createArrayOf("DOUBLE",new Object[]{1.2,2.3,null,3.4}); + + assertEquals(rs.getArray(1),array); + conn.close(); + + } + + @Test + public void testArrayUpsertDateWithNulls1() throws Exception { + Connection conn = DriverManager.getConnection(getUrl()); + conn.createStatement().execute("CREATE TABLE t9 ( k VARCHAR PRIMARY KEY, a DATE[])"); + PreparedStatement stmt = conn.prepareStatement("UPSERT INTO t9 VALUES('a',ARRAY[TO_DATE('2015-05-20 06:12:14.184'),null,TO_DATE('2015-05-20 06:12:14.184'),null])"); + stmt.execute(); + conn.commit(); + + ResultSet rs = conn.createStatement().executeQuery("Select a from t9 where k = 'a'"); + rs.next(); + Array array = conn.createArrayOf("DATE",new Date[]{new Date(1432102334184l),new Date(0l),new Date(1432102334184l),new Date(0l)}); + + assertEquals(rs.getArray(1),array); + conn.close(); + } + + @Test + public void testArrayUpsertDateWithNulls2() throws Exception { + Connection conn = DriverManager.getConnection(getUrl()); + conn.createStatement().execute("CREATE TABLE t10 ( k VARCHAR PRIMARY KEY, a DATE[])"); + PreparedStatement stmt = conn.prepareStatement("UPSERT INTO t10 VALUES('a',ARRAY[TO_DATE('1970-01-01 00:00:00.000'), TO_DATE('2015-05-20 06:12:14.184'),TO_DATE('2015-05-20 06:12:14.184')])"); + stmt.execute(); + conn.commit(); + + ResultSet rs = conn.createStatement().executeQuery("Select a from t10 where k = 'a'"); + rs.next(); + Array array = conn.createArrayOf("DATE",new Date[]{new Date(0l), new Date(1432102334184l), new Date(1432102334184l)}); + + assertEquals(rs.getArray(1),array); + conn.close(); + } + + @Test + public void testArrayUpsertTimeWithNulls1() throws Exception { + Connection conn = DriverManager.getConnection(getUrl()); + conn.createStatement().execute("CREATE TABLE t11 ( k VARCHAR PRIMARY KEY, a TIME[])"); + PreparedStatement stmt = conn.prepareStatement("UPSERT INTO t11 VALUES('a',ARRAY[TO_TIME('2015-05-20 06:12:14.184'),null,TO_TIME('2015-05-20 06:12:14.184'),null])"); + stmt.execute(); + conn.commit(); + + ResultSet rs = conn.createStatement().executeQuery("Select a from t11 where k = 'a'"); + rs.next(); + Array array = conn.createArrayOf("TIME",new Time[]{new Time(1432102334184l),new Time(0l),new Time(1432102334184l),new Time(0l)}); + + assertEquals(rs.getArray(1),array); + conn.close(); + } + + @Test + public void testArrayUpsertTimeWithNulls2() throws Exception { + Connection conn = DriverManager.getConnection(getUrl()); + conn.createStatement().execute("CREATE TABLE t12 ( k VARCHAR PRIMARY KEY, a TIME[])"); + PreparedStatement stmt = conn.prepareStatement("UPSERT INTO t12 VALUES('a',ARRAY[TO_TIME('1970-01-01 00:00:00.000'), TO_TIME('2015-05-20 06:12:14.184'),null,TO_TIME('2015-05-20 06:12:14.184'),null])"); + stmt.execute(); + conn.commit(); + + ResultSet rs = conn.createStatement().executeQuery("Select a from t12 where k = 'a'"); + rs.next(); + Array array = conn.createArrayOf("TIME",new Time[]{new Time(0l),new Time(1432102334184l),new Time(0l),new Time(1432102334184l),new Time(0l)}); + + assertEquals(rs.getArray(1),array); + conn.close(); + } + + @Test + public void testArrayUpsertTimeStampWithNulls1() throws Exception { + Connection conn = DriverManager.getConnection(getUrl()); + conn.createStatement().execute("CREATE TABLE t13 ( k VARCHAR PRIMARY KEY, a TIMESTAMP[])"); + PreparedStatement stmt = conn.prepareStatement("UPSERT INTO t13 VALUES('a',ARRAY[TO_TIMESTAMP('2015-05-20 06:12:14.184'),null,TO_TIMESTAMP('2015-05-20 06:12:14.184'),TO_TIMESTAMP('1970-01-01 00:00:00.000')])"); + stmt.execute(); + conn.commit(); + + ResultSet rs = conn.createStatement().executeQuery("Select a from t13 where k = 'a'"); + rs.next(); + + assertEquals(rs.getArray(1),conn.createArrayOf("TIMESTAMP",new Timestamp[]{new Timestamp(1432102334184l),new Timestamp(0l),new Timestamp(1432102334184l),new Timestamp(0l)})); + conn.close(); + } + + @Test + public void testArrayUpsertTimeStampWithNulls2() throws Exception { + Connection conn = DriverManager.getConnection(getUrl()); + conn.createStatement().execute("CREATE TABLE t14 ( k VARCHAR PRIMARY KEY, a TIMESTAMP[])"); + PreparedStatement stmt = conn.prepareStatement("UPSERT INTO t14 VALUES('a',ARRAY[TO_TIMESTAMP('1970-01-01 00:00:00.000'),TO_TIMESTAMP('2015-05-20 06:12:14.184'),TO_TIMESTAMP('1970-01-01 00:00:00.000'),TO_TIMESTAMP('2015-05-20 06:12:14.184'),TO_TIMESTAMP('1970-01-01 00:00:00.000')])"); + stmt.execute(); + conn.commit(); + + ResultSet rs = conn.createStatement().executeQuery("Select a from t14 where k = 'a'"); + rs.next(); + + assertEquals(rs.getArray(1),conn.createArrayOf("TIMESTAMP",new Timestamp[]{new Timestamp(0l),new Timestamp(1432102334184l),new Timestamp(0l),new Timestamp(1432102334184l),new Timestamp(0l)})); + conn.close(); + } + + @Test + public void testArrayUpsertCharWithNulls1() throws Exception { + Connection conn = DriverManager.getConnection(getUrl()); + conn.createStatement().execute("CREATE TABLE t15 ( k VARCHAR PRIMARY KEY, a CHAR(15)[])"); + PreparedStatement stmt = conn.prepareStatement("UPSERT INTO t15 VALUES('a',ARRAY['foo',null,'fo','foo'])"); + stmt.execute(); + conn.commit(); + + ResultSet rs = conn.createStatement().executeQuery("Select a from t15 where k = 'a'"); + rs.next(); + + assertEquals(rs.getArray(1),conn.createArrayOf("CHAR",new String[]{"foo","","fo","foo"})); + conn.close(); + } + + @Test + public void testArrayUpsertCharWithNulls2() throws Exception { + Connection conn = DriverManager.getConnection(getUrl()); + conn.createStatement().execute("CREATE TABLE t16 ( k VARCHAR PRIMARY KEY, a CHAR(15)[])"); + PreparedStatement stmt = conn.prepareStatement("UPSERT INTO t16 VALUES('a',ARRAY[null,'foo',null,'fo','foo'])"); + stmt.execute(); + conn.commit(); + + ResultSet rs = conn.createStatement().executeQuery("Select a from t16 where k = 'a'"); + rs.next(); + + assertEquals(rs.getArray(1),conn.createArrayOf("CHAR",new String[]{"","foo","","fo","foo"})); + conn.close(); + } +} http://git-wip-us.apache.org/repos/asf/phoenix/blob/6f890ade/phoenix-core/src/main/java/org/apache/phoenix/compile/ExpressionCompiler.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/ExpressionCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/ExpressionCompiler.java index 66c1b85..39baf7a 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/compile/ExpressionCompiler.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/ExpressionCompiler.java @@ -1271,8 +1271,13 @@ public class ExpressionCompiler extends UnsupportedAllParseNodeVisitor<Expressio for (int i = 0; i < children.size(); i++) { Expression child = children.get(i); child.evaluate(null, ptr); - Object value = arrayElemDataType.toObject(ptr, child.getDataType(), child.getSortOrder()); - elements[i] = LiteralExpression.newConstant(value, child.getDataType(), child.getDeterminism()).getValue(); + Object value = null; + if (child.getDataType() == null) { + value = arrayElemDataType.toObject(ptr, theArrayElemDataType, child.getSortOrder()); + } else { + value = arrayElemDataType.toObject(ptr, child.getDataType(), child.getSortOrder()); + } + elements[i] = LiteralExpression.newConstant(value, theArrayElemDataType, child.getDeterminism()).getValue(); } Object value = PArrayDataType.instantiatePhoenixArray(arrayElemDataType, elements); return LiteralExpression.newConstant(value, http://git-wip-us.apache.org/repos/asf/phoenix/blob/6f890ade/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PBinary.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PBinary.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PBinary.java index d6d07fd..b397554 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PBinary.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PBinary.java @@ -48,7 +48,7 @@ public class PBinary extends PDataType<byte[]> { public Object pad(Object object, Integer maxLength) { byte[] b = (byte[]) object; if (b == null) { - return null; + return new byte[maxLength]; } if (b.length == maxLength) { return object; http://git-wip-us.apache.org/repos/asf/phoenix/blob/6f890ade/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PChar.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PChar.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PChar.java index 2effc38..c4d482c 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PChar.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PChar.java @@ -25,6 +25,7 @@ import org.apache.hadoop.hbase.io.ImmutableBytesWritable; import org.apache.hadoop.hbase.util.Bytes; import org.apache.phoenix.exception.DataExceedsCapacityException; import org.apache.phoenix.schema.SortOrder; +import org.apache.phoenix.util.ByteUtil; import org.apache.phoenix.util.StringUtil; import com.google.common.base.Strings; @@ -55,7 +56,7 @@ public class PChar extends PDataType<String> { public Object pad(Object object, Integer maxLength) { String s = (String) object; if (s == null) { - return s; + return Strings.padEnd("", maxLength, ' '); } if (s.length() == maxLength) { return object; @@ -69,7 +70,7 @@ public class PChar extends PDataType<String> { @Override public byte[] toBytes(Object object) { if (object == null) { - throw newIllegalDataException(this + " may not be null"); + return ByteUtil.EMPTY_BYTE_ARRAY; } byte[] b = PVarchar.INSTANCE.toBytes(object); if (b.length != ((String) object).length()) { http://git-wip-us.apache.org/repos/asf/phoenix/blob/6f890ade/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDate.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDate.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDate.java index 947c30e..b10b1ac 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDate.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDate.java @@ -39,9 +39,6 @@ public class PDate extends PDataType<Date> { @Override public byte[] toBytes(Object object) { - if (object == null) { - throw newIllegalDataException(this + " may not be null"); - } byte[] bytes = new byte[getByteSize()]; toBytes(object, bytes, 0); return bytes; @@ -50,7 +47,8 @@ public class PDate extends PDataType<Date> { @Override public int toBytes(Object object, byte[] bytes, int offset) { if (object == null) { - throw newIllegalDataException(this + " may not be null"); + getCodec().encodeLong(0l, bytes, offset); + return this.getByteSize(); } getCodec().encodeLong(((java.util.Date) object).getTime(), bytes, offset); return this.getByteSize(); http://git-wip-us.apache.org/repos/asf/phoenix/blob/6f890ade/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDecimal.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDecimal.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDecimal.java index 656113c..199ed28 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDecimal.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDecimal.java @@ -393,6 +393,9 @@ public class PDecimal extends PRealNumber<BigDecimal> { @Override public String toStringLiteral(Object o, Format formatter) { if (formatter == null) { + if(o == null) { + return String.valueOf(o); + } return ((BigDecimal)o).toPlainString(); } return super.toStringLiteral(o, formatter); http://git-wip-us.apache.org/repos/asf/phoenix/blob/6f890ade/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PTimestamp.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PTimestamp.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PTimestamp.java index 9a82cc0..d396adc 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PTimestamp.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PTimestamp.java @@ -39,9 +39,6 @@ public class PTimestamp extends PDataType<Timestamp> { @Override public byte[] toBytes(Object object) { - if (object == null) { - throw newIllegalDataException(this + " may not be null"); - } byte[] bytes = new byte[getByteSize()]; toBytes(object, bytes, 0); return bytes; @@ -50,16 +47,18 @@ public class PTimestamp extends PDataType<Timestamp> { @Override public int toBytes(Object object, byte[] bytes, int offset) { if (object == null) { - throw newIllegalDataException(this + " may not be null"); + PDate.INSTANCE.getCodec().encodeLong(0l, bytes, offset); + Bytes.putInt(bytes, offset + Bytes.SIZEOF_LONG, 0); + return getByteSize(); } java.sql.Timestamp value = (java.sql.Timestamp) object; PDate.INSTANCE.getCodec().encodeLong(value.getTime(), bytes, offset); - /* - * By not getting the stuff that got spilled over from the millis part, - * it leaves the timestamp's byte representation saner - 8 bytes of millis | 4 bytes of nanos. - * Also, it enables timestamp bytes to be directly compared with date/time bytes. - */ + /* + * By not getting the stuff that got spilled over from the millis part, + * it leaves the timestamp's byte representation saner - 8 bytes of millis | 4 bytes of nanos. + * Also, it enables timestamp bytes to be directly compared with date/time bytes. + */ Bytes.putInt(bytes, offset + Bytes.SIZEOF_LONG, value.getNanos() % 1000000); return getByteSize(); } http://git-wip-us.apache.org/repos/asf/phoenix/blob/6f890ade/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PhoenixArray.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PhoenixArray.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PhoenixArray.java index 9ffac83..843c831 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PhoenixArray.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PhoenixArray.java @@ -23,6 +23,7 @@ import java.sql.SQLException; import java.util.Arrays; import java.util.Map; +import com.google.common.base.Strings; import org.apache.phoenix.util.SQLCloseable; /** @@ -54,11 +55,15 @@ public class PhoenixArray implements Array,SQLCloseable { private static Object[] coerceToNewLength(PDataType baseType, Object[] elements, int maxLength) { Object[] resizedElements = new Object[elements.length]; for (int i = 0; i < elements.length; i++) { - int length = baseType.getMaxLength(elements[i]); - if (length == maxLength) { - resizedElements[i] = elements[i]; + Integer length = baseType.getMaxLength(elements[i]); + if (length != null) { + if (length == maxLength) { + resizedElements[i] = elements[i]; + } else { + resizedElements[i] = baseType.pad(elements[i], maxLength); + } } else { - resizedElements[i] = baseType.pad(elements[i],maxLength); + resizedElements[i] = baseType.pad(elements[i], maxLength); } } return resizedElements; @@ -67,18 +72,25 @@ public class PhoenixArray implements Array,SQLCloseable { if (elements == null || elements.length == 0) { return elements; } - Object element = elements[0]; - int maxLength = baseType.getMaxLength(element); - boolean resizeElements = false; - for (int i = 1; i < elements.length; i++) { - int length = baseType.getMaxLength(elements[i]); - if (length > maxLength) { - maxLength = length; - resizeElements = true; - } else if (length < maxLength) { - resizeElements = true; - } - } + int maxLength = 0; + boolean resizeElements = false; + for (int i = 0; i < elements.length; i++) { + Integer length = baseType.getMaxLength(elements[i]); + if (length != null) { + if (maxLength == 0){ + maxLength = length; + continue; + } + if (length > maxLength) { + maxLength = length; + resizeElements = true; + } else if (length < maxLength) { + resizeElements = true; + } + } else { + resizeElements = true; + } + } if (!resizeElements) { return elements; } @@ -92,7 +104,12 @@ public class PhoenixArray implements Array,SQLCloseable { if (baseType.getByteSize() == null) { elements = coerceToEqualLength(baseType, elements); if (elements != null && elements.length > 0) { - this.maxLength = baseType.getMaxLength(elements[0]); + for(int i = 0; i < elements.length; i++) { + if(elements[i] != null) { + maxLength = baseType.getMaxLength(elements[i]); + break; + } + } } } else { maxLength = baseType.getByteSize();