You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by el...@apache.org on 2020/11/13 21:41:38 UTC
[calcite-avatica] branch master updated: [CALCITE-4379] Meta.Frame
created with java float values in rows hits a ClassCastException in
toProto()
This is an automated email from the ASF dual-hosted git repository.
elserj pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/calcite-avatica.git
The following commit(s) were added to refs/heads/master by this push:
new 9dfc5ca [CALCITE-4379] Meta.Frame created with java float values in rows hits a ClassCastException in toProto()
9dfc5ca is described below
commit 9dfc5cad3efe72e9b14513b15a988ba86ab5a4ea
Author: Dmitri Bourlatchkov <dm...@datastax.com>
AuthorDate: Thu Nov 5 12:38:46 2020 -0500
[CALCITE-4379] Meta.Frame created with java float values in rows hits a ClassCastException in toProto()
* Remove unnecessary conversion of Float values to long in
TypedValue.toProto(...). The subsequently invoked writeToProtoWithType(...)
method actually expects float values in this case.
* Make a similar fix for Character values.
* Add Frame serialization round-trip unit tests to cover this failure mode.
* Note: a similar problem appears to still exist for Timestamp and Date/Time
values in this context, but I did not attempt to fix it in this commit because
there is apparently no use case for putting Timestamp/Date/Time objects into
Frames. Those values are normally returned as plain numbers in result rows.
Closes #130
Signed-off-by: Josh Elser <el...@apache.org>
---
.../apache/calcite/avatica/remote/TypedValue.java | 4 +-
.../java/org/apache/calcite/avatica/FrameTest.java | 79 ++++++++++++++++++++++
2 files changed, 81 insertions(+), 2 deletions(-)
diff --git a/core/src/main/java/org/apache/calcite/avatica/remote/TypedValue.java b/core/src/main/java/org/apache/calcite/avatica/remote/TypedValue.java
index 9b98d2a..29b7487 100644
--- a/core/src/main/java/org/apache/calcite/avatica/remote/TypedValue.java
+++ b/core/src/main/java/org/apache/calcite/avatica/remote/TypedValue.java
@@ -802,7 +802,7 @@ public class TypedValue {
writeToProtoWithType(builder, o, Common.Rep.DOUBLE);
return Common.Rep.DOUBLE;
} else if (o instanceof Float) {
- writeToProtoWithType(builder, ((Float) o).longValue(), Common.Rep.FLOAT);
+ writeToProtoWithType(builder, o, Common.Rep.FLOAT);
return Common.Rep.FLOAT;
} else if (o instanceof BigDecimal) {
writeToProtoWithType(builder, o, Common.Rep.BIG_DECIMAL);
@@ -812,7 +812,7 @@ public class TypedValue {
writeToProtoWithType(builder, o, Common.Rep.STRING);
return Common.Rep.STRING;
} else if (o instanceof Character) {
- writeToProtoWithType(builder, o.toString(), Common.Rep.CHARACTER);
+ writeToProtoWithType(builder, o, Common.Rep.CHARACTER);
return Common.Rep.CHARACTER;
// Bytes
} else if (o instanceof byte[]) {
diff --git a/core/src/test/java/org/apache/calcite/avatica/FrameTest.java b/core/src/test/java/org/apache/calcite/avatica/FrameTest.java
index 4f34a3c..88345ef 100644
--- a/core/src/test/java/org/apache/calcite/avatica/FrameTest.java
+++ b/core/src/test/java/org/apache/calcite/avatica/FrameTest.java
@@ -23,6 +23,7 @@ import org.apache.calcite.avatica.proto.Common.TypedValue;
import org.junit.Test;
+import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -105,6 +106,84 @@ public class FrameTest {
serializeAndTestEquality(singleRow);
}
+ protected void testValueRoundTrip(Object value) {
+ List<Object> rows = Collections.singletonList(new Object[]{value});
+ serializeAndTestEquality(new Frame(0, true, rows));
+ }
+
+ @Test
+ public void testInteger() {
+ testValueRoundTrip(Integer.MIN_VALUE);
+ testValueRoundTrip(Integer.MAX_VALUE);
+ }
+
+ @Test
+ public void testLong() {
+ testValueRoundTrip(1L);
+ testValueRoundTrip(0L);
+ testValueRoundTrip(Long.MIN_VALUE);
+ testValueRoundTrip(Long.MAX_VALUE);
+ }
+
+ @Test
+ public void testFloat() {
+ testValueRoundTrip(Float.MIN_VALUE);
+ testValueRoundTrip(Float.MAX_VALUE);
+ testValueRoundTrip(Float.MIN_NORMAL);
+ }
+
+ @Test
+ public void testDouble() {
+ testValueRoundTrip(Double.MIN_VALUE);
+ testValueRoundTrip(Double.MAX_VALUE);
+ testValueRoundTrip(Double.MIN_NORMAL);
+ }
+
+ @Test
+ public void testString() {
+ testValueRoundTrip("example-value");
+ testValueRoundTrip("");
+ }
+
+ @Test
+ public void testChar() {
+ testValueRoundTrip('a');
+ testValueRoundTrip('\0');
+ }
+
+ @Test
+ public void testByte() {
+ testValueRoundTrip(Byte.MAX_VALUE);
+ testValueRoundTrip(Byte.MIN_VALUE);
+ }
+
+ @Test
+ public void testByteArray() {
+ testValueRoundTrip(new byte[] {1, 0});
+ }
+
+ @Test
+ public void testBoolean() {
+ testValueRoundTrip(true);
+ testValueRoundTrip(false);
+ }
+
+ @Test
+ public void testShort() {
+ testValueRoundTrip(Short.MAX_VALUE);
+ testValueRoundTrip(Short.MIN_VALUE);
+ }
+
+ @Test
+ public void testBigDecimal() {
+ testValueRoundTrip(BigDecimal.valueOf(0));
+ testValueRoundTrip(BigDecimal.valueOf(1));
+ testValueRoundTrip(BigDecimal // make a non-integer value larger than Long.MAX_VALUE
+ .valueOf(Long.MAX_VALUE)
+ .multiply(BigDecimal.TEN)
+ .add(BigDecimal.valueOf(0.12345d)));
+ }
+
@Test public void testMalformedColumnValue() {
// Invalid ColumnValue: has an array and scalar
final ColumnValue bothAttributesColumnValue = ColumnValue.newBuilder().setHasArrayValue(true)