diff --git a/externals/kyuubi-spark-sql-engine/src/test/scala/org/apache/kyuubi/engine/spark/operation/SparkArrowbasedOperationSuite.scala b/externals/kyuubi-spark-sql-engine/src/test/scala/org/apache/kyuubi/engine/spark/operation/SparkArrowbasedOperationSuite.scala index 5324ceb6997..277a6bd1698 100644 --- a/externals/kyuubi-spark-sql-engine/src/test/scala/org/apache/kyuubi/engine/spark/operation/SparkArrowbasedOperationSuite.scala +++ b/externals/kyuubi-spark-sql-engine/src/test/scala/org/apache/kyuubi/engine/spark/operation/SparkArrowbasedOperationSuite.scala @@ -85,7 +85,7 @@ class SparkArrowbasedOperationSuite extends WithSparkSQLEngine with SparkDataTyp statement.executeQuery(s"set ${KyuubiConf.ARROW_BASED_ROWSET_TIMESTAMP_AS_STRING.key}=false") checkArrowBasedRowSetTimestampAsString(statement, "false") setTimeZone("UTC") - check("2022-12-08 01:15:35.0") + check("2022-12-07 17:15:35.0") setTimeZone("GMT+8") check("2022-12-08 01:15:35.0") } diff --git a/kyuubi-hive-jdbc/src/main/java/org/apache/kyuubi/jdbc/hive/KyuubiArrowBasedResultSet.java b/kyuubi-hive-jdbc/src/main/java/org/apache/kyuubi/jdbc/hive/KyuubiArrowBasedResultSet.java index 43b1a11ae81..1336bf84074 100644 --- a/kyuubi-hive-jdbc/src/main/java/org/apache/kyuubi/jdbc/hive/KyuubiArrowBasedResultSet.java +++ b/kyuubi-hive-jdbc/src/main/java/org/apache/kyuubi/jdbc/hive/KyuubiArrowBasedResultSet.java @@ -312,8 +312,14 @@ private Object getColumnValue(int columnIndex) throws SQLException { wasNull = row.isNullAt(columnIndex - 1); if (wasNull) { return null; + } else if (columnType == TTypeId.TIMESTAMP_TYPE) { + return row.get( + columnIndex - 1, + columnType, + columnAttributes.get(columnIndex - 1).timeZone, + timestampAsString); } else { - return row.get(columnIndex - 1, columnType, timestampAsString); + return row.get(columnIndex - 1, columnType, null, timestampAsString); } } catch (Exception e) { e.printStackTrace(); diff --git a/kyuubi-hive-jdbc/src/main/java/org/apache/kyuubi/jdbc/hive/arrow/ArrowColumnarBatchRow.java b/kyuubi-hive-jdbc/src/main/java/org/apache/kyuubi/jdbc/hive/arrow/ArrowColumnarBatchRow.java index cd8a0aec056..3033c87403a 100644 --- a/kyuubi-hive-jdbc/src/main/java/org/apache/kyuubi/jdbc/hive/arrow/ArrowColumnarBatchRow.java +++ b/kyuubi-hive-jdbc/src/main/java/org/apache/kyuubi/jdbc/hive/arrow/ArrowColumnarBatchRow.java @@ -19,6 +19,11 @@ import java.math.BigDecimal; import java.sql.Timestamp; +import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; +import java.util.TimeZone; +import java.util.concurrent.TimeUnit; +import org.apache.arrow.vector.util.DateUtility; import org.apache.hive.service.rpc.thrift.TTypeId; import org.apache.kyuubi.jdbc.hive.common.DateUtils; import org.apache.kyuubi.jdbc.hive.common.HiveIntervalDayTime; @@ -104,7 +109,7 @@ public Object getMap(int ordinal) { throw new UnsupportedOperationException(); } - public Object get(int ordinal, TTypeId dataType, boolean timestampAsString) { + public Object get(int ordinal, TTypeId dataType, String timeZone, boolean timestampAsString) { long seconds; long milliseconds; long microseconds; @@ -134,12 +139,14 @@ public Object get(int ordinal, TTypeId dataType, boolean timestampAsString) { if (timestampAsString) { return Timestamp.valueOf(getString(ordinal)); } else { - microseconds = getLong(ordinal); - System.out.println("microseconds: " + microseconds); - nanos = (int) (microseconds % 1_000_000) * 1000; - Timestamp timestamp = new Timestamp(microseconds / 1_000); - timestamp.setNanos(nanos); - return timestamp; + LocalDateTime localDateTime = + DateUtility.getLocalDateTimeFromEpochMicro(getLong(ordinal), timeZone); + long millis = TimeUnit.MICROSECONDS.toMillis(getLong(ordinal)); + TimeZone zone = TimeZone.getTimeZone(timeZone); + localDateTime = + localDateTime.minus( + zone.getOffset(millis) - zone.getOffset(millis), ChronoUnit.MILLIS); + return Timestamp.valueOf(localDateTime); } case DATE_TYPE: return DateUtils.internalToDate(getInt(ordinal));