[Feature](Nereids) add executable function to support fold constant for functions (#18209)
1. Add date-time functions for fold constant for Nereids.
This is the list of executable date-time function nereids supports up to now:
- now()
- now(int)
- current_timestamp()
- current_timestamp(int)
- localtime()
- localtimestamp()
- curdate()
- current_date()
- curtime()
- current_time()
- date_{add/sub}(),{years/months/days/hours/minutes/seconds}_{add/sub}()
- datediff()
- {date/datev2}()
- {year/quarter/month/day/hour/minute/second}()
- dayof{year/month/week}()
- date_format()
- date_trunc()
- from_days()
- last_day()
- to_monday()
- from_unixtime()
- unix_timestamp()
- utc_timestamp()
- to_date()
- to_days()
- str_to_date()
- makedate()
2. solved problem:
- enable datev2/datetimev2 default.
- refactor Nereids foldConstantOnFE and support fold nested expression.
- separate the executable into multi-files for easily-reading and adding new functions
This commit is contained in:
@ -686,8 +686,6 @@ public class AnalyticExpr extends Expr {
|
||||
Preconditions.checkState(getFnCall().getChildren().size() == 3);
|
||||
}
|
||||
|
||||
Type type = getFnCall().getChildren().get(2).getType();
|
||||
|
||||
try {
|
||||
if (!Type.matchExactType(getFnCall().getChildren().get(0).getType(),
|
||||
getFnCall().getChildren().get(2).getType())) {
|
||||
@ -700,10 +698,10 @@ public class AnalyticExpr extends Expr {
|
||||
+ getFnCall().getChildren().get(0).getType());
|
||||
}
|
||||
|
||||
if (getFnCall().getChildren().get(2) instanceof CastExpr) {
|
||||
throw new AnalysisException("Type = " + type + " can't not convert to "
|
||||
+ getFnCall().getChildren().get(0).getType());
|
||||
}
|
||||
// if (getFnCall().getChildren().get(2) instanceof CastExpr) {
|
||||
// throw new AnalysisException("Type = " + type + " can't not convert to "
|
||||
// + getFnCall().getChildren().get(0).getType());
|
||||
// }
|
||||
|
||||
// check the value whether out of range
|
||||
checkDefaultValue(analyzer);
|
||||
|
||||
@ -1349,6 +1349,7 @@ public class FunctionCallExpr extends Expr {
|
||||
uncheckedCastChild(assignmentCompatibleType, 2);
|
||||
}
|
||||
}
|
||||
childTypes[0] = Type.BOOLEAN;
|
||||
childTypes[1] = assignmentCompatibleType;
|
||||
childTypes[2] = assignmentCompatibleType;
|
||||
fn = getBuiltinFunction(fnName.getFunction(), childTypes,
|
||||
|
||||
@ -24,7 +24,6 @@ import org.apache.doris.catalog.PrimitiveType;
|
||||
import org.apache.doris.catalog.ScalarType;
|
||||
import org.apache.doris.catalog.Type;
|
||||
import org.apache.doris.common.AnalysisException;
|
||||
import org.apache.doris.common.Config;
|
||||
import org.apache.doris.common.ErrorCode;
|
||||
import org.apache.doris.common.ErrorReport;
|
||||
import org.apache.doris.thrift.TExprNode;
|
||||
@ -146,10 +145,6 @@ public class TimestampArithmeticExpr extends Expr {
|
||||
if (t1 == PrimitiveType.DATEV2) {
|
||||
return Type.DATEV2;
|
||||
}
|
||||
if (Config.enable_date_conversion
|
||||
&& PrimitiveType.isImplicitCast(t1, PrimitiveType.DATETIMEV2)) {
|
||||
return Type.DATETIMEV2;
|
||||
}
|
||||
if (PrimitiveType.isImplicitCast(t1, PrimitiveType.DATETIME)) {
|
||||
return Type.DATETIME;
|
||||
}
|
||||
|
||||
@ -51,6 +51,7 @@ import org.apache.doris.nereids.trees.expressions.functions.scalar.CurrentCatalo
|
||||
import org.apache.doris.nereids.trees.expressions.functions.scalar.CurrentUser;
|
||||
import org.apache.doris.nereids.trees.expressions.functions.scalar.Database;
|
||||
import org.apache.doris.nereids.trees.expressions.functions.scalar.Date;
|
||||
import org.apache.doris.nereids.trees.expressions.functions.scalar.If;
|
||||
import org.apache.doris.nereids.trees.expressions.functions.scalar.User;
|
||||
import org.apache.doris.nereids.trees.expressions.functions.scalar.Version;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.ArrayLiteral;
|
||||
@ -69,11 +70,12 @@ import org.apache.doris.nereids.types.DataType;
|
||||
import org.apache.doris.nereids.util.ExpressionUtils;
|
||||
import org.apache.doris.qe.GlobalVariable;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* evaluate an expression on fe.
|
||||
@ -89,24 +91,12 @@ public class FoldConstantRuleOnFE extends AbstractExpressionRewriteRule {
|
||||
} else if (expr instanceof AggregateExpression && ((AggregateExpression) expr).getFunction().isDistinct()) {
|
||||
return expr;
|
||||
}
|
||||
|
||||
expr = rewriteChildren(expr, ctx);
|
||||
if (expr instanceof PropagateNullable
|
||||
&& !(expr instanceof NullableAggregateFunction)
|
||||
&& argsHasNullLiteral(expr)) {
|
||||
return new NullLiteral(expr.getDataType());
|
||||
}
|
||||
return expr.accept(this, ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* process constant expression.
|
||||
*/
|
||||
@Override
|
||||
public Expression visit(Expression expr, ExpressionRewriteContext ctx) {
|
||||
return expr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expression visitSlot(Slot slot, ExpressionRewriteContext context) {
|
||||
return slot;
|
||||
@ -119,24 +109,30 @@ public class FoldConstantRuleOnFE extends AbstractExpressionRewriteRule {
|
||||
|
||||
@Override
|
||||
public Expression visitEqualTo(EqualTo equalTo, ExpressionRewriteContext context) {
|
||||
if (!allArgsIsAllLiteral(equalTo)) {
|
||||
return equalTo;
|
||||
equalTo = rewriteChildren(equalTo, context);
|
||||
Optional<Expression> checkedExpr = preProcess(equalTo);
|
||||
if (checkedExpr.isPresent()) {
|
||||
return checkedExpr.get();
|
||||
}
|
||||
return BooleanLiteral.of(((Literal) equalTo.left()).compareTo((Literal) equalTo.right()) == 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expression visitGreaterThan(GreaterThan greaterThan, ExpressionRewriteContext context) {
|
||||
if (!allArgsIsAllLiteral(greaterThan)) {
|
||||
return greaterThan;
|
||||
greaterThan = rewriteChildren(greaterThan, context);
|
||||
Optional<Expression> checkedExpr = preProcess(greaterThan);
|
||||
if (checkedExpr.isPresent()) {
|
||||
return checkedExpr.get();
|
||||
}
|
||||
return BooleanLiteral.of(((Literal) greaterThan.left()).compareTo((Literal) greaterThan.right()) > 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expression visitGreaterThanEqual(GreaterThanEqual greaterThanEqual, ExpressionRewriteContext context) {
|
||||
if (!allArgsIsAllLiteral(greaterThanEqual)) {
|
||||
return greaterThanEqual;
|
||||
greaterThanEqual = rewriteChildren(greaterThanEqual, context);
|
||||
Optional<Expression> checkedExpr = preProcess(greaterThanEqual);
|
||||
if (checkedExpr.isPresent()) {
|
||||
return checkedExpr.get();
|
||||
}
|
||||
return BooleanLiteral.of(((Literal) greaterThanEqual.left())
|
||||
.compareTo((Literal) greaterThanEqual.right()) >= 0);
|
||||
@ -144,24 +140,30 @@ public class FoldConstantRuleOnFE extends AbstractExpressionRewriteRule {
|
||||
|
||||
@Override
|
||||
public Expression visitLessThan(LessThan lessThan, ExpressionRewriteContext context) {
|
||||
if (!allArgsIsAllLiteral(lessThan)) {
|
||||
return lessThan;
|
||||
lessThan = rewriteChildren(lessThan, context);
|
||||
Optional<Expression> checkedExpr = preProcess(lessThan);
|
||||
if (checkedExpr.isPresent()) {
|
||||
return checkedExpr.get();
|
||||
}
|
||||
return BooleanLiteral.of(((Literal) lessThan.left()).compareTo((Literal) lessThan.right()) < 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expression visitLessThanEqual(LessThanEqual lessThanEqual, ExpressionRewriteContext context) {
|
||||
if (!allArgsIsAllLiteral(lessThanEqual)) {
|
||||
return lessThanEqual;
|
||||
lessThanEqual = rewriteChildren(lessThanEqual, context);
|
||||
Optional<Expression> checkedExpr = preProcess(lessThanEqual);
|
||||
if (checkedExpr.isPresent()) {
|
||||
return checkedExpr.get();
|
||||
}
|
||||
return BooleanLiteral.of(((Literal) lessThanEqual.left()).compareTo((Literal) lessThanEqual.right()) <= 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expression visitNullSafeEqual(NullSafeEqual nullSafeEqual, ExpressionRewriteContext context) {
|
||||
if (!allArgsIsAllLiteral(nullSafeEqual)) {
|
||||
return nullSafeEqual;
|
||||
nullSafeEqual = rewriteChildren(nullSafeEqual, context);
|
||||
Optional<Expression> checkedExpr = preProcess(nullSafeEqual);
|
||||
if (checkedExpr.isPresent()) {
|
||||
return checkedExpr.get();
|
||||
}
|
||||
Literal l = (Literal) nullSafeEqual.left();
|
||||
Literal r = (Literal) nullSafeEqual.right();
|
||||
@ -176,8 +178,10 @@ public class FoldConstantRuleOnFE extends AbstractExpressionRewriteRule {
|
||||
|
||||
@Override
|
||||
public Expression visitNot(Not not, ExpressionRewriteContext context) {
|
||||
if (!allArgsIsAllLiteral(not)) {
|
||||
return not;
|
||||
not = rewriteChildren(not, context);
|
||||
Optional<Expression> checkedExpr = preProcess(not);
|
||||
if (checkedExpr.isPresent()) {
|
||||
return checkedExpr.get();
|
||||
}
|
||||
return BooleanLiteral.of(!((BooleanLiteral) not.child()).getValue());
|
||||
}
|
||||
@ -213,22 +217,20 @@ public class FoldConstantRuleOnFE extends AbstractExpressionRewriteRule {
|
||||
|
||||
@Override
|
||||
public Expression visitAnd(And and, ExpressionRewriteContext context) {
|
||||
if (and.getArguments().stream().anyMatch(BooleanLiteral.FALSE::equals)) {
|
||||
return BooleanLiteral.FALSE;
|
||||
List<Expression> nonTrueLiteral = Lists.newArrayList();
|
||||
for (Expression e : and.children()) {
|
||||
e = e.accept(this, context);
|
||||
if (BooleanLiteral.FALSE.equals(e)) {
|
||||
return BooleanLiteral.FALSE;
|
||||
} else if (e instanceof NullLiteral) {
|
||||
return e;
|
||||
} else if (!BooleanLiteral.TRUE.equals(e)) {
|
||||
nonTrueLiteral.add(e);
|
||||
}
|
||||
}
|
||||
if (argsHasNullLiteral(and)) {
|
||||
return new NullLiteral(BooleanType.INSTANCE);
|
||||
}
|
||||
List<Expression> nonTrueLiteral = and.children()
|
||||
.stream()
|
||||
.filter(conjunct -> !BooleanLiteral.TRUE.equals(conjunct))
|
||||
.collect(ImmutableList.toImmutableList());
|
||||
if (nonTrueLiteral.isEmpty()) {
|
||||
return BooleanLiteral.TRUE;
|
||||
}
|
||||
if (nonTrueLiteral.size() == and.arity()) {
|
||||
return and;
|
||||
}
|
||||
if (nonTrueLiteral.size() == 1) {
|
||||
return nonTrueLiteral.get(0);
|
||||
}
|
||||
@ -237,22 +239,20 @@ public class FoldConstantRuleOnFE extends AbstractExpressionRewriteRule {
|
||||
|
||||
@Override
|
||||
public Expression visitOr(Or or, ExpressionRewriteContext context) {
|
||||
if (or.getArguments().stream().anyMatch(BooleanLiteral.TRUE::equals)) {
|
||||
return BooleanLiteral.TRUE;
|
||||
List<Expression> nonFalseLiteral = Lists.newArrayList();
|
||||
for (Expression e : or.children()) {
|
||||
e = e.accept(this, context);
|
||||
if (BooleanLiteral.TRUE.equals(e)) {
|
||||
return BooleanLiteral.TRUE;
|
||||
} else if (e instanceof NullLiteral) {
|
||||
return e;
|
||||
} else if (!BooleanLiteral.FALSE.equals(e)) {
|
||||
nonFalseLiteral.add(e);
|
||||
}
|
||||
}
|
||||
if (ExpressionUtils.isAllNullLiteral(or.getArguments())) {
|
||||
return new NullLiteral(BooleanType.INSTANCE);
|
||||
}
|
||||
List<Expression> nonFalseLiteral = or.children()
|
||||
.stream()
|
||||
.filter(conjunct -> !BooleanLiteral.FALSE.equals(conjunct))
|
||||
.collect(ImmutableList.toImmutableList());
|
||||
if (nonFalseLiteral.isEmpty()) {
|
||||
return BooleanLiteral.FALSE;
|
||||
}
|
||||
if (nonFalseLiteral.size() == or.arity()) {
|
||||
return or;
|
||||
}
|
||||
if (nonFalseLiteral.size() == 1) {
|
||||
return nonFalseLiteral.get(0);
|
||||
}
|
||||
@ -266,8 +266,10 @@ public class FoldConstantRuleOnFE extends AbstractExpressionRewriteRule {
|
||||
|
||||
@Override
|
||||
public Expression visitCast(Cast cast, ExpressionRewriteContext context) {
|
||||
if (!allArgsIsAllLiteral(cast)) {
|
||||
return cast;
|
||||
cast = rewriteChildren(cast, context);
|
||||
Optional<Expression> checkedExpr = preProcess(cast);
|
||||
if (checkedExpr.isPresent()) {
|
||||
return checkedExpr.get();
|
||||
}
|
||||
Expression child = cast.child();
|
||||
// todo: process other null case
|
||||
@ -287,23 +289,31 @@ public class FoldConstantRuleOnFE extends AbstractExpressionRewriteRule {
|
||||
|
||||
@Override
|
||||
public Expression visitBoundFunction(BoundFunction boundFunction, ExpressionRewriteContext context) {
|
||||
boundFunction = rewriteChildren(boundFunction, context);
|
||||
//functions, like current_date, do not have arg
|
||||
if (boundFunction.getArguments().isEmpty()) {
|
||||
return boundFunction;
|
||||
}
|
||||
if (!ExpressionUtils.isAllLiteral(boundFunction.getArguments())) {
|
||||
return boundFunction;
|
||||
Optional<Expression> checkedExpr = preProcess(boundFunction);
|
||||
if (checkedExpr.isPresent()) {
|
||||
return checkedExpr.get();
|
||||
}
|
||||
return ExpressionEvaluator.INSTANCE.eval(boundFunction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expression visitBinaryArithmetic(BinaryArithmetic binaryArithmetic, ExpressionRewriteContext context) {
|
||||
binaryArithmetic = rewriteChildren(binaryArithmetic, context);
|
||||
Optional<Expression> checkedExpr = preProcess(binaryArithmetic);
|
||||
if (checkedExpr.isPresent()) {
|
||||
return checkedExpr.get();
|
||||
}
|
||||
return ExpressionEvaluator.INSTANCE.eval(binaryArithmetic);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expression visitCaseWhen(CaseWhen caseWhen, ExpressionRewriteContext context) {
|
||||
caseWhen = rewriteChildren(caseWhen, context);
|
||||
Expression newDefault = null;
|
||||
boolean foundNewDefault = false;
|
||||
|
||||
@ -335,50 +345,68 @@ public class FoldConstantRuleOnFE extends AbstractExpressionRewriteRule {
|
||||
return new CaseWhen(whenClauses, defaultResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expression visitIf(If ifExpr, ExpressionRewriteContext context) {
|
||||
ifExpr = rewriteChildren(ifExpr, context);
|
||||
if (ifExpr.child(0) instanceof NullLiteral || ifExpr.child(0).equals(BooleanLiteral.FALSE)) {
|
||||
return ifExpr.child(2);
|
||||
} else if (ifExpr.child(0).equals(BooleanLiteral.TRUE)) {
|
||||
return ifExpr.child(1);
|
||||
}
|
||||
return ifExpr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expression visitInPredicate(InPredicate inPredicate, ExpressionRewriteContext context) {
|
||||
inPredicate = rewriteChildren(inPredicate, context);
|
||||
Optional<Expression> checkedExpr = preProcess(inPredicate);
|
||||
if (checkedExpr.isPresent()) {
|
||||
return checkedExpr.get();
|
||||
}
|
||||
// now the inPredicate contains literal only.
|
||||
Expression value = inPredicate.child(0);
|
||||
if (value.isNullLiteral()) {
|
||||
return new NullLiteral(BooleanType.INSTANCE);
|
||||
}
|
||||
|
||||
boolean valueIsLiteral = value.isLiteral();
|
||||
if (!valueIsLiteral) {
|
||||
return inPredicate;
|
||||
}
|
||||
|
||||
boolean hasNull = false;
|
||||
boolean isOptionContainsNull = false;
|
||||
for (Expression item : inPredicate.getOptions()) {
|
||||
if (item.isNullLiteral()) {
|
||||
hasNull = true;
|
||||
}
|
||||
if (valueIsLiteral && value.equals(item)) {
|
||||
if (value.equals(item)) {
|
||||
return BooleanLiteral.TRUE;
|
||||
} else if (item.isNullLiteral()) {
|
||||
isOptionContainsNull = true;
|
||||
}
|
||||
}
|
||||
if (hasNull) {
|
||||
return NullLiteral.INSTANCE;
|
||||
}
|
||||
return BooleanLiteral.FALSE;
|
||||
return isOptionContainsNull
|
||||
? new NullLiteral(BooleanType.INSTANCE)
|
||||
: BooleanLiteral.FALSE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expression visitIsNull(IsNull isNull, ExpressionRewriteContext context) {
|
||||
if (!allArgsIsAllLiteral(isNull)) {
|
||||
return isNull;
|
||||
isNull = rewriteChildren(isNull, context);
|
||||
Optional<Expression> checkedExpr = preProcess(isNull);
|
||||
if (checkedExpr.isPresent()) {
|
||||
return checkedExpr.get();
|
||||
}
|
||||
return Literal.of(isNull.child().nullable());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expression visitTimestampArithmetic(TimestampArithmetic arithmetic, ExpressionRewriteContext context) {
|
||||
arithmetic = rewriteChildren(arithmetic, context);
|
||||
Optional<Expression> checkedExpr = preProcess(arithmetic);
|
||||
if (checkedExpr.isPresent()) {
|
||||
return checkedExpr.get();
|
||||
}
|
||||
return ExpressionEvaluator.INSTANCE.eval(arithmetic);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expression visitArray(Array array, ExpressionRewriteContext context) {
|
||||
if (!allArgsIsAllLiteral(array)) {
|
||||
return array;
|
||||
array = rewriteChildren(array, context);
|
||||
Optional<Expression> checkedExpr = preProcess(array);
|
||||
if (checkedExpr.isPresent()) {
|
||||
return checkedExpr.get();
|
||||
}
|
||||
List<Literal> arguments = (List) array.getArguments();
|
||||
return new ArrayLiteral(arguments);
|
||||
@ -386,8 +414,10 @@ public class FoldConstantRuleOnFE extends AbstractExpressionRewriteRule {
|
||||
|
||||
@Override
|
||||
public Expression visitDate(Date date, ExpressionRewriteContext context) {
|
||||
if (!allArgsIsAllLiteral(date)) {
|
||||
return date;
|
||||
date = rewriteChildren(date, context);
|
||||
Optional<Expression> checkedExpr = preProcess(date);
|
||||
if (checkedExpr.isPresent()) {
|
||||
return checkedExpr.get();
|
||||
}
|
||||
Literal child = (Literal) date.child();
|
||||
if (child instanceof NullLiteral) {
|
||||
@ -409,17 +439,8 @@ public class FoldConstantRuleOnFE extends AbstractExpressionRewriteRule {
|
||||
return new StringLiteral(GlobalVariable.version);
|
||||
}
|
||||
|
||||
private Expression rewriteChildren(Expression expr, ExpressionRewriteContext ctx) {
|
||||
List<Expression> newChildren = new ArrayList<>();
|
||||
boolean hasNewChildren = false;
|
||||
for (Expression child : expr.children()) {
|
||||
Expression newChild = rewrite(child, ctx);
|
||||
if (newChild != child) {
|
||||
hasNewChildren = true;
|
||||
}
|
||||
newChildren.add(newChild);
|
||||
}
|
||||
return hasNewChildren ? expr.withChildren(newChildren) : expr;
|
||||
private <E> E rewriteChildren(Expression expr, ExpressionRewriteContext ctx) {
|
||||
return (E) super.visit(expr, ctx);
|
||||
}
|
||||
|
||||
private boolean allArgsIsAllLiteral(Expression expression) {
|
||||
@ -429,5 +450,16 @@ public class FoldConstantRuleOnFE extends AbstractExpressionRewriteRule {
|
||||
private boolean argsHasNullLiteral(Expression expression) {
|
||||
return ExpressionUtils.hasNullLiteral(expression.getArguments());
|
||||
}
|
||||
|
||||
private Optional<Expression> preProcess(Expression expression) {
|
||||
if (expression instanceof PropagateNullable && !(expression instanceof NullableAggregateFunction)
|
||||
&& argsHasNullLiteral(expression)) {
|
||||
return Optional.of(new NullLiteral(expression.getDataType()));
|
||||
}
|
||||
if (!allArgsIsAllLiteral(expression)) {
|
||||
return Optional.of(expression);
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -22,6 +22,7 @@ import org.apache.doris.nereids.rules.expression.ExpressionRewriteContext;
|
||||
import org.apache.doris.nereids.trees.expressions.EqualTo;
|
||||
import org.apache.doris.nereids.trees.expressions.Expression;
|
||||
import org.apache.doris.nereids.trees.expressions.InPredicate;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.BooleanLiteral;
|
||||
import org.apache.doris.nereids.util.ExpressionUtils;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
@ -52,13 +53,17 @@ public class InPredicateToEqualToRule extends AbstractExpressionRewriteRule {
|
||||
Expression cmpExpr = inPredicate.getCompareExpr();
|
||||
List<Expression> options = inPredicate.getOptions();
|
||||
Preconditions.checkArgument(options.size() > 0, "InPredicate.options should not be empty");
|
||||
if (options.size() > 2) {
|
||||
if (options.size() > 2 || isOptionContainNullLiteral(options)) {
|
||||
return new InPredicate(cmpExpr.accept(this, context), options);
|
||||
}
|
||||
Expression newCmpExpr = cmpExpr.accept(this, context);
|
||||
List<Expression> disjunction = options.stream()
|
||||
.map(option -> new EqualTo(newCmpExpr, option.accept(this, context)))
|
||||
.collect(Collectors.toList());
|
||||
return ExpressionUtils.or(disjunction);
|
||||
return disjunction.isEmpty() ? BooleanLiteral.FALSE : ExpressionUtils.or(disjunction);
|
||||
}
|
||||
|
||||
private boolean isOptionContainNullLiteral(List<Expression> options) {
|
||||
return options.stream().anyMatch(Expression::isNullLiteral);
|
||||
}
|
||||
}
|
||||
|
||||
@ -174,7 +174,7 @@ public class SimplifyComparisonPredicate extends AbstractExpressionRewriteRule {
|
||||
private Expression migrateToDateV2(DateTimeLiteral l, AdjustType type) {
|
||||
DateV2Literal d = new DateV2Literal(l.getYear(), l.getMonth(), l.getDay());
|
||||
if (type == AdjustType.UPPER && (l.getHour() != 0 || l.getMinute() != 0 || l.getSecond() != 0)) {
|
||||
d = d.plusDays(1);
|
||||
d = ((DateV2Literal) d.plusDays(1));
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
@ -19,13 +19,21 @@ package org.apache.doris.nereids.trees.expressions;
|
||||
|
||||
import org.apache.doris.catalog.Env;
|
||||
import org.apache.doris.common.AnalysisException;
|
||||
import org.apache.doris.nereids.trees.expressions.functions.ExecutableFunctions;
|
||||
import org.apache.doris.nereids.trees.expressions.functions.BoundFunction;
|
||||
import org.apache.doris.nereids.trees.expressions.functions.ExpressionTrait;
|
||||
import org.apache.doris.nereids.trees.expressions.functions.agg.AggregateFunction;
|
||||
import org.apache.doris.nereids.trees.expressions.functions.executable.DateTimeAcquire;
|
||||
import org.apache.doris.nereids.trees.expressions.functions.executable.DateTimeArithmetic;
|
||||
import org.apache.doris.nereids.trees.expressions.functions.executable.DateTimeExtractAndTransform;
|
||||
import org.apache.doris.nereids.trees.expressions.functions.executable.ExecutableFunctions;
|
||||
import org.apache.doris.nereids.trees.expressions.functions.executable.NumericArithmetic;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.DateLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.Literal;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.NullLiteral;
|
||||
import org.apache.doris.nereids.types.DataType;
|
||||
import org.apache.doris.nereids.types.DecimalV3Type;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
@ -65,6 +73,10 @@ public enum ExpressionEvaluator {
|
||||
TimestampArithmetic arithmetic = (TimestampArithmetic) expression;
|
||||
fnName = arithmetic.getFuncName();
|
||||
args = new DataType[]{arithmetic.left().getDataType(), arithmetic.right().getDataType()};
|
||||
} else if (expression instanceof BoundFunction) {
|
||||
BoundFunction function = ((BoundFunction) expression);
|
||||
fnName = function.getName();
|
||||
args = function.children().stream().map(ExpressionTrait::getDataType).toArray(DataType[]::new);
|
||||
}
|
||||
|
||||
if ((Env.getCurrentEnv().isNullResultWithOneNullParamFunction(fnName))) {
|
||||
@ -123,15 +135,24 @@ public enum ExpressionEvaluator {
|
||||
}
|
||||
ImmutableMultimap.Builder<String, FunctionInvoker> mapBuilder =
|
||||
new ImmutableMultimap.Builder<String, FunctionInvoker>();
|
||||
Class clazz = ExecutableFunctions.class;
|
||||
for (Method method : clazz.getDeclaredMethods()) {
|
||||
ExecFunctionList annotationList = method.getAnnotation(ExecFunctionList.class);
|
||||
if (annotationList != null) {
|
||||
for (ExecFunction f : annotationList.value()) {
|
||||
registerFEFunction(mapBuilder, method, f);
|
||||
List<Class> classes = ImmutableList.of(
|
||||
DateTimeExtractAndTransform.class,
|
||||
ExecutableFunctions.class,
|
||||
DateLiteral.class,
|
||||
DateTimeArithmetic.class,
|
||||
DateTimeAcquire.class,
|
||||
NumericArithmetic.class
|
||||
);
|
||||
for (Class cls : classes) {
|
||||
for (Method method : cls.getDeclaredMethods()) {
|
||||
ExecFunctionList annotationList = method.getAnnotation(ExecFunctionList.class);
|
||||
if (annotationList != null) {
|
||||
for (ExecFunction f : annotationList.value()) {
|
||||
registerFEFunction(mapBuilder, method, f);
|
||||
}
|
||||
}
|
||||
registerFEFunction(mapBuilder, method, method.getAnnotation(ExecFunction.class));
|
||||
}
|
||||
registerFEFunction(mapBuilder, method, method.getAnnotation(ExecFunction.class));
|
||||
}
|
||||
this.functions = mapBuilder.build();
|
||||
}
|
||||
|
||||
@ -0,0 +1,100 @@
|
||||
// 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.
|
||||
|
||||
package org.apache.doris.nereids.trees.expressions.functions.executable;
|
||||
|
||||
import org.apache.doris.nereids.trees.expressions.ExecFunction;
|
||||
import org.apache.doris.nereids.trees.expressions.Expression;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.DateLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.DateTimeLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.DateTimeV2Literal;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.TimeZone;
|
||||
|
||||
/**
|
||||
* executable functions:
|
||||
* unclassified date function
|
||||
*/
|
||||
public class DateTimeAcquire {
|
||||
/**
|
||||
* date acquire function: now
|
||||
*/
|
||||
@ExecFunction(name = "now", argTypes = {}, returnType = "DATETIME")
|
||||
public static Expression now() {
|
||||
return DateTimeLiteral.fromJavaDateType(LocalDateTime.now());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "now", argTypes = {"INT"}, returnType = "DATETIMEV2")
|
||||
public static Expression now(IntegerLiteral precision) {
|
||||
return DateTimeV2Literal.fromJavaDateType(LocalDateTime.now(),
|
||||
precision.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* date acquire function: current_timestamp
|
||||
*/
|
||||
@ExecFunction(name = "current_timestamp", argTypes = {}, returnType = "DATETIME")
|
||||
public static Expression currentTimestamp() {
|
||||
return DateTimeLiteral.fromJavaDateType(LocalDateTime.now());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "current_timestamp", argTypes = {"INT"}, returnType = "DATETIMEV2")
|
||||
public static Expression currentTimestamp(IntegerLiteral precision) {
|
||||
return DateTimeV2Literal.fromJavaDateType(LocalDateTime.now(), precision.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* date acquire function: localtime/localtimestamp
|
||||
*/
|
||||
@ExecFunction(name = "localtime", argTypes = {}, returnType = "DATETIME")
|
||||
public static Expression localTime() {
|
||||
return DateTimeLiteral.fromJavaDateType(LocalDateTime.now(TimeZone.getDefault().toZoneId()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "localtimestamp", argTypes = {}, returnType = "DATETIME")
|
||||
public static Expression localTimestamp() {
|
||||
return DateTimeV2Literal.fromJavaDateType(LocalDateTime.now(TimeZone.getDefault().toZoneId()));
|
||||
}
|
||||
|
||||
/**
|
||||
* date acquire function: current_date
|
||||
*/
|
||||
@ExecFunction(name = "curdate", argTypes = {}, returnType = "DATE")
|
||||
public static Expression curDate() {
|
||||
return DateLiteral.fromJavaDateType(LocalDateTime.now());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "current_date", argTypes = {}, returnType = "DATE")
|
||||
public static Expression currentDate() {
|
||||
return DateLiteral.fromJavaDateType(LocalDateTime.now());
|
||||
}
|
||||
|
||||
/**
|
||||
* date acquire function: current_time
|
||||
*/
|
||||
@ExecFunction(name = "curtime", argTypes = {}, returnType = "DATETIME")
|
||||
public static Expression curTime() {
|
||||
return DateTimeLiteral.fromJavaDateType(LocalDateTime.now());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "current_time", argTypes = {}, returnType = "DATETIME")
|
||||
public static Expression currentTime() {
|
||||
return DateTimeLiteral.fromJavaDateType(LocalDateTime.now());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,337 @@
|
||||
// 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.
|
||||
|
||||
package org.apache.doris.nereids.trees.expressions.functions.executable;
|
||||
|
||||
import org.apache.doris.nereids.trees.expressions.ExecFunction;
|
||||
import org.apache.doris.nereids.trees.expressions.Expression;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.DateLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.DateTimeLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.DateTimeV2Literal;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.DateV2Literal;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
|
||||
/**
|
||||
* executable function:
|
||||
* date_add/sub, years/months/days/hours/minutes/seconds_add/sub, datediff
|
||||
*/
|
||||
public class DateTimeArithmetic {
|
||||
/**
|
||||
* datetime arithmetic function date-add.
|
||||
*/
|
||||
@ExecFunction(name = "date_add", argTypes = {"DATE", "INT"}, returnType = "DATE")
|
||||
public static Expression dateAdd(DateLiteral date, IntegerLiteral day) {
|
||||
return daysAdd(date, day);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "date_add", argTypes = {"DATETIME", "INT"}, returnType = "DATETIME")
|
||||
public static Expression dateAdd(DateTimeLiteral date, IntegerLiteral day) {
|
||||
return daysAdd(date, day);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "date_add", argTypes = {"DATEV2", "INT"}, returnType = "DATEV2")
|
||||
public static Expression dateAdd(DateV2Literal date, IntegerLiteral day) {
|
||||
return daysAdd(date, day);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "date_add", argTypes = {"DATETIMEV2", "INT"}, returnType = "DATETIMEV2")
|
||||
public static Expression dateAdd(DateTimeV2Literal date, IntegerLiteral day) {
|
||||
return daysAdd(date, day);
|
||||
}
|
||||
|
||||
/**
|
||||
* datetime arithmetic function date-sub.
|
||||
*/
|
||||
@ExecFunction(name = "date_sub", argTypes = {"DATE", "INT"}, returnType = "DATE")
|
||||
public static Expression dateSub(DateLiteral date, IntegerLiteral day) {
|
||||
return dateAdd(date, new IntegerLiteral(-day.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "date_sub", argTypes = {"DATETIME", "INT"}, returnType = "DATETIME")
|
||||
public static Expression dateSub(DateTimeLiteral date, IntegerLiteral day) {
|
||||
return dateAdd(date, new IntegerLiteral(-day.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "date_sub", argTypes = {"DATEV2", "INT"}, returnType = "DATEV2")
|
||||
public static Expression dateSub(DateV2Literal date, IntegerLiteral day) {
|
||||
return dateAdd(date, new IntegerLiteral(-day.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "date_sub", argTypes = {"DATETIMEV2", "INT"}, returnType = "DATETIMEV2")
|
||||
public static Expression dateSub(DateTimeV2Literal date, IntegerLiteral day) {
|
||||
return dateAdd(date, new IntegerLiteral(-day.getValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* datetime arithmetic function years-add.
|
||||
*/
|
||||
@ExecFunction(name = "years_add", argTypes = {"DATE", "INT"}, returnType = "DATE")
|
||||
public static Expression yearsAdd(DateLiteral date, IntegerLiteral year) {
|
||||
return date.plusYears(year.getValue());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "years_add", argTypes = {"DATETIME", "INT"}, returnType = "DATETIME")
|
||||
public static Expression yearsAdd(DateTimeLiteral date, IntegerLiteral year) {
|
||||
return date.plusYears(year.getValue());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "years_add", argTypes = {"DATEV2", "INT"}, returnType = "DATEV2")
|
||||
public static Expression yearsAdd(DateV2Literal date, IntegerLiteral year) {
|
||||
return date.plusYears(year.getValue());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "years_add", argTypes = {"DATETIMEV2", "INT"}, returnType = "DATETIMEV2")
|
||||
public static Expression yearsAdd(DateTimeV2Literal date, IntegerLiteral year) {
|
||||
return date.plusYears(year.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* datetime arithmetic function months-add.
|
||||
*/
|
||||
@ExecFunction(name = "months_add", argTypes = {"DATE", "INT"}, returnType = "DATE")
|
||||
public static Expression monthsAdd(DateLiteral date, IntegerLiteral month) {
|
||||
return date.plusMonths(month.getValue());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "months_add", argTypes = {"DATETIME", "INT"}, returnType = "DATETIME")
|
||||
public static Expression monthsAdd(DateTimeLiteral date, IntegerLiteral month) {
|
||||
return date.plusMonths(month.getValue());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "months_add", argTypes = {"DATEV2", "INT"}, returnType = "DATEV2")
|
||||
public static Expression monthsAdd(DateV2Literal date, IntegerLiteral month) {
|
||||
return date.plusMonths(month.getValue());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "months_add", argTypes = {"DATETIMEV2", "INT"}, returnType = "DATETIMEV2")
|
||||
public static Expression monthsAdd(DateTimeV2Literal date, IntegerLiteral month) {
|
||||
return date.plusMonths(month.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* datetime arithmetic function days-add.
|
||||
*/
|
||||
@ExecFunction(name = "days_add", argTypes = {"DATE", "INT"}, returnType = "DATE")
|
||||
public static Expression daysAdd(DateLiteral date, IntegerLiteral day) {
|
||||
return date.plusDays(day.getValue());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "days_add", argTypes = {"DATETIME", "INT"}, returnType = "DATETIME")
|
||||
public static Expression daysAdd(DateTimeLiteral date, IntegerLiteral day) {
|
||||
return date.plusDays(day.getValue());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "days_add", argTypes = {"DATEV2", "INT"}, returnType = "DATEV2")
|
||||
public static Expression daysAdd(DateV2Literal date, IntegerLiteral day) {
|
||||
return date.plusDays(day.getValue());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "days_add", argTypes = {"DATETIMEV2", "INT"}, returnType = "DATETIMEV2")
|
||||
public static Expression daysAdd(DateTimeV2Literal date, IntegerLiteral day) {
|
||||
return date.plusDays(day.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* datetime arithmetic function hours-add.
|
||||
*/
|
||||
@ExecFunction(name = "hours_add", argTypes = {"DATETIME", "INT"}, returnType = "DATETIME")
|
||||
public static Expression hoursAdd(DateTimeLiteral date, IntegerLiteral hour) {
|
||||
return date.plusHours(hour.getValue());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "hours_add", argTypes = {"DATETIMEV2", "INT"}, returnType = "DATETIMEV2")
|
||||
public static Expression hoursAdd(DateTimeV2Literal date, IntegerLiteral hour) {
|
||||
return date.plusHours(hour.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* datetime arithmetic function minutes-add.
|
||||
*/
|
||||
@ExecFunction(name = "minutes_add", argTypes = {"DATETIME", "INT"}, returnType = "DATETIME")
|
||||
public static Expression minutesAdd(DateTimeLiteral date, IntegerLiteral minute) {
|
||||
return date.plusMinutes(minute.getValue());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "minutes_add", argTypes = {"DATETIMEV2", "INT"}, returnType = "DATETIMEV2")
|
||||
public static Expression minutesAdd(DateTimeV2Literal date, IntegerLiteral minute) {
|
||||
return date.plusMinutes(minute.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* datetime arithmetic function seconds-add.
|
||||
*/
|
||||
@ExecFunction(name = "seconds_add", argTypes = {"DATETIME", "INT"}, returnType = "DATETIME")
|
||||
public static Expression secondsAdd(DateTimeLiteral date, IntegerLiteral second) {
|
||||
return date.plusSeconds(second.getValue());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "seconds_add", argTypes = {"DATETIMEV2", "INT"}, returnType = "DATETIMEV2")
|
||||
public static Expression secondsAdd(DateTimeV2Literal date, IntegerLiteral second) {
|
||||
return date.plusSeconds(second.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* datetime arithmetic function microseconds-add.
|
||||
*/
|
||||
@ExecFunction(name = "microseconds_add", argTypes = {"DATETIMEV2", "INT"}, returnType = "DATETIMEV2")
|
||||
public static Expression microSecondsAdd(DateTimeV2Literal date, IntegerLiteral microSecond) {
|
||||
return date.plusMicroSeconds(microSecond.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* datetime arithmetic function years-sub.
|
||||
*/
|
||||
@ExecFunction(name = "years_sub", argTypes = {"DATE", "INT"}, returnType = "DATE")
|
||||
public static Expression yearsSub(DateLiteral date, IntegerLiteral year) {
|
||||
return yearsAdd(date, new IntegerLiteral(-year.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "years_sub", argTypes = {"DATETIME", "INT"}, returnType = "DATETIME")
|
||||
public static Expression yearsSub(DateTimeLiteral date, IntegerLiteral year) {
|
||||
return yearsAdd(date, new IntegerLiteral(-year.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "years_sub", argTypes = {"DATEV2", "INT"}, returnType = "DATEV2")
|
||||
public static Expression yearsSub(DateV2Literal date, IntegerLiteral year) {
|
||||
return yearsAdd(date, new IntegerLiteral(-year.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "years_sub", argTypes = {"DATETIMEV2", "INT"}, returnType = "DATETIMEV2")
|
||||
public static Expression yearsSub(DateTimeV2Literal date, IntegerLiteral year) {
|
||||
return yearsAdd(date, new IntegerLiteral(-year.getValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* datetime arithmetic function months-sub
|
||||
*/
|
||||
@ExecFunction(name = "months_sub", argTypes = {"DATE", "INT"}, returnType = "DATE")
|
||||
public static Expression monthsSub(DateLiteral date, IntegerLiteral month) {
|
||||
return monthsAdd(date, new IntegerLiteral(-month.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "months_sub", argTypes = {"DATETIME", "INT"}, returnType = "DATETIME")
|
||||
public static Expression monthsSub(DateTimeLiteral date, IntegerLiteral month) {
|
||||
return monthsAdd(date, new IntegerLiteral(-month.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "months_sub", argTypes = {"DATEV2", "INT"}, returnType = "DATEV2")
|
||||
public static Expression monthsSub(DateV2Literal date, IntegerLiteral month) {
|
||||
return monthsAdd(date, new IntegerLiteral(-month.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "months_sub", argTypes = {"DATETIMEV2", "INT"}, returnType = "DATETIMEV2")
|
||||
public static Expression monthsSub(DateTimeV2Literal date, IntegerLiteral month) {
|
||||
return monthsAdd(date, new IntegerLiteral(-month.getValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* datetime arithmetic function days-sub
|
||||
*/
|
||||
@ExecFunction(name = "days_sub", argTypes = {"DATE", "INT"}, returnType = "DATE")
|
||||
public static Expression daysSub(DateLiteral date, IntegerLiteral day) {
|
||||
return daysAdd(date, new IntegerLiteral(-day.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "days_sub", argTypes = {"DATETIME", "INT"}, returnType = "DATETIME")
|
||||
public static Expression daysSub(DateTimeLiteral date, IntegerLiteral day) {
|
||||
return daysAdd(date, new IntegerLiteral(-day.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "days_sub", argTypes = {"DATEV2", "INT"}, returnType = "DATEV2")
|
||||
public static Expression daysSub(DateV2Literal date, IntegerLiteral day) {
|
||||
return daysAdd(date, new IntegerLiteral(-day.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "days_sub", argTypes = {"DATETIMEV2", "INT"}, returnType = "DATETIMEV2")
|
||||
public static Expression daysSub(DateTimeV2Literal date, IntegerLiteral day) {
|
||||
return daysAdd(date, new IntegerLiteral(-day.getValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* datetime arithmetic function hours-sub
|
||||
*/
|
||||
@ExecFunction(name = "hours_sub", argTypes = {"DATETIME", "INT"}, returnType = "DATETIME")
|
||||
public static Expression hoursSub(DateTimeLiteral date, IntegerLiteral hour) {
|
||||
return hoursAdd(date, new IntegerLiteral(-hour.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "hours_sub", argTypes = {"DATETIMEV2", "INT"}, returnType = "DATETIMEV2")
|
||||
public static Expression hoursSub(DateTimeV2Literal date, IntegerLiteral hour) {
|
||||
return hoursAdd(date, new IntegerLiteral(-hour.getValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* datetime arithmetic function minutes-sub
|
||||
*/
|
||||
@ExecFunction(name = "minutes_sub", argTypes = {"DATETIME", "INT"}, returnType = "DATETIME")
|
||||
public static Expression minutesSub(DateTimeLiteral date, IntegerLiteral minute) {
|
||||
return minutesAdd(date, new IntegerLiteral(-minute.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "minutes_sub", argTypes = {"DATETIMEV2", "INT"}, returnType = "DATETIMEV2")
|
||||
public static Expression minutesSub(DateTimeV2Literal date, IntegerLiteral minute) {
|
||||
return minutesAdd(date, new IntegerLiteral(-minute.getValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* datetime arithmetic function seconds-sub
|
||||
*/
|
||||
@ExecFunction(name = "seconds_sub", argTypes = {"DATETIME", "INT"}, returnType = "DATETIME")
|
||||
public static Expression secondsSub(DateTimeLiteral date, IntegerLiteral second) {
|
||||
return secondsAdd(date, new IntegerLiteral(-second.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "seconds_sub", argTypes = {"DATETIMEV2", "INT"}, returnType = "DATETIMEV2")
|
||||
public static Expression secondsSub(DateTimeV2Literal date, IntegerLiteral second) {
|
||||
return secondsAdd(date, new IntegerLiteral(-second.getValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* datetime arithmetic function datediff
|
||||
*/
|
||||
@ExecFunction(name = "datediff", argTypes = {"DATETIME", "DATETIME"}, returnType = "INT")
|
||||
public static Expression dateDiff(DateTimeLiteral date1, DateTimeLiteral date2) {
|
||||
return new IntegerLiteral(dateDiff(date1.toJavaDateType(), date2.toJavaDateType()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "datediff", argTypes = {"DATEV2", "DATEV2"}, returnType = "INT")
|
||||
public static Expression dateDiff(DateV2Literal date1, DateV2Literal date2) {
|
||||
return new IntegerLiteral(dateDiff(date1.toJavaDateType(), date2.toJavaDateType()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "datediff", argTypes = {"DATEV2", "DATETIMEV2"}, returnType = "INT")
|
||||
public static Expression dateDiff(DateV2Literal date1, DateTimeV2Literal date2) {
|
||||
return new IntegerLiteral(dateDiff(date1.toJavaDateType(), date2.toJavaDateType()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "datediff", argTypes = {"DATETIMEV2", "DATEV2"}, returnType = "INT")
|
||||
public static Expression dateDiff(DateTimeV2Literal date1, DateV2Literal date2) {
|
||||
return new IntegerLiteral(dateDiff(date1.toJavaDateType(), date2.toJavaDateType()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "datediff", argTypes = {"DATETIMEV2", "DATETIMEV2"}, returnType = "INT")
|
||||
public static Expression dateDiff(DateTimeV2Literal date1, DateTimeV2Literal date2) {
|
||||
return new IntegerLiteral(dateDiff(date1.toJavaDateType(), date2.toJavaDateType()));
|
||||
}
|
||||
|
||||
private static int dateDiff(LocalDateTime date1, LocalDateTime date2) {
|
||||
return ((int) ChronoUnit.DAYS.between(date2.toLocalDate(), date1.toLocalDate()));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,583 @@
|
||||
// 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.
|
||||
|
||||
package org.apache.doris.nereids.trees.expressions.functions.executable;
|
||||
|
||||
import org.apache.doris.nereids.exceptions.AnalysisException;
|
||||
import org.apache.doris.nereids.trees.expressions.ExecFunction;
|
||||
import org.apache.doris.nereids.trees.expressions.Expression;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.DateLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.DateTimeLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.DateTimeV2Literal;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.DateV2Literal;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.VarcharLiteral;
|
||||
import org.apache.doris.nereids.util.DateUtils;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeParseException;
|
||||
|
||||
/**
|
||||
* executable function:
|
||||
* year, quarter, month, week, dayOfYear, dayOfweek, dayOfMonth, hour, minute, second
|
||||
*/
|
||||
public class DateTimeExtractAndTransform {
|
||||
/**
|
||||
* datetime arithmetic function date-v2
|
||||
*/
|
||||
@ExecFunction(name = "datev2", argTypes = {"DATETIMEV2"}, returnType = "DATEV2")
|
||||
public static Expression dateV2(DateTimeV2Literal dateTime) {
|
||||
return new DateV2Literal(dateTime.getYear(), dateTime.getMonth(), dateTime.getDay());
|
||||
}
|
||||
|
||||
/**
|
||||
* Executable datetime extract year
|
||||
*/
|
||||
@ExecFunction(name = "year", argTypes = {"DATE"}, returnType = "INT")
|
||||
public static Expression year(DateLiteral date) {
|
||||
return new IntegerLiteral(((int) date.getYear()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "year", argTypes = {"DATETIME"}, returnType = "INT")
|
||||
public static Expression year(DateTimeLiteral date) {
|
||||
return new IntegerLiteral(((int) date.getYear()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "year", argTypes = {"DATEV2"}, returnType = "INT")
|
||||
public static Expression year(DateV2Literal date) {
|
||||
return new IntegerLiteral(((int) date.getYear()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "year", argTypes = {"DATETIMEV2"}, returnType = "INT")
|
||||
public static Expression year(DateTimeV2Literal date) {
|
||||
return new IntegerLiteral(((int) date.getYear()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Executable datetime extract quarter
|
||||
*/
|
||||
@ExecFunction(name = "quarter", argTypes = {"DATE"}, returnType = "INT")
|
||||
public static Expression quarter(DateLiteral date) {
|
||||
return new IntegerLiteral(((int) date.getMonth() - 1) / 3 + 1);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "quarter", argTypes = {"DATETIME"}, returnType = "INT")
|
||||
public static Expression quarter(DateTimeLiteral date) {
|
||||
return new IntegerLiteral(((int) date.getMonth() - 1) / 3 + 1);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "quarter", argTypes = {"DATEV2"}, returnType = "INT")
|
||||
public static Expression quarter(DateV2Literal date) {
|
||||
return new IntegerLiteral(((int) date.getMonth() - 1) / 3 + 1);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "quarter", argTypes = {"DATETIMEV2"}, returnType = "INT")
|
||||
public static Expression quarter(DateTimeV2Literal date) {
|
||||
return new IntegerLiteral(((int) date.getMonth() - 1) / 3 + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executable datetime extract month
|
||||
*/
|
||||
@ExecFunction(name = "month", argTypes = {"DATE"}, returnType = "INT")
|
||||
public static Expression month(DateLiteral date) {
|
||||
return new IntegerLiteral(((int) date.getMonth()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "month", argTypes = {"DATETIME"}, returnType = "INT")
|
||||
public static Expression month(DateTimeLiteral date) {
|
||||
return new IntegerLiteral(((int) date.getMonth()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "month", argTypes = {"DATEV2"}, returnType = "INT")
|
||||
public static Expression month(DateV2Literal date) {
|
||||
return new IntegerLiteral(((int) date.getMonth()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "month", argTypes = {"DATETIMEV2"}, returnType = "INT")
|
||||
public static Expression month(DateTimeV2Literal date) {
|
||||
return new IntegerLiteral(((int) date.getMonth()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Executable datetime extract day
|
||||
*/
|
||||
@ExecFunction(name = "day", argTypes = {"DATE"}, returnType = "INT")
|
||||
public static Expression day(DateLiteral date) {
|
||||
return new IntegerLiteral(((int) date.getDay()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "day", argTypes = {"DATETIME"}, returnType = "INT")
|
||||
public static Expression day(DateTimeLiteral date) {
|
||||
return new IntegerLiteral(((int) date.getDay()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "day", argTypes = {"DATEV2"}, returnType = "INT")
|
||||
public static Expression day(DateV2Literal date) {
|
||||
return new IntegerLiteral(((int) date.getDay()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "day", argTypes = {"DATETIMEV2"}, returnType = "INT")
|
||||
public static Expression day(DateTimeV2Literal date) {
|
||||
return new IntegerLiteral(((int) date.getDay()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Executable datetime extract hour
|
||||
*/
|
||||
@ExecFunction(name = "hour", argTypes = {"DATETIME"}, returnType = "INT")
|
||||
public static Expression hour(DateTimeLiteral date) {
|
||||
return new IntegerLiteral(((int) date.getHour()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "hour", argTypes = {"DATETIMEV2"}, returnType = "INT")
|
||||
public static Expression hour(DateTimeV2Literal date) {
|
||||
return new IntegerLiteral(((int) date.getHour()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Executable datetime extract hour
|
||||
*/
|
||||
@ExecFunction(name = "minute", argTypes = {"DATETIME"}, returnType = "INT")
|
||||
public static Expression minute(DateTimeLiteral date) {
|
||||
return new IntegerLiteral(((int) date.getMinute()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "minute", argTypes = {"DATETIMEV2"}, returnType = "INT")
|
||||
public static Expression minute(DateTimeV2Literal date) {
|
||||
return new IntegerLiteral(((int) date.getMinute()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Executable datetime extract hour
|
||||
*/
|
||||
@ExecFunction(name = "second", argTypes = {"DATETIME"}, returnType = "INT")
|
||||
public static Expression second(DateTimeLiteral date) {
|
||||
return new IntegerLiteral(((int) date.getSecond()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "second", argTypes = {"DATETIMEV2"}, returnType = "INT")
|
||||
public static Expression second(DateTimeV2Literal date) {
|
||||
return new IntegerLiteral(((int) date.getSecond()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Executable datetime extract dayofyear
|
||||
*/
|
||||
@ExecFunction(name = "dayofyear", argTypes = {"DATE"}, returnType = "INT")
|
||||
public static Expression dayOfYear(DateLiteral date) {
|
||||
return new IntegerLiteral(date.toJavaDateType().getDayOfYear());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "dayofyear", argTypes = {"DATETIME"}, returnType = "INT")
|
||||
public static Expression dayOfYear(DateTimeLiteral date) {
|
||||
return new IntegerLiteral(date.toJavaDateType().getDayOfYear());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "dayofyear", argTypes = {"DATEV2"}, returnType = "INT")
|
||||
public static Expression dayOfYear(DateV2Literal date) {
|
||||
return new IntegerLiteral(date.toJavaDateType().getDayOfYear());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "dayofyear", argTypes = {"DATETIMEV2"}, returnType = "INT")
|
||||
public static Expression dayOfYear(DateTimeV2Literal date) {
|
||||
return new IntegerLiteral(date.toJavaDateType().getDayOfYear());
|
||||
}
|
||||
|
||||
/**
|
||||
* Executable datetime extract dayofmonth
|
||||
*/
|
||||
@ExecFunction(name = "dayofmonth", argTypes = {"DATE"}, returnType = "INT")
|
||||
public static Expression dayOfMonth(DateLiteral date) {
|
||||
return new IntegerLiteral(date.toJavaDateType().getDayOfMonth());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "dayofmonth", argTypes = {"DATETIME"}, returnType = "INT")
|
||||
public static Expression dayOfMonth(DateTimeLiteral date) {
|
||||
return new IntegerLiteral(date.toJavaDateType().getDayOfMonth());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "dayofmonth", argTypes = {"DATEV2"}, returnType = "INT")
|
||||
public static Expression dayOfMonth(DateV2Literal date) {
|
||||
return new IntegerLiteral(date.toJavaDateType().getDayOfMonth());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "dayofmonth", argTypes = {"DATETIMEV2"}, returnType = "INT")
|
||||
public static Expression dayOfMonth(DateTimeV2Literal date) {
|
||||
return new IntegerLiteral(date.toJavaDateType().getDayOfMonth());
|
||||
}
|
||||
|
||||
/**
|
||||
* Executable datetime extract dayofweek
|
||||
*/
|
||||
@ExecFunction(name = "dayofweek", argTypes = {"DATE"}, returnType = "INT")
|
||||
public static Expression dayOfWeek(DateLiteral date) {
|
||||
return new IntegerLiteral(date.toJavaDateType().getDayOfWeek().getValue() % 7 + 1);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "dayofweek", argTypes = {"DATETIME"}, returnType = "INT")
|
||||
public static Expression dayOfWeek(DateTimeLiteral date) {
|
||||
return new IntegerLiteral(date.toJavaDateType().getDayOfWeek().getValue() % 7 + 1);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "dayofweek", argTypes = {"DATEV2"}, returnType = "INT")
|
||||
public static Expression dayOfWeek(DateV2Literal date) {
|
||||
return new IntegerLiteral(date.toJavaDateType().getDayOfWeek().getValue() % 7 + 1);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "dayofweek", argTypes = {"DATETIMEV2"}, returnType = "INT")
|
||||
public static Expression dayOfWeek(DateTimeV2Literal date) {
|
||||
return new IntegerLiteral(date.toJavaDateType().getDayOfWeek().getValue() % 7 + 1);
|
||||
}
|
||||
|
||||
private static int distanceToFirstDayOfWeek(LocalDateTime dateTime) {
|
||||
return dateTime.getDayOfWeek().getValue() - 1;
|
||||
}
|
||||
|
||||
private static LocalDateTime firstDayOfWeek(LocalDateTime dateTime) {
|
||||
return dateTime.plusDays(-distanceToFirstDayOfWeek(dateTime));
|
||||
}
|
||||
|
||||
/**
|
||||
* datetime arithmetic function date-format
|
||||
*/
|
||||
@ExecFunction(name = "date_format", argTypes = {"DATE", "VARCHAR"}, returnType = "VARCHAR")
|
||||
public static Expression dateFormat(DateLiteral date, VarcharLiteral format) {
|
||||
return new VarcharLiteral(DateUtils.formatBuilder(format.getValue()).toFormatter().format(
|
||||
java.time.LocalDate.of(((int) date.getYear()), ((int) date.getMonth()), ((int) date.getDay()))));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "date_format", argTypes = {"DATETIME", "VARCHAR"}, returnType = "VARCHAR")
|
||||
public static Expression dateFormat(DateTimeLiteral date, VarcharLiteral format) {
|
||||
return new VarcharLiteral(DateUtils.formatBuilder(format.getValue()).toFormatter().format(
|
||||
java.time.LocalDateTime.of(((int) date.getYear()), ((int) date.getMonth()), ((int) date.getDay()),
|
||||
((int) date.getHour()), ((int) date.getMinute()), ((int) date.getSecond()))));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "date_format", argTypes = {"DATEV2", "VARCHAR"}, returnType = "VARCHAR")
|
||||
public static Expression dateFormat(DateV2Literal date, VarcharLiteral format) {
|
||||
return new VarcharLiteral(DateUtils.formatBuilder(format.getValue()).toFormatter().format(
|
||||
java.time.LocalDate.of(((int) date.getYear()), ((int) date.getMonth()), ((int) date.getDay()))));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "date_format", argTypes = {"DATETIMEV2", "VARCHAR"}, returnType = "VARCHAR")
|
||||
public static Expression dateFormat(DateTimeV2Literal date, VarcharLiteral format) {
|
||||
return new VarcharLiteral(DateUtils.formatBuilder(format.getValue()).toFormatter().format(
|
||||
java.time.LocalDateTime.of(((int) date.getYear()), ((int) date.getMonth()), ((int) date.getDay()),
|
||||
((int) date.getHour()), ((int) date.getMinute()), ((int) date.getSecond()))));
|
||||
}
|
||||
|
||||
/**
|
||||
* datetime arithmetic function date
|
||||
*/
|
||||
@ExecFunction(name = "date", argTypes = {"DATETIME"}, returnType = "DATE")
|
||||
public static Expression date(DateTimeLiteral dateTime) throws AnalysisException {
|
||||
return new DateLiteral(dateTime.getYear(), dateTime.getMonth(), dateTime.getDay());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "date", argTypes = {"DATETIMEV2"}, returnType = "DATE")
|
||||
public static Expression date(DateTimeV2Literal dateTime) throws AnalysisException {
|
||||
return new DateLiteral(dateTime.getYear(), dateTime.getMonth(), dateTime.getDay());
|
||||
}
|
||||
|
||||
/**
|
||||
* datetime arithmetic function date-trunc
|
||||
*/
|
||||
@ExecFunction(name = "date_trunc", argTypes = {"DATETIME", "VARCHAR"}, returnType = "DATETIME")
|
||||
public static Expression dateTrunc(DateTimeLiteral date, VarcharLiteral trunc) {
|
||||
return DateTimeLiteral.fromJavaDateType(dateTruncHelper(date.toJavaDateType(), trunc.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "date_trunc", argTypes = {"DATETIMEV2", "VARCHAR"}, returnType = "DATETIMEV2")
|
||||
public static Expression dateTrunc(DateTimeV2Literal date, VarcharLiteral trunc) {
|
||||
return DateTimeV2Literal.fromJavaDateType(dateTruncHelper(date.toJavaDateType(), trunc.getValue()));
|
||||
}
|
||||
|
||||
private static LocalDateTime dateTruncHelper(LocalDateTime dateTime, String trunc) {
|
||||
int year = dateTime.getYear();
|
||||
int month = dateTime.getMonthValue();
|
||||
int day = dateTime.getDayOfMonth();
|
||||
int hour = dateTime.getHour();
|
||||
int minute = dateTime.getMinute();
|
||||
int second = dateTime.getSecond();
|
||||
switch (trunc.toLowerCase()) {
|
||||
case "year":
|
||||
month = 0;
|
||||
case "quarter": // CHECKSTYLE IGNORE THIS LINE
|
||||
month = ((month - 1) / 3) * 3 + 1;
|
||||
case "month": // CHECKSTYLE IGNORE THIS LINE
|
||||
day = 1;
|
||||
break;
|
||||
case "week":
|
||||
LocalDateTime firstDayOfWeek = firstDayOfWeek(dateTime);
|
||||
year = firstDayOfWeek.getYear();
|
||||
month = firstDayOfWeek.getMonthValue();
|
||||
day = firstDayOfWeek.getDayOfMonth();
|
||||
default: // CHECKSTYLE IGNORE THIS LINE
|
||||
break;
|
||||
}
|
||||
switch (trunc.toLowerCase()) {
|
||||
case "year":
|
||||
case "quarter":
|
||||
case "month":
|
||||
case "week":
|
||||
case "day": // CHECKSTYLE IGNORE THIS LINE
|
||||
hour = 0;
|
||||
case "hour": // CHECKSTYLE IGNORE THIS LINE
|
||||
minute = 0;
|
||||
case "minute": // CHECKSTYLE IGNORE THIS LINE
|
||||
second = 0;
|
||||
default: // CHECKSTYLE IGNORE THIS LINE
|
||||
}
|
||||
return LocalDateTime.of(year, month, day, hour, minute, second);
|
||||
}
|
||||
|
||||
/**
|
||||
* from_days.
|
||||
*/
|
||||
@ExecFunction(name = "from_days", argTypes = {"INT"}, returnType = "DATE")
|
||||
public static Expression fromDays(IntegerLiteral n) {
|
||||
// doris treat 0000AD as ordinary year but java LocalDateTime treat it as lunar year.
|
||||
LocalDateTime res = LocalDateTime.of(0, 1, 1, 0, 0, 0)
|
||||
.plusDays(n.getValue());
|
||||
if (res.isBefore(LocalDateTime.of(0, 3, 1, 0, 0, 0))) {
|
||||
res = res.plusDays(-1);
|
||||
}
|
||||
return DateLiteral.fromJavaDateType(res);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "last_day", argTypes = {"DATE"}, returnType = "DATE")
|
||||
public static Expression lastDay(DateLiteral date) {
|
||||
LocalDateTime nextMonthFirstDay = LocalDateTime.of((int) date.getYear(), (int) date.getMonth(), 1,
|
||||
0, 0, 0).plusMonths(1);
|
||||
return DateLiteral.fromJavaDateType(nextMonthFirstDay.minusDays(1));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "last_day", argTypes = {"DATETIME"}, returnType = "DATE")
|
||||
public static Expression lastDay(DateTimeLiteral date) {
|
||||
LocalDateTime nextMonthFirstDay = LocalDateTime.of((int) date.getYear(), (int) date.getMonth(), 1,
|
||||
0, 0, 0).plusMonths(1);
|
||||
return DateLiteral.fromJavaDateType(nextMonthFirstDay.minusDays(1));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "last_day", argTypes = {"DATEV2"}, returnType = "DATEV2")
|
||||
public static Expression lastDay(DateV2Literal date) {
|
||||
LocalDateTime nextMonthFirstDay = LocalDateTime.of((int) date.getYear(), (int) date.getMonth(), 1,
|
||||
0, 0, 0).plusMonths(1);
|
||||
return DateV2Literal.fromJavaDateType(nextMonthFirstDay.minusDays(1));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "last_day", argTypes = {"DATETIMEV2"}, returnType = "DATEV2")
|
||||
public static Expression lastDay(DateTimeV2Literal date) {
|
||||
LocalDateTime nextMonthFirstDay = LocalDateTime.of((int) date.getYear(), (int) date.getMonth(), 1,
|
||||
0, 0, 0).plusMonths(1);
|
||||
return DateV2Literal.fromJavaDateType(nextMonthFirstDay.minusDays(1));
|
||||
}
|
||||
|
||||
/**
|
||||
* datetime transformation function: to_monday
|
||||
*/
|
||||
@ExecFunction(name = "to_monday", argTypes = {"DATE"}, returnType = "DATE")
|
||||
public static Expression toMonday(DateLiteral date) {
|
||||
return DateLiteral.fromJavaDateType(toMonday(date.toJavaDateType()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "to_monday", argTypes = {"DATETIME"}, returnType = "DATE")
|
||||
public static Expression toMonday(DateTimeLiteral date) {
|
||||
return DateLiteral.fromJavaDateType(toMonday(date.toJavaDateType()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "to_monday", argTypes = {"DATEV2"}, returnType = "DATEV2")
|
||||
public static Expression toMonday(DateV2Literal date) {
|
||||
return DateV2Literal.fromJavaDateType(toMonday(date.toJavaDateType()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "to_monday", argTypes = {"DATETIMEV2"}, returnType = "DATEV2")
|
||||
public static Expression toMonday(DateTimeV2Literal date) {
|
||||
return DateV2Literal.fromJavaDateType(toMonday(date.toJavaDateType()));
|
||||
}
|
||||
|
||||
private static LocalDateTime toMonday(LocalDateTime dateTime) {
|
||||
LocalDateTime specialUpperBound = LocalDateTime.of(1970, 1, 4, 0, 0, 0);
|
||||
LocalDateTime specialLowerBound = LocalDateTime.of(1970, 1, 1, 0, 0, 0);
|
||||
if (dateTime.isAfter(specialUpperBound) || dateTime.isBefore(specialLowerBound)) {
|
||||
return dateTime.plusDays(-dateTime.getDayOfWeek().getValue() + 1);
|
||||
}
|
||||
return specialLowerBound;
|
||||
}
|
||||
|
||||
/**
|
||||
* date transformation function: from_unixtime
|
||||
*/
|
||||
@ExecFunction(name = "from_unixtime", argTypes = {"INT"}, returnType = "VARCHAR")
|
||||
public static Expression fromUnixTime(IntegerLiteral second) {
|
||||
if (second.getValue() < 0 || second.getValue() >= 253402271999L) {
|
||||
return null;
|
||||
}
|
||||
return fromUnixTime(second, new VarcharLiteral("%Y-%m-%d %H:%i:%s"));
|
||||
}
|
||||
|
||||
/**
|
||||
* date transformation function: from_unixtime
|
||||
*/
|
||||
@ExecFunction(name = "from_unixtime", argTypes = {"INT", "VARCHAR"}, returnType = "VARCHAR")
|
||||
public static Expression fromUnixTime(IntegerLiteral second, VarcharLiteral format) {
|
||||
if (second.getValue() < 0) {
|
||||
return null;
|
||||
}
|
||||
ZonedDateTime dateTime = LocalDateTime.of(1970, 1, 1, 0, 0, 0)
|
||||
.plusSeconds(second.getValue())
|
||||
.atZone(ZoneId.of("UTC+0"))
|
||||
.toOffsetDateTime()
|
||||
.atZoneSameInstant(ZoneId.systemDefault());
|
||||
return dateFormat(new DateTimeLiteral(dateTime.getYear(), dateTime.getMonthValue(),
|
||||
dateTime.getDayOfMonth(), dateTime.getHour(), dateTime.getMinute(), dateTime.getSecond()),
|
||||
format);
|
||||
}
|
||||
|
||||
/**
|
||||
* date transformation function: unix_timestamp
|
||||
*/
|
||||
@ExecFunction(name = "unix_timestamp", argTypes = {}, returnType = "INT")
|
||||
public static Expression unixTimestamp() {
|
||||
return new IntegerLiteral(getTimestamp(LocalDateTime.now()));
|
||||
}
|
||||
|
||||
/**
|
||||
* date transformation function: unix_timestamp
|
||||
*/
|
||||
@ExecFunction(name = "unix_timestamp", argTypes = {"DATE"}, returnType = "INT")
|
||||
public static Expression unixTimestamp(DateLiteral date) {
|
||||
return new IntegerLiteral(getTimestamp(date.toJavaDateType()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "unix_timestamp", argTypes = {"DATETIME"}, returnType = "INT")
|
||||
public static Expression unixTimestamp(DateTimeLiteral date) {
|
||||
return new IntegerLiteral(getTimestamp(date.toJavaDateType()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "unix_timestamp", argTypes = {"DATEV2"}, returnType = "INT")
|
||||
public static Expression unixTimestamp(DateV2Literal date) {
|
||||
return new IntegerLiteral(getTimestamp(date.toJavaDateType()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "unix_timestamp", argTypes = {"DATETIMEV2"}, returnType = "INT")
|
||||
public static Expression unixTimestamp(DateTimeV2Literal date) {
|
||||
return new IntegerLiteral(getTimestamp(date.toJavaDateType()));
|
||||
}
|
||||
|
||||
/**
|
||||
* date transformation function: unix_timestamp
|
||||
*/
|
||||
@ExecFunction(name = "unix_timestamp", argTypes = {"VARCHAR", "VARCHAR"}, returnType = "INT")
|
||||
public static Expression unixTimestamp(VarcharLiteral date, VarcharLiteral format) {
|
||||
DateTimeFormatter formatter = DateUtils.formatBuilder(format.getValue()).toFormatter();
|
||||
LocalDateTime dateObj;
|
||||
try {
|
||||
dateObj = LocalDateTime.parse(date.getValue(), formatter);
|
||||
} catch (DateTimeParseException e) {
|
||||
// means the date string doesn't contain time fields.
|
||||
dateObj = LocalDate.parse(date.getValue(), formatter).atStartOfDay();
|
||||
}
|
||||
return new IntegerLiteral(getTimestamp(dateObj));
|
||||
}
|
||||
|
||||
private static Integer getTimestamp(LocalDateTime dateTime) {
|
||||
LocalDateTime specialUpperBound = LocalDateTime.of(2038, 1, 19, 3, 14, 7);
|
||||
LocalDateTime specialLowerBound = LocalDateTime.of(1970, 1, 1, 0, 0, 0);
|
||||
if (dateTime.isBefore(specialLowerBound) || dateTime.isAfter(specialUpperBound)) {
|
||||
return 0;
|
||||
}
|
||||
return ((int) Duration.between(
|
||||
specialLowerBound,
|
||||
dateTime
|
||||
.atZone(ZoneId.systemDefault())
|
||||
.toOffsetDateTime().atZoneSameInstant(ZoneId.of("UTC+0"))
|
||||
.toLocalDateTime()).getSeconds());
|
||||
}
|
||||
|
||||
/**
|
||||
* date transformation function: utc_timestamp
|
||||
*/
|
||||
@ExecFunction(name = "utc_timestamp", argTypes = {}, returnType = "INT")
|
||||
public static Expression utcTimestamp() {
|
||||
return DateTimeLiteral.fromJavaDateType(LocalDateTime.now());
|
||||
}
|
||||
|
||||
/**
|
||||
* date transformation function: to_date
|
||||
*/
|
||||
@ExecFunction(name = "to_date", argTypes = {"DATETIME"}, returnType = "DATE")
|
||||
public static Expression toDate(DateTimeLiteral date) {
|
||||
return new DateLiteral(date.getYear(), date.getMonth(), date.getDay());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "to_date", argTypes = {"DATETIMEV2"}, returnType = "DATE")
|
||||
public static Expression toDate(DateTimeV2Literal date) {
|
||||
return new DateLiteral(date.getYear(), date.getMonth(), date.getDay());
|
||||
}
|
||||
|
||||
/**
|
||||
* date transformation function: to_days
|
||||
*/
|
||||
@ExecFunction(name = "to_days", argTypes = {"DATE"}, returnType = "INT")
|
||||
public static Expression toDays(DateLiteral date) {
|
||||
return new IntegerLiteral(((int) Duration.between(
|
||||
LocalDateTime.of(0, 1, 1, 0, 0, 0), date.toJavaDateType()).toDays()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "to_days", argTypes = {"DATETIME"}, returnType = "INT")
|
||||
public static Expression toDays(DateTimeLiteral date) {
|
||||
return new IntegerLiteral(((int) Duration.between(
|
||||
LocalDateTime.of(0, 1, 1, 0, 0, 0), date.toJavaDateType()).toDays()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "to_days", argTypes = {"DATEV2"}, returnType = "INT")
|
||||
public static Expression toDays(DateV2Literal date) {
|
||||
return new IntegerLiteral(((int) Duration.between(
|
||||
LocalDateTime.of(0, 1, 1, 0, 0, 0), date.toJavaDateType()).toDays()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "to_days", argTypes = {"DATETIMEV2"}, returnType = "INT")
|
||||
public static Expression toDays(DateTimeV2Literal date) {
|
||||
return new IntegerLiteral(((int) Duration.between(
|
||||
LocalDateTime.of(0, 1, 1, 0, 0, 0), date.toJavaDateType()).toDays()));
|
||||
}
|
||||
|
||||
/**
|
||||
* date transformation function: makedate
|
||||
*/
|
||||
@ExecFunction(name = "makedate", argTypes = {"INT", "INT"}, returnType = "DATE")
|
||||
public static Expression makeDate(IntegerLiteral year, IntegerLiteral dayOfYear) {
|
||||
return DateLiteral.fromJavaDateType(LocalDateTime.of(year.getValue(), 1, 1, 0, 0, 0)
|
||||
.plusDays(dayOfYear.getValue() - 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* date transformation function: str_to_date
|
||||
*/
|
||||
@ExecFunction(name = "str_to_date", argTypes = {"VARCHAR, VARCHAR"}, returnType = "DATETIME")
|
||||
public static Expression strToDate(VarcharLiteral str, VarcharLiteral format) {
|
||||
return DateTimeLiteral.fromJavaDateType(DateUtils.getTime(DateUtils.formatBuilder(format.getValue())
|
||||
.toFormatter(), str.getValue()));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,129 @@
|
||||
// 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.
|
||||
|
||||
package org.apache.doris.nereids.trees.expressions.functions.executable;
|
||||
|
||||
import org.apache.doris.nereids.trees.expressions.ExecFunction;
|
||||
import org.apache.doris.nereids.trees.expressions.Expression;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.BigIntLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.DecimalLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.DecimalV3Literal;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.DoubleLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.FloatLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.LargeIntLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.SmallIntLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.TinyIntLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.VarcharLiteral;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* functions that can be executed in FE.
|
||||
*/
|
||||
public class ExecutableFunctions {
|
||||
public static final ExecutableFunctions INSTANCE = new ExecutableFunctions();
|
||||
private static final Random RANDOM = new Random();
|
||||
|
||||
/**
|
||||
* other scalar function
|
||||
*/
|
||||
@ExecFunction(name = "abs", argTypes = {"TINYINT"}, returnType = "TINYINT")
|
||||
public static Expression abs(TinyIntLiteral literal) {
|
||||
return new TinyIntLiteral((byte) Math.abs(literal.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "abs", argTypes = {"SMALLINT"}, returnType = "SMALLINT")
|
||||
public static Expression abs(SmallIntLiteral literal) {
|
||||
return new SmallIntLiteral((short) Math.abs(literal.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "abs", argTypes = {"INT"}, returnType = "INT")
|
||||
public static Expression abs(IntegerLiteral literal) {
|
||||
return new IntegerLiteral(Math.abs(literal.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "abs", argTypes = {"BIGINT"}, returnType = "BIGINT")
|
||||
public static Expression abs(BigIntLiteral literal) {
|
||||
return new BigIntLiteral(Math.abs(literal.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "abs", argTypes = {"LARGEINT"}, returnType = "LARGEINT")
|
||||
public static Expression abs(LargeIntLiteral literal) {
|
||||
return new LargeIntLiteral(literal.getValue().abs());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "abs", argTypes = {"FLOAT"}, returnType = "FLOAT")
|
||||
public static Expression abs(FloatLiteral literal) {
|
||||
return new FloatLiteral(Math.abs(literal.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "abs", argTypes = {"DOUBLE"}, returnType = "DOUBLE")
|
||||
public static Expression abs(DoubleLiteral literal) {
|
||||
return new DoubleLiteral(Math.abs(literal.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "abs", argTypes = {"DECIMAL"}, returnType = "DECIMAL")
|
||||
public static Expression abs(DecimalLiteral literal) {
|
||||
return new DecimalLiteral(literal.getValue().abs());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "abs", argTypes = {"DECIMALV3"}, returnType = "DECIMALV3")
|
||||
public static Expression abs(DecimalV3Literal literal) {
|
||||
return new DecimalV3Literal(literal.getValue().abs());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "acos", argTypes = {"DOUBLE"}, returnType = "DOUBLE")
|
||||
public static Expression acos(DoubleLiteral literal) {
|
||||
return new DoubleLiteral(Math.acos(literal.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "append_trailing_if_char_absent", argTypes = {"VARCHAR", "VARCHAR"}, returnType = "VARCHAR")
|
||||
public static Expression appendTrailingIfCharAbsent(VarcharLiteral literal, VarcharLiteral chr) {
|
||||
if (literal.getValue().length() != 1) {
|
||||
return null;
|
||||
}
|
||||
return literal.getValue().endsWith(chr.getValue()) ? literal
|
||||
: new VarcharLiteral(literal.getValue() + chr.getValue());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "e", argTypes = {}, returnType = "DOUBLE")
|
||||
public static Expression e() { // CHECKSTYLE IGNORE THIS LINE
|
||||
return new DoubleLiteral(Math.E);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "p1", argTypes = {}, returnType = "DOUBLE")
|
||||
public static Expression pi() {
|
||||
return new DoubleLiteral(Math.PI);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "uuid", argTypes = {}, returnType = "VARCHAR")
|
||||
public static Expression uuid() {
|
||||
return new VarcharLiteral(UUID.randomUUID().toString());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "rand", argTypes = {}, returnType = "DOUBLE")
|
||||
public static Expression rand() {
|
||||
return new DoubleLiteral(RANDOM.nextDouble());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "random", argTypes = {}, returnType = "DOUBLE")
|
||||
public static Expression random() {
|
||||
return new DoubleLiteral(RANDOM.nextDouble());
|
||||
}
|
||||
}
|
||||
@ -15,21 +15,16 @@
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.doris.nereids.trees.expressions.functions;
|
||||
package org.apache.doris.nereids.trees.expressions.functions.executable;
|
||||
|
||||
import org.apache.doris.nereids.exceptions.AnalysisException;
|
||||
import org.apache.doris.nereids.trees.expressions.ExecFunction;
|
||||
import org.apache.doris.nereids.trees.expressions.Expression;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.BigIntLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.DateLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.DateTimeLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.DateTimeV2Literal;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.DateV2Literal;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.DecimalLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.DecimalV3Literal;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.DoubleLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.LargeIntLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.Literal;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.NullLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.SmallIntLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.TinyIntLiteral;
|
||||
@ -39,509 +34,513 @@ import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* functions that can be executed in FE.
|
||||
* executable functions:
|
||||
* add, subtract, multiply, divide
|
||||
*/
|
||||
public class ExecutableFunctions {
|
||||
public static final ExecutableFunctions INSTANCE = new ExecutableFunctions();
|
||||
|
||||
public class NumericArithmetic {
|
||||
/**
|
||||
* Executable arithmetic functions
|
||||
* Executable arithmetic functions add
|
||||
*/
|
||||
|
||||
@ExecFunction(name = "add", argTypes = {"TINYINT", "TINYINT"}, returnType = "SMALLINT")
|
||||
public static SmallIntLiteral addTinyIntTinyInt(TinyIntLiteral first, TinyIntLiteral second) {
|
||||
public static Expression addTinyIntTinyInt(TinyIntLiteral first, TinyIntLiteral second) {
|
||||
short result = (short) Math.addExact(first.getValue(), second.getValue());
|
||||
return new SmallIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "add", argTypes = {"TINYINT", "SMALLINT"}, returnType = "INT")
|
||||
public static IntegerLiteral addTinyIntSmallInt(TinyIntLiteral first, SmallIntLiteral second) {
|
||||
public static Expression addTinyIntSmallInt(TinyIntLiteral first, SmallIntLiteral second) {
|
||||
int result = Math.addExact(first.getValue(), second.getValue());
|
||||
return new IntegerLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "add", argTypes = {"TINYINT", "INT"}, returnType = "BIGINT")
|
||||
public static BigIntLiteral addTinyIntInt(TinyIntLiteral first, IntegerLiteral second) {
|
||||
public static Expression addTinyIntInt(TinyIntLiteral first, IntegerLiteral second) {
|
||||
long result = Math.addExact((long) first.getValue(), (long) second.getValue());
|
||||
return new BigIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "add", argTypes = {"TINYINT", "BIGINT"}, returnType = "BIGINT")
|
||||
public static BigIntLiteral addTinyIntBigInt(TinyIntLiteral first, BigIntLiteral second) {
|
||||
public static Expression addTinyIntBigInt(TinyIntLiteral first, BigIntLiteral second) {
|
||||
long result = Math.addExact((long) first.getValue(), (long) second.getValue());
|
||||
return new BigIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "add", argTypes = {"TINYINT", "LARGEINT"}, returnType = "LARGEINT")
|
||||
public static LargeIntLiteral addTinyIntLargeInt(TinyIntLiteral first, LargeIntLiteral second) {
|
||||
public static Expression addTinyIntLargeInt(TinyIntLiteral first, LargeIntLiteral second) {
|
||||
BigInteger result = second.getValue().add(new BigInteger(first.getValue().toString()));
|
||||
return new LargeIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "add", argTypes = {"SMALLINT", "TINYINT"}, returnType = "INT")
|
||||
public static IntegerLiteral addSmallIntTinyInt(SmallIntLiteral first, TinyIntLiteral second) {
|
||||
public static Expression addSmallIntTinyInt(SmallIntLiteral first, TinyIntLiteral second) {
|
||||
int result = Math.addExact(first.getValue(), second.getValue());
|
||||
return new IntegerLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "add", argTypes = {"SMALLINT", "SMALLINT"}, returnType = "INT")
|
||||
public static IntegerLiteral addSmallIntSmallInt(SmallIntLiteral first, SmallIntLiteral second) {
|
||||
public static Expression addSmallIntSmallInt(SmallIntLiteral first, SmallIntLiteral second) {
|
||||
int result = Math.addExact(first.getValue(), second.getValue());
|
||||
return new IntegerLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "add", argTypes = {"SMALLINT", "INT"}, returnType = "BIGINT")
|
||||
public static BigIntLiteral addSmallIntInt(SmallIntLiteral first, IntegerLiteral second) {
|
||||
public static Expression addSmallIntInt(SmallIntLiteral first, IntegerLiteral second) {
|
||||
long result = Math.addExact((long) first.getValue(), (long) second.getValue());
|
||||
return new BigIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "add", argTypes = {"SMALLINT", "BIGINT"}, returnType = "BIGINT")
|
||||
public static BigIntLiteral addSmallIntBigInt(SmallIntLiteral first, BigIntLiteral second) {
|
||||
public static Expression addSmallIntBigInt(SmallIntLiteral first, BigIntLiteral second) {
|
||||
long result = Math.addExact(first.getValue(), second.getValue());
|
||||
return new BigIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "add", argTypes = {"SMALLINT", "LARGEINT"}, returnType = "LARGEINT")
|
||||
public static LargeIntLiteral addSmallIntLargeInt(SmallIntLiteral first, LargeIntLiteral second) {
|
||||
public static Expression addSmallIntLargeInt(SmallIntLiteral first, LargeIntLiteral second) {
|
||||
BigInteger result = second.getValue().add(new BigInteger(first.getValue().toString()));
|
||||
return new LargeIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "add", argTypes = {"INT", "TINYINT"}, returnType = "BIGINT")
|
||||
public static BigIntLiteral addIntTinyInt(IntegerLiteral first, TinyIntLiteral second) {
|
||||
public static Expression addIntTinyInt(IntegerLiteral first, TinyIntLiteral second) {
|
||||
long result = Math.addExact((long) first.getValue(), (long) second.getValue());
|
||||
return new BigIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "add", argTypes = {"INT", "SMALLINT"}, returnType = "BIGINT")
|
||||
public static BigIntLiteral addIntSmallInt(IntegerLiteral first, SmallIntLiteral second) {
|
||||
public static Expression addIntSmallInt(IntegerLiteral first, SmallIntLiteral second) {
|
||||
long result = Math.addExact((long) first.getValue(), (long) second.getValue());
|
||||
return new BigIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "add", argTypes = {"INT", "INT"}, returnType = "BIGINT")
|
||||
public static BigIntLiteral addIntInt(IntegerLiteral first, IntegerLiteral second) {
|
||||
public static Expression addIntInt(IntegerLiteral first, IntegerLiteral second) {
|
||||
long result = Math.addExact((long) first.getValue(), (long) second.getValue());
|
||||
return new BigIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "add", argTypes = {"INT", "BIGINT"}, returnType = "BIGINT")
|
||||
public static BigIntLiteral addIntBigInt(IntegerLiteral first, BigIntLiteral second) {
|
||||
public static Expression addIntBigInt(IntegerLiteral first, BigIntLiteral second) {
|
||||
long result = Math.addExact(first.getValue(), second.getValue());
|
||||
return new BigIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "add", argTypes = {"INT", "LARGEINT"}, returnType = "LARGEINT")
|
||||
public static LargeIntLiteral addIntLargeInt(IntegerLiteral first, LargeIntLiteral second) {
|
||||
public static Expression addIntLargeInt(IntegerLiteral first, LargeIntLiteral second) {
|
||||
BigInteger result = second.getValue().add(new BigInteger(first.getValue().toString()));
|
||||
return new LargeIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "add", argTypes = {"BIGINT", "TINYINT"}, returnType = "BIGINT")
|
||||
public static BigIntLiteral addBigIntTinyInt(BigIntLiteral first, TinyIntLiteral second) {
|
||||
public static Expression addBigIntTinyInt(BigIntLiteral first, TinyIntLiteral second) {
|
||||
long result = Math.addExact(first.getValue(), second.getValue());
|
||||
return new BigIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "add", argTypes = {"BIGINT", "SMALLINT"}, returnType = "BIGINT")
|
||||
public static BigIntLiteral addBigIntSmallInt(BigIntLiteral first, SmallIntLiteral second) {
|
||||
public static Expression addBigIntSmallInt(BigIntLiteral first, SmallIntLiteral second) {
|
||||
long result = Math.addExact(first.getValue(), second.getValue());
|
||||
return new BigIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "add", argTypes = {"BIGINT", "INT"}, returnType = "BIGINT")
|
||||
public static BigIntLiteral addBigIntInt(BigIntLiteral first, IntegerLiteral second) {
|
||||
public static Expression addBigIntInt(BigIntLiteral first, IntegerLiteral second) {
|
||||
long result = Math.addExact(first.getValue(), second.getValue());
|
||||
return new BigIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "add", argTypes = {"BIGINT", "BIGINT"}, returnType = "BIGINT")
|
||||
public static BigIntLiteral addBigIntBigInt(BigIntLiteral first, BigIntLiteral second) {
|
||||
public static Expression addBigIntBigInt(BigIntLiteral first, BigIntLiteral second) {
|
||||
long result = Math.addExact(first.getValue(), second.getValue());
|
||||
return new BigIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "add", argTypes = {"BIGINT", "LARGEINT"}, returnType = "LARGEINT")
|
||||
public static LargeIntLiteral addBigIntLargeInt(BigIntLiteral first, LargeIntLiteral second) {
|
||||
public static Expression addBigIntLargeInt(BigIntLiteral first, LargeIntLiteral second) {
|
||||
BigInteger result = second.getValue().add(new BigInteger(first.getValue().toString()));
|
||||
return new LargeIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "add", argTypes = {"LARGEINT", "TINYINT"}, returnType = "BIGINT")
|
||||
public static LargeIntLiteral addLargeIntTinyInt(LargeIntLiteral first, TinyIntLiteral second) {
|
||||
public static Expression addLargeIntTinyInt(LargeIntLiteral first, TinyIntLiteral second) {
|
||||
BigInteger result = first.getValue().add(new BigInteger(second.getValue().toString()));
|
||||
return new LargeIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "add", argTypes = {"LARGEINT", "SMALLINT"}, returnType = "BIGINT")
|
||||
public static LargeIntLiteral addLargeIntSmallInt(LargeIntLiteral first, SmallIntLiteral second) {
|
||||
public static Expression addLargeIntSmallInt(LargeIntLiteral first, SmallIntLiteral second) {
|
||||
BigInteger result = first.getValue().add(new BigInteger(second.getValue().toString()));
|
||||
return new LargeIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "add", argTypes = {"LARGEINT", "INT"}, returnType = "BIGINT")
|
||||
public static LargeIntLiteral addLargeIntInt(LargeIntLiteral first, IntegerLiteral second) {
|
||||
public static Expression addLargeIntInt(LargeIntLiteral first, IntegerLiteral second) {
|
||||
BigInteger result = first.getValue().add(new BigInteger(second.getValue().toString()));
|
||||
return new LargeIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "add", argTypes = {"LARGEINT", "BIGINT"}, returnType = "BIGINT")
|
||||
public static LargeIntLiteral addLargeIntBigInt(LargeIntLiteral first, BigIntLiteral second) {
|
||||
public static Expression addLargeIntBigInt(LargeIntLiteral first, BigIntLiteral second) {
|
||||
BigInteger result = first.getValue().add(new BigInteger(second.getValue().toString()));
|
||||
return new LargeIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "add", argTypes = {"LARGEINT", "LARGEINT"}, returnType = "LARGEINT")
|
||||
public static LargeIntLiteral addLargeIntLargeInt(LargeIntLiteral first, LargeIntLiteral second) {
|
||||
public static Expression addLargeIntLargeInt(LargeIntLiteral first, LargeIntLiteral second) {
|
||||
BigInteger result = first.getValue().add(new BigInteger(second.getValue().toString()));
|
||||
return new LargeIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "add", argTypes = {"DOUBLE", "DOUBLE"}, returnType = "DOUBLE")
|
||||
public static DoubleLiteral addDoubleDouble(DoubleLiteral first, DoubleLiteral second) {
|
||||
public static Expression addDoubleDouble(DoubleLiteral first, DoubleLiteral second) {
|
||||
double result = first.getValue() + second.getValue();
|
||||
return new DoubleLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "add", argTypes = {"DECIMAL", "DECIMAL"}, returnType = "DECIMAL")
|
||||
public static DecimalLiteral addDecimalDecimal(DecimalLiteral first, DecimalLiteral second) {
|
||||
public static Expression addDecimalDecimal(DecimalLiteral first, DecimalLiteral second) {
|
||||
BigDecimal result = first.getValue().add(second.getValue());
|
||||
return new DecimalLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "add", argTypes = {"DECIMALV3", "DECIMALV3"}, returnType = "DECIMALV3")
|
||||
public static DecimalV3Literal addDecimalV3DecimalV3(DecimalV3Literal first, DecimalV3Literal second) {
|
||||
public static Expression addDecimalV3DecimalV3(DecimalV3Literal first, DecimalV3Literal second) {
|
||||
BigDecimal result = first.getValue().add(second.getValue());
|
||||
return new DecimalV3Literal((DecimalV3Type) first.getDataType(), result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executable arithmetic functions subtract
|
||||
*/
|
||||
@ExecFunction(name = "subtract", argTypes = {"TINYINT", "TINYINT"}, returnType = "SMALLINT")
|
||||
public static SmallIntLiteral subtractTinyIntTinyInt(TinyIntLiteral first, TinyIntLiteral second) {
|
||||
public static Expression subtractTinyIntTinyInt(TinyIntLiteral first, TinyIntLiteral second) {
|
||||
short result = (short) Math.subtractExact(first.getValue(), second.getValue());
|
||||
return new SmallIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "subtract", argTypes = {"TINYINT", "SMALLINT"}, returnType = "INT")
|
||||
public static IntegerLiteral subtractTinyIntSmallInt(TinyIntLiteral first, SmallIntLiteral second) {
|
||||
public static Expression subtractTinyIntSmallInt(TinyIntLiteral first, SmallIntLiteral second) {
|
||||
int result = Math.subtractExact(first.getValue(), second.getValue());
|
||||
return new IntegerLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "subtract", argTypes = {"TINYINT", "INT"}, returnType = "BIGINT")
|
||||
public static BigIntLiteral subtractTinyIntInt(TinyIntLiteral first, IntegerLiteral second) {
|
||||
public static Expression subtractTinyIntInt(TinyIntLiteral first, IntegerLiteral second) {
|
||||
long result = Math.subtractExact((long) first.getValue(), (long) second.getValue());
|
||||
return new BigIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "subtract", argTypes = {"TINYINT", "BIGINT"}, returnType = "BIGINT")
|
||||
public static BigIntLiteral subtractTinyIntBigInt(TinyIntLiteral first, BigIntLiteral second) {
|
||||
public static Expression subtractTinyIntBigInt(TinyIntLiteral first, BigIntLiteral second) {
|
||||
long result = Math.subtractExact((long) first.getValue(), (long) second.getValue());
|
||||
return new BigIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "subtract", argTypes = {"TINYINT", "LARGEINT"}, returnType = "LARGEINT")
|
||||
public static LargeIntLiteral subtractTinyIntLargeInt(TinyIntLiteral first, LargeIntLiteral second) {
|
||||
public static Expression subtractTinyIntLargeInt(TinyIntLiteral first, LargeIntLiteral second) {
|
||||
BigInteger result = second.getValue().subtract(new BigInteger(first.getValue().toString()));
|
||||
return new LargeIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "subtract", argTypes = {"SMALLINT", "TINYINT"}, returnType = "INT")
|
||||
public static IntegerLiteral subtractSmallIntTinyInt(SmallIntLiteral first, TinyIntLiteral second) {
|
||||
public static Expression subtractSmallIntTinyInt(SmallIntLiteral first, TinyIntLiteral second) {
|
||||
int result = Math.subtractExact(first.getValue(), second.getValue());
|
||||
return new IntegerLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "subtract", argTypes = {"SMALLINT", "SMALLINT"}, returnType = "INT")
|
||||
public static IntegerLiteral subtractSmallIntSmallInt(SmallIntLiteral first, SmallIntLiteral second) {
|
||||
public static Expression subtractSmallIntSmallInt(SmallIntLiteral first, SmallIntLiteral second) {
|
||||
int result = Math.subtractExact(first.getValue(), second.getValue());
|
||||
return new IntegerLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "subtract", argTypes = {"SMALLINT", "INT"}, returnType = "BIGINT")
|
||||
public static BigIntLiteral subtractSmallIntInt(SmallIntLiteral first, IntegerLiteral second) {
|
||||
public static Expression subtractSmallIntInt(SmallIntLiteral first, IntegerLiteral second) {
|
||||
long result = Math.subtractExact((long) first.getValue(), (long) second.getValue());
|
||||
return new BigIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "subtract", argTypes = {"SMALLINT", "BIGINT"}, returnType = "BIGINT")
|
||||
public static BigIntLiteral subtractSmallIntBigInt(SmallIntLiteral first, BigIntLiteral second) {
|
||||
public static Expression subtractSmallIntBigInt(SmallIntLiteral first, BigIntLiteral second) {
|
||||
long result = Math.subtractExact(first.getValue(), second.getValue());
|
||||
return new BigIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "subtract", argTypes = {"SMALLINT", "LARGEINT"}, returnType = "LARGEINT")
|
||||
public static LargeIntLiteral subtractSmallIntLargeInt(SmallIntLiteral first, LargeIntLiteral second) {
|
||||
public static Expression subtractSmallIntLargeInt(SmallIntLiteral first, LargeIntLiteral second) {
|
||||
BigInteger result = second.getValue().subtract(new BigInteger(first.getValue().toString()));
|
||||
return new LargeIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "subtract", argTypes = {"INT", "TINYINT"}, returnType = "BIGINT")
|
||||
public static BigIntLiteral subtractIntTinyInt(IntegerLiteral first, TinyIntLiteral second) {
|
||||
public static Expression subtractIntTinyInt(IntegerLiteral first, TinyIntLiteral second) {
|
||||
long result = Math.subtractExact((long) first.getValue(), (long) second.getValue());
|
||||
return new BigIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "subtract", argTypes = {"INT", "SMALLINT"}, returnType = "BIGINT")
|
||||
public static BigIntLiteral subtractIntSmallInt(IntegerLiteral first, SmallIntLiteral second) {
|
||||
public static Expression subtractIntSmallInt(IntegerLiteral first, SmallIntLiteral second) {
|
||||
long result = Math.subtractExact((long) first.getValue(), (long) second.getValue());
|
||||
return new BigIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "subtract", argTypes = {"INT", "INT"}, returnType = "BIGINT")
|
||||
public static BigIntLiteral subtractIntInt(IntegerLiteral first, IntegerLiteral second) {
|
||||
public static Expression subtractIntInt(IntegerLiteral first, IntegerLiteral second) {
|
||||
long result = Math.subtractExact((long) first.getValue(), (long) second.getValue());
|
||||
return new BigIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "subtract", argTypes = {"INT", "BIGINT"}, returnType = "BIGINT")
|
||||
public static BigIntLiteral subtractIntBigInt(IntegerLiteral first, BigIntLiteral second) {
|
||||
public static Expression subtractIntBigInt(IntegerLiteral first, BigIntLiteral second) {
|
||||
long result = Math.subtractExact(first.getValue(), second.getValue());
|
||||
return new BigIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "subtract", argTypes = {"INT", "LARGEINT"}, returnType = "LARGEINT")
|
||||
public static LargeIntLiteral subtractIntLargeInt(IntegerLiteral first, LargeIntLiteral second) {
|
||||
public static Expression subtractIntLargeInt(IntegerLiteral first, LargeIntLiteral second) {
|
||||
BigInteger result = second.getValue().subtract(new BigInteger(first.getValue().toString()));
|
||||
return new LargeIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "subtract", argTypes = {"BIGINT", "TINYINT"}, returnType = "BIGINT")
|
||||
public static BigIntLiteral subtractBigIntTinyInt(BigIntLiteral first, TinyIntLiteral second) {
|
||||
public static Expression subtractBigIntTinyInt(BigIntLiteral first, TinyIntLiteral second) {
|
||||
long result = Math.subtractExact(first.getValue(), second.getValue());
|
||||
return new BigIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "subtract", argTypes = {"BIGINT", "SMALLINT"}, returnType = "BIGINT")
|
||||
public static BigIntLiteral subtractBigIntSmallInt(BigIntLiteral first, SmallIntLiteral second) {
|
||||
public static Expression subtractBigIntSmallInt(BigIntLiteral first, SmallIntLiteral second) {
|
||||
long result = Math.subtractExact(first.getValue(), second.getValue());
|
||||
return new BigIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "subtract", argTypes = {"BIGINT", "INT"}, returnType = "BIGINT")
|
||||
public static BigIntLiteral subtractBigIntInt(BigIntLiteral first, IntegerLiteral second) {
|
||||
public static Expression subtractBigIntInt(BigIntLiteral first, IntegerLiteral second) {
|
||||
long result = Math.subtractExact(first.getValue(), second.getValue());
|
||||
return new BigIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "subtract", argTypes = {"BIGINT", "BIGINT"}, returnType = "BIGINT")
|
||||
public static BigIntLiteral subtractBigIntBigInt(BigIntLiteral first, BigIntLiteral second) {
|
||||
public static Expression subtractBigIntBigInt(BigIntLiteral first, BigIntLiteral second) {
|
||||
long result = Math.subtractExact(first.getValue(), second.getValue());
|
||||
return new BigIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "subtract", argTypes = {"BIGINT", "LARGEINT"}, returnType = "LARGEINT")
|
||||
public static LargeIntLiteral subtractBigIntLargeInt(BigIntLiteral first, LargeIntLiteral second) {
|
||||
public static Expression subtractBigIntLargeInt(BigIntLiteral first, LargeIntLiteral second) {
|
||||
BigInteger result = second.getValue().subtract(new BigInteger(first.getValue().toString()));
|
||||
return new LargeIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "subtract", argTypes = {"LARGEINT", "TINYINT"}, returnType = "BIGINT")
|
||||
public static LargeIntLiteral subtractLargeIntTinyInt(LargeIntLiteral first, TinyIntLiteral second) {
|
||||
public static Expression subtractLargeIntTinyInt(LargeIntLiteral first, TinyIntLiteral second) {
|
||||
BigInteger result = first.getValue().subtract(new BigInteger(second.getValue().toString()));
|
||||
return new LargeIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "subtract", argTypes = {"LARGEINT", "SMALLINT"}, returnType = "BIGINT")
|
||||
public static LargeIntLiteral subtractLargeIntSmallInt(LargeIntLiteral first, SmallIntLiteral second) {
|
||||
public static Expression subtractLargeIntSmallInt(LargeIntLiteral first, SmallIntLiteral second) {
|
||||
BigInteger result = first.getValue().subtract(new BigInteger(second.getValue().toString()));
|
||||
return new LargeIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "subtract", argTypes = {"LARGEINT", "INT"}, returnType = "BIGINT")
|
||||
public static LargeIntLiteral subtractLargeIntInt(LargeIntLiteral first, IntegerLiteral second) {
|
||||
public static Expression subtractLargeIntInt(LargeIntLiteral first, IntegerLiteral second) {
|
||||
BigInteger result = first.getValue().subtract(new BigInteger(second.getValue().toString()));
|
||||
return new LargeIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "subtract", argTypes = {"LARGEINT", "BIGINT"}, returnType = "BIGINT")
|
||||
public static LargeIntLiteral subtractLargeIntBigInt(LargeIntLiteral first, BigIntLiteral second) {
|
||||
public static Expression subtractLargeIntBigInt(LargeIntLiteral first, BigIntLiteral second) {
|
||||
BigInteger result = first.getValue().subtract(new BigInteger(second.getValue().toString()));
|
||||
return new LargeIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "subtract", argTypes = {"LARGEINT", "LARGEINT"}, returnType = "LARGEINT")
|
||||
public static LargeIntLiteral subtractLargeIntLargeInt(LargeIntLiteral first, LargeIntLiteral second) {
|
||||
public static Expression subtractLargeIntLargeInt(LargeIntLiteral first, LargeIntLiteral second) {
|
||||
BigInteger result = first.getValue().subtract(new BigInteger(second.getValue().toString()));
|
||||
return new LargeIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "subtract", argTypes = {"DOUBLE", "DOUBLE"}, returnType = "DOUBLE")
|
||||
public static DoubleLiteral subtractDoubleDouble(DoubleLiteral first, DoubleLiteral second) {
|
||||
public static Expression subtractDoubleDouble(DoubleLiteral first, DoubleLiteral second) {
|
||||
double result = first.getValue() - second.getValue();
|
||||
return new DoubleLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "subtract", argTypes = {"DECIMAL", "DECIMAL"}, returnType = "DECIMAL")
|
||||
public static DecimalLiteral subtractDecimalDecimal(DecimalLiteral first, DecimalLiteral second) {
|
||||
public static Expression subtractDecimalDecimal(DecimalLiteral first, DecimalLiteral second) {
|
||||
BigDecimal result = first.getValue().subtract(second.getValue());
|
||||
return new DecimalLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "subtract", argTypes = {"DECIMALV3", "DECIMALV3"}, returnType = "DECIMALV3")
|
||||
public static DecimalV3Literal subtractDecimalV3DecimalV3(DecimalV3Literal first, DecimalV3Literal second) {
|
||||
public static Expression subtractDecimalV3DecimalV3(DecimalV3Literal first, DecimalV3Literal second) {
|
||||
BigDecimal result = first.getValue().subtract(second.getValue());
|
||||
return new DecimalV3Literal((DecimalV3Type) first.getDataType(), result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executable arithmetic functions multiply
|
||||
*/
|
||||
@ExecFunction(name = "multiply", argTypes = {"TINYINT", "TINYINT"}, returnType = "SMALLINT")
|
||||
public static SmallIntLiteral multiplyTinyIntTinyInt(TinyIntLiteral first, TinyIntLiteral second) {
|
||||
public static Expression multiplyTinyIntTinyInt(TinyIntLiteral first, TinyIntLiteral second) {
|
||||
short result = (short) Math.multiplyExact(first.getValue(), second.getValue());
|
||||
return new SmallIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "multiply", argTypes = {"TINYINT", "SMALLINT"}, returnType = "INT")
|
||||
public static IntegerLiteral multiplyTinyIntSmallInt(TinyIntLiteral first, SmallIntLiteral second) {
|
||||
public static Expression multiplyTinyIntSmallInt(TinyIntLiteral first, SmallIntLiteral second) {
|
||||
int result = Math.multiplyExact(first.getValue(), second.getValue());
|
||||
return new IntegerLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "multiply", argTypes = {"TINYINT", "INT"}, returnType = "BIGINT")
|
||||
public static BigIntLiteral multiplyTinyIntInt(TinyIntLiteral first, IntegerLiteral second) {
|
||||
public static Expression multiplyTinyIntInt(TinyIntLiteral first, IntegerLiteral second) {
|
||||
long result = Math.multiplyExact((long) first.getValue(), (long) second.getValue());
|
||||
return new BigIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "multiply", argTypes = {"TINYINT", "BIGINT"}, returnType = "BIGINT")
|
||||
public static BigIntLiteral multiplyTinyIntBigInt(TinyIntLiteral first, BigIntLiteral second) {
|
||||
public static Expression multiplyTinyIntBigInt(TinyIntLiteral first, BigIntLiteral second) {
|
||||
long result = Math.multiplyExact((long) first.getValue(), (long) second.getValue());
|
||||
return new BigIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "multiply", argTypes = {"TINYINT", "LARGEINT"}, returnType = "LARGEINT")
|
||||
public static LargeIntLiteral multiplyTinyIntLargeInt(TinyIntLiteral first, LargeIntLiteral second) {
|
||||
public static Expression multiplyTinyIntLargeInt(TinyIntLiteral first, LargeIntLiteral second) {
|
||||
BigInteger result = second.getValue().multiply(new BigInteger(first.getValue().toString()));
|
||||
return new LargeIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "multiply", argTypes = {"SMALLINT", "TINYINT"}, returnType = "INT")
|
||||
public static IntegerLiteral multiplySmallIntTinyInt(SmallIntLiteral first, TinyIntLiteral second) {
|
||||
public static Expression multiplySmallIntTinyInt(SmallIntLiteral first, TinyIntLiteral second) {
|
||||
int result = Math.multiplyExact(first.getValue(), second.getValue());
|
||||
return new IntegerLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "multiply", argTypes = {"SMALLINT", "SMALLINT"}, returnType = "INT")
|
||||
public static IntegerLiteral multiplySmallIntSmallInt(SmallIntLiteral first, SmallIntLiteral second) {
|
||||
public static Expression multiplySmallIntSmallInt(SmallIntLiteral first, SmallIntLiteral second) {
|
||||
int result = Math.multiplyExact(first.getValue(), second.getValue());
|
||||
return new IntegerLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "multiply", argTypes = {"SMALLINT", "INT"}, returnType = "BIGINT")
|
||||
public static BigIntLiteral multiplySmallIntInt(SmallIntLiteral first, IntegerLiteral second) {
|
||||
public static Expression multiplySmallIntInt(SmallIntLiteral first, IntegerLiteral second) {
|
||||
long result = Math.multiplyExact((long) first.getValue(), (long) second.getValue());
|
||||
return new BigIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "multiply", argTypes = {"SMALLINT", "BIGINT"}, returnType = "BIGINT")
|
||||
public static BigIntLiteral multiplySmallIntBigInt(SmallIntLiteral first, BigIntLiteral second) {
|
||||
public static Expression multiplySmallIntBigInt(SmallIntLiteral first, BigIntLiteral second) {
|
||||
long result = Math.multiplyExact(first.getValue(), second.getValue());
|
||||
return new BigIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "multiply", argTypes = {"SMALLINT", "LARGEINT"}, returnType = "LARGEINT")
|
||||
public static LargeIntLiteral multiplySmallIntLargeInt(SmallIntLiteral first, LargeIntLiteral second) {
|
||||
public static Expression multiplySmallIntLargeInt(SmallIntLiteral first, LargeIntLiteral second) {
|
||||
BigInteger result = second.getValue().multiply(new BigInteger(first.getValue().toString()));
|
||||
return new LargeIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "multiply", argTypes = {"INT", "TINYINT"}, returnType = "BIGINT")
|
||||
public static BigIntLiteral multiplyIntTinyInt(IntegerLiteral first, TinyIntLiteral second) {
|
||||
public static Expression multiplyIntTinyInt(IntegerLiteral first, TinyIntLiteral second) {
|
||||
long result = Math.multiplyExact((long) first.getValue(), (long) second.getValue());
|
||||
return new BigIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "multiply", argTypes = {"INT", "SMALLINT"}, returnType = "BIGINT")
|
||||
public static BigIntLiteral multiplyIntSmallInt(IntegerLiteral first, SmallIntLiteral second) {
|
||||
public static Expression multiplyIntSmallInt(IntegerLiteral first, SmallIntLiteral second) {
|
||||
long result = Math.multiplyExact((long) first.getValue(), (long) second.getValue());
|
||||
return new BigIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "multiply", argTypes = {"INT", "INT"}, returnType = "BIGINT")
|
||||
public static BigIntLiteral multiplyIntInt(IntegerLiteral first, IntegerLiteral second) {
|
||||
public static Expression multiplyIntInt(IntegerLiteral first, IntegerLiteral second) {
|
||||
long result = Math.multiplyExact((long) first.getValue(), (long) second.getValue());
|
||||
return new BigIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "multiply", argTypes = {"INT", "BIGINT"}, returnType = "BIGINT")
|
||||
public static BigIntLiteral multiplyIntBigInt(IntegerLiteral first, BigIntLiteral second) {
|
||||
public static Expression multiplyIntBigInt(IntegerLiteral first, BigIntLiteral second) {
|
||||
long result = Math.multiplyExact(first.getValue(), second.getValue());
|
||||
return new BigIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "multiply", argTypes = {"INT", "LARGEINT"}, returnType = "LARGEINT")
|
||||
public static LargeIntLiteral multiplyIntLargeInt(IntegerLiteral first, LargeIntLiteral second) {
|
||||
public static Expression multiplyIntLargeInt(IntegerLiteral first, LargeIntLiteral second) {
|
||||
BigInteger result = second.getValue().multiply(new BigInteger(first.getValue().toString()));
|
||||
return new LargeIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "multiply", argTypes = {"BIGINT", "TINYINT"}, returnType = "BIGINT")
|
||||
public static BigIntLiteral multiplyBigIntTinyInt(BigIntLiteral first, TinyIntLiteral second) {
|
||||
public static Expression multiplyBigIntTinyInt(BigIntLiteral first, TinyIntLiteral second) {
|
||||
long result = Math.multiplyExact(first.getValue(), second.getValue());
|
||||
return new BigIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "multiply", argTypes = {"BIGINT", "SMALLINT"}, returnType = "BIGINT")
|
||||
public static BigIntLiteral multiplyBigIntSmallInt(BigIntLiteral first, SmallIntLiteral second) {
|
||||
public static Expression multiplyBigIntSmallInt(BigIntLiteral first, SmallIntLiteral second) {
|
||||
long result = Math.multiplyExact(first.getValue(), second.getValue());
|
||||
return new BigIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "multiply", argTypes = {"BIGINT", "INT"}, returnType = "BIGINT")
|
||||
public static BigIntLiteral multiplyBigIntInt(BigIntLiteral first, IntegerLiteral second) {
|
||||
public static Expression multiplyBigIntInt(BigIntLiteral first, IntegerLiteral second) {
|
||||
long result = Math.multiplyExact(first.getValue(), second.getValue());
|
||||
return new BigIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "multiply", argTypes = {"BIGINT", "BIGINT"}, returnType = "BIGINT")
|
||||
public static BigIntLiteral multiplyBigIntBigInt(BigIntLiteral first, BigIntLiteral second) {
|
||||
public static Expression multiplyBigIntBigInt(BigIntLiteral first, BigIntLiteral second) {
|
||||
long result = Math.multiplyExact(first.getValue(), second.getValue());
|
||||
return new BigIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "multiply", argTypes = {"BIGINT", "LARGEINT"}, returnType = "LARGEINT")
|
||||
public static LargeIntLiteral multiplyBigIntLargeInt(BigIntLiteral first, LargeIntLiteral second) {
|
||||
public static Expression multiplyBigIntLargeInt(BigIntLiteral first, LargeIntLiteral second) {
|
||||
BigInteger result = second.getValue().multiply(new BigInteger(first.getValue().toString()));
|
||||
return new LargeIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "multiply", argTypes = {"LARGEINT", "TINYINT"}, returnType = "BIGINT")
|
||||
public static LargeIntLiteral multiplyLargeIntTinyInt(LargeIntLiteral first, TinyIntLiteral second) {
|
||||
public static Expression multiplyLargeIntTinyInt(LargeIntLiteral first, TinyIntLiteral second) {
|
||||
BigInteger result = first.getValue().multiply(new BigInteger(second.getValue().toString()));
|
||||
return new LargeIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "multiply", argTypes = {"LARGEINT", "SMALLINT"}, returnType = "BIGINT")
|
||||
public static LargeIntLiteral multiplyLargeIntSmallInt(LargeIntLiteral first, SmallIntLiteral second) {
|
||||
public static Expression multiplyLargeIntSmallInt(LargeIntLiteral first, SmallIntLiteral second) {
|
||||
BigInteger result = first.getValue().multiply(new BigInteger(second.getValue().toString()));
|
||||
return new LargeIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "multiply", argTypes = {"LARGEINT", "INT"}, returnType = "BIGINT")
|
||||
public static LargeIntLiteral multiplyLargeIntInt(LargeIntLiteral first, IntegerLiteral second) {
|
||||
public static Expression multiplyLargeIntInt(LargeIntLiteral first, IntegerLiteral second) {
|
||||
BigInteger result = first.getValue().multiply(new BigInteger(second.getValue().toString()));
|
||||
return new LargeIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "multiply", argTypes = {"LARGEINT", "BIGINT"}, returnType = "BIGINT")
|
||||
public static LargeIntLiteral multiplyLargeIntBigInt(LargeIntLiteral first, BigIntLiteral second) {
|
||||
public static Expression multiplyLargeIntBigInt(LargeIntLiteral first, BigIntLiteral second) {
|
||||
BigInteger result = first.getValue().multiply(new BigInteger(second.getValue().toString()));
|
||||
return new LargeIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "multiply", argTypes = {"LARGEINT", "LARGEINT"}, returnType = "LARGEINT")
|
||||
public static LargeIntLiteral multiplyLargeIntLargeInt(LargeIntLiteral first, LargeIntLiteral second) {
|
||||
public static Expression multiplyLargeIntLargeInt(LargeIntLiteral first, LargeIntLiteral second) {
|
||||
BigInteger result = first.getValue().multiply(new BigInteger(second.getValue().toString()));
|
||||
return new LargeIntLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "multiply", argTypes = {"DOUBLE", "DOUBLE"}, returnType = "DOUBLE")
|
||||
public static DoubleLiteral multiplyDoubleDouble(DoubleLiteral first, DoubleLiteral second) {
|
||||
public static Expression multiplyDoubleDouble(DoubleLiteral first, DoubleLiteral second) {
|
||||
double result = first.getValue() * second.getValue();
|
||||
return new DoubleLiteral(result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "multiply", argTypes = {"DECIMAL", "DECIMAL"}, returnType = "DECIMAL")
|
||||
public static DecimalLiteral multiplyDecimalDecimal(DecimalLiteral first, DecimalLiteral second) {
|
||||
public static Expression multiplyDecimalDecimal(DecimalLiteral first, DecimalLiteral second) {
|
||||
BigDecimal result = first.getValue().multiply(second.getValue());
|
||||
return new DecimalLiteral(result);
|
||||
}
|
||||
@ -550,7 +549,7 @@ public class ExecutableFunctions {
|
||||
* decimalV3 multiply in FE
|
||||
*/
|
||||
@ExecFunction(name = "multiply", argTypes = {"DECIMALV3", "DECIMALV3"}, returnType = "DECIMALV3")
|
||||
public static DecimalV3Literal multiplyDecimalV3DecimalV3(DecimalV3Literal first, DecimalV3Literal second) {
|
||||
public static Expression multiplyDecimalV3DecimalV3(DecimalV3Literal first, DecimalV3Literal second) {
|
||||
BigDecimal result = first.getValue().multiply(second.getValue());
|
||||
DecimalV3Type t1 = (DecimalV3Type) first.getDataType();
|
||||
DecimalV3Type t2 = (DecimalV3Type) second.getDataType();
|
||||
@ -559,8 +558,11 @@ public class ExecutableFunctions {
|
||||
return new DecimalV3Literal(DecimalV3Type.createDecimalV3Type(precision, scale), result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executable arithmetic functions divide
|
||||
*/
|
||||
@ExecFunction(name = "divide", argTypes = {"DOUBLE", "DOUBLE"}, returnType = "DOUBLE")
|
||||
public static Literal divideDouble(DoubleLiteral first, DoubleLiteral second) {
|
||||
public static Expression divideDouble(DoubleLiteral first, DoubleLiteral second) {
|
||||
if (second.getValue() == 0.0) {
|
||||
return new NullLiteral(first.getDataType());
|
||||
}
|
||||
@ -569,7 +571,7 @@ public class ExecutableFunctions {
|
||||
}
|
||||
|
||||
@ExecFunction(name = "divide", argTypes = {"DECIMAL", "DECIMAL"}, returnType = "DECIMAL")
|
||||
public static Literal divideDecimal(DecimalLiteral first, DecimalLiteral second) {
|
||||
public static Expression divideDecimal(DecimalLiteral first, DecimalLiteral second) {
|
||||
if (first.getValue().compareTo(BigDecimal.ZERO) == 0) {
|
||||
return new NullLiteral(first.getDataType());
|
||||
}
|
||||
@ -581,7 +583,7 @@ public class ExecutableFunctions {
|
||||
* decimalv3 divide in FE
|
||||
*/
|
||||
@ExecFunction(name = "divide", argTypes = {"DECIMALV3", "DECIMALV3"}, returnType = "DECIMALV3")
|
||||
public static Literal divideDecimalV3(DecimalV3Literal first, DecimalV3Literal second) {
|
||||
public static Expression divideDecimalV3(DecimalV3Literal first, DecimalV3Literal second) {
|
||||
if (first.getValue().compareTo(BigDecimal.ZERO) == 0) {
|
||||
return new NullLiteral(first.getDataType());
|
||||
}
|
||||
@ -591,224 +593,4 @@ public class ExecutableFunctions {
|
||||
return new DecimalV3Literal(DecimalV3Type.createDecimalV3Type(
|
||||
t1.getPrecision(), t1.getScale() - t2.getScale()), result);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "date_sub", argTypes = { "DATE", "INT" }, returnType = "DATE")
|
||||
public static DateLiteral dateSub(DateLiteral date, IntegerLiteral day) throws AnalysisException {
|
||||
return dateAdd(date, new IntegerLiteral(-day.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "date_sub", argTypes = { "DATETIME", "INT" }, returnType = "DATETIME")
|
||||
public static DateTimeLiteral dateSub(DateTimeLiteral date, IntegerLiteral day) throws AnalysisException {
|
||||
return dateAdd(date, new IntegerLiteral(-day.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "date_sub", argTypes = { "DATEV2", "INT" }, returnType = "DATEV2")
|
||||
public static DateV2Literal dateSub(DateV2Literal date, IntegerLiteral day) throws AnalysisException {
|
||||
return dateAdd(date, new IntegerLiteral(-day.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "date_sub", argTypes = { "DATETIMEV2", "INT" }, returnType = "DATETIMEV2")
|
||||
public static DateTimeV2Literal dateSub(DateTimeV2Literal date, IntegerLiteral day) throws AnalysisException {
|
||||
return dateAdd(date, new IntegerLiteral(-day.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "date_add", argTypes = { "DATE", "INT" }, returnType = "DATE")
|
||||
public static DateLiteral dateAdd(DateLiteral date, IntegerLiteral day) throws AnalysisException {
|
||||
return daysAdd(date, day);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "date_add", argTypes = { "DATETIME", "INT" }, returnType = "DATETIME")
|
||||
public static DateTimeLiteral dateAdd(DateTimeLiteral date, IntegerLiteral day) throws AnalysisException {
|
||||
return daysAdd(date, day);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "date_add", argTypes = { "DATEV2", "INT" }, returnType = "DATEV2")
|
||||
public static DateV2Literal dateAdd(DateV2Literal date, IntegerLiteral day) throws AnalysisException {
|
||||
return daysAdd(date, day);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "date_add", argTypes = { "DATETIMEV2", "INT" }, returnType = "DATETIMEV2")
|
||||
public static DateTimeV2Literal dateAdd(DateTimeV2Literal date, IntegerLiteral day) throws AnalysisException {
|
||||
return daysAdd(date, day);
|
||||
}
|
||||
|
||||
@ExecFunction(name = "years_add", argTypes = { "DATE", "INT" }, returnType = "DATE")
|
||||
public static DateLiteral yearsAdd(DateLiteral date, IntegerLiteral year) throws AnalysisException {
|
||||
return date.plusYears(year.getValue());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "years_add", argTypes = { "DATETIME", "INT" }, returnType = "DATETIME")
|
||||
public static DateTimeLiteral yearsAdd(DateTimeLiteral date, IntegerLiteral year) throws AnalysisException {
|
||||
return date.plusYears(year.getValue());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "years_add", argTypes = { "DATEV2", "INT" }, returnType = "DATEV2")
|
||||
public static DateV2Literal yearsAdd(DateV2Literal date, IntegerLiteral year) throws AnalysisException {
|
||||
return date.plusYears(year.getValue());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "years_add", argTypes = { "DATETIMEV2", "INT" }, returnType = "DATETIMEV2")
|
||||
public static DateTimeV2Literal yearsAdd(DateTimeV2Literal date, IntegerLiteral year) throws AnalysisException {
|
||||
return date.plusYears(year.getValue());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "months_add", argTypes = { "DATE", "INT" }, returnType = "DATE")
|
||||
public static DateLiteral monthsAdd(DateLiteral date, IntegerLiteral month) throws AnalysisException {
|
||||
return date.plusMonths(month.getValue());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "months_add", argTypes = { "DATETIME", "INT" }, returnType = "DATETIME")
|
||||
public static DateTimeLiteral monthsAdd(DateTimeLiteral date, IntegerLiteral month) throws AnalysisException {
|
||||
return date.plusMonths(month.getValue());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "months_add", argTypes = { "DATEV2", "INT" }, returnType = "DATEV2")
|
||||
public static DateV2Literal monthsAdd(DateV2Literal date, IntegerLiteral month) throws AnalysisException {
|
||||
return date.plusMonths(month.getValue());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "months_add", argTypes = { "DATETIMEV2", "INT" }, returnType = "DATETIMEV2")
|
||||
public static DateTimeV2Literal monthsAdd(DateTimeV2Literal date, IntegerLiteral month) throws AnalysisException {
|
||||
return date.plusMonths(month.getValue());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "days_add", argTypes = { "DATE", "INT" }, returnType = "DATE")
|
||||
public static DateLiteral daysAdd(DateLiteral date, IntegerLiteral day) throws AnalysisException {
|
||||
return date.plusDays(day.getValue());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "days_add", argTypes = { "DATETIME", "INT" }, returnType = "DATETIME")
|
||||
public static DateTimeLiteral daysAdd(DateTimeLiteral date, IntegerLiteral day) throws AnalysisException {
|
||||
return date.plusDays(day.getValue());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "days_add", argTypes = { "DATEV2", "INT" }, returnType = "DATEV2")
|
||||
public static DateV2Literal daysAdd(DateV2Literal date, IntegerLiteral day) throws AnalysisException {
|
||||
return date.plusDays(day.getValue());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "days_add", argTypes = { "DATETIMEV2", "INT" }, returnType = "DATETIMEV2")
|
||||
public static DateTimeV2Literal daysAdd(DateTimeV2Literal date, IntegerLiteral day) throws AnalysisException {
|
||||
return date.plusDays(day.getValue());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "hours_add", argTypes = { "DATETIME", "INT" }, returnType = "DATETIME")
|
||||
public static DateTimeLiteral hoursAdd(DateTimeLiteral date, IntegerLiteral hour) throws AnalysisException {
|
||||
return date.plusHours(hour.getValue());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "hours_add", argTypes = { "DATETIMEV2", "INT" }, returnType = "DATETIMEV2")
|
||||
public static DateTimeV2Literal hoursAdd(DateTimeV2Literal date, IntegerLiteral hour) throws AnalysisException {
|
||||
return date.plusHours(hour.getValue());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "minutes_add", argTypes = { "DATETIME", "INT" }, returnType = "DATETIME")
|
||||
public static DateTimeLiteral minutesAdd(DateTimeLiteral date, IntegerLiteral minute) throws AnalysisException {
|
||||
return date.plusMinutes(minute.getValue());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "minutes_add", argTypes = { "DATETIMEV2", "INT" }, returnType = "DATETIMEV2")
|
||||
public static DateTimeV2Literal minutesAdd(DateTimeV2Literal date, IntegerLiteral minute) throws AnalysisException {
|
||||
return date.plusMinutes(minute.getValue());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "seconds_add", argTypes = { "DATETIME", "INT" }, returnType = "DATETIME")
|
||||
public static DateTimeLiteral secondsAdd(DateTimeLiteral date, IntegerLiteral second) throws AnalysisException {
|
||||
return date.plusSeconds(second.getValue());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "seconds_add", argTypes = { "DATETIMEV2", "INT" }, returnType = "DATETIMEV2")
|
||||
public static DateTimeV2Literal secondsAdd(DateTimeV2Literal date, IntegerLiteral second) throws AnalysisException {
|
||||
return date.plusSeconds(second.getValue());
|
||||
}
|
||||
|
||||
@ExecFunction(name = "years_sub", argTypes = { "DATE", "INT" }, returnType = "DATE")
|
||||
public static DateLiteral yearsSub(DateLiteral date, IntegerLiteral year) throws AnalysisException {
|
||||
return yearsAdd(date, new IntegerLiteral(-year.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "years_sub", argTypes = { "DATETIME", "INT" }, returnType = "DATETIME")
|
||||
public static DateTimeLiteral yearsSub(DateTimeLiteral date, IntegerLiteral year) throws AnalysisException {
|
||||
return yearsAdd(date, new IntegerLiteral(-year.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "years_sub", argTypes = { "DATEV2", "INT" }, returnType = "DATEV2")
|
||||
public static DateV2Literal yearsSub(DateV2Literal date, IntegerLiteral year) throws AnalysisException {
|
||||
return yearsAdd(date, new IntegerLiteral(-year.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "years_sub", argTypes = { "DATETIMEV2", "INT" }, returnType = "DATETIMEV2")
|
||||
public static DateTimeV2Literal yearsSub(DateTimeV2Literal date, IntegerLiteral year) throws AnalysisException {
|
||||
return yearsAdd(date, new IntegerLiteral(-year.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "months_sub", argTypes = { "DATE", "INT" }, returnType = "DATE")
|
||||
public static DateLiteral monthsSub(DateLiteral date, IntegerLiteral month) throws AnalysisException {
|
||||
return monthsAdd(date, new IntegerLiteral(-month.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "months_sub", argTypes = { "DATETIME", "INT" }, returnType = "DATETIME")
|
||||
public static DateTimeLiteral monthsSub(DateTimeLiteral date, IntegerLiteral month) throws AnalysisException {
|
||||
return monthsAdd(date, new IntegerLiteral(-month.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "months_sub", argTypes = { "DATEV2", "INT" }, returnType = "DATEV2")
|
||||
public static DateV2Literal monthsSub(DateV2Literal date, IntegerLiteral month) throws AnalysisException {
|
||||
return monthsAdd(date, new IntegerLiteral(-month.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "months_sub", argTypes = { "DATETIMEV2", "INT" }, returnType = "DATETIMEV2")
|
||||
public static DateTimeV2Literal monthsSub(DateTimeV2Literal date, IntegerLiteral month) throws AnalysisException {
|
||||
return monthsAdd(date, new IntegerLiteral(-month.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "days_sub", argTypes = { "DATE", "INT" }, returnType = "DATE")
|
||||
public static DateLiteral daysSub(DateLiteral date, IntegerLiteral day) throws AnalysisException {
|
||||
return daysAdd(date, new IntegerLiteral(-day.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "days_sub", argTypes = { "DATETIME", "INT" }, returnType = "DATETIME")
|
||||
public static DateTimeLiteral daysSub(DateTimeLiteral date, IntegerLiteral day) throws AnalysisException {
|
||||
return daysAdd(date, new IntegerLiteral(-day.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "days_sub", argTypes = { "DATEV2", "INT" }, returnType = "DATEV2")
|
||||
public static DateV2Literal daysSub(DateV2Literal date, IntegerLiteral day) throws AnalysisException {
|
||||
return daysAdd(date, new IntegerLiteral(-day.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "days_sub", argTypes = { "DATETIMEV2", "INT" }, returnType = "DATETIMEV2")
|
||||
public static DateTimeV2Literal daysSub(DateTimeV2Literal date, IntegerLiteral day) throws AnalysisException {
|
||||
return daysAdd(date, new IntegerLiteral(-day.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "hours_sub", argTypes = { "DATETIME", "INT" }, returnType = "DATETIME")
|
||||
public static DateTimeLiteral hoursSub(DateTimeLiteral date, IntegerLiteral hour) throws AnalysisException {
|
||||
return hoursAdd(date, new IntegerLiteral(-hour.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "hours_sub", argTypes = { "DATETIMEV2", "INT" }, returnType = "DATETIMEV2")
|
||||
public static DateTimeV2Literal hoursSub(DateTimeV2Literal date, IntegerLiteral hour) throws AnalysisException {
|
||||
return hoursAdd(date, new IntegerLiteral(-hour.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "minutes_sub", argTypes = { "DATETIME", "INT" }, returnType = "DATETIME")
|
||||
public static DateTimeLiteral minutesSub(DateTimeLiteral date, IntegerLiteral minute) throws AnalysisException {
|
||||
return minutesAdd(date, new IntegerLiteral(-minute.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "minutes_sub", argTypes = { "DATETIMEV2", "INT" }, returnType = "DATETIMEV2")
|
||||
public static DateTimeV2Literal minutesSub(DateTimeV2Literal date, IntegerLiteral minute) throws AnalysisException {
|
||||
return minutesAdd(date, new IntegerLiteral(-minute.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "seconds_sub", argTypes = { "DATETIME", "INT" }, returnType = "DATETIME")
|
||||
public static DateTimeLiteral secondsSub(DateTimeLiteral date, IntegerLiteral second) throws AnalysisException {
|
||||
return secondsAdd(date, new IntegerLiteral(-second.getValue()));
|
||||
}
|
||||
|
||||
@ExecFunction(name = "seconds_sub", argTypes = { "DATETIMEV2", "INT" }, returnType = "DATETIMEV2")
|
||||
public static DateTimeV2Literal secondsSub(DateTimeV2Literal date, IntegerLiteral second) throws AnalysisException {
|
||||
return secondsAdd(date, new IntegerLiteral(-second.getValue()));
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -48,7 +48,7 @@ public class SecondsSub extends ScalarFunction
|
||||
);
|
||||
|
||||
public SecondsSub(Expression arg0, Expression arg1) {
|
||||
super("Seconds_sub", arg0, arg1);
|
||||
super("seconds_sub", arg0, arg1);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -20,6 +20,7 @@ package org.apache.doris.nereids.trees.expressions.literal;
|
||||
import org.apache.doris.analysis.LiteralExpr;
|
||||
import org.apache.doris.catalog.Type;
|
||||
import org.apache.doris.nereids.exceptions.AnalysisException;
|
||||
import org.apache.doris.nereids.trees.expressions.Expression;
|
||||
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
|
||||
import org.apache.doris.nereids.types.DataType;
|
||||
import org.apache.doris.nereids.types.DateType;
|
||||
@ -44,7 +45,10 @@ public class DateLiteral extends Literal {
|
||||
protected static DateTimeFormatter DATE_FORMATTER = null;
|
||||
protected static DateTimeFormatter DATE_FORMATTER_TWO_DIGIT = null;
|
||||
protected static DateTimeFormatter DATEKEY_FORMATTER = null;
|
||||
|
||||
// for cast datetime type to date type.
|
||||
protected static DateTimeFormatter DATE_TIME_FORMATTER = null;
|
||||
private static final LocalDateTime startOfAD = LocalDateTime.of(0, 1, 1, 0, 0, 0);
|
||||
private static final LocalDateTime endOfAD = LocalDateTime.of(9999, 12, 31, 23, 59, 59);
|
||||
private static final Logger LOG = LogManager.getLogger(DateLiteral.class);
|
||||
|
||||
private static final DateLiteral MIN_DATE = new DateLiteral(0000, 1, 1);
|
||||
@ -61,6 +65,7 @@ public class DateLiteral extends Literal {
|
||||
DATE_FORMATTER = DateUtils.formatBuilder("%Y-%m-%d").toFormatter();
|
||||
DATEKEY_FORMATTER = DateUtils.formatBuilder("%Y%m%d").toFormatter();
|
||||
DATE_FORMATTER_TWO_DIGIT = DateUtils.formatBuilder("%y-%m-%d").toFormatter();
|
||||
DATE_TIME_FORMATTER = DateUtils.formatBuilder("%Y-%m-%d %H:%i:%s").toFormatter();
|
||||
} catch (AnalysisException e) {
|
||||
LOG.error("invalid date format", e);
|
||||
System.exit(-1);
|
||||
@ -114,6 +119,8 @@ public class DateLiteral extends Literal {
|
||||
dateTime = DATE_FORMATTER_TWO_DIGIT.parse(s);
|
||||
} else if (s.length() == DATEKEY_LENGTH && !s.contains("-")) {
|
||||
dateTime = DATEKEY_FORMATTER.parse(s);
|
||||
} else if (s.length() == 19) {
|
||||
dateTime = DATE_TIME_FORMATTER.parse(s);
|
||||
} else {
|
||||
dateTime = DATE_FORMATTER.parse(s);
|
||||
}
|
||||
@ -143,6 +150,10 @@ public class DateLiteral extends Literal {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected static boolean isDateOutOfRange(LocalDateTime dateTime) {
|
||||
return dateTime.isBefore(startOfAD) || dateTime.isAfter(endOfAD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getValue() {
|
||||
return (year * 10000 + month * 100 + day) * 1000000L;
|
||||
@ -190,18 +201,25 @@ public class DateLiteral extends Literal {
|
||||
return day;
|
||||
}
|
||||
|
||||
public DateLiteral plusDays(int days) {
|
||||
LocalDateTime dateTime = DateUtils.getTime(DATE_FORMATTER, getStringValue()).plusDays(days);
|
||||
return new DateLiteral(dateTime.getYear(), dateTime.getMonthValue(), dateTime.getDayOfMonth());
|
||||
public Expression plusDays(int days) {
|
||||
return fromJavaDateType(DateUtils.getTime(DATE_FORMATTER, getStringValue()).plusDays(days));
|
||||
}
|
||||
|
||||
public DateLiteral plusMonths(int months) {
|
||||
LocalDateTime dateTime = DateUtils.getTime(DATE_FORMATTER, getStringValue()).plusMonths(months);
|
||||
return new DateLiteral(dateTime.getYear(), dateTime.getMonthValue(), dateTime.getDayOfMonth());
|
||||
public Expression plusMonths(int months) {
|
||||
return fromJavaDateType(DateUtils.getTime(DATE_FORMATTER, getStringValue()).plusMonths(months));
|
||||
}
|
||||
|
||||
public DateLiteral plusYears(int years) {
|
||||
LocalDateTime dateTime = DateUtils.getTime(DATE_FORMATTER, getStringValue()).plusYears(years);
|
||||
return new DateLiteral(dateTime.getYear(), dateTime.getMonthValue(), dateTime.getDayOfMonth());
|
||||
public Expression plusYears(int years) {
|
||||
return fromJavaDateType(DateUtils.getTime(DATE_FORMATTER, getStringValue()).plusYears(years));
|
||||
}
|
||||
|
||||
public LocalDateTime toJavaDateType() {
|
||||
return LocalDateTime.of(((int) getYear()), ((int) getMonth()), ((int) getDay()), 0, 0, 0);
|
||||
}
|
||||
|
||||
public static Expression fromJavaDateType(LocalDateTime dateTime) {
|
||||
return isDateOutOfRange(dateTime)
|
||||
? new NullLiteral(DateType.INSTANCE)
|
||||
: new DateLiteral(dateTime.getYear(), dateTime.getMonthValue(), dateTime.getDayOfMonth());
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,6 +20,7 @@ package org.apache.doris.nereids.trees.expressions.literal;
|
||||
import org.apache.doris.analysis.LiteralExpr;
|
||||
import org.apache.doris.catalog.Type;
|
||||
import org.apache.doris.nereids.exceptions.AnalysisException;
|
||||
import org.apache.doris.nereids.trees.expressions.Expression;
|
||||
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
|
||||
import org.apache.doris.nereids.types.DateTimeType;
|
||||
import org.apache.doris.nereids.types.coercion.DateLikeType;
|
||||
@ -44,8 +45,6 @@ import java.util.Objects;
|
||||
* date time literal.
|
||||
*/
|
||||
public class DateTimeLiteral extends DateLiteral {
|
||||
|
||||
protected static DateTimeFormatter DATE_TIME_FORMATTER = null;
|
||||
protected static DateTimeFormatter DATE_TIME_FORMATTER_TO_HOUR = null;
|
||||
protected static DateTimeFormatter DATE_TIME_FORMATTER_TO_MINUTE = null;
|
||||
protected static DateTimeFormatter DATE_TIME_FORMATTER_TWO_DIGIT = null;
|
||||
@ -272,40 +271,28 @@ public class DateTimeLiteral extends DateLiteral {
|
||||
return new org.apache.doris.analysis.DateLiteral(year, month, day, hour, minute, second, Type.DATETIME);
|
||||
}
|
||||
|
||||
public DateTimeLiteral plusDays(int days) {
|
||||
LocalDateTime d = DateUtils.getTime(DATE_TIME_FORMATTER, getStringValue()).plusDays(days);
|
||||
return new DateTimeLiteral(d.getYear(), d.getMonthValue(), d.getDayOfMonth(),
|
||||
d.getHour(), d.getMinute(), d.getSecond());
|
||||
public Expression plusYears(int years) {
|
||||
return fromJavaDateType(DateUtils.getTime(DATE_TIME_FORMATTER, getStringValue()).plusYears(years));
|
||||
}
|
||||
|
||||
public DateTimeLiteral plusYears(int years) {
|
||||
LocalDateTime d = DateUtils.getTime(DATE_TIME_FORMATTER, getStringValue()).plusYears(years);
|
||||
return new DateTimeLiteral(d.getYear(), d.getMonthValue(), d.getDayOfMonth(),
|
||||
d.getHour(), d.getMinute(), d.getSecond());
|
||||
public Expression plusMonths(int months) {
|
||||
return fromJavaDateType(DateUtils.getTime(DATE_TIME_FORMATTER, getStringValue()).plusMonths(months));
|
||||
}
|
||||
|
||||
public DateTimeLiteral plusMonths(int months) {
|
||||
LocalDateTime d = DateUtils.getTime(DATE_TIME_FORMATTER, getStringValue()).plusMonths(months);
|
||||
return new DateTimeLiteral(d.getYear(), d.getMonthValue(), d.getDayOfMonth(),
|
||||
d.getHour(), d.getMinute(), d.getSecond());
|
||||
public Expression plusDays(int days) {
|
||||
return fromJavaDateType(DateUtils.getTime(DATE_TIME_FORMATTER, getStringValue()).plusDays(days));
|
||||
}
|
||||
|
||||
public DateTimeLiteral plusHours(int hours) {
|
||||
LocalDateTime d = DateUtils.getTime(DATE_TIME_FORMATTER, getStringValue()).plusHours(hours);
|
||||
return new DateTimeLiteral(d.getYear(), d.getMonthValue(), d.getDayOfMonth(),
|
||||
d.getHour(), d.getMinute(), d.getSecond());
|
||||
public Expression plusHours(int hours) {
|
||||
return fromJavaDateType(DateUtils.getTime(DATE_TIME_FORMATTER, getStringValue()).plusHours(hours));
|
||||
}
|
||||
|
||||
public DateTimeLiteral plusMinutes(int minutes) {
|
||||
LocalDateTime d = DateUtils.getTime(DATE_TIME_FORMATTER, getStringValue()).plusMinutes(minutes);
|
||||
return new DateTimeLiteral(d.getYear(), d.getMonthValue(), d.getDayOfMonth(),
|
||||
d.getHour(), d.getMinute(), d.getSecond());
|
||||
public Expression plusMinutes(int minutes) {
|
||||
return fromJavaDateType(DateUtils.getTime(DATE_TIME_FORMATTER, getStringValue()).plusMinutes(minutes));
|
||||
}
|
||||
|
||||
public DateTimeLiteral plusSeconds(int seconds) {
|
||||
LocalDateTime d = DateUtils.getTime(DATE_TIME_FORMATTER, getStringValue()).plusSeconds(seconds);
|
||||
return new DateTimeLiteral(d.getYear(), d.getMonthValue(), d.getDayOfMonth(),
|
||||
d.getHour(), d.getMinute(), d.getSecond());
|
||||
public Expression plusSeconds(long seconds) {
|
||||
return fromJavaDateType(DateUtils.getTime(DATE_TIME_FORMATTER, getStringValue()).plusSeconds(seconds));
|
||||
}
|
||||
|
||||
public long getHour() {
|
||||
@ -331,4 +318,16 @@ public class DateTimeLiteral extends DateLiteral {
|
||||
DateTimeLiteral other = (DateTimeLiteral) o;
|
||||
return Objects.equals(getValue(), other.getValue());
|
||||
}
|
||||
|
||||
public LocalDateTime toJavaDateType() {
|
||||
return LocalDateTime.of(((int) getYear()), ((int) getMonth()), ((int) getDay()),
|
||||
((int) getHour()), ((int) getMinute()), ((int) getSecond()));
|
||||
}
|
||||
|
||||
public static Expression fromJavaDateType(LocalDateTime dateTime) {
|
||||
return isDateOutOfRange(dateTime)
|
||||
? new NullLiteral(DateTimeType.INSTANCE)
|
||||
: new DateTimeLiteral(dateTime.getYear(), dateTime.getMonthValue(), dateTime.getDayOfMonth(),
|
||||
dateTime.getHour(), dateTime.getMinute(), dateTime.getSecond());
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,6 +19,7 @@ package org.apache.doris.nereids.trees.expressions.literal;
|
||||
|
||||
import org.apache.doris.analysis.LiteralExpr;
|
||||
import org.apache.doris.nereids.exceptions.UnboundException;
|
||||
import org.apache.doris.nereids.trees.expressions.Expression;
|
||||
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
|
||||
import org.apache.doris.nereids.types.DateTimeV2Type;
|
||||
import org.apache.doris.nereids.util.DateUtils;
|
||||
@ -38,6 +39,10 @@ public class DateTimeV2Literal extends DateTimeLiteral {
|
||||
super(dateType, s);
|
||||
}
|
||||
|
||||
public DateTimeV2Literal(long year, long month, long day, long hour, long minute, long second) {
|
||||
super(DateTimeV2Type.SYSTEM_DEFAULT, year, month, day, hour, minute, second, 0);
|
||||
}
|
||||
|
||||
public DateTimeV2Literal(long year, long month, long day, long hour, long minute, long second, long microSecond) {
|
||||
super(DateTimeV2Type.SYSTEM_DEFAULT, year, month, day, hour, minute, second, microSecond);
|
||||
}
|
||||
@ -77,44 +82,59 @@ public class DateTimeV2Literal extends DateTimeLiteral {
|
||||
}
|
||||
|
||||
@Override
|
||||
public DateTimeV2Literal plusYears(int years) {
|
||||
LocalDateTime d = DateUtils.getTime(DATE_TIME_FORMATTER_TO_MICRO_SECOND, getStringValue()).plusYears(years);
|
||||
return new DateTimeV2Literal(this.getDataType(), d.getYear(), d.getMonthValue(), d.getDayOfMonth(),
|
||||
d.getHour(), d.getMinute(), d.getSecond(), d.getNano() / 1000L);
|
||||
public Expression plusYears(int years) {
|
||||
return fromJavaDateType(DateUtils.getTime(DATE_TIME_FORMATTER_TO_MICRO_SECOND, getStringValue())
|
||||
.plusYears(years), getDataType().getScale());
|
||||
}
|
||||
|
||||
@Override
|
||||
public DateTimeV2Literal plusMonths(int months) {
|
||||
LocalDateTime d = DateUtils.getTime(DATE_TIME_FORMATTER_TO_MICRO_SECOND, getStringValue()).plusMonths(months);
|
||||
return new DateTimeV2Literal(this.getDataType(), d.getYear(), d.getMonthValue(), d.getDayOfMonth(),
|
||||
d.getHour(), d.getMinute(), d.getSecond(), d.getNano() / 1000L);
|
||||
public Expression plusMonths(int months) {
|
||||
return fromJavaDateType(DateUtils.getTime(DATE_TIME_FORMATTER_TO_MICRO_SECOND, getStringValue())
|
||||
.plusMonths(months), getDataType().getScale());
|
||||
}
|
||||
|
||||
@Override
|
||||
public DateTimeV2Literal plusDays(int days) {
|
||||
LocalDateTime d = DateUtils.getTime(DATE_TIME_FORMATTER_TO_MICRO_SECOND, getStringValue()).plusDays(days);
|
||||
return new DateTimeV2Literal(this.getDataType(), d.getYear(), d.getMonthValue(), d.getDayOfMonth(),
|
||||
d.getHour(), d.getMinute(), d.getSecond(), d.getNano() / 1000L);
|
||||
public Expression plusDays(int days) {
|
||||
return fromJavaDateType(DateUtils.getTime(DATE_TIME_FORMATTER_TO_MICRO_SECOND, getStringValue())
|
||||
.plusDays(days), getDataType().getScale());
|
||||
}
|
||||
|
||||
@Override
|
||||
public DateTimeV2Literal plusHours(int hours) {
|
||||
LocalDateTime d = DateUtils.getTime(DATE_TIME_FORMATTER_TO_MICRO_SECOND, getStringValue()).plusHours(hours);
|
||||
return new DateTimeV2Literal(this.getDataType(), d.getYear(), d.getMonthValue(), d.getDayOfMonth(),
|
||||
d.getHour(), d.getMinute(), d.getSecond(), d.getNano() / 1000L);
|
||||
public Expression plusHours(int hours) {
|
||||
return fromJavaDateType(DateUtils.getTime(DATE_TIME_FORMATTER_TO_MICRO_SECOND, getStringValue())
|
||||
.plusHours(hours), getDataType().getScale());
|
||||
}
|
||||
|
||||
@Override
|
||||
public DateTimeV2Literal plusMinutes(int minutes) {
|
||||
LocalDateTime d = DateUtils.getTime(DATE_TIME_FORMATTER_TO_MICRO_SECOND, getStringValue()).plusMinutes(minutes);
|
||||
return new DateTimeV2Literal(this.getDataType(), d.getYear(), d.getMonthValue(), d.getDayOfMonth(),
|
||||
d.getHour(), d.getMinute(), d.getSecond(), d.getNano() / 1000L);
|
||||
public Expression plusMinutes(int minutes) {
|
||||
return fromJavaDateType(DateUtils.getTime(DATE_TIME_FORMATTER_TO_MICRO_SECOND, getStringValue())
|
||||
.plusMinutes(minutes), getDataType().getScale());
|
||||
}
|
||||
|
||||
@Override
|
||||
public DateTimeV2Literal plusSeconds(int seconds) {
|
||||
LocalDateTime d = DateUtils.getTime(DATE_TIME_FORMATTER_TO_MICRO_SECOND, getStringValue()).plusSeconds(seconds);
|
||||
return new DateTimeV2Literal(this.getDataType(), d.getYear(), d.getMonthValue(), d.getDayOfMonth(),
|
||||
d.getHour(), d.getMinute(), d.getSecond(), d.getNano() / 1000L);
|
||||
public Expression plusSeconds(long seconds) {
|
||||
return fromJavaDateType(DateUtils.getTime(DATE_TIME_FORMATTER_TO_MICRO_SECOND, getStringValue())
|
||||
.plusSeconds(seconds), getDataType().getScale());
|
||||
}
|
||||
|
||||
public Expression plusMicroSeconds(int microSeconds) {
|
||||
return fromJavaDateType(DateUtils.getTime(DATE_TIME_FORMATTER_TO_MICRO_SECOND, getStringValue())
|
||||
.plusNanos(microSeconds * 1000L), getDataType().getScale());
|
||||
}
|
||||
|
||||
public static Expression fromJavaDateType(LocalDateTime dateTime) {
|
||||
return fromJavaDateType(dateTime, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* convert java LocalDateTime object to DateTimeV2Literal object.
|
||||
*/
|
||||
public static Expression fromJavaDateType(LocalDateTime dateTime, int precision) {
|
||||
return isDateOutOfRange(dateTime)
|
||||
? new NullLiteral(DateTimeV2Type.of(precision))
|
||||
: new DateTimeV2Literal(DateTimeV2Type.of(precision),
|
||||
dateTime.getYear(), dateTime.getMonthValue(), dateTime.getDayOfMonth(),
|
||||
dateTime.getHour(), dateTime.getMinute(), dateTime.getSecond(),
|
||||
dateTime.getNano() / (long) Math.pow(10, 9 - precision));
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,6 +20,7 @@ package org.apache.doris.nereids.trees.expressions.literal;
|
||||
import org.apache.doris.analysis.LiteralExpr;
|
||||
import org.apache.doris.catalog.Type;
|
||||
import org.apache.doris.nereids.exceptions.AnalysisException;
|
||||
import org.apache.doris.nereids.trees.expressions.Expression;
|
||||
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
|
||||
import org.apache.doris.nereids.types.DateV2Type;
|
||||
import org.apache.doris.nereids.util.DateUtils;
|
||||
@ -49,18 +50,21 @@ public class DateV2Literal extends DateLiteral {
|
||||
return visitor.visitDateV2Literal(this, context);
|
||||
}
|
||||
|
||||
public DateV2Literal plusDays(int days) {
|
||||
LocalDateTime dateTime = DateUtils.getTime(DATE_FORMATTER, getStringValue()).plusDays(days);
|
||||
return new DateV2Literal(dateTime.getYear(), dateTime.getMonthValue(), dateTime.getDayOfMonth());
|
||||
public Expression plusDays(int days) {
|
||||
return fromJavaDateType(DateUtils.getTime(DATE_FORMATTER, getStringValue()).plusDays(days));
|
||||
}
|
||||
|
||||
public DateV2Literal plusMonths(int months) {
|
||||
LocalDateTime dateTime = DateUtils.getTime(DATE_FORMATTER, getStringValue()).plusMonths(months);
|
||||
return new DateV2Literal(dateTime.getYear(), dateTime.getMonthValue(), dateTime.getDayOfMonth());
|
||||
public Expression plusMonths(int months) {
|
||||
return fromJavaDateType(DateUtils.getTime(DATE_FORMATTER, getStringValue()).plusMonths(months));
|
||||
}
|
||||
|
||||
public DateV2Literal plusYears(int years) {
|
||||
LocalDateTime dateTime = DateUtils.getTime(DATE_FORMATTER, getStringValue()).plusYears(years);
|
||||
return new DateV2Literal(dateTime.getYear(), dateTime.getMonthValue(), dateTime.getDayOfMonth());
|
||||
public Expression plusYears(int years) {
|
||||
return fromJavaDateType(DateUtils.getTime(DATE_FORMATTER, getStringValue()).plusYears(years));
|
||||
}
|
||||
|
||||
public static Expression fromJavaDateType(LocalDateTime dateTime) {
|
||||
return isDateOutOfRange(dateTime)
|
||||
? new NullLiteral(DateV2Type.INSTANCE)
|
||||
: new DateV2Literal(dateTime.getYear(), dateTime.getMonthValue(), dateTime.getDayOfMonth());
|
||||
}
|
||||
}
|
||||
|
||||
@ -180,7 +180,7 @@ public abstract class DataType implements AbstractDataType {
|
||||
case "null_type": // ScalarType.NULL.toSql() return "null_type", so support it
|
||||
return NullType.INSTANCE;
|
||||
case "date":
|
||||
return fromCatalogType(ScalarType.createDateType());
|
||||
return DateType.INSTANCE;
|
||||
case "datev2":
|
||||
return DateV2Type.INSTANCE;
|
||||
case "time":
|
||||
|
||||
@ -59,6 +59,7 @@ import org.apache.doris.nereids.trees.expressions.literal.FloatLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.LargeIntLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.Literal;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.NullLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.SmallIntLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.StringLikeLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.StringLiteral;
|
||||
@ -227,7 +228,9 @@ public class TypeCoercionUtils {
|
||||
* cast input type if input's datatype is not same with dateType.
|
||||
*/
|
||||
public static Expression castIfNotSameType(Expression input, DataType targetType) {
|
||||
if (input.getDataType().equals(targetType) || isSubqueryAndDataTypeIsBitmap(input)
|
||||
if (input.isNullLiteral()) {
|
||||
return new NullLiteral(targetType);
|
||||
} else if (input.getDataType().equals(targetType) || isSubqueryAndDataTypeIsBitmap(input)
|
||||
|| (isVarCharOrStringType(input.getDataType())
|
||||
&& isVarCharOrStringType(targetType))) {
|
||||
return input;
|
||||
@ -1011,7 +1014,7 @@ public class TypeCoercionUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* two types' common type, see {@link TypeCoercionUtilsTest#testFindPrimitiveCommonType()}
|
||||
* two types' common type, see TypeCoercionUtilsTest#testFindCommonPrimitiveTypeForCaseWhen()
|
||||
*/
|
||||
@VisibleForTesting
|
||||
protected static Optional<DataType> findCommonPrimitiveTypeForCaseWhen(DataType t1, DataType t2) {
|
||||
|
||||
Reference in New Issue
Block a user