Repository: phoenix Updated Branches: refs/heads/3.0 7f78ad84d -> 8aeb7a7a7
PHOENIX-1242: ArrayoutofBoundException Phoenix mapping to exisiting Hbase (Alicia Ying Shu) Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/8aeb7a7a Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/8aeb7a7a Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/8aeb7a7a Branch: refs/heads/3.0 Commit: 8aeb7a7a70ae6f8033284a911a367c8498e7ed83 Parents: 7f78ad8 Author: Jeffrey Zhong <jeffr...@apache.org> Authored: Sat Oct 18 15:27:57 2014 -0700 Committer: Jeffrey Zhong <jeffr...@apache.org> Committed: Sat Oct 18 15:34:17 2014 -0700 ---------------------------------------------------------------------- .../org/apache/phoenix/schema/PDataType.java | 208 +++++++++++-------- .../schema/MappingTableDataTypeTest.java | 119 +++++++++++ 2 files changed, 241 insertions(+), 86 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/8aeb7a7a/phoenix-core/src/main/java/org/apache/phoenix/schema/PDataType.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PDataType.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PDataType.java index fa588b8..c1d1936 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PDataType.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PDataType.java @@ -5894,25 +5894,31 @@ public enum PDataType { @Override public long decodeLong(byte[] bytes, int o, SortOrder sortOrder) { - Preconditions.checkNotNull(sortOrder); - long v; - byte b = bytes[o]; + Preconditions.checkNotNull(sortOrder); + long v = 0L; + byte b = bytes[o]; + try { if (sortOrder == SortOrder.ASC) { - v = b ^ 0x80; // Flip sign bit back - for (int i = 1; i < Bytes.SIZEOF_LONG; i++) { - b = bytes[o + i]; - v = (v << 8) + (b & 0xff); - } + v = b ^ 0x80; // Flip sign bit back + for (int i = 1; i < Bytes.SIZEOF_LONG; i++) { + b = bytes[o + i]; + v = (v << 8) + (b & 0xff); + } } else { - b = (byte)(b ^ 0xff); - v = b ^ 0x80; // Flip sign bit back - for (int i = 1; i < Bytes.SIZEOF_LONG; i++) { - b = bytes[o + i]; - b ^= 0xff; - v = (v << 8) + (b & 0xff); - } + b = (byte) (b ^ 0xff); + v = b ^ 0x80; // Flip sign bit back + for (int i = 1; i < Bytes.SIZEOF_LONG; i++) { + b = bytes[o + i]; + b ^= 0xff; + v = (v << 8) + (b & 0xff); + } } - return v; + } catch (RuntimeException e) { + if (e instanceof ArrayIndexOutOfBoundsException) { + throw new IllegalDataException("cannot coerced to data type LONG"); + } + } + return v; } @@ -6017,17 +6023,23 @@ public enum PDataType { @Override public int decodeInt(byte[] bytes, int o, SortOrder sortOrder) { Preconditions.checkNotNull(sortOrder); - int v; - if (sortOrder == SortOrder.ASC) { + int v = 0; + try { + if (sortOrder == SortOrder.ASC) { v = bytes[o] ^ 0x80; // Flip sign bit back for (int i = 1; i < Bytes.SIZEOF_INT; i++) { - v = (v << 8) + (bytes[o + i] & 0xff); + v = (v << 8) + (bytes[o + i] & 0xff); } - } else { + } else { v = bytes[o] ^ 0xff ^ 0x80; // Flip sign bit back for (int i = 1; i < Bytes.SIZEOF_INT; i++) { - v = (v << 8) + ((bytes[o + i] ^ 0xff) & 0xff); + v = (v << 8) + ((bytes[o + i] ^ 0xff) & 0xff); } + } + } catch (RuntimeException e) { + if (e instanceof ArrayIndexOutOfBoundsException) { + throw new IllegalDataException("cannot coerced to data type INT"); + } } return v; } @@ -6130,18 +6142,24 @@ public enum PDataType { @Override public short decodeShort(byte[] b, int o, SortOrder sortOrder) { - Preconditions.checkNotNull(sortOrder); - int v; - if (sortOrder == SortOrder.ASC) { + Preconditions.checkNotNull(sortOrder); + int v = 0; + try { + if (sortOrder == SortOrder.ASC) { v = b[o] ^ 0x80; // Flip sign bit back for (int i = 1; i < Bytes.SIZEOF_SHORT; i++) { - v = (v << 8) + (b[o + i] & 0xff); + v = (v << 8) + (b[o + i] & 0xff); } - } else { + } else { v = b[o] ^ 0xff ^ 0x80; // Flip sign bit back for (int i = 1; i < Bytes.SIZEOF_SHORT; i++) { - v = (v << 8) + ((b[o + i] ^ 0xff) & 0xff); + v = (v << 8) + ((b[o + i] ^ 0xff) & 0xff); } + } + } catch (RuntimeException e) { + if (e instanceof ArrayIndexOutOfBoundsException) { + throw new IllegalDataException("cannot coerced to data type SHORT"); + } } return (short)v; } @@ -6317,10 +6335,10 @@ public enum PDataType { @Override public byte decodeByte(byte[] b, int o, SortOrder sortOrder) { - Preconditions.checkNotNull(sortOrder); + Preconditions.checkNotNull(sortOrder); if (sortOrder == SortOrder.DESC) { b = SortOrder.invert(b, o, new byte[Bytes.SIZEOF_BYTE], 0, Bytes.SIZEOF_BYTE); - } + } byte v = b[o]; if (v < 0) { throw new IllegalDataException(); @@ -6347,19 +6365,25 @@ public enum PDataType { public long decodeLong(byte[] b, int o, SortOrder sortOrder) { Preconditions.checkNotNull(sortOrder); long v = 0; - if (sortOrder == SortOrder.ASC) { + try { + if (sortOrder == SortOrder.ASC) { for(int i = o; i < o + Bytes.SIZEOF_LONG; i++) { v <<= 8; v ^= b[i] & 0xFF; } - } else { + } else { for(int i = o; i < o + Bytes.SIZEOF_LONG; i++) { - v <<= 8; - v ^= (b[i] & 0xFF) ^ 0xFF; - } + v <<= 8; + v ^= (b[i] & 0xFF) ^ 0xFF; + } + } + } catch (RuntimeException e) { + if (e instanceof ArrayIndexOutOfBoundsException) { + throw new IllegalDataException("cannot coerced to data type LONG"); + } } if (v < 0) { - throw new IllegalDataException(); + throw new IllegalDataException(); } return v; } @@ -6380,15 +6404,15 @@ public enum PDataType { @Override public short decodeShort(byte[] b, int o, SortOrder sortOrder) { - Preconditions.checkNotNull(sortOrder); - if (sortOrder == SortOrder.DESC) { - b = SortOrder.invert(b, o, new byte[Bytes.SIZEOF_INT], 0, Bytes.SIZEOF_INT); - } - short v = Bytes.toShort(b, o); - if (v < 0) { - throw new IllegalDataException(); - } - return v; + Preconditions.checkNotNull(sortOrder); + if (sortOrder == SortOrder.DESC) { + b = SortOrder.invert(b, o, new byte[Bytes.SIZEOF_INT], 0, Bytes.SIZEOF_INT); + } + short v = Bytes.toShort(b, o); + if (v < 0) { + throw new IllegalDataException(); + } + return v; } @Override @@ -6408,15 +6432,15 @@ public enum PDataType { @Override public int decodeInt(byte[] b, int o, SortOrder sortOrder) { - Preconditions.checkNotNull(sortOrder); - if (sortOrder == SortOrder.DESC) { - b = SortOrder.invert(b, o, new byte[Bytes.SIZEOF_INT], 0, Bytes.SIZEOF_INT); - } - int v = Bytes.toInt(b, o); - if (v < 0) { - throw new IllegalDataException(); - } - return v; + Preconditions.checkNotNull(sortOrder); + if (sortOrder == SortOrder.DESC) { + b = SortOrder.invert(b, o, new byte[Bytes.SIZEOF_INT], 0, Bytes.SIZEOF_INT); + } + int v = Bytes.toInt(b, o); + if (v < 0) { + throw new IllegalDataException(); + } + return v; } @Override @@ -6478,16 +6502,22 @@ public enum PDataType { @Override public float decodeFloat(byte[] b, int o, SortOrder sortOrder) { - Preconditions.checkNotNull(sortOrder); + Preconditions.checkNotNull(sortOrder); + try { if (sortOrder == SortOrder.DESC) { - for (int i = o; i < Bytes.SIZEOF_INT; i++) { - b[i] = (byte) (b[i] ^ 0xff); - } + for (int i = o; i < Bytes.SIZEOF_INT; i++) { + b[i] = (byte) (b[i] ^ 0xff); + } } - int i = Bytes.toInt(b, o); - i--; - i ^= (~i >> Integer.SIZE - 1) | Integer.MIN_VALUE; - return Float.intBitsToFloat(i); + } catch(RuntimeException e) { + if (e instanceof ArrayIndexOutOfBoundsException) { + throw new IllegalDataException("cannot coerced to data type FLOAT"); + } + } + int i = Bytes.toInt(b, o); + i--; + i ^= (~i >> Integer.SIZE - 1) | Integer.MIN_VALUE; + return Float.intBitsToFloat(i); } @Override @@ -6584,16 +6614,22 @@ public enum PDataType { @Override public double decodeDouble(byte[] b, int o, SortOrder sortOrder) { - Preconditions.checkNotNull(sortOrder); + Preconditions.checkNotNull(sortOrder); + try { if (sortOrder == SortOrder.DESC) { - for (int i = o; i < Bytes.SIZEOF_LONG; i++) { - b[i] = (byte) (b[i] ^ 0xff); - } + for (int i = o; i < Bytes.SIZEOF_LONG; i++) { + b[i] = (byte) (b[i] ^ 0xff); + } } - long l = Bytes.toLong(b, o); - l--; - l ^= (~l >> Long.SIZE - 1) | Long.MIN_VALUE; - return Double.longBitsToDouble(l); + } catch(RuntimeException e) { + if (e instanceof ArrayIndexOutOfBoundsException) { + throw new IllegalDataException("cannot coerced to data type DOUBLE"); + } + } + long l = Bytes.toLong(b, o); + l--; + l ^= (~l >> Long.SIZE - 1) | Long.MIN_VALUE; + return Double.longBitsToDouble(l); } @Override @@ -6668,15 +6704,15 @@ public enum PDataType { @Override public float decodeFloat(byte[] b, int o, SortOrder sortOrder) { - Preconditions.checkNotNull(sortOrder); - if (sortOrder == SortOrder.DESC) { - b = SortOrder.invert(b, o, new byte[Bytes.SIZEOF_FLOAT], 0, Bytes.SIZEOF_FLOAT); - } - float v = Bytes.toFloat(b, o); - if (v < 0) { - throw new IllegalDataException(); - } - return v; + Preconditions.checkNotNull(sortOrder); + if (sortOrder == SortOrder.DESC) { + b = SortOrder.invert(b, o, new byte[Bytes.SIZEOF_FLOAT], 0, Bytes.SIZEOF_FLOAT); + } + float v = Bytes.toFloat(b, o); + if (v < 0) { + throw new IllegalDataException(); + } + return v; } } @@ -6697,14 +6733,14 @@ public enum PDataType { public double decodeDouble(byte[] b, int o, SortOrder sortOrder) { Preconditions.checkNotNull(sortOrder); - if (sortOrder == SortOrder.DESC) { - b = SortOrder.invert(b, o, new byte[Bytes.SIZEOF_DOUBLE], 0, Bytes.SIZEOF_DOUBLE); - } - double v = Bytes.toDouble(b, o); - if (v < 0) { - throw new IllegalDataException(); - } - return v; + if (sortOrder == SortOrder.DESC) { + b = SortOrder.invert(b, o, new byte[Bytes.SIZEOF_DOUBLE], 0, Bytes.SIZEOF_DOUBLE); + } + double v = Bytes.toDouble(b, o); + if (v < 0) { + throw new IllegalDataException(); + } + return v; } } http://git-wip-us.apache.org/repos/asf/phoenix/blob/8aeb7a7a/phoenix-core/src/test/java/org/apache/phoenix/schema/MappingTableDataTypeTest.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/test/java/org/apache/phoenix/schema/MappingTableDataTypeTest.java b/phoenix-core/src/test/java/org/apache/phoenix/schema/MappingTableDataTypeTest.java new file mode 100644 index 0000000..64df35f --- /dev/null +++ b/phoenix-core/src/test/java/org/apache/phoenix/schema/MappingTableDataTypeTest.java @@ -0,0 +1,119 @@ +/* + * 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.schema; + +import static org.apache.phoenix.util.PhoenixRuntime.JDBC_PROTOCOL; +import static org.apache.phoenix.util.PhoenixRuntime.JDBC_PROTOCOL_SEPARATOR; +import static org.apache.phoenix.util.PhoenixRuntime.JDBC_PROTOCOL_TERMINATOR; +import static org.apache.phoenix.util.PhoenixRuntime.PHOENIX_TEST_DRIVER_URL_PARAM; +import static org.apache.phoenix.util.TestUtil.LOCALHOST; +import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES; + +import java.io.IOException; +import java.sql.Connection; +import java.sql.ResultSet; +import java.util.Properties; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hbase.HBaseConfiguration; +import org.apache.hadoop.hbase.HBaseTestingUtility; +import org.apache.hadoop.hbase.TableName; +import org.apache.hadoop.hbase.client.HBaseAdmin; +import org.apache.hadoop.hbase.client.HTable; +import org.apache.hadoop.hbase.client.Put; +import org.apache.hadoop.hbase.util.Bytes; +import org.apache.phoenix.query.BaseTest; +import org.apache.phoenix.query.QueryServices; +import org.apache.phoenix.util.PropertiesUtil; +import org.apache.phoenix.util.ReadOnlyProps; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + + +public class MappingTableDataTypeTest extends BaseTest{ + + private static final Log LOG = LogFactory.getLog(MappingTableDataTypeTest.class); + + private static HBaseTestingUtility UTIL = null; + private static String URL = null; + private static HBaseAdmin admin = null; + + @BeforeClass + public static void before() throws Exception { + Configuration conf = HBaseConfiguration.create(); + setUpConfigForMiniCluster(conf); + UTIL = new HBaseTestingUtility(conf); + UTIL.startMiniCluster(1); + String clientPort = UTIL.getConfiguration().get(QueryServices.ZOOKEEPER_PORT_ATTRIB); + URL = + JDBC_PROTOCOL + JDBC_PROTOCOL_SEPARATOR + LOCALHOST + JDBC_PROTOCOL_SEPARATOR + clientPort + + JDBC_PROTOCOL_TERMINATOR + PHOENIX_TEST_DRIVER_URL_PARAM; + driver = initAndRegisterDriver(URL, ReadOnlyProps.EMPTY_PROPS); + admin = new HBaseAdmin(UTIL.getConfiguration()); + } + + @AfterClass + public static void tearDownAfterClass() throws Exception { + UTIL.shutdownMiniCluster(); + } + + @Test + public void testMappingHbaseTableToPhoenixTable() throws Exception { + final TableName tableName = TableName.valueOf("MTEST"); + // Create table then get the single region for our new table. + HTable t = UTIL.createTable(tableName.getName(), Bytes.toBytes("cf")); + insertData(tableName.getName(), admin, t); + t.close(); + try { + testCreateTableMismatchedType(); + } catch (IllegalDataException e) { + } + } + + private void insertData(final byte[] tableName, HBaseAdmin admin, HTable t) throws IOException, + InterruptedException { + Put p = new Put(Bytes.toBytes("row")); + p.add(Bytes.toBytes("cf"), Bytes.toBytes("q1"), Bytes.toBytes("value1")); + t.put(p); + t.flushCommits(); + admin.flush(tableName); + } + + /** + * Test create a table in Phoenix with mismatched data type UNSIGNED_LONG + */ + private void testCreateTableMismatchedType() throws Exception { + String ddl = + "create table IF NOT EXISTS MTEST (" + " id varchar NOT NULL primary key," + + " \"cf\".\"q1\" unsigned_long" + " ) "; + Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES); + Connection conn = driver.connect(URL, props); + conn.createStatement().execute(ddl); + conn.commit(); + String query = "select * from MTEST"; + ResultSet rs = conn.createStatement().executeQuery(query); + rs.next(); + rs.getLong(2); + } + +} + +