This is an automated email from the ASF dual-hosted git repository.
Mryange pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new 040cdca6fcb [fix](function) Preserve TIMESTAMPTZ in microsecond
interval arithmetic (#70215)
040cdca6fcb is described below
commit 040cdca6fcb99c6415f51c026eb9a45d6c6d40db
Author: Mryange <[email protected]>
AuthorDate: Thu Nov 5 14:34:47 2026 +0800
[fix](function) Preserve TIMESTAMPTZ in microsecond interval arithmetic
(#70215)
### What problem does this PR solve?
Microsecond interval arithmetic can convert low-precision TIMESTAMPTZ
inputs to DATETIMEV2. Some composite interval functions also overwrite
the TIMESTAMPTZ signature during precision inference.
Use wildcard family signatures and preserve TIMESTAMPTZ while promoting
arguments and results to scale 6. This covers composite microsecond
intervals and microsecond/millisecond addition and subtraction. Existing
BE implementations require no changes.
### Release note
Fix TIMESTAMPTZ type and microsecond precision preservation in interval
addition and subtraction.
### Check List (For Author)
- Test:
- [x] Regression test: `test_timestamptz_microsecond_interval` passed
with `-forceGenOut` and a normal rerun; covers 36 expressions and result
column types.
- [x] Unit Test: focused FE signature test passed, covering 7 input
scales across 12 functions.
- FE build (`build.sh --fe -j48`) and Checkstyle passed.
- Behavior changed:
- [x] Yes. Affected TIMESTAMPTZ expressions preserve their type and
return scale 6.
- Does this need documentation?
- [x] No.
### Check List (For Reviewer who merge this PR)
- [ ] Confirm the release note
- [ ] Confirm test cases
- [ ] Confirm document
- [ ] Add branch pick label
---
.../functions/scalar/DayMicrosecondAdd.java | 11 +--
.../functions/scalar/DayMicrosecondSub.java | 11 +--
.../functions/scalar/HourMicrosecondAdd.java | 11 +--
.../functions/scalar/HourMicrosecondSub.java | 11 +--
.../functions/scalar/MicroSecondsAdd.java | 4 +-
.../functions/scalar/MicroSecondsSub.java | 4 +-
.../functions/scalar/MilliSecondsAdd.java | 4 +-
.../functions/scalar/MilliSecondsSub.java | 4 +-
.../functions/scalar/MinuteMicrosecondAdd.java | 11 +--
.../functions/scalar/MinuteMicrosecondSub.java | 11 +--
.../functions/scalar/SecondMicrosecondAdd.java | 4 +-
.../functions/scalar/SecondMicrosecondSub.java | 4 +-
.../scalar/TimestampNsFunctionSignatureTest.java | 26 +++++++
.../test_timestamptz_microsecond_interval.out | 43 ++++++++++++
.../datetime_functions/test_add_sub_union_type.out | 36 +++++-----
.../test_timestamptz_microsecond_interval.groovy | 79 ++++++++++++++++++++++
16 files changed, 220 insertions(+), 54 deletions(-)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/DayMicrosecondAdd.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/DayMicrosecondAdd.java
index b56848e6793..30f7e2a4d95 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/DayMicrosecondAdd.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/DayMicrosecondAdd.java
@@ -42,12 +42,12 @@ public class DayMicrosecondAdd extends ScalarFunction
implements BinaryExpression, ExplicitlyCastableSignature,
ComputeSignatureForDateArithmetic, PropagateNullable,
DateAddSubMonotonic {
public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
- FunctionSignature.ret(DateTimeV2Type.MAX)
- .args(DateTimeV2Type.MAX, VarcharType.SYSTEM_DEFAULT),
+ FunctionSignature.ret(DateTimeV2Type.WILDCARD)
+ .args(DateTimeV2Type.WILDCARD, VarcharType.SYSTEM_DEFAULT),
FunctionSignature.ret(TimeStampNsType.INSTANCE)
.args(TimeStampNsType.INSTANCE,
VarcharType.SYSTEM_DEFAULT),
- FunctionSignature.ret(TimeStampTzType.MAX)
- .args(TimeStampTzType.MAX, VarcharType.SYSTEM_DEFAULT)
+ FunctionSignature.ret(TimeStampTzType.WILDCARD)
+ .args(TimeStampTzType.WILDCARD, VarcharType.SYSTEM_DEFAULT)
);
public DayMicrosecondAdd(Expression arg0, Expression arg1) {
@@ -86,6 +86,9 @@ public class DayMicrosecondAdd extends ScalarFunction
if (signature.returnType instanceof TimeStampNsType) {
return signature;
}
+ if (signature.argumentsTypes.get(0) instanceof TimeStampTzType) {
+ return signature.withArgumentType(0,
TimeStampTzType.MAX).withReturnType(TimeStampTzType.MAX);
+ }
return signature.withArgumentType(0,
DateTimeV2Type.MAX).withReturnType(DateTimeV2Type.MAX);
}
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/DayMicrosecondSub.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/DayMicrosecondSub.java
index 197c28eb7db..a1f1720d874 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/DayMicrosecondSub.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/DayMicrosecondSub.java
@@ -42,12 +42,12 @@ public class DayMicrosecondSub extends ScalarFunction
implements BinaryExpression, ExplicitlyCastableSignature,
ComputeSignatureForDateArithmetic, PropagateNullable,
DateAddSubMonotonic {
public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
- FunctionSignature.ret(DateTimeV2Type.MAX)
- .args(DateTimeV2Type.MAX, VarcharType.SYSTEM_DEFAULT),
+ FunctionSignature.ret(DateTimeV2Type.WILDCARD)
+ .args(DateTimeV2Type.WILDCARD, VarcharType.SYSTEM_DEFAULT),
FunctionSignature.ret(TimeStampNsType.INSTANCE)
.args(TimeStampNsType.INSTANCE,
VarcharType.SYSTEM_DEFAULT),
- FunctionSignature.ret(TimeStampTzType.MAX)
- .args(TimeStampTzType.MAX, VarcharType.SYSTEM_DEFAULT)
+ FunctionSignature.ret(TimeStampTzType.WILDCARD)
+ .args(TimeStampTzType.WILDCARD, VarcharType.SYSTEM_DEFAULT)
);
public DayMicrosecondSub(Expression arg0, Expression arg1) {
@@ -86,6 +86,9 @@ public class DayMicrosecondSub extends ScalarFunction
if (signature.returnType instanceof TimeStampNsType) {
return signature;
}
+ if (signature.argumentsTypes.get(0) instanceof TimeStampTzType) {
+ return signature.withArgumentType(0,
TimeStampTzType.MAX).withReturnType(TimeStampTzType.MAX);
+ }
return signature.withArgumentType(0,
DateTimeV2Type.MAX).withReturnType(DateTimeV2Type.MAX);
}
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/HourMicrosecondAdd.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/HourMicrosecondAdd.java
index 5bd21fa05d7..fc39c14ad1b 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/HourMicrosecondAdd.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/HourMicrosecondAdd.java
@@ -42,12 +42,12 @@ public class HourMicrosecondAdd extends ScalarFunction
implements BinaryExpression, ExplicitlyCastableSignature,
ComputeSignatureForDateArithmetic, PropagateNullable,
DateAddSubMonotonic {
public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
- FunctionSignature.ret(DateTimeV2Type.MAX)
- .args(DateTimeV2Type.MAX, VarcharType.SYSTEM_DEFAULT),
+ FunctionSignature.ret(DateTimeV2Type.WILDCARD)
+ .args(DateTimeV2Type.WILDCARD, VarcharType.SYSTEM_DEFAULT),
FunctionSignature.ret(TimeStampNsType.INSTANCE)
.args(TimeStampNsType.INSTANCE,
VarcharType.SYSTEM_DEFAULT),
- FunctionSignature.ret(TimeStampTzType.MAX)
- .args(TimeStampTzType.MAX, VarcharType.SYSTEM_DEFAULT)
+ FunctionSignature.ret(TimeStampTzType.WILDCARD)
+ .args(TimeStampTzType.WILDCARD, VarcharType.SYSTEM_DEFAULT)
);
public HourMicrosecondAdd(Expression arg0, Expression arg1) {
@@ -86,6 +86,9 @@ public class HourMicrosecondAdd extends ScalarFunction
if (signature.returnType instanceof TimeStampNsType) {
return signature;
}
+ if (signature.argumentsTypes.get(0) instanceof TimeStampTzType) {
+ return signature.withArgumentType(0,
TimeStampTzType.MAX).withReturnType(TimeStampTzType.MAX);
+ }
return signature.withArgumentType(0,
DateTimeV2Type.MAX).withReturnType(DateTimeV2Type.MAX);
}
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/HourMicrosecondSub.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/HourMicrosecondSub.java
index 156e6a77aec..4d10e741b15 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/HourMicrosecondSub.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/HourMicrosecondSub.java
@@ -42,12 +42,12 @@ public class HourMicrosecondSub extends ScalarFunction
implements BinaryExpression, ExplicitlyCastableSignature,
ComputeSignatureForDateArithmetic, PropagateNullable,
DateAddSubMonotonic {
public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
- FunctionSignature.ret(DateTimeV2Type.MAX)
- .args(DateTimeV2Type.MAX, VarcharType.SYSTEM_DEFAULT),
+ FunctionSignature.ret(DateTimeV2Type.WILDCARD)
+ .args(DateTimeV2Type.WILDCARD, VarcharType.SYSTEM_DEFAULT),
FunctionSignature.ret(TimeStampNsType.INSTANCE)
.args(TimeStampNsType.INSTANCE,
VarcharType.SYSTEM_DEFAULT),
- FunctionSignature.ret(TimeStampTzType.MAX)
- .args(TimeStampTzType.MAX, VarcharType.SYSTEM_DEFAULT)
+ FunctionSignature.ret(TimeStampTzType.WILDCARD)
+ .args(TimeStampTzType.WILDCARD, VarcharType.SYSTEM_DEFAULT)
);
public HourMicrosecondSub(Expression arg0, Expression arg1) {
@@ -86,6 +86,9 @@ public class HourMicrosecondSub extends ScalarFunction
if (signature.returnType instanceof TimeStampNsType) {
return signature;
}
+ if (signature.argumentsTypes.get(0) instanceof TimeStampTzType) {
+ return signature.withArgumentType(0,
TimeStampTzType.MAX).withReturnType(TimeStampTzType.MAX);
+ }
return signature.withArgumentType(0,
DateTimeV2Type.MAX).withReturnType(DateTimeV2Type.MAX);
}
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MicroSecondsAdd.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MicroSecondsAdd.java
index 2c69152e9ad..5cb53229853 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MicroSecondsAdd.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MicroSecondsAdd.java
@@ -41,9 +41,9 @@ public class MicroSecondsAdd extends ScalarFunction
implements BinaryExpression,
PropagateNullable, DateAddSubMonotonic {
private static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
- FunctionSignature.ret(DateTimeV2Type.MAX).args(DateTimeV2Type.MAX,
BigIntType.INSTANCE),
+
FunctionSignature.ret(DateTimeV2Type.WILDCARD).args(DateTimeV2Type.WILDCARD,
BigIntType.INSTANCE),
FunctionSignature.ret(TimeStampNsType.INSTANCE).args(TimeStampNsType.INSTANCE,
BigIntType.INSTANCE),
-
FunctionSignature.ret(TimeStampTzType.MAX).args(TimeStampTzType.MAX,
BigIntType.INSTANCE)
+
FunctionSignature.ret(TimeStampTzType.WILDCARD).args(TimeStampTzType.WILDCARD,
BigIntType.INSTANCE)
);
public MicroSecondsAdd(Expression arg0, Expression arg1) {
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MicroSecondsSub.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MicroSecondsSub.java
index b618d06c270..1d3bba51f56 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MicroSecondsSub.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MicroSecondsSub.java
@@ -41,9 +41,9 @@ public class MicroSecondsSub extends ScalarFunction
implements BinaryExpression,
PropagateNullable, DateAddSubMonotonic {
private static final List<FunctionSignature> SIGNATURES = ImmutableList
-
.of(FunctionSignature.ret(DateTimeV2Type.MAX).args(DateTimeV2Type.MAX,
BigIntType.INSTANCE),
+
.of(FunctionSignature.ret(DateTimeV2Type.WILDCARD).args(DateTimeV2Type.WILDCARD,
BigIntType.INSTANCE),
FunctionSignature.ret(TimeStampNsType.INSTANCE).args(TimeStampNsType.INSTANCE,
BigIntType.INSTANCE),
-
FunctionSignature.ret(TimeStampTzType.MAX).args(TimeStampTzType.MAX,
BigIntType.INSTANCE)
+
FunctionSignature.ret(TimeStampTzType.WILDCARD).args(TimeStampTzType.WILDCARD,
BigIntType.INSTANCE)
);
public MicroSecondsSub(Expression arg0, Expression arg1) {
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MilliSecondsAdd.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MilliSecondsAdd.java
index 7b95fdc632e..4793192fae8 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MilliSecondsAdd.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MilliSecondsAdd.java
@@ -41,9 +41,9 @@ public class MilliSecondsAdd extends ScalarFunction
implements BinaryExpression,
PropagateNullable, DateAddSubMonotonic {
private static final List<FunctionSignature> SIGNATURES = ImmutableList
-
.of(FunctionSignature.ret(DateTimeV2Type.MAX).args(DateTimeV2Type.MAX,
BigIntType.INSTANCE),
+
.of(FunctionSignature.ret(DateTimeV2Type.WILDCARD).args(DateTimeV2Type.WILDCARD,
BigIntType.INSTANCE),
FunctionSignature.ret(TimeStampNsType.INSTANCE).args(TimeStampNsType.INSTANCE,
BigIntType.INSTANCE),
-
FunctionSignature.ret(TimeStampTzType.MAX).args(TimeStampTzType.MAX,
BigIntType.INSTANCE)
+
FunctionSignature.ret(TimeStampTzType.WILDCARD).args(TimeStampTzType.WILDCARD,
BigIntType.INSTANCE)
);
public MilliSecondsAdd(Expression arg0, Expression arg1) {
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MilliSecondsSub.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MilliSecondsSub.java
index 363d1f20df9..3180497ae23 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MilliSecondsSub.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MilliSecondsSub.java
@@ -41,9 +41,9 @@ public class MilliSecondsSub extends ScalarFunction
implements BinaryExpression,
PropagateNullable, DateAddSubMonotonic {
private static final List<FunctionSignature> SIGNATURES = ImmutableList
-
.of(FunctionSignature.ret(DateTimeV2Type.MAX).args(DateTimeV2Type.MAX,
BigIntType.INSTANCE),
+
.of(FunctionSignature.ret(DateTimeV2Type.WILDCARD).args(DateTimeV2Type.WILDCARD,
BigIntType.INSTANCE),
FunctionSignature.ret(TimeStampNsType.INSTANCE).args(TimeStampNsType.INSTANCE,
BigIntType.INSTANCE),
-
FunctionSignature.ret(TimeStampTzType.MAX).args(TimeStampTzType.MAX,
BigIntType.INSTANCE)
+
FunctionSignature.ret(TimeStampTzType.WILDCARD).args(TimeStampTzType.WILDCARD,
BigIntType.INSTANCE)
);
public MilliSecondsSub(Expression arg0, Expression arg1) {
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MinuteMicrosecondAdd.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MinuteMicrosecondAdd.java
index 96c8bb37d40..1bed67d7060 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MinuteMicrosecondAdd.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MinuteMicrosecondAdd.java
@@ -42,12 +42,12 @@ public class MinuteMicrosecondAdd extends ScalarFunction
implements BinaryExpression, ExplicitlyCastableSignature,
ComputeSignatureForDateArithmetic, PropagateNullable,
DateAddSubMonotonic {
public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
- FunctionSignature.ret(DateTimeV2Type.MAX)
- .args(DateTimeV2Type.MAX, VarcharType.SYSTEM_DEFAULT),
+ FunctionSignature.ret(DateTimeV2Type.WILDCARD)
+ .args(DateTimeV2Type.WILDCARD, VarcharType.SYSTEM_DEFAULT),
FunctionSignature.ret(TimeStampNsType.INSTANCE)
.args(TimeStampNsType.INSTANCE,
VarcharType.SYSTEM_DEFAULT),
- FunctionSignature.ret(TimeStampTzType.MAX)
- .args(TimeStampTzType.MAX, VarcharType.SYSTEM_DEFAULT)
+ FunctionSignature.ret(TimeStampTzType.WILDCARD)
+ .args(TimeStampTzType.WILDCARD, VarcharType.SYSTEM_DEFAULT)
);
public MinuteMicrosecondAdd(Expression arg0, Expression arg1) {
@@ -86,6 +86,9 @@ public class MinuteMicrosecondAdd extends ScalarFunction
if (signature.returnType instanceof TimeStampNsType) {
return signature;
}
+ if (signature.argumentsTypes.get(0) instanceof TimeStampTzType) {
+ return signature.withArgumentType(0,
TimeStampTzType.MAX).withReturnType(TimeStampTzType.MAX);
+ }
return signature.withArgumentType(0,
DateTimeV2Type.MAX).withReturnType(DateTimeV2Type.MAX);
}
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MinuteMicrosecondSub.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MinuteMicrosecondSub.java
index b9ebfdf8654..def1326640f 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MinuteMicrosecondSub.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MinuteMicrosecondSub.java
@@ -42,12 +42,12 @@ public class MinuteMicrosecondSub extends ScalarFunction
implements BinaryExpression, ExplicitlyCastableSignature,
ComputeSignatureForDateArithmetic, PropagateNullable,
DateAddSubMonotonic {
public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
- FunctionSignature.ret(DateTimeV2Type.MAX)
- .args(DateTimeV2Type.MAX, VarcharType.SYSTEM_DEFAULT),
+ FunctionSignature.ret(DateTimeV2Type.WILDCARD)
+ .args(DateTimeV2Type.WILDCARD, VarcharType.SYSTEM_DEFAULT),
FunctionSignature.ret(TimeStampNsType.INSTANCE)
.args(TimeStampNsType.INSTANCE,
VarcharType.SYSTEM_DEFAULT),
- FunctionSignature.ret(TimeStampTzType.MAX)
- .args(TimeStampTzType.MAX, VarcharType.SYSTEM_DEFAULT)
+ FunctionSignature.ret(TimeStampTzType.WILDCARD)
+ .args(TimeStampTzType.WILDCARD, VarcharType.SYSTEM_DEFAULT)
);
public MinuteMicrosecondSub(Expression arg0, Expression arg1) {
@@ -86,6 +86,9 @@ public class MinuteMicrosecondSub extends ScalarFunction
if (signature.returnType instanceof TimeStampNsType) {
return signature;
}
+ if (signature.argumentsTypes.get(0) instanceof TimeStampTzType) {
+ return signature.withArgumentType(0,
TimeStampTzType.MAX).withReturnType(TimeStampTzType.MAX);
+ }
return signature.withArgumentType(0,
DateTimeV2Type.MAX).withReturnType(DateTimeV2Type.MAX);
}
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/SecondMicrosecondAdd.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/SecondMicrosecondAdd.java
index 83e32fef0f6..c1e08a8802a 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/SecondMicrosecondAdd.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/SecondMicrosecondAdd.java
@@ -42,11 +42,11 @@ public class SecondMicrosecondAdd extends ScalarFunction
implements BinaryExpression, ExplicitlyCastableSignature,
ComputeSignatureForDateArithmetic, PropagateNullable,
DateAddSubMonotonic {
public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
- FunctionSignature.ret(DateTimeV2Type.MAX).args(DateTimeV2Type.MAX,
+
FunctionSignature.ret(DateTimeV2Type.WILDCARD).args(DateTimeV2Type.WILDCARD,
VarcharType.SYSTEM_DEFAULT),
FunctionSignature.ret(TimeStampNsType.INSTANCE).args(TimeStampNsType.INSTANCE,
VarcharType.SYSTEM_DEFAULT),
-
FunctionSignature.ret(TimeStampTzType.MAX).args(TimeStampTzType.MAX,
+
FunctionSignature.ret(TimeStampTzType.WILDCARD).args(TimeStampTzType.WILDCARD,
VarcharType.SYSTEM_DEFAULT)
);
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/SecondMicrosecondSub.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/SecondMicrosecondSub.java
index 303f4bdcad6..f04e00fca89 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/SecondMicrosecondSub.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/SecondMicrosecondSub.java
@@ -42,11 +42,11 @@ public class SecondMicrosecondSub extends ScalarFunction
implements BinaryExpression, ExplicitlyCastableSignature,
ComputeSignatureForDateArithmetic, PropagateNullable,
DateAddSubMonotonic {
public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
- FunctionSignature.ret(DateTimeV2Type.MAX).args(DateTimeV2Type.MAX,
+
FunctionSignature.ret(DateTimeV2Type.WILDCARD).args(DateTimeV2Type.WILDCARD,
VarcharType.SYSTEM_DEFAULT),
FunctionSignature.ret(TimeStampNsType.INSTANCE).args(TimeStampNsType.INSTANCE,
VarcharType.SYSTEM_DEFAULT),
-
FunctionSignature.ret(TimeStampTzType.MAX).args(TimeStampTzType.MAX,
+
FunctionSignature.ret(TimeStampTzType.WILDCARD).args(TimeStampTzType.WILDCARD,
VarcharType.SYSTEM_DEFAULT)
);
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/scalar/TimestampNsFunctionSignatureTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/scalar/TimestampNsFunctionSignatureTest.java
index 03ba59dd4e6..1ef6e4c1452 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/scalar/TimestampNsFunctionSignatureTest.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/functions/scalar/TimestampNsFunctionSignatureTest.java
@@ -285,6 +285,32 @@ class TimestampNsFunctionSignatureTest {
assertTimestampNsStringBinary(new SecondMicrosecondSub(timestampNs,
interval));
}
+ @Test
+ void testMicrosecondArithmeticPreservesTimestampTzAndPromotesPrecision() {
+ for (int scale = 0; scale <= TimeStampTzType.MAX_SCALE; scale++) {
+ Expression timestampTz = SlotReference.of(
+ "timestamp_tz_" + scale, TimeStampTzType.of(scale));
+ VarcharLiteral interval = new VarcharLiteral("1:02:03.123456");
+ for (ScalarFunction function : new ScalarFunction[] {
+ new DayMicrosecondAdd(timestampTz, interval),
+ new DayMicrosecondSub(timestampTz, interval),
+ new HourMicrosecondAdd(timestampTz, interval),
+ new HourMicrosecondSub(timestampTz, interval),
+ new MinuteMicrosecondAdd(timestampTz, interval),
+ new MinuteMicrosecondSub(timestampTz, interval),
+ new SecondMicrosecondAdd(timestampTz, interval),
+ new SecondMicrosecondSub(timestampTz, interval),
+ new MicroSecondsAdd(timestampTz, new BigIntLiteral(1)),
+ new MicroSecondsSub(timestampTz, new BigIntLiteral(1)),
+ new MilliSecondsAdd(timestampTz, new BigIntLiteral(1)),
+ new MilliSecondsSub(timestampTz, new BigIntLiteral(1))}) {
+ assertSignature(function, TimeStampTzType.MAX,
+ TimeStampTzType.MAX, function.child(1) instanceof
VarcharLiteral
+ ? VarcharType.SYSTEM_DEFAULT :
BigIntType.INSTANCE);
+ }
+ }
+ }
+
@Test
void testNanosecondFunctionsAreRegistered() {
String timestamp = "cast('1970-01-01 00:00:00.000000001' as
timestamp_ns)";
diff --git
a/regression-test/data/datatype_p0/timestamptz/test_timestamptz_microsecond_interval.out
b/regression-test/data/datatype_p0/timestamptz/test_timestamptz_microsecond_interval.out
new file mode 100644
index 00000000000..0e392aba05c
--- /dev/null
+++
b/regression-test/data/datatype_p0/timestamptz/test_timestamptz_microsecond_interval.out
@@ -0,0 +1,43 @@
+-- This file is automatically generated. You should know what you did if you
want to edit this
+-- !result_types --
+day_microsecond_add_p0 timestamp(6)
+day_microsecond_add_p3 timestamp(6)
+day_microsecond_add_p6 timestamp(6)
+day_microsecond_sub_p0 timestamp(6)
+day_microsecond_sub_p3 timestamp(6)
+day_microsecond_sub_p6 timestamp(6)
+hour_microsecond_add_p0 timestamp(6)
+hour_microsecond_add_p3 timestamp(6)
+hour_microsecond_add_p6 timestamp(6)
+hour_microsecond_sub_p0 timestamp(6)
+hour_microsecond_sub_p3 timestamp(6)
+hour_microsecond_sub_p6 timestamp(6)
+id int(11)
+microseconds_add_p0 timestamp(6)
+microseconds_add_p3 timestamp(6)
+microseconds_add_p6 timestamp(6)
+microseconds_sub_p0 timestamp(6)
+microseconds_sub_p3 timestamp(6)
+microseconds_sub_p6 timestamp(6)
+milliseconds_add_p0 timestamp(6)
+milliseconds_add_p3 timestamp(6)
+milliseconds_add_p6 timestamp(6)
+milliseconds_sub_p0 timestamp(6)
+milliseconds_sub_p3 timestamp(6)
+milliseconds_sub_p6 timestamp(6)
+minute_microsecond_add_p0 timestamp(6)
+minute_microsecond_add_p3 timestamp(6)
+minute_microsecond_add_p6 timestamp(6)
+minute_microsecond_sub_p0 timestamp(6)
+minute_microsecond_sub_p3 timestamp(6)
+minute_microsecond_sub_p6 timestamp(6)
+second_microsecond_add_p0 timestamp(6)
+second_microsecond_add_p3 timestamp(6)
+second_microsecond_add_p6 timestamp(6)
+second_microsecond_sub_p0 timestamp(6)
+second_microsecond_sub_p3 timestamp(6)
+second_microsecond_sub_p6 timestamp(6)
+
+-- !results --
+1 2024-01-03 05:07:09.123456+08:00 2024-01-01
01:01:00.876544+08:00 2024-01-02 05:07:09.123456+08:00 2024-01-02
01:01:00.876544+08:00 2024-01-02 03:07:09.123456+08:00 2024-01-02
03:01:00.876544+08:00 2024-01-02 03:04:09.123456+08:00 2024-01-02
03:04:00.876544+08:00 2024-01-02 03:04:05.000001+08:00 2024-01-02
03:04:04.999999+08:00 2024-01-02 03:04:05.001000+08:00 2024-01-02
03:04:04.999000+08:00 2024-01-03 05:07:09.246456+08:00 2024-01-01
01:01:00.999544+08:00 2024-01-02 05:07:09.246456+0 [...]
+
diff --git
a/regression-test/data/query_p0/sql_functions/datetime_functions/test_add_sub_union_type.out
b/regression-test/data/query_p0/sql_functions/datetime_functions/test_add_sub_union_type.out
index 1236449bdfc..b3791ba116c 100644
---
a/regression-test/data/query_p0/sql_functions/datetime_functions/test_add_sub_union_type.out
+++
b/regression-test/data/query_p0/sql_functions/datetime_functions/test_add_sub_union_type.out
@@ -331,13 +331,13 @@
2024-07-31T10:20:30.123456
-- !day_microsecond_add_11 --
-2024-08-31T11:20:30.123456
+2024-08-31 11:20:30.123456+08:00
-- !day_microsecond_add_12 --
-2024-09-30T19:20:30.123456
+2024-09-30 19:20:30.123456+08:00
-- !day_microsecond_add_13 --
-2024-11-01T00:50:30.123456
+2024-11-01 00:50:30.123456+08:00
-- !day_microsecond_sub_1 --
2023-01-01T01:01:00.555566
@@ -352,13 +352,13 @@
2017-02-27T13:39:29.876544
-- !day_microsecond_sub_5 --
-2017-03-30T14:39:29.876544
+2017-03-30 14:39:29.876544+08:00
-- !day_microsecond_sub_6 --
-2017-04-29T22:39:29.876544
+2017-04-29 22:39:29.876544+08:00
-- !day_microsecond_sub_7 --
-2017-05-31T04:09:29.876544
+2017-05-31 04:09:29.876544+08:00
-- !day_microsecond_extract_1 --
02 03:04:05.123456
@@ -550,13 +550,13 @@
2013-12-31T10:20:30.123456
-- !hour_microsecond_add_10 --
-2013-11-30T11:20:30.123456
+2013-11-30 11:20:30.123456+08:00
-- !hour_microsecond_add_11 --
-2013-10-31T19:20:30.123456
+2013-10-31 19:20:30.123456+08:00
-- !hour_microsecond_add_12 --
-2013-10-01T00:50:30.123456
+2013-10-01 00:50:30.123456+08:00
-- !hour_microsecond_sub_1 --
2023-01-02T00:33:25
@@ -571,13 +571,13 @@
2011-12-30T13:39:29.876544
-- !hour_microsecond_sub_5 --
-2011-11-29T14:39:29.876544
+2011-11-29 14:39:29.876544+08:00
-- !hour_microsecond_sub_6 --
-2011-10-30T22:39:29.876544
+2011-10-30 22:39:29.876544+08:00
-- !hour_microsecond_sub_7 --
-2011-09-30T04:09:29.876544
+2011-09-30 04:09:29.876544+08:00
-- !hour_microsecond_extract_1 --
03:04:05.123456
@@ -699,13 +699,13 @@
2007-12-30T00:10:20.123456
-- !minute_microsecond_add_11 --
-2007-11-30T01:10:20.123456
+2007-11-30 01:10:20.123456+08:00
-- !minute_microsecond_add_12 --
-2007-10-31T09:10:20.123456
+2007-10-31 09:10:20.123456+08:00
-- !minute_microsecond_add_13 --
-2007-09-30T14:40:20.123456
+2007-09-30 14:40:20.123456+08:00
-- !minute_microsecond_sub_1 --
2023-01-02T02:18:15
@@ -720,13 +720,13 @@
2005-12-30T23:49:39.876544
-- !minute_microsecond_sub_5 --
-2005-11-30T00:49:39.876544
+2005-11-30 00:49:39.876544+08:00
-- !minute_microsecond_sub_6 --
-2005-10-31T08:49:39.876544
+2005-10-31 08:49:39.876544+08:00
-- !minute_microsecond_sub_7 --
-2005-09-30T14:19:39.876544
+2005-09-30 14:19:39.876544+08:00
-- !minute_microsecond_extract_1 --
04:05.123456
diff --git
a/regression-test/suites/datatype_p0/timestamptz/test_timestamptz_microsecond_interval.groovy
b/regression-test/suites/datatype_p0/timestamptz/test_timestamptz_microsecond_interval.groovy
new file mode 100644
index 00000000000..c884005b678
--- /dev/null
+++
b/regression-test/suites/datatype_p0/timestamptz/test_timestamptz_microsecond_interval.groovy
@@ -0,0 +1,79 @@
+// 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.
+
+suite("test_timestamptz_microsecond_interval") {
+ sql "set time_zone = '+08:00'"
+
+ sql "DROP TABLE IF EXISTS test_timestamptz_microsecond_interval_result"
+ sql "DROP TABLE IF EXISTS test_timestamptz_microsecond_interval_input"
+
+ sql """
+ CREATE TABLE test_timestamptz_microsecond_interval_input (
+ id INT,
+ tz0 TIMESTAMPTZ(0),
+ tz3 TIMESTAMPTZ(3),
+ tz6 TIMESTAMPTZ(6)
+ ) DUPLICATE KEY(id)
+ DISTRIBUTED BY HASH(id) BUCKETS 1
+ PROPERTIES ('replication_num' = '1')
+ """
+ sql """
+ INSERT INTO test_timestamptz_microsecond_interval_input VALUES
+ (1,
+ CAST('2024-01-02 03:04:05.123456+08:00' AS TIMESTAMPTZ(0)),
+ CAST('2024-01-02 03:04:05.123456+08:00' AS TIMESTAMPTZ(3)),
+ CAST('2024-01-02 03:04:05.123456+08:00' AS TIMESTAMPTZ(6)))
+ """
+
+ def operations = [
+ [name: 'day_microsecond', unit: 'DAY_MICROSECOND', interval: "'1
02:03:04.123456'"],
+ [name: 'hour_microsecond', unit: 'HOUR_MICROSECOND', interval:
"'02:03:04.123456'"],
+ [name: 'minute_microsecond', unit: 'MINUTE_MICROSECOND', interval:
"'03:04.123456'"],
+ [name: 'second_microsecond', unit: 'SECOND_MICROSECOND', interval:
"'04.123456'"],
+ [name: 'microseconds', function: 'microseconds', interval: '1'],
+ [name: 'milliseconds', function: 'milliseconds', interval: '1']
+ ]
+ def projections = []
+ for (int scale : [0, 3, 6]) {
+ for (def operation : operations) {
+ for (String op : ['add', 'sub']) {
+ def expression = operation.function
+ ? "${operation.function}_${op}(tz${scale},
${operation.interval})"
+ : "date_${op}(tz${scale}, INTERVAL
${operation.interval} ${operation.unit})"
+ projections.add("${expression} AS
${operation.name}_${op}_p${scale}")
+ }
+ }
+ }
+ sql """
+ CREATE TABLE test_timestamptz_microsecond_interval_result
+ PROPERTIES ('replication_num' = '1') AS
+ SELECT id, ${projections.join(',\n')}
+ FROM test_timestamptz_microsecond_interval_input
+ """
+
+ order_qt_result_types """
+ SELECT column_name, column_type
+ FROM information_schema.columns
+ WHERE table_schema = DATABASE()
+ AND table_name = 'test_timestamptz_microsecond_interval_result'
+ ORDER BY ordinal_position
+ """
+
+ order_qt_results """
+ SELECT * FROM test_timestamptz_microsecond_interval_result ORDER BY id
+ """
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]