Skip to content

Commit

Permalink
[BugFix] Support cast constant time type to DateTime (#55804)
Browse files Browse the repository at this point in the history
Signed-off-by: Jiao Mingye <[email protected]>
(cherry picked from commit f91fcfa)
  • Loading branch information
mxdzs0612 authored and mergify[bot] committed Feb 27, 2025
1 parent 856a6f4 commit 12ba126
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import java.text.DecimalFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Objects;
Expand Down Expand Up @@ -373,6 +374,11 @@ public String toString() {
} else if (type.isDate()) {
LocalDateTime time = (LocalDateTime) Optional.ofNullable(value).orElse(LocalDateTime.MIN);
return time.format(DateUtils.DATE_FORMATTER_UNIX);
} else if (type.isTime()) {
// Time is a double value but we only need int when casting to datetime
if (value instanceof Double) {
return String.valueOf(((Double) value).intValue());
}
} else if (type.isFloatingPointType()) {
double val = (double) Optional.ofNullable(value).orElse((double) 0);
BigDecimal decimal = BigDecimal.valueOf(val);
Expand Down Expand Up @@ -499,8 +505,8 @@ public Optional<ConstantOperator> castToStrictly(Type type) {
}

public Optional<ConstantOperator> castTo(Type desc) {
if (type.isTime() || desc.isTime()) {
// Don't support constant time cast in FE
if ((type.isTime() || desc.isTime()) && !(type.isTime() && desc.isDatetime())) {
// Don't support constant time cast to types other than datetime in FE
return Optional.empty();
}

Expand Down Expand Up @@ -558,12 +564,25 @@ public Optional<ConstantOperator> castTo(Type desc) {
}
res = ConstantOperator.createDouble(Double.parseDouble(childString));
} else if (desc.isDate() || desc.isDatetime()) {
String dateStr = StringUtils.strip(childString, "\r\n\t ");
LocalDateTime dateTime = DateUtils.parseStrictDateTime(dateStr);
if (Type.DATE.equals(desc)) {
dateTime = dateTime.truncatedTo(ChronoUnit.DAYS);
if (type.isTime()) {
// Cast time to datetime
String timeStr = StringUtils.strip(childString, "\r\n\t ");
int time = Integer.parseInt(timeStr);
int hours = time / 3600;
int minutes = (time % 3600) / 60;
int seconds = time % 60;
LocalDate date = LocalDate.now();
LocalTime localTime = LocalTime.of(hours, minutes, seconds);
LocalDateTime dateTime = LocalDateTime.of(date, localTime);
res = ConstantOperator.createDatetime(dateTime, desc);
} else {
String dateStr = StringUtils.strip(childString, "\r\n\t ");
LocalDateTime dateTime = DateUtils.parseStrictDateTime(dateStr);
if (Type.DATE.equals(desc)) {
dateTime = dateTime.truncatedTo(ChronoUnit.DAYS);
}
res = ConstantOperator.createDatetime(dateTime, desc);
}
res = ConstantOperator.createDatetime(dateTime, desc);
} else if (desc.isDecimalV2()) {
res = ConstantOperator.createDecimal(BigDecimal.valueOf(Double.parseDouble(childString)), Type.DECIMALV2);
} else if (desc.isDecimalV3()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,18 @@ public static ConstantOperator fromUnixTime(ConstantOperator unixTime, ConstantO
return dateFormat(dl, fmtLiteral);
}

@ConstantFunction.List(list = {
@ConstantFunction(name = "curtime", argTypes = {}, returnType = TIME),
@ConstantFunction(name = "current_time", argTypes = {}, returnType = TIME)
})
public static ConstantOperator curTime() {
ConnectContext connectContext = ConnectContext.get();
LocalDateTime startTime = Instant.ofEpochMilli(connectContext.getStartTime() / 1000 * 1000)
.atZone(TimeUtils.getTimeZone().toZoneId()).toLocalDateTime();
double second = startTime.getHour() * 3600D + startTime.getMinute() * 60D + startTime.getSecond();
return ConstantOperator.createTime(second);
}

@ConstantFunction.List(list = {
@ConstantFunction(name = "now", argTypes = {}, returnType = DATETIME),
@ConstantFunction(name = "current_timestamp", argTypes = {}, returnType = DATETIME),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public void testCastToDateValid() throws Exception {
}

@Test
public void testCaseToDateInvalid() {
public void testCastToDateInvalid() {
String[] testCases = {
// Invalid year.
"20190-05-31",
Expand Down Expand Up @@ -110,7 +110,7 @@ public void testCaseToDateInvalid() {
}

@Test
public void testCaseDateToNumber() throws Exception {
public void testCastDateToNumber() throws Exception {
ConstantOperator date = ConstantOperator.createDate(LocalDateTime.of(2023, 01, 01, 0, 0));
ConstantOperator datetime = ConstantOperator.createDatetime(LocalDateTime.of(2023, 01, 01, 0, 0, 0));

Expand Down Expand Up @@ -142,6 +142,14 @@ public void testCaseDateToNumber() throws Exception {
Assert.assertEquals(datetimeDoubleNumber, datetime.castTo(Type.DOUBLE).get());
}

@Test
public void testCastTimeToDateTime() {
LocalDateTime now = LocalDateTime.now().withNano(0);
ConstantOperator time = ConstantOperator.createTime(now.getHour() * 3600D + now.getMinute() * 60D + now.getSecond());
ConstantOperator datetime = ConstantOperator.createDatetime(now);
Assert.assertEquals(datetime, time.castTo(Type.DATETIME).get());
}

@Test
public void testDistance() {
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1373,6 +1373,8 @@ public void testNow() {
LocalDateTime expected = Instant.ofEpochMilli(ctx.getStartTime() / 1000 * 1000)
.atZone(TimeUtils.getTimeZone().toZoneId()).toLocalDateTime();
assertEquals(expected, ScalarOperatorFunctions.now().getDatetime());
double expectedTime = expected.getHour() * 3600D + expected.getMinute() * 60D + expected.getSecond();
assertEquals(expectedTime, ScalarOperatorFunctions.curTime().getTime(), 0.1);
}

@Test
Expand Down

0 comments on commit 12ba126

Please sign in to comment.