You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by ja...@apache.org on 2016/11/18 00:12:59 UTC

phoenix git commit: PHOENIX-3494 ArrayIndexOutOfBoundsException with decimal desc key

Repository: phoenix
Updated Branches:
  refs/heads/master d59f0e539 -> 8e2f087bd


PHOENIX-3494 ArrayIndexOutOfBoundsException with decimal desc key


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

Branch: refs/heads/master
Commit: 8e2f087bdb3b86fcbdf2e7e00918b8abb2ac8752
Parents: d59f0e5
Author: James Taylor <ja...@apache.org>
Authored: Thu Nov 17 16:12:44 2016 -0800
Committer: James Taylor <ja...@apache.org>
Committed: Thu Nov 17 16:12:44 2016 -0800

----------------------------------------------------------------------
 .../apache/phoenix/end2end/UpsertValuesIT.java  | 22 ++++++++++++++++++++
 .../apache/phoenix/schema/types/PDataType.java  |  4 ++--
 .../apache/phoenix/schema/types/PDecimal.java   |  6 +++---
 .../phoenix/schema/types/PDataTypeTest.java     | 18 +++++++++++-----
 4 files changed, 40 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/8e2f087b/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpsertValuesIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpsertValuesIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpsertValuesIT.java
index 498c4a3..eb81ae3 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpsertValuesIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpsertValuesIT.java
@@ -162,6 +162,28 @@ public class UpsertValuesIT extends BaseClientManagedTimeIT {
         assertEquals("a", rs.getString(1));
         assertEquals("2013-06-08 00:00:00.000", rs.getString(2));
     }
+    
+    @Test
+    public void testUpsertValuesWithDescDecimal() throws Exception {
+        long ts = nextTimestamp();
+        Properties props = new Properties();
+        props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts));
+        Connection conn = DriverManager.getConnection(getUrl(), props);
+        conn.createStatement().execute("create table UpsertDecimalDescTest (k DECIMAL(12,3) NOT NULL PRIMARY KEY DESC)");
+        conn.close();
+
+        props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts+5));
+        conn = DriverManager.getConnection(getUrl(), props);
+        conn.createStatement().execute("upsert into UpsertDecimalDescTest values (0.0)");
+        conn.commit();
+        conn.close();
+        
+        props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts+10));
+        conn = DriverManager.getConnection(getUrl(), props);
+        ResultSet rs = conn.createStatement().executeQuery("select k from UpsertDecimalDescTest");
+        assertTrue(rs.next());
+        assertEquals(0.0, rs.getDouble(1), 0.001);
+    }
 
     @Test
     public void testUpsertRandomValues() throws Exception {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/8e2f087b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDataType.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDataType.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDataType.java
index 58018ac..18956e8 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDataType.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDataType.java
@@ -689,9 +689,9 @@ public abstract class PDataType<T> implements DataType<T>, Comparable<PDataType<
     // Calculate the precision and scale of a raw decimal bytes. Returns the values as an int
     // array. The first value is precision, the second value is scale.
     // Default scope for testing
-    protected static int[] getDecimalPrecisionAndScale(byte[] bytes, int offset, int length) {
+    protected static int[] getDecimalPrecisionAndScale(byte[] bytes, int offset, int length, SortOrder sortOrder) {
         // 0, which should have no precision nor scale.
-        if (length == 1 && bytes[offset] == ZERO_BYTE) { return new int[] { 0, 0 }; }
+        if (length == 1 && sortOrder.normalize(bytes[offset])  == ZERO_BYTE) { return new int[] { 0, 0 }; }
         int signum = ((bytes[offset] & 0x80) == 0) ? -1 : 1;
         int scale;
         int index;

http://git-wip-us.apache.org/repos/asf/phoenix/blob/8e2f087b/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 9fff730..b76febb 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
@@ -321,8 +321,8 @@ public class PDecimal extends PRealNumber<BigDecimal> {
             maxLength = v.precision();
             scale = v.scale();
         } else {
-            this.coerceBytes(ptr, value, srcType, maxLength, scale, SortOrder.getDefault(), desiredMaxLength, desiredScale, sortOrder, true);
-            int[] v = getDecimalPrecisionAndScale(ptr.get(), ptr.getOffset(), ptr.getLength());
+            this.coerceBytes(ptr, value, srcType, maxLength, scale, sortOrder, desiredMaxLength, desiredScale, sortOrder, true);
+            int[] v = getDecimalPrecisionAndScale(ptr.get(), ptr.getOffset(), ptr.getLength(), sortOrder);
             maxLength = v[0];
             scale = v[1];
         }
@@ -352,7 +352,7 @@ public class PDecimal extends PRealNumber<BigDecimal> {
                 BigDecimal v = (BigDecimal) object;
                 scale = v.scale();
             } else {
-                int[] v = getDecimalPrecisionAndScale(ptr.get(), ptr.getOffset(), ptr.getLength());
+                int[] v = getDecimalPrecisionAndScale(ptr.get(), ptr.getOffset(), ptr.getLength(), actualModifier);
                 scale = v[1];
             }
         }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/8e2f087b/phoenix-core/src/test/java/org/apache/phoenix/schema/types/PDataTypeTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/schema/types/PDataTypeTest.java b/phoenix-core/src/test/java/org/apache/phoenix/schema/types/PDataTypeTest.java
index ba48a8a..d07364c 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/schema/types/PDataTypeTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/schema/types/PDataTypeTest.java
@@ -1537,7 +1537,14 @@ public class PDataTypeTest {
         // Special case for 0.
         BigDecimal bd = new BigDecimal("0");
         byte[] b = PDecimal.INSTANCE.toBytes(bd);
-        int[] v = PDataType.getDecimalPrecisionAndScale(b, 0, b.length);
+        int[] v = PDataType.getDecimalPrecisionAndScale(b, 0, b.length, SortOrder.getDefault());
+        assertEquals(0, v[0]);
+        assertEquals(0, v[1]);
+
+        // Special case for 0 descending
+        bd = new BigDecimal("0");
+        b = PDecimal.INSTANCE.toBytes(bd, SortOrder.DESC);
+        v = PDataType.getDecimalPrecisionAndScale(b, 0, b.length, SortOrder.DESC);
         assertEquals(0, v[0]);
         assertEquals(0, v[1]);
 
@@ -1572,8 +1579,9 @@ public class PDataTypeTest {
         };
 
         for (int i=0; i<bds.length; i++) {
-            testReadDecimalPrecisionAndScaleFromRawBytes(bds[i]);
-            testReadDecimalPrecisionAndScaleFromRawBytes(bds[i].negate());
+            testReadDecimalPrecisionAndScaleFromRawBytes(bds[i], SortOrder.ASC);
+            testReadDecimalPrecisionAndScaleFromRawBytes(bds[i], SortOrder.DESC);
+            testReadDecimalPrecisionAndScaleFromRawBytes(bds[i].negate(), SortOrder.getDefault());
         }
         
         assertTrue(new BigDecimal("5").remainder(BigDecimal.ONE).equals(BigDecimal.ZERO));
@@ -1662,9 +1670,9 @@ public class PDataTypeTest {
         }
     }
 
-    private void testReadDecimalPrecisionAndScaleFromRawBytes(BigDecimal bd) {
+    private void testReadDecimalPrecisionAndScaleFromRawBytes(BigDecimal bd, SortOrder sortOrder) {
         byte[] b = PDecimal.INSTANCE.toBytes(bd);
-        int[] v = PDataType.getDecimalPrecisionAndScale(b, 0, b.length);
+        int[] v = PDataType.getDecimalPrecisionAndScale(b, 0, b.length, sortOrder);
         assertEquals(bd.toString(), bd.precision(), v[0]);
         assertEquals(bd.toString(), bd.scale(), v[1]);
     }