Skip to content

Commit

Permalink
[Fix](Nereids) fix date and date time arithmatic (apache#40745)
Browse files Browse the repository at this point in the history
fix date and time arithmatic of: hours_add, minutes_add, seconds_add,
to_days
  • Loading branch information
LiBinfeng-01 committed Oct 8, 2024
1 parent 21718c5 commit e085eef
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,16 @@ public static Expression daysAdd(DateTimeV2Literal date, IntegerLiteral day) {
/**
* datetime arithmetic function hours-add.
*/
@ExecFunction(name = "hours_add", argTypes = {"DATE", "INT"}, returnType = "DATE")
public static Expression hoursAdd(DateLiteral date, IntegerLiteral hour) {
return date.toBeginOfTheDay().plusHours(hour.getValue());
}

@ExecFunction(name = "hours_add", argTypes = {"DATEV2", "INT"}, returnType = "DATEV2")
public static Expression hoursAdd(DateV2Literal date, IntegerLiteral hour) {
return date.toBeginOfTheDay().plusHours(hour.getValue());
}

@ExecFunction(name = "hours_add", argTypes = {"DATETIME", "INT"}, returnType = "DATETIME")
public static Expression hoursAdd(DateTimeLiteral date, IntegerLiteral hour) {
return date.plusHours(hour.getValue());
Expand All @@ -187,6 +197,16 @@ public static Expression hoursAdd(DateTimeV2Literal date, IntegerLiteral hour) {
/**
* datetime arithmetic function minutes-add.
*/
@ExecFunction(name = "minutes_add", argTypes = {"DATE", "INT"}, returnType = "DATE")
public static Expression minutesAdd(DateLiteral date, IntegerLiteral minute) {
return date.toBeginOfTheDay().plusMinutes(minute.getValue());
}

@ExecFunction(name = "minutes_add", argTypes = {"DATEV2", "INT"}, returnType = "DATEV2")
public static Expression minutesAdd(DateV2Literal date, IntegerLiteral minute) {
return date.toBeginOfTheDay().plusMinutes(minute.getValue());
}

@ExecFunction(name = "minutes_add", argTypes = {"DATETIME", "INT"}, returnType = "DATETIME")
public static Expression minutesAdd(DateTimeLiteral date, IntegerLiteral minute) {
return date.plusMinutes(minute.getValue());
Expand All @@ -200,6 +220,16 @@ public static Expression minutesAdd(DateTimeV2Literal date, IntegerLiteral minut
/**
* datetime arithmetic function seconds-add.
*/
@ExecFunction(name = "seconds_add", argTypes = {"DATE", "INT"}, returnType = "DATE")
public static Expression secondsAdd(DateLiteral date, IntegerLiteral second) {
return date.toBeginOfTheDay().plusSeconds(second.getValue());
}

@ExecFunction(name = "seconds_add", argTypes = {"DATEV2", "INT"}, returnType = "DATEV2")
public static Expression secondsAdd(DateV2Literal date, IntegerLiteral second) {
return date.toBeginOfTheDay().plusSeconds(second.getValue());
}

@ExecFunction(name = "seconds_add", argTypes = {"DATETIME", "INT"}, returnType = "DATETIME")
public static Expression secondsAdd(DateTimeLiteral date, IntegerLiteral second) {
return date.plusSeconds(second.getValue());
Expand Down Expand Up @@ -380,4 +410,14 @@ public static Expression dateDiff(DateTimeV2Literal date1, DateTimeV2Literal dat
private static int dateDiff(LocalDateTime date1, LocalDateTime date2) {
return ((int) ChronoUnit.DAYS.between(date2.toLocalDate(), date1.toLocalDate()));
}

@ExecFunction(name = "to_days")
public static Expression toDays(DateLiteral date) {
return new IntegerLiteral((int) date.getDay());
}

@ExecFunction(name = "to_days")
public static Expression toDays(DateV2Literal date) {
return new IntegerLiteral((int) date.getDay());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,18 @@
import org.apache.doris.nereids.trees.expressions.TimestampArithmetic;
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.TimeRoundSeries;
import org.apache.doris.nereids.trees.expressions.functions.scalar.AppendTrailingCharIfAbsent;
import org.apache.doris.nereids.trees.expressions.functions.scalar.ConvertTz;
import org.apache.doris.nereids.trees.expressions.functions.scalar.DateFormat;
import org.apache.doris.nereids.trees.expressions.functions.scalar.DateTrunc;
import org.apache.doris.nereids.trees.expressions.functions.scalar.FromUnixtime;
import org.apache.doris.nereids.trees.expressions.functions.scalar.HoursAdd;
import org.apache.doris.nereids.trees.expressions.functions.scalar.MinutesAdd;
import org.apache.doris.nereids.trees.expressions.functions.scalar.SecondsAdd;
import org.apache.doris.nereids.trees.expressions.functions.scalar.StrToDate;
import org.apache.doris.nereids.trees.expressions.functions.scalar.ToDays;
import org.apache.doris.nereids.trees.expressions.functions.scalar.UnixTimestamp;
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;
Expand All @@ -39,6 +51,8 @@
import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral;
import org.apache.doris.nereids.trees.expressions.literal.Interval.TimeUnit;
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.StringLiteral;
import org.apache.doris.nereids.trees.expressions.literal.VarcharLiteral;
import org.apache.doris.nereids.trees.plans.RelationId;
import org.apache.doris.nereids.types.DateTimeV2Type;
Expand Down Expand Up @@ -155,8 +169,77 @@ public void testCastFold() {
}

@Test
public void testCompareFold() {
executor = new ExpressionRuleExecutor(ImmutableList.of(FoldConstantRuleOnFE.INSTANCE));
void testFoldDate() {
executor = new ExpressionRuleExecutor(ImmutableList.of(
bottomUp(FoldConstantRuleOnFE.VISITOR_INSTANCE)
));
HoursAdd hoursAdd = new HoursAdd(DateLiteral.fromJavaDateType(LocalDateTime.of(1, 1, 1, 1, 1, 1)),
new IntegerLiteral(1));
Expression rewritten = executor.rewrite(hoursAdd, context);
Assertions.assertEquals(new DateTimeLiteral("0001-01-01 01:00:00"), rewritten);
hoursAdd = new HoursAdd(DateV2Literal.fromJavaDateType(LocalDateTime.of(1, 1, 1, 1, 1, 1)),
new IntegerLiteral(1));
rewritten = executor.rewrite(hoursAdd, context);
Assertions.assertEquals(new DateTimeV2Literal("0001-01-01 01:00:00"), rewritten);
hoursAdd = new HoursAdd(DateV2Literal.fromJavaDateType(LocalDateTime.of(9999, 12, 31, 23, 1, 1)),
new IntegerLiteral(24));
rewritten = executor.rewrite(hoursAdd, context);
Assertions.assertEquals(new NullLiteral(hoursAdd.getDataType()), rewritten);
hoursAdd = new HoursAdd(DateV2Literal.fromJavaDateType(LocalDateTime.of(0, 1, 1, 1, 1, 1)),
new IntegerLiteral(-25));
rewritten = executor.rewrite(hoursAdd, context);
Assertions.assertEquals(new NullLiteral(hoursAdd.getDataType()), rewritten);

MinutesAdd minutesAdd = new MinutesAdd(DateLiteral.fromJavaDateType(LocalDateTime.of(1, 1, 1, 1, 1, 1)),
new IntegerLiteral(1));
rewritten = executor.rewrite(minutesAdd, context);
Assertions.assertEquals(new DateTimeLiteral("0001-01-01 00:01:00"), rewritten);
minutesAdd = new MinutesAdd(DateV2Literal.fromJavaDateType(LocalDateTime.of(1, 1, 1, 1, 1, 1)),
new IntegerLiteral(1));
rewritten = executor.rewrite(minutesAdd, context);
Assertions.assertEquals(new DateTimeV2Literal("0001-01-01 00:01:00"), rewritten);
minutesAdd = new MinutesAdd(DateV2Literal.fromJavaDateType(LocalDateTime.of(9999, 12, 31, 23, 59, 1)),
new IntegerLiteral(1440));
rewritten = executor.rewrite(minutesAdd, context);
Assertions.assertEquals(new NullLiteral(minutesAdd.getDataType()), rewritten);
minutesAdd = new MinutesAdd(DateV2Literal.fromJavaDateType(LocalDateTime.of(0, 1, 1, 0, 1, 1)),
new IntegerLiteral(-2));
rewritten = executor.rewrite(minutesAdd, context);
Assertions.assertEquals(new NullLiteral(minutesAdd.getDataType()), rewritten);

SecondsAdd secondsAdd = new SecondsAdd(DateLiteral.fromJavaDateType(LocalDateTime.of(1, 1, 1, 1, 1, 1)),
new IntegerLiteral(1));
rewritten = executor.rewrite(secondsAdd, context);
Assertions.assertEquals(new DateTimeLiteral("0001-01-01 00:00:01"), rewritten);
secondsAdd = new SecondsAdd(DateV2Literal.fromJavaDateType(LocalDateTime.of(1, 1, 1, 1, 1, 1)),
new IntegerLiteral(1));
rewritten = executor.rewrite(secondsAdd, context);
Assertions.assertEquals(new DateTimeV2Literal("0001-01-01 00:00:01"), rewritten);
secondsAdd = new SecondsAdd(DateV2Literal.fromJavaDateType(LocalDateTime.of(9999, 12, 31, 23, 59, 59)),
new IntegerLiteral(86400));
rewritten = executor.rewrite(secondsAdd, context);
Assertions.assertEquals(new NullLiteral(secondsAdd.getDataType()), rewritten);
secondsAdd = new SecondsAdd(DateV2Literal.fromJavaDateType(LocalDateTime.of(0, 1, 1, 0, 1, 1)),
new IntegerLiteral(-61));
rewritten = executor.rewrite(secondsAdd, context);
Assertions.assertEquals(new NullLiteral(secondsAdd.getDataType()), rewritten);

ToDays toDays = new ToDays(DateLiteral.fromJavaDateType(LocalDateTime.of(1, 1, 1, 1, 1, 1)));
rewritten = executor.rewrite(toDays, context);
Assertions.assertEquals(new IntegerLiteral(366), rewritten);
toDays = new ToDays(DateV2Literal.fromJavaDateType(LocalDateTime.of(1, 1, 1, 1, 1, 1)));
rewritten = executor.rewrite(toDays, context);
Assertions.assertEquals(new IntegerLiteral(366), rewritten);
toDays = new ToDays(DateV2Literal.fromJavaDateType(LocalDateTime.of(9999, 12, 31, 1, 1, 1)));
rewritten = executor.rewrite(toDays, context);
Assertions.assertEquals(new IntegerLiteral(3652424), rewritten);
}

@Test
void testCompareFold() {
executor = new ExpressionRuleExecutor(ImmutableList.of(
bottomUp(FoldConstantRuleOnFE.VISITOR_INSTANCE)
));
assertRewriteAfterTypeCoercion("'1' = 2", "false");
assertRewriteAfterTypeCoercion("1 = 2", "false");
assertRewriteAfterTypeCoercion("1 != 2", "true");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,4 +161,6 @@ suite("test_fold_constant_by_fe") {
res = sql """explain select "12" like '%123%'"""
assertTrue(res.contains("like"))

testFoldConst("select DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY) + INTERVAL 3600 SECOND")

}

0 comments on commit e085eef

Please sign in to comment.