[
https://issues.apache.org/jira/browse/HIVE-21964?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17199318#comment-17199318
]
chenruotao edited comment on HIVE-21964 at 9/21/20, 10:35 AM:
--------------------------------------------------------------
I has the same problem like this, but not Decimal.
the type of date and timestramp would throw the same exception when job
running, so I do not use the type provided by
hive(org.apache.hadoop.hive.common.type), and it worked. the code like this :
case DATE:
// if (rowVal instanceof java.sql.Date){
// LocalDate localDate = ((java.sql.Date) rowVal).toLocalDate();
//rowVal=Date.of(localDate.getYear(),localDate.getMonthValue(),localDate.getDayOfMonth();
// }else{
// rowVal = Date.valueOf (rowVal.toString());
// }
rowVal = Date.valueOf (rowVal.toString());
break;
case TIMESTAMP:
// if (rowVal instanceof java.sql.Timestamp){
// LocalDateTime localDateTime = ((java.sql.Timestamp)
rowVal).toLocalDateTime();
//rowVal=Timestamp.ofEpochSecond(localDateTime.toEpochSecond(UTC),localDateTime.geNano());
// }else{
// rowVal = Timestamp.valueOf (rowVal.toString());
// }
rowVal = Timestamp.valueOf (rowVal.toString());
was (Author: chenruotao):
I has the same problem like this, but not Decimal.
the type of date and timestramp would throw the same exception when job
running, so I do not use the type provided by
hive(org.apache.hadoop.hive.common.type), and it worked. the code like this :
case DATE:
// if (rowVal instanceof java.sql.Date) {
// LocalDate localDate = ((java.sql.Date) rowVal).toLocalDate();
// rowVal = Date.of(localDate.getYear(), localDate.getMonthValue(),
localDate.getDayOfMonth());
// } else {
// rowVal = Date.valueOf (rowVal.toString());
// }
rowVal = Date.valueOf (rowVal.toString());
break;
case TIMESTAMP:
// if (rowVal instanceof java.sql.Timestamp) {
// LocalDateTime localDateTime = ((java.sql.Timestamp)
rowVal).toLocalDateTime();
// rowVal = Timestamp.ofEpochSecond(localDateTime.toEpochSecond(UTC),
localDateTime.getNano());
// } else {
// rowVal = Timestamp.valueOf (rowVal.toString());
// }
rowVal = Timestamp.valueOf (rowVal.toString());
> jdbc handler class cast exception
> ---------------------------------
>
> Key: HIVE-21964
> URL: https://issues.apache.org/jira/browse/HIVE-21964
> Project: Hive
> Issue Type: Improvement
> Components: JDBC
> Affects Versions: 3.1.1
> Reporter: Aloys Zhang
> Priority: Major
>
> Using hive jdbc handler to query external mysql data source with type decimal
> type, it throws class cast Exception :
>
> {code:java}
> 2019-07-08T11:11:50,424 ERROR [7787918f-3111-4706-a3b3-0097fa1bc117 main]
> CliDriver: Failed with exception
> java.io.IOException:org.apache.hadoop.hive.ql.metadata.HiveException:
> java.lang.ClassCastException: java.math.BigDecimal cannot be cast to
> org.apache.hadoop.hive.common.type.HiveDecimal
> java.io.IOException: org.apache.hadoop.hive.ql.metadata.HiveException:
> java.lang.ClassCastException: java.math.BigDecimal cannot be cast to
> org.apache.hadoop.hive.common.type.HiveDecimal
> at org.apache.hadoop.hive.ql.exec.FetchTask.fetch(FetchTask.java:162)
> at org.apache.hadoop.hive.ql.Driver.getResults(Driver.java:2691)
> at
> org.apache.hadoop.hive.ql.reexec.ReExecDriver.getResults(ReExecDriver.java:229)
> at org.apache.hadoop.hive.cli.CliDriver.processLocalCmd(CliDriver.java:259)
> at org.apache.hadoop.hive.cli.CliDriver.processCmd(CliDriver.java:188)
> at org.apache.hadoop.hive.cli.CliDriver.processLine(CliDriver.java:402)
> at org.apache.hadoop.hive.cli.CliDriver.executeDriver(CliDriver.java:821)
> at org.apache.hadoop.hive.cli.CliDriver.run(CliDriver.java:759)
> at org.apache.hadoop.hive.cli.CliDriver.main(CliDriver.java:683)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
> at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> at java.lang.reflect.Method.invoke(Method.java:498)
> at org.apache.hadoop.util.RunJar.run(RunJar.java:226)
> at org.apache.hadoop.util.RunJar.main(RunJar.java:141)
> Caused by: org.apache.hadoop.hive.ql.metadata.HiveException:
> java.lang.ClassCastException: java.math.BigDecimal cannot be cast to
> org.apache.hadoop.hive.common.type.HiveDecimal
> at
> org.apache.hadoop.hive.ql.exec.ListSinkOperator.process(ListSinkOperator.java:98)
> at org.apache.hadoop.hive.ql.exec.Operator.baseForward(Operator.java:995)
> at org.apache.hadoop.hive.ql.exec.Operator.forward(Operator.java:941)
> at org.apache.hadoop.hive.ql.exec.Operator.forward(Operator.java:928)
> at
> org.apache.hadoop.hive.ql.exec.SelectOperator.process(SelectOperator.java:95)
> at org.apache.hadoop.hive.ql.exec.Operator.baseForward(Operator.java:995)
> at org.apache.hadoop.hive.ql.exec.Operator.forward(Operator.java:941)
> at
> org.apache.hadoop.hive.ql.exec.TableScanOperator.process(TableScanOperator.java:125)
> at
> org.apache.hadoop.hive.ql.exec.FetchOperator.pushRow(FetchOperator.java:519)
> at
> org.apache.hadoop.hive.ql.exec.FetchOperator.pushRow(FetchOperator.java:511)
> at org.apache.hadoop.hive.ql.exec.FetchTask.fetch(FetchTask.java:146)
> ... 14 more
> Caused by: java.lang.ClassCastException: java.math.BigDecimal cannot be cast
> to org.apache.hadoop.hive.common.type.HiveDecimal
> at
> org.apache.hadoop.hive.serde2.objectinspector.primitive.JavaHiveDecimalObjectInspector.getPrimitiveJavaObject(JavaHiveDecimalObjectInspector.java:55)
> at
> org.apache.hadoop.hive.serde2.lazy.LazyUtils.writePrimitiveUTF8(LazyUtils.java:329)
> at
> org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe.serialize(LazySimpleSerDe.java:292)
> at
> org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe.serializeField(LazySimpleSerDe.java:247)
> at
> org.apache.hadoop.hive.serde2.DelimitedJSONSerDe.serializeField(DelimitedJSONSerDe.java:72)
> at
> org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe.doSerialize(LazySimpleSerDe.java:231)
> at
> org.apache.hadoop.hive.serde2.AbstractEncodingAwareSerDe.serialize(AbstractEncodingAwareSerDe.java:55)
> at
> org.apache.hadoop.hive.serde2.DefaultFetchFormatter.convert(DefaultFetchFormatter.java:67)
> at
> org.apache.hadoop.hive.serde2.DefaultFetchFormatter.convert(DefaultFetchFormatter.java:36)
> at
> org.apache.hadoop.hive.ql.exec.ListSinkOperator.process(ListSinkOperator.java:94)
> ... 24 more
> {code}
> Same problem with type date and timestamp.
>
> I debug the code and find that was caused by hive-jdbc-handler return
> result wity type
> java.math.Decimal , but when serialize the result row by calling
> JavaHiveDecimalObjectInspector#getPrimitiveJavaObject , java.math.Decimal
> cann't cast to org.apache.hadoop.hive.common.type.HiveDecimal.
> So, IMO, this is a bug in jdbc-handler code when processing decimal, date and
> timestamp teyps. I think jdbc-handler should return result with type cast
> like this :
> {code:java}
> @Override
> public Map<String, Object> next() {
> try {
> ResultSetMetaData metadata = rs.getMetaData();
> int numColumns = metadata.getColumnCount();
> Map<String, Object> record = new HashMap<String, Object>(numColumns);
> for (int i = 0; i < numColumns; i++) {
> String key = metadata.getColumnName(i + 1);
> Object value;
> if (columnTypes!=null && columnTypes.get(i) instanceof
> PrimitiveTypeInfo) {
> // This is not a complete list, barely make information schema work
> switch (((PrimitiveTypeInfo)columnTypes.get(i)).getTypeName()) {
> case "int":
> case "smallint":
> case "tinyint":
> value = rs.getInt(i + 1);
> break;
> case "bigint":
> value = rs.getLong(i + 1);
> break;
> case "float":
> value = rs.getFloat(i + 1);
> break;
> case "double":
> value = rs.getDouble(i + 1);
> break;
> case "decimal":
> case "bigdecimal":
> value = HiveDecimal.create(rs.getBigDecimal(i + 1));
> break;
> case "boolean":
> value = rs.getBoolean(i + 1);
> break;
> case "string":
> case "char":
> case "varchar":
> value = rs.getString(i + 1);
> break;
> case "date":
> case "datetime":
> value = new Date(rs.getDate(i + 1).toLocalDate());
> break;
> case "timestamp":
> value = new Timestamp((rs.getTimestamp(i + 1)).toLocalDateTime());
> break;
> default:
> value = rs.getObject(i + 1);
> break;
> }
> } else {
> value = rs.getObject(i + 1);
> }
> record.put(key, value);
> }
> return record;
> }
> catch (Exception e) {
> LOGGER.warn("next() threw exception", e);
> return null;
> }
> }
> {code}
> I want to know whether this change has other effects or not .
> Any suggestions are appreciated.
--
This message was sent by Atlassian Jira
(v8.3.4#803005)