Skip to content

Commit 2f05c3a

Browse files
Mryangewyxxxcat
authored andcommitted
[fix](function) MicroSecondsSub without scale (apache#38945)
## Proposed changes Added the computeSignature function for millisecond/microsecond calculation functions to generate parameters and return values with the appropriate precision. Modified the microSecondsAdd function, which was used for constant folding, because constant folding uses the precision of the parameters for calculation. However, for millisecond/microsecond calculations, it is necessary to set the precision to the maximum to ensure correct display. before ``` mysql> SELECT MICROSECONDS_SUB('2010-11-30 23:50:50', 2); +-------------------------------------------------------------------+ | microseconds_sub(cast('2010-11-30 23:50:50' as DATETIMEV2(0)), 2) | +-------------------------------------------------------------------+ | 2010-11-30 23:50:49 | +-------------------------------------------------------------------+ ``` now ``` mysql> SELECT MICROSECONDS_SUB('2010-11-30 23:50:50', 2); +-------------------------------------------------------------------+ | microseconds_sub(cast('2010-11-30 23:50:50' as DATETIMEV2(0)), 2) | +-------------------------------------------------------------------+ | 2010-11-30 23:50:49.999998 | +-------------------------------------------------------------------+ ``` <!--Describe your changes.-->
1 parent 716eb7a commit 2f05c3a

File tree

9 files changed

+125
-17
lines changed

9 files changed

+125
-17
lines changed

fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeArithmetic.java

+24
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,30 @@ public static Expression microSecondsAdd(DateTimeV2Literal date, IntegerLiteral
218218
return date.plusMicroSeconds(microSecond.getValue());
219219
}
220220

221+
/**
222+
* datetime arithmetic function microseconds_sub.
223+
*/
224+
@ExecFunction(name = "microseconds_sub", argTypes = { "DATETIMEV2", "INT" }, returnType = "DATETIMEV2")
225+
public static Expression microSecondsSub(DateTimeV2Literal date, IntegerLiteral microSecond) {
226+
return date.plusMicroSeconds(-microSecond.getValue());
227+
}
228+
229+
/**
230+
* datetime arithmetic function milliseconds_add.
231+
*/
232+
@ExecFunction(name = "milliseconds_add", argTypes = { "DATETIMEV2", "INT" }, returnType = "DATETIMEV2")
233+
public static Expression milliSecondsAdd(DateTimeV2Literal date, IntegerLiteral milliSecond) {
234+
return date.plusMilliSeconds(milliSecond.getValue());
235+
}
236+
237+
/**
238+
* datetime arithmetic function milliseconds_sub.
239+
*/
240+
@ExecFunction(name = "milliseconds_sub", argTypes = { "DATETIMEV2", "INT" }, returnType = "DATETIMEV2")
241+
public static Expression milliSecondsSub(DateTimeV2Literal date, IntegerLiteral milliSecond) {
242+
return date.plusMilliSeconds(-milliSecond.getValue());
243+
}
244+
221245
/**
222246
* datetime arithmetic function years-sub.
223247
*/

fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MicroSecondsAdd.java

+8-3
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,8 @@ public class MicroSecondsAdd extends ScalarFunction
3838
implements BinaryExpression, ExplicitlyCastableSignature, PropagateNullableOnDateLikeV2Args {
3939

4040
private static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
41-
FunctionSignature.ret(DateTimeV2Type.SYSTEM_DEFAULT)
42-
.args(DateTimeV2Type.SYSTEM_DEFAULT, IntegerType.INSTANCE)
43-
);
41+
FunctionSignature.ret(DateTimeV2Type.MAX)
42+
.args(DateTimeV2Type.MAX, IntegerType.INSTANCE));
4443

4544
public MicroSecondsAdd(Expression arg0, Expression arg1) {
4645
super("microseconds_add", arg0, arg1);
@@ -57,6 +56,12 @@ public List<FunctionSignature> getSignatures() {
5756
return SIGNATURES;
5857
}
5958

59+
@Override
60+
public FunctionSignature computeSignature(FunctionSignature signature) {
61+
signature = super.computeSignature(signature);
62+
return signature.withArgumentType(0, DateTimeV2Type.MAX).withReturnType(DateTimeV2Type.MAX);
63+
}
64+
6065
@Override
6166
public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
6267
return visitor.visitMicroSecondsAdd(this, context);

fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MicroSecondsSub.java

+8-3
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,8 @@ public class MicroSecondsSub extends ScalarFunction
3838
implements BinaryExpression, ExplicitlyCastableSignature, PropagateNullableOnDateLikeV2Args {
3939

4040
private static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
41-
FunctionSignature.ret(DateTimeV2Type.SYSTEM_DEFAULT)
42-
.args(DateTimeV2Type.SYSTEM_DEFAULT, IntegerType.INSTANCE)
43-
);
41+
FunctionSignature.ret(DateTimeV2Type.MAX)
42+
.args(DateTimeV2Type.MAX, IntegerType.INSTANCE));
4443

4544
public MicroSecondsSub(Expression arg0, Expression arg1) {
4645
super("microseconds_sub", arg0, arg1);
@@ -57,6 +56,12 @@ public List<FunctionSignature> getSignatures() {
5756
return SIGNATURES;
5857
}
5958

59+
@Override
60+
public FunctionSignature computeSignature(FunctionSignature signature) {
61+
signature = super.computeSignature(signature);
62+
return signature.withArgumentType(0, DateTimeV2Type.MAX).withReturnType(DateTimeV2Type.MAX);
63+
}
64+
6065
@Override
6166
public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
6267
return visitor.visitMicroSecondsSub(this, context);

fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MilliSecondsAdd.java

+8-3
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,8 @@ public class MilliSecondsAdd extends ScalarFunction
3838
implements BinaryExpression, ExplicitlyCastableSignature, PropagateNullableOnDateLikeV2Args {
3939

4040
private static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
41-
FunctionSignature.ret(DateTimeV2Type.SYSTEM_DEFAULT)
42-
.args(DateTimeV2Type.SYSTEM_DEFAULT, IntegerType.INSTANCE)
43-
);
41+
FunctionSignature.ret(DateTimeV2Type.MAX)
42+
.args(DateTimeV2Type.MAX, IntegerType.INSTANCE));
4443

4544
public MilliSecondsAdd(Expression arg0, Expression arg1) {
4645
super("milliseconds_add", arg0, arg1);
@@ -57,6 +56,12 @@ public List<FunctionSignature> getSignatures() {
5756
return SIGNATURES;
5857
}
5958

59+
@Override
60+
public FunctionSignature computeSignature(FunctionSignature signature) {
61+
signature = super.computeSignature(signature);
62+
return signature.withArgumentType(0, DateTimeV2Type.MAX).withReturnType(DateTimeV2Type.MAX);
63+
}
64+
6065
@Override
6166
public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
6267
return visitor.visitMilliSecondsAdd(this, context);

fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/MilliSecondsSub.java

+8-3
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,8 @@ public class MilliSecondsSub extends ScalarFunction
3838
implements BinaryExpression, ExplicitlyCastableSignature, PropagateNullableOnDateLikeV2Args {
3939

4040
private static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
41-
FunctionSignature.ret(DateTimeV2Type.SYSTEM_DEFAULT)
42-
.args(DateTimeV2Type.SYSTEM_DEFAULT, IntegerType.INSTANCE)
43-
);
41+
FunctionSignature.ret(DateTimeV2Type.MAX)
42+
.args(DateTimeV2Type.MAX, IntegerType.INSTANCE));
4443

4544
public MilliSecondsSub(Expression arg0, Expression arg1) {
4645
super("milliseconds_sub", arg0, arg1);
@@ -57,6 +56,12 @@ public List<FunctionSignature> getSignatures() {
5756
return SIGNATURES;
5857
}
5958

59+
@Override
60+
public FunctionSignature computeSignature(FunctionSignature signature) {
61+
signature = super.computeSignature(signature);
62+
return signature.withArgumentType(0, DateTimeV2Type.MAX).withReturnType(DateTimeV2Type.MAX);
63+
}
64+
6065
@Override
6166
public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
6267
return visitor.visitMilliSecondsSub(this, context);

fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DateTimeV2Literal.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,14 @@ public Expression plusSeconds(long seconds) {
215215
return fromJavaDateType(toJavaDateType().plusSeconds(seconds), getDataType().getScale());
216216
}
217217

218+
// When performing addition or subtraction with MicroSeconds, the precision must
219+
// be set to 6 to display it completely.
218220
public Expression plusMicroSeconds(long microSeconds) {
219-
return fromJavaDateType(toJavaDateType().plusNanos(microSeconds * 1000L), getDataType().getScale());
221+
return fromJavaDateType(toJavaDateType().plusNanos(microSeconds * 1000L), 6);
222+
}
223+
224+
public Expression plusMilliSeconds(long microSeconds) {
225+
return plusMicroSeconds(microSeconds * 1000L);
220226
}
221227

222228
/**

fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/FoldConstantTest.java

+15-4
Original file line numberDiff line numberDiff line change
@@ -549,12 +549,17 @@ void testDateTimeV2TypeDateTimeArithmeticFunctions() {
549549
VarcharLiteral format = new VarcharLiteral("%Y-%m-%d");
550550

551551
String[] answer = {
552-
"'2000-01-30 23:59:59'", "'1999-12-01 23:59:59'", "'2029-12-31 23:59:59'", "'1969-12-31 23:59:59'",
553-
"'2002-06-30 23:59:59'", "'1997-06-30 23:59:59'", "'2000-01-30 23:59:59'", "'1999-12-01 23:59:59'",
552+
"'2000-01-30 23:59:59'", "'1999-12-01 23:59:59'", "'2029-12-31 23:59:59'",
553+
"'1969-12-31 23:59:59'",
554+
"'2002-06-30 23:59:59'", "'1997-06-30 23:59:59'", "'2000-01-30 23:59:59'",
555+
"'1999-12-01 23:59:59'",
554556
"'2000-01-02 05:59:59'", "'1999-12-30 17:59:59'", "'2000-01-01 00:29:59'",
555-
"'1999-12-31 23:29:59'", "'2000-01-01 00:00:29'", "'1999-12-31 23:59:29'", "'1999-12-31 23:59:59'",
557+
"'1999-12-31 23:29:59'", "'2000-01-01 00:00:29'", "'1999-12-31 23:59:29'",
558+
"'1999-12-31 23:59:59.000030'", "'1999-12-31 23:59:58.999970'", "'1999-12-31 23:59:59.030000'",
559+
"'1999-12-31 23:59:58.970000'",
556560
"1999", "4", "12", "6", "31", "365", "31", "23", "59", "59",
557-
"'1999-12-31'", "'1999-12-27'", "'1999-12-31'", "'1999-12-31'", "730484", "'1999-12-31'", "'1999-12-31'"
561+
"'1999-12-31'", "'1999-12-27'", "'1999-12-31'", "'1999-12-31'", "730484", "'1999-12-31'",
562+
"'1999-12-31'"
558563
};
559564
int answerIdx = 0;
560565

@@ -578,6 +583,12 @@ void testDateTimeV2TypeDateTimeArithmeticFunctions() {
578583
answer[answerIdx++]);
579584
Assertions.assertEquals(DateTimeArithmetic.microSecondsAdd(dateLiteral, integerLiteral).toSql(),
580585
answer[answerIdx++]);
586+
Assertions.assertEquals(DateTimeArithmetic.microSecondsSub(dateLiteral, integerLiteral).toSql(),
587+
answer[answerIdx++]);
588+
Assertions.assertEquals(DateTimeArithmetic.milliSecondsAdd(dateLiteral, integerLiteral).toSql(),
589+
answer[answerIdx++]);
590+
Assertions.assertEquals(DateTimeArithmetic.milliSecondsSub(dateLiteral, integerLiteral).toSql(),
591+
answer[answerIdx++]);
581592

582593
Assertions.assertEquals(DateTimeExtractAndTransform.year(dateLiteral).toSql(), answer[answerIdx++]);
583594
Assertions.assertEquals(DateTimeExtractAndTransform.quarter(dateLiteral).toSql(), answer[answerIdx++]);

regression-test/data/correctness/test_from_millisecond_microsecond.out

+16
Original file line numberDiff line numberDiff line change
@@ -159,3 +159,19 @@
159159
-- !sql --
160160
\N
161161

162+
-- !sql_all_constent --
163+
2010-11-30T23:50:50.000002 2010-11-30T23:50:49.999998 2010-11-30T23:50:50.002 2010-11-30T23:50:49.998
164+
165+
-- !sql_all_constent --
166+
2010-11-30T23:50:50.000002 2010-11-30T23:50:49.999998 2010-11-30T23:50:50.002 2010-11-30T23:50:49.998
167+
168+
-- !select_null_datetime --
169+
1 2023-01-01T00:00:00.000002 2022-12-31T23:59:59.999998 2023-01-01T00:00:00.002 2022-12-31T23:59:59.998
170+
2 2023-01-01T00:00:00.123002 2023-01-01T00:00:00.122998 2023-01-01T00:00:00.125 2023-01-01T00:00:00.121
171+
3 2023-01-01T00:00:00.123458 2023-01-01T00:00:00.123454 2023-01-01T00:00:00.125456 2023-01-01T00:00:00.121456
172+
173+
-- !select_null_datetime --
174+
1 2023-01-01T00:00:00.000002 2022-12-31T23:59:59.999998 2023-01-01T00:00:00.002 2022-12-31T23:59:59.998
175+
2 2023-01-01T00:00:00.123002 2023-01-01T00:00:00.122998 2023-01-01T00:00:00.125 2023-01-01T00:00:00.121
176+
3 2023-01-01T00:00:00.123458 2023-01-01T00:00:00.123454 2023-01-01T00:00:00.125456 2023-01-01T00:00:00.121456
177+

regression-test/suites/correctness/test_from_millisecond_microsecond.groovy

+31
Original file line numberDiff line numberDiff line change
@@ -316,4 +316,35 @@ suite("test_from_millisecond_microsecond") {
316316
qt_sql " select from_second(-1) "
317317
qt_sql " select from_microsecond(253402271999999999) "
318318
qt_sql " select from_microsecond(253402272000000000) "
319+
320+
321+
qt_sql_all_constent """
322+
select microseconds_add('2010-11-30 23:50:50', 2) , microseconds_sub('2010-11-30 23:50:50', 2) , milliseconds_add('2010-11-30 23:50:50', 2) , milliseconds_sub('2010-11-30 23:50:50', 2);
323+
"""
324+
325+
qt_sql_all_constent """
326+
select microseconds_add(cast('2010-11-30 23:50:50' as DATETIME(3)), 2) , microseconds_sub(cast('2010-11-30 23:50:50' as DATETIME(3)), 2) , milliseconds_add(cast('2010-11-30 23:50:50' as DATETIME(3)), 2) , milliseconds_sub(cast('2010-11-30 23:50:50' as DATETIME(3)), 2);
327+
"""
328+
329+
qt_select_null_datetime """
330+
select
331+
id,
332+
microseconds_add(t,2),
333+
microseconds_sub(t,2),
334+
milliseconds_add(t,2),
335+
milliseconds_sub(t,2)
336+
from millimicro
337+
order by id;
338+
"""
339+
340+
qt_select_null_datetime """
341+
select
342+
id,
343+
microseconds_add(cast(t as DATETIME(3)),2),
344+
microseconds_sub(cast(t as DATETIME(3)),2),
345+
milliseconds_add(cast(t as DATETIME(3)),2),
346+
milliseconds_sub(cast(t as DATETIME(3)),2)
347+
from millimicro
348+
order by id;
349+
"""
319350
}

0 commit comments

Comments
 (0)