[feature](datetime) "timediff" supports calculating microseconds (#21371)

This commit is contained in:
Mryange
2023-07-10 19:21:32 +08:00
committed by GitHub
parent 202a5c636f
commit 8973610543
28 changed files with 518 additions and 21 deletions

View File

@ -2457,7 +2457,7 @@ public abstract class Expr extends TreeNode<Expr> implements ParseNode, Cloneabl
}
}
protected Type getActualScalarType(Type originType) {
protected Type getActualScalarType(Type originType) {
if (originType.getPrimitiveType() == PrimitiveType.DECIMAL32) {
return Type.DECIMAL32;
} else if (originType.getPrimitiveType() == PrimitiveType.DECIMAL64) {
@ -2472,6 +2472,8 @@ public abstract class Expr extends TreeNode<Expr> implements ParseNode, Cloneabl
return Type.CHAR;
} else if (originType.getPrimitiveType() == PrimitiveType.DECIMALV2) {
return Type.MAX_DECIMALV2_TYPE;
} else if (originType.getPrimitiveType() == PrimitiveType.TIMEV2) {
return Type.TIMEV2;
}
return originType;
}

View File

@ -1559,6 +1559,13 @@ public class FunctionCallExpr extends Expr {
}
if (fn.getFunctionName().getFunction().equals("timediff")) {
fn.getReturnType().getPrimitiveType().setTimeType();
ScalarType left = (ScalarType) argTypes[0];
ScalarType right = (ScalarType) argTypes[1];
if (left.isDatetimeV2() || right.isDatetimeV2() || left.isDateV2() || right.isDateV2()) {
Type ret = ScalarType.createTimeV2Type(Math.max(left.getScalarScale(), right.getScalarScale()));
fn.setReturnType(ret);
fn.getReturnType().getPrimitiveType().setTimeType();
}
}
if (fnName.getFunction().equalsIgnoreCase("map")) {

View File

@ -21,6 +21,7 @@ import org.apache.doris.catalog.FunctionSignature;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
import org.apache.doris.nereids.trees.expressions.functions.PropagateNullableOnDateLikeV2Args;
import org.apache.doris.nereids.trees.expressions.literal.StringLikeLiteral;
import org.apache.doris.nereids.trees.expressions.shape.BinaryExpression;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
import org.apache.doris.nereids.types.DateTimeType;
@ -28,6 +29,7 @@ import org.apache.doris.nereids.types.DateTimeV2Type;
import org.apache.doris.nereids.types.DateV2Type;
import org.apache.doris.nereids.types.TimeType;
import org.apache.doris.nereids.types.TimeV2Type;
import org.apache.doris.nereids.types.coercion.AbstractDataType;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
@ -46,8 +48,7 @@ public class TimeDiff extends ScalarFunction
FunctionSignature.ret(TimeType.INSTANCE).args(DateTimeType.INSTANCE, DateTimeType.INSTANCE),
FunctionSignature.ret(TimeV2Type.INSTANCE).args(DateTimeV2Type.SYSTEM_DEFAULT, DateV2Type.INSTANCE),
FunctionSignature.ret(TimeV2Type.INSTANCE).args(DateV2Type.INSTANCE, DateTimeV2Type.SYSTEM_DEFAULT),
FunctionSignature.ret(TimeV2Type.INSTANCE).args(DateV2Type.INSTANCE, DateV2Type.INSTANCE)
);
FunctionSignature.ret(TimeV2Type.INSTANCE).args(DateV2Type.INSTANCE, DateV2Type.INSTANCE));
/**
* constructor with 2 arguments.
@ -74,4 +75,41 @@ public class TimeDiff extends ScalarFunction
public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
return visitor.visitTimeDiff(this, context);
}
@Override
public FunctionSignature computeSignature(FunctionSignature signature) {
signature = super.computeSignature(signature);
boolean useTimev2 = false;
int scale = 0;
if (getArgument(0).getDataType() instanceof DateTimeV2Type) {
DateTimeV2Type left = (DateTimeV2Type) getArgument(0).getDataType();
scale = Math.max(scale, left.getScale());
useTimev2 = true;
}
if (getArgument(1).getDataType() instanceof DateTimeV2Type) {
DateTimeV2Type right = (DateTimeV2Type) getArgument(1).getDataType();
scale = Math.max(scale, right.getScale());
useTimev2 = true;
}
if (useTimev2) {
signature = signature.withReturnType(TimeV2Type.of(scale));
}
return signature;
}
@Override
public List<AbstractDataType> expectedInputTypes() {
FunctionSignature signature = getSignature();
if (getArgument(0) instanceof StringLikeLiteral) {
StringLikeLiteral str = (StringLikeLiteral) getArgument(0);
DateTimeV2Type left = DateTimeV2Type.forTypeFromString(str.getStringValue());
signature = signature.withArgumentType(0, left);
}
if (getArgument(1) instanceof StringLikeLiteral) {
StringLikeLiteral str = (StringLikeLiteral) getArgument(1);
DateTimeV2Type right = DateTimeV2Type.forTypeFromString(str.getStringValue());
signature = signature.withArgumentType(1, right);
}
return signature.argumentsTypes;
}
}

View File

@ -17,6 +17,7 @@
package org.apache.doris.nereids.types;
import org.apache.doris.catalog.ScalarType;
import org.apache.doris.catalog.Type;
import org.apache.doris.nereids.types.coercion.PrimitiveType;
@ -28,13 +29,26 @@ public class TimeV2Type extends PrimitiveType {
public static final TimeV2Type INSTANCE = new TimeV2Type();
private static final int WIDTH = 8;
private final int scale;
private TimeV2Type(int scale) {
this.scale = scale;
}
private TimeV2Type() {
scale = 0;
}
@Override
public Type toCatalogDataType() {
return Type.TIMEV2;
return ScalarType.createTimeV2Type(scale);
}
/**
* create TimeV2Type from scale
*/
public static TimeV2Type of(int scale) {
return new TimeV2Type(scale);
}
@Override
@ -46,4 +60,8 @@ public class TimeV2Type extends PrimitiveType {
public int width() {
return WIDTH;
}
public int getScale() {
return scale;
}
}