[CARBONDATA-1392] Fixed bug for fetching the error value of decimal type in presto
This closes #1236
diff --git a/integration/presto/src/main/java/org/apache/carbondata/presto/CarbondataErrorCode.java b/integration/presto/src/main/java/org/apache/carbondata/presto/CarbondataErrorCode.java
new file mode 100644
index 0000000..45971d0
--- /dev/null
+++ b/integration/presto/src/main/java/org/apache/carbondata/presto/CarbondataErrorCode.java
@@ -0,0 +1,38 @@
+/*
+ * 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.carbondata.presto;
+
+import com.facebook.presto.spi.ErrorCode;
+import com.facebook.presto.spi.ErrorCodeSupplier;
+import com.facebook.presto.spi.ErrorType;
+
+import static com.facebook.presto.spi.ErrorType.EXTERNAL;
+import static com.facebook.presto.spi.ErrorType.INTERNAL_ERROR;
+
+public enum CarbondataErrorCode implements ErrorCodeSupplier {
+ CARBON_NOT_SUPPORT_TYPE(1, INTERNAL_ERROR), CARBON_INVALID_TYPE_VALUE(2, EXTERNAL);
+
+ private final ErrorCode errorCode;
+
+ CarbondataErrorCode(int code, ErrorType type) {
+ errorCode = new ErrorCode(code + 0x0100_0000, name(), type);
+ }
+
+ @Override public ErrorCode toErrorCode() {
+ return errorCode;
+ }
+}
diff --git a/integration/presto/src/main/java/org/apache/carbondata/presto/CarbondataRecordCursor.java b/integration/presto/src/main/java/org/apache/carbondata/presto/CarbondataRecordCursor.java
index d6b1422..001392e 100755
--- a/integration/presto/src/main/java/org/apache/carbondata/presto/CarbondataRecordCursor.java
+++ b/integration/presto/src/main/java/org/apache/carbondata/presto/CarbondataRecordCursor.java
@@ -44,6 +44,7 @@
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
import static io.airlift.slice.Slices.utf8Slice;
+import static org.apache.carbondata.presto.CarbondataUtil.shortDecimalPartitionKey;
public class CarbondataRecordCursor implements RecordCursor {
@@ -54,7 +55,7 @@
private CarbondataSplit split;
private CarbonIterator<Object[]> rowCursor;
private CarbonDictionaryDecodeReaderSupport readSupport;
- private Tuple3<DataType,Dictionary,Int>[] dictionary;
+ private Tuple3<DataType, Dictionary, Int>[] dictionary;
private long totalBytes;
private long nanoStart;
@@ -62,7 +63,7 @@
public CarbondataRecordCursor(CarbonDictionaryDecodeReaderSupport readSupport,
CarbonIterator<Object[]> carbonIterator, List<CarbondataColumnHandle> columnHandles,
- CarbondataSplit split, Tuple3<DataType,Dictionary,Int>[] dictionaries ) {
+ CarbondataSplit split, Tuple3<DataType, Dictionary, Int>[] dictionaries) {
this.rowCursor = carbonIterator;
this.columnHandles = columnHandles;
this.readSupport = readSupport;
@@ -98,8 +99,8 @@
}
if (rowCursor.hasNext()) {
- fields = readSupport.readRow(rowCursor.next(),dictionary);
- totalBytes += fields.length;
+ fields = readSupport.readRow(rowCursor.next(), dictionary);
+ totalBytes += fields.length;
return true;
}
return false;
@@ -107,22 +108,26 @@
@Override public boolean getBoolean(int field) {
checkFieldType(field, BOOLEAN);
- return (Boolean)getFieldValue(field);
+ return (Boolean) getFieldValue(field);
}
@Override public long getLong(int field) {
Object obj = getFieldValue(field);
Long timeStr = 0L;
- if( obj instanceof Integer ){
- timeStr = ((Integer)obj).longValue();
- } else if( obj instanceof Long ) {
- timeStr = (Long)obj;
+ if (obj instanceof Integer) {
+ timeStr = ((Integer) obj).longValue();
+ } else if (obj instanceof Long) {
+ timeStr = (Long) obj;
} else {
timeStr = Math.round(Double.parseDouble(obj.toString()));
}
Type actual = getType(field);
- if(actual instanceof TimestampType){
- return new Timestamp(timeStr).getTime()/1000;
+
+ if (actual instanceof TimestampType) {
+ return new Timestamp(timeStr).getTime() / 1000;
+ } else if (isShortDecimal(actual)) {
+ return shortDecimalPartitionKey(obj.toString(), (DecimalType) actual,
+ columnHandles.get(field).getColumnName());
}
//suppose the
return timeStr;
@@ -130,7 +135,7 @@
@Override public double getDouble(int field) {
checkFieldType(field, DOUBLE);
- return (Double)getFieldValue(field);
+ return (Double) getFieldValue(field);
}
@Override public Slice getSlice(int field) {
@@ -138,8 +143,9 @@
if (decimalType instanceof DecimalType) {
DecimalType actual = (DecimalType) decimalType;
CarbondataColumnHandle carbondataColumnHandle = columnHandles.get(field);
- if(carbondataColumnHandle.getPrecision() > 0 ) {
- checkFieldType(field, DecimalType.createDecimalType(carbondataColumnHandle.getPrecision(), carbondataColumnHandle.getScale()));
+ if (carbondataColumnHandle.getPrecision() > 0) {
+ checkFieldType(field, DecimalType.createDecimalType(carbondataColumnHandle.getPrecision(),
+ carbondataColumnHandle.getScale()));
} else {
checkFieldType(field, DecimalType.createDecimalType());
}
diff --git a/integration/presto/src/main/java/org/apache/carbondata/presto/CarbondataUtil.java b/integration/presto/src/main/java/org/apache/carbondata/presto/CarbondataUtil.java
new file mode 100644
index 0000000..52c8920
--- /dev/null
+++ b/integration/presto/src/main/java/org/apache/carbondata/presto/CarbondataUtil.java
@@ -0,0 +1,49 @@
+/*
+ * 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.carbondata.presto;
+
+import java.math.BigDecimal;
+
+import com.facebook.presto.spi.PrestoException;
+import com.facebook.presto.spi.type.DecimalType;
+
+import static java.lang.String.format;
+import static java.math.BigDecimal.ROUND_UNNECESSARY;
+import static org.apache.carbondata.presto.CarbondataErrorCode.CARBON_INVALID_TYPE_VALUE;
+
+public class CarbondataUtil {
+
+ public static long shortDecimalPartitionKey(String value, DecimalType type, String name) {
+ return decimalPartitionKey(value, type, name).unscaledValue().longValue();
+ }
+
+ private static BigDecimal decimalPartitionKey(String value, DecimalType type, String name) {
+ try {
+ BigDecimal decimal = new BigDecimal(value);
+ decimal = decimal.setScale(type.getScale(), ROUND_UNNECESSARY);
+ if (decimal.precision() > type.getPrecision()) {
+ throw new PrestoException(CARBON_INVALID_TYPE_VALUE,
+ format("Invalid type value '%s' for %s type key: %s", value, type.toString(), name));
+ }
+ return decimal;
+ } catch (NumberFormatException e) {
+ throw new PrestoException(CARBON_INVALID_TYPE_VALUE,
+ format("Invalid type value '%s' for %s type key: %s", value, type.toString(), name));
+ }
+ }
+}