Skip to content

Commit

Permalink
[fix](function) MicroSecondsSub without scale (apache#38945)
Browse files Browse the repository at this point in the history
## 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.-->
  • Loading branch information
Mryange authored and wyxxxcat committed Aug 14, 2024
1 parent 716eb7a commit 2f05c3a
Show file tree
Hide file tree
Showing 9 changed files with 125 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,30 @@ public static Expression microSecondsAdd(DateTimeV2Literal date, IntegerLiteral
return date.plusMicroSeconds(microSecond.getValue());
}

/**
* datetime arithmetic function microseconds_sub.
*/
@ExecFunction(name = "microseconds_sub", argTypes = { "DATETIMEV2", "INT" }, returnType = "DATETIMEV2")
public static Expression microSecondsSub(DateTimeV2Literal date, IntegerLiteral microSecond) {
return date.plusMicroSeconds(-microSecond.getValue());
}

/**
* datetime arithmetic function milliseconds_add.
*/
@ExecFunction(name = "milliseconds_add", argTypes = { "DATETIMEV2", "INT" }, returnType = "DATETIMEV2")
public static Expression milliSecondsAdd(DateTimeV2Literal date, IntegerLiteral milliSecond) {
return date.plusMilliSeconds(milliSecond.getValue());
}

/**
* datetime arithmetic function milliseconds_sub.
*/
@ExecFunction(name = "milliseconds_sub", argTypes = { "DATETIMEV2", "INT" }, returnType = "DATETIMEV2")
public static Expression milliSecondsSub(DateTimeV2Literal date, IntegerLiteral milliSecond) {
return date.plusMilliSeconds(-milliSecond.getValue());
}

/**
* datetime arithmetic function years-sub.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,8 @@ public class MicroSecondsAdd extends ScalarFunction
implements BinaryExpression, ExplicitlyCastableSignature, PropagateNullableOnDateLikeV2Args {

private static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
FunctionSignature.ret(DateTimeV2Type.SYSTEM_DEFAULT)
.args(DateTimeV2Type.SYSTEM_DEFAULT, IntegerType.INSTANCE)
);
FunctionSignature.ret(DateTimeV2Type.MAX)
.args(DateTimeV2Type.MAX, IntegerType.INSTANCE));

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

@Override
public FunctionSignature computeSignature(FunctionSignature signature) {
signature = super.computeSignature(signature);
return signature.withArgumentType(0, DateTimeV2Type.MAX).withReturnType(DateTimeV2Type.MAX);
}

@Override
public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
return visitor.visitMicroSecondsAdd(this, context);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,8 @@ public class MicroSecondsSub extends ScalarFunction
implements BinaryExpression, ExplicitlyCastableSignature, PropagateNullableOnDateLikeV2Args {

private static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
FunctionSignature.ret(DateTimeV2Type.SYSTEM_DEFAULT)
.args(DateTimeV2Type.SYSTEM_DEFAULT, IntegerType.INSTANCE)
);
FunctionSignature.ret(DateTimeV2Type.MAX)
.args(DateTimeV2Type.MAX, IntegerType.INSTANCE));

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

@Override
public FunctionSignature computeSignature(FunctionSignature signature) {
signature = super.computeSignature(signature);
return signature.withArgumentType(0, DateTimeV2Type.MAX).withReturnType(DateTimeV2Type.MAX);
}

@Override
public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
return visitor.visitMicroSecondsSub(this, context);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,8 @@ public class MilliSecondsAdd extends ScalarFunction
implements BinaryExpression, ExplicitlyCastableSignature, PropagateNullableOnDateLikeV2Args {

private static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
FunctionSignature.ret(DateTimeV2Type.SYSTEM_DEFAULT)
.args(DateTimeV2Type.SYSTEM_DEFAULT, IntegerType.INSTANCE)
);
FunctionSignature.ret(DateTimeV2Type.MAX)
.args(DateTimeV2Type.MAX, IntegerType.INSTANCE));

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

@Override
public FunctionSignature computeSignature(FunctionSignature signature) {
signature = super.computeSignature(signature);
return signature.withArgumentType(0, DateTimeV2Type.MAX).withReturnType(DateTimeV2Type.MAX);
}

@Override
public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
return visitor.visitMilliSecondsAdd(this, context);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,8 @@ public class MilliSecondsSub extends ScalarFunction
implements BinaryExpression, ExplicitlyCastableSignature, PropagateNullableOnDateLikeV2Args {

private static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
FunctionSignature.ret(DateTimeV2Type.SYSTEM_DEFAULT)
.args(DateTimeV2Type.SYSTEM_DEFAULT, IntegerType.INSTANCE)
);
FunctionSignature.ret(DateTimeV2Type.MAX)
.args(DateTimeV2Type.MAX, IntegerType.INSTANCE));

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

@Override
public FunctionSignature computeSignature(FunctionSignature signature) {
signature = super.computeSignature(signature);
return signature.withArgumentType(0, DateTimeV2Type.MAX).withReturnType(DateTimeV2Type.MAX);
}

@Override
public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
return visitor.visitMilliSecondsSub(this, context);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,14 @@ public Expression plusSeconds(long seconds) {
return fromJavaDateType(toJavaDateType().plusSeconds(seconds), getDataType().getScale());
}

// When performing addition or subtraction with MicroSeconds, the precision must
// be set to 6 to display it completely.
public Expression plusMicroSeconds(long microSeconds) {
return fromJavaDateType(toJavaDateType().plusNanos(microSeconds * 1000L), getDataType().getScale());
return fromJavaDateType(toJavaDateType().plusNanos(microSeconds * 1000L), 6);
}

public Expression plusMilliSeconds(long microSeconds) {
return plusMicroSeconds(microSeconds * 1000L);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -549,12 +549,17 @@ void testDateTimeV2TypeDateTimeArithmeticFunctions() {
VarcharLiteral format = new VarcharLiteral("%Y-%m-%d");

String[] answer = {
"'2000-01-30 23:59:59'", "'1999-12-01 23:59:59'", "'2029-12-31 23:59:59'", "'1969-12-31 23:59:59'",
"'2002-06-30 23:59:59'", "'1997-06-30 23:59:59'", "'2000-01-30 23:59:59'", "'1999-12-01 23:59:59'",
"'2000-01-30 23:59:59'", "'1999-12-01 23:59:59'", "'2029-12-31 23:59:59'",
"'1969-12-31 23:59:59'",
"'2002-06-30 23:59:59'", "'1997-06-30 23:59:59'", "'2000-01-30 23:59:59'",
"'1999-12-01 23:59:59'",
"'2000-01-02 05:59:59'", "'1999-12-30 17:59:59'", "'2000-01-01 00:29:59'",
"'1999-12-31 23:29:59'", "'2000-01-01 00:00:29'", "'1999-12-31 23:59:29'", "'1999-12-31 23:59:59'",
"'1999-12-31 23:29:59'", "'2000-01-01 00:00:29'", "'1999-12-31 23:59:29'",
"'1999-12-31 23:59:59.000030'", "'1999-12-31 23:59:58.999970'", "'1999-12-31 23:59:59.030000'",
"'1999-12-31 23:59:58.970000'",
"1999", "4", "12", "6", "31", "365", "31", "23", "59", "59",
"'1999-12-31'", "'1999-12-27'", "'1999-12-31'", "'1999-12-31'", "730484", "'1999-12-31'", "'1999-12-31'"
"'1999-12-31'", "'1999-12-27'", "'1999-12-31'", "'1999-12-31'", "730484", "'1999-12-31'",
"'1999-12-31'"
};
int answerIdx = 0;

Expand All @@ -578,6 +583,12 @@ void testDateTimeV2TypeDateTimeArithmeticFunctions() {
answer[answerIdx++]);
Assertions.assertEquals(DateTimeArithmetic.microSecondsAdd(dateLiteral, integerLiteral).toSql(),
answer[answerIdx++]);
Assertions.assertEquals(DateTimeArithmetic.microSecondsSub(dateLiteral, integerLiteral).toSql(),
answer[answerIdx++]);
Assertions.assertEquals(DateTimeArithmetic.milliSecondsAdd(dateLiteral, integerLiteral).toSql(),
answer[answerIdx++]);
Assertions.assertEquals(DateTimeArithmetic.milliSecondsSub(dateLiteral, integerLiteral).toSql(),
answer[answerIdx++]);

Assertions.assertEquals(DateTimeExtractAndTransform.year(dateLiteral).toSql(), answer[answerIdx++]);
Assertions.assertEquals(DateTimeExtractAndTransform.quarter(dateLiteral).toSql(), answer[answerIdx++]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,3 +159,19 @@
-- !sql --
\N

-- !sql_all_constent --
2010-11-30T23:50:50.000002 2010-11-30T23:50:49.999998 2010-11-30T23:50:50.002 2010-11-30T23:50:49.998

-- !sql_all_constent --
2010-11-30T23:50:50.000002 2010-11-30T23:50:49.999998 2010-11-30T23:50:50.002 2010-11-30T23:50:49.998

-- !select_null_datetime --
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
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
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

-- !select_null_datetime --
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
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
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

Original file line number Diff line number Diff line change
Expand Up @@ -316,4 +316,35 @@ suite("test_from_millisecond_microsecond") {
qt_sql " select from_second(-1) "
qt_sql " select from_microsecond(253402271999999999) "
qt_sql " select from_microsecond(253402272000000000) "


qt_sql_all_constent """
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);
"""

qt_sql_all_constent """
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);
"""

qt_select_null_datetime """
select
id,
microseconds_add(t,2),
microseconds_sub(t,2),
milliseconds_add(t,2),
milliseconds_sub(t,2)
from millimicro
order by id;
"""

qt_select_null_datetime """
select
id,
microseconds_add(cast(t as DATETIME(3)),2),
microseconds_sub(cast(t as DATETIME(3)),2),
milliseconds_add(cast(t as DATETIME(3)),2),
milliseconds_sub(cast(t as DATETIME(3)),2)
from millimicro
order by id;
"""
}

0 comments on commit 2f05c3a

Please sign in to comment.