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/06/14 01:02:42 UTC

[4/4] phoenix git commit: PHOENIX-2983 ClassCastException on auto coerce of BIGINT to DECIMAL

PHOENIX-2983 ClassCastException on auto coerce of BIGINT to DECIMAL


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

Branch: refs/heads/4.x-HBase-1.1
Commit: a4e37753acab9b960b2062760e5d898f36b69151
Parents: 95b4a7b
Author: James Taylor <ja...@apache.org>
Authored: Sun Jun 12 22:10:39 2016 -0700
Committer: James Taylor <ja...@apache.org>
Committed: Mon Jun 13 18:05:14 2016 -0700

----------------------------------------------------------------------
 .../apache/phoenix/end2end/UpsertValuesIT.java   | 19 +++++++++++++++++++
 .../apache/phoenix/schema/types/PDataType.java   | 12 ++++++++++++
 .../apache/phoenix/schema/types/PDecimal.java    |  8 ++++++++
 3 files changed, 39 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/a4e37753/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 5cefd7d..9bbe23e 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
@@ -925,6 +925,25 @@ public class UpsertValuesIT extends BaseClientManagedTimeIT {
         }
     }
     
+    @Test
+    public void testAutoCastLongToBigDecimal() throws Exception {
+        long ts = nextTimestamp();
+        try (Connection conn = getConnection(ts)) {
+            conn.createStatement().execute("CREATE TABLE LONG_BUG (NAME VARCHAR PRIMARY KEY, AMOUNT DECIMAL)");
+        }
+        try (Connection conn = getConnection(ts + 10)) {
+            conn.createStatement().execute("UPSERT INTO LONG_BUG (NAME, AMOUNT) VALUES('HELLO1', -50000)");
+            conn.commit();
+        }
+        try (Connection conn = getConnection(ts + 20)) {
+            ResultSet rs = conn.createStatement().executeQuery("SELECT NAME, AMOUNT FROM LONG_BUG");
+            assertTrue(rs.next());
+            assertEquals("HELLO1", rs.getString(1));
+            assertTrue(new BigDecimal(-50000).compareTo(rs.getBigDecimal(2)) == 0);
+            assertFalse(rs.next());
+        }
+    }
+    
     private static Connection getConnection(long ts) throws SQLException {
         Properties props = PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES);
         props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts));

http://git-wip-us.apache.org/repos/asf/phoenix/blob/a4e37753/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 1b5b695..0f0328a 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
@@ -730,6 +730,18 @@ public abstract class PDataType<T> implements DataType<T>, Comparable<PDataType<
         return isCoercibleTo(targetType);
     }
 
+    /**
+     * Checks whether or not the value represented by value (or ptr if value is null) is compatible in terms
+     * of size with the desired max length and scale. The srcType must be coercible to this type.
+     * @param ptr bytes pointer for the value
+     * @param value object representation of the value. May be null in which case ptr will be used
+     * @param srcType the type of the value
+     * @param maxLength the max length of the source value or null if not applicable
+     * @param scale the scale of the source value or null if not applicable
+     * @param desiredMaxLength the desired max length for the value to be coerced
+     * @param desiredScale the desired scale for the value to be coerced 
+     * @return true if the value may be coerced without losing precision and false otherwise.
+     */
     public boolean isSizeCompatible(ImmutableBytesWritable ptr, Object value, PDataType srcType, Integer maxLength,
             Integer scale, Integer desiredMaxLength, Integer desiredScale) {
         return true;

http://git-wip-us.apache.org/repos/asf/phoenix/blob/a4e37753/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 228aef1..ff6e186 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
@@ -26,6 +26,7 @@ import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.phoenix.query.QueryConstants;
 import org.apache.phoenix.schema.SortOrder;
+import org.apache.phoenix.schema.TypeMismatchException;
 import org.apache.phoenix.util.ByteUtil;
 import org.apache.phoenix.util.NumberUtil;
 
@@ -304,6 +305,13 @@ public class PDecimal extends PRealNumber<BigDecimal> {
     if (ptr.getLength() == 0) {
       return true;
     }
+    // Any numeric type fits into a DECIMAL
+    if (srcType != PDecimal.INSTANCE) {
+        if(!srcType.isCoercibleTo(this)) {
+            throw new IllegalArgumentException(TypeMismatchException.newException(srcType, this));
+        }
+        return true;
+    }
     // Use the scale from the value if provided, as it prevents a deserialization.
     // The maxLength and scale for the underlying expression are ignored, because they
     // are not relevant in this case: for example a DECIMAL(10,2) may be assigned to a