This is an automated email from the ASF dual-hosted git repository.
lzljs3620320 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/paimon.git
The following commit(s) were added to refs/heads/master by this push:
new cb136340a [core] Support TimestampToNumericPrimitiveCastRule in
casting (#3854)
cb136340a is described below
commit cb136340af4b5037d44b3adb97d7ec825833761c
Author: xuzifu666 <[email protected]>
AuthorDate: Mon Aug 12 15:21:05 2024 +0800
[core] Support TimestampToNumericPrimitiveCastRule in casting (#3854)
---
.../org/apache/paimon/casting/CastExecutors.java | 1 +
.../TimestampToNumericPrimitiveCastRule.java | 71 ++++++++++++++++++++++
.../apache/paimon/casting/CastExecutorTest.java | 53 ++++++++++++++++
3 files changed, 125 insertions(+)
diff --git
a/paimon-core/src/main/java/org/apache/paimon/casting/CastExecutors.java
b/paimon-core/src/main/java/org/apache/paimon/casting/CastExecutors.java
index 054d6fca1..beb7aa0a5 100644
--- a/paimon-core/src/main/java/org/apache/paimon/casting/CastExecutors.java
+++ b/paimon-core/src/main/java/org/apache/paimon/casting/CastExecutors.java
@@ -70,6 +70,7 @@ public class CastExecutors {
.addRule(TimestampToTimeCastRule.INSTANCE)
.addRule(DateToTimestampCastRule.INSTANCE)
.addRule(TimeToTimestampCastRule.INSTANCE)
+ .addRule(TimestampToNumericPrimitiveCastRule.INSTANCE)
// To binary rules
.addRule(BinaryToBinaryCastRule.INSTANCE);
}
diff --git
a/paimon-core/src/main/java/org/apache/paimon/casting/TimestampToNumericPrimitiveCastRule.java
b/paimon-core/src/main/java/org/apache/paimon/casting/TimestampToNumericPrimitiveCastRule.java
new file mode 100644
index 000000000..f7cd21bab
--- /dev/null
+++
b/paimon-core/src/main/java/org/apache/paimon/casting/TimestampToNumericPrimitiveCastRule.java
@@ -0,0 +1,71 @@
+/*
+ * 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.paimon.casting;
+
+import org.apache.paimon.data.Timestamp;
+import org.apache.paimon.types.DataType;
+import org.apache.paimon.types.DataTypeFamily;
+import org.apache.paimon.types.DataTypeRoot;
+import org.apache.paimon.utils.DateTimeUtils;
+
+/**
+ * {@link DataTypeRoot#TIMESTAMP_WITHOUT_TIME_ZONE}/{@link
+ * DataTypeRoot#TIMESTAMP_WITH_LOCAL_TIME_ZONE} to {@link
DataTypeFamily#NUMERIC} cast rule.
+ */
+public class TimestampToNumericPrimitiveCastRule extends
AbstractCastRule<Timestamp, Number> {
+
+ static final TimestampToNumericPrimitiveCastRule INSTANCE =
+ new TimestampToNumericPrimitiveCastRule();
+
+ private TimestampToNumericPrimitiveCastRule() {
+ super(
+ CastRulePredicate.builder()
+ .input(DataTypeRoot.TIMESTAMP_WITHOUT_TIME_ZONE)
+ .input(DataTypeRoot.TIMESTAMP_WITH_LOCAL_TIME_ZONE)
+ .target(DataTypeRoot.BIGINT)
+ .target(DataTypeRoot.INTEGER)
+ .build());
+ }
+
+ @Override
+ public CastExecutor<Timestamp, Number> create(DataType inputType, DataType
targetType) {
+ if (inputType.is(DataTypeRoot.TIMESTAMP_WITHOUT_TIME_ZONE)) {
+ if (targetType.is(DataTypeRoot.BIGINT)) {
+ return value ->
DateTimeUtils.unixTimestamp(value.getMillisecond());
+ } else if (targetType.is(DataTypeRoot.INTEGER)) {
+ return value -> (int)
DateTimeUtils.unixTimestamp(value.getMillisecond());
+ }
+ } else if (inputType.is(DataTypeRoot.TIMESTAMP_WITH_LOCAL_TIME_ZONE)) {
+ if (targetType.is(DataTypeRoot.BIGINT)) {
+ return value ->
+ DateTimeUtils.unixTimestamp(
+
Timestamp.fromLocalDateTime(value.toLocalDateTime())
+ .getMillisecond());
+ } else if (targetType.is(DataTypeRoot.INTEGER)) {
+ return value ->
+ (int)
+ DateTimeUtils.unixTimestamp(
+
Timestamp.fromLocalDateTime(value.toLocalDateTime())
+ .getMillisecond());
+ }
+ }
+
+ return null;
+ }
+}
diff --git
a/paimon-core/src/test/java/org/apache/paimon/casting/CastExecutorTest.java
b/paimon-core/src/test/java/org/apache/paimon/casting/CastExecutorTest.java
index ff805993c..5c41f2b5f 100644
--- a/paimon-core/src/test/java/org/apache/paimon/casting/CastExecutorTest.java
+++ b/paimon-core/src/test/java/org/apache/paimon/casting/CastExecutorTest.java
@@ -286,6 +286,59 @@ public class CastExecutorTest {
DateTimeUtils.formatTimestamp(timestamp,
TimeZone.getDefault(), 5)));
}
+ @Test
+ public void testTimestampToNumeric() {
+ long mills = System.currentTimeMillis() / 1000 * 1000;
+ Timestamp timestamp1 = Timestamp.fromEpochMillis(mills);
+ long millisecond = timestamp1.getMillisecond();
+ Timestamp timestamp2 =
+ Timestamp.fromLocalDateTime(
+ DateTimeUtils.toLocalDateTime(mills,
TimeZone.getDefault().toZoneId()));
+ long millisecond1 = timestamp2.getMillisecond();
+
+ // cast from TimestampType to BigIntType or IntType
+ compareCastResult(
+ CastExecutors.resolve(new TimestampType(3), new
BigIntType(false)),
+ timestamp1,
+ DateTimeUtils.unixTimestamp(millisecond));
+
+ compareCastResult(
+ CastExecutors.resolve(new LocalZonedTimestampType(3), new
BigIntType(false)),
+ timestamp2,
+ DateTimeUtils.unixTimestamp(millisecond1));
+
+ compareCastResult(
+ CastExecutors.resolve(new TimestampType(3), new
IntType(false)),
+ timestamp1,
+ (int) DateTimeUtils.unixTimestamp(millisecond));
+
+ compareCastResult(
+ CastExecutors.resolve(new LocalZonedTimestampType(3), new
IntType(false)),
+ timestamp2,
+ (int) DateTimeUtils.unixTimestamp(millisecond1));
+
+ // cast from BigIntType or IntType to TimestampType
+ compareCastResult(
+ CastExecutors.resolve(new BigIntType(false), new
TimestampType(3)),
+ DateTimeUtils.unixTimestamp(millisecond),
+ timestamp1);
+
+ compareCastResult(
+ CastExecutors.resolve(new BigIntType(false), new
LocalZonedTimestampType(3)),
+ DateTimeUtils.unixTimestamp(millisecond),
+ timestamp2);
+
+ compareCastResult(
+ CastExecutors.resolve(new IntType(false), new
TimestampType(3)),
+ (int) DateTimeUtils.unixTimestamp(millisecond),
+ timestamp1);
+
+ compareCastResult(
+ CastExecutors.resolve(new IntType(false), new
LocalZonedTimestampType(3)),
+ (int) DateTimeUtils.unixTimestamp(millisecond),
+ timestamp2);
+ }
+
@Test
public void testTimeToString() {
compareCastResult(