[fix](function) MicroSecondsSub without scale (#38945) (#39194)

## Proposed changes
https://github.com/apache/doris/pull/38945
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.-->

## Proposed changes

Issue Number: close #xxx

<!--Describe your changes.-->
This commit is contained in:
Mryange
2024-08-12 10:01:28 +08:00
committed by GitHub
parent b38caed808
commit ebf5d70c9d
9 changed files with 125 additions and 17 deletions

View File

@ -218,6 +218,30 @@ public class DateTimeArithmetic {
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.
*/

View File

@ -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);
@ -57,6 +56,12 @@ public class MicroSecondsAdd extends ScalarFunction
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);

View File

@ -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);
@ -57,6 +56,12 @@ public class MicroSecondsSub extends ScalarFunction
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);

View File

@ -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);
@ -57,6 +56,12 @@ public class MilliSecondsAdd extends ScalarFunction
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);

View File

@ -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);
@ -57,6 +56,12 @@ public class MilliSecondsSub extends ScalarFunction
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);

View File

@ -215,8 +215,14 @@ public class DateTimeV2Literal extends DateTimeLiteral {
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);
}
/**