Skip to content

Commit

Permalink
Add Timestampdiff Function To OpenSearch SQL (#1467)
Browse files Browse the repository at this point in the history
* Add `Timestampdiff` Function To OpenSearch SQL

Added Tests And Implementation For Timestampdiff

---------

Signed-off-by: GabeFernandez310 <[email protected]>

* Removed Import

Signed-off-by: GabeFernandez310 <[email protected]>

---------

Signed-off-by: GabeFernandez310 <[email protected]>
(cherry picked from commit 31148da)
  • Loading branch information
GabeFernandez310 authored and github-actions[bot] committed Mar 24, 2023
1 parent 49a82ae commit b9a568b
Show file tree
Hide file tree
Showing 11 changed files with 534 additions and 13 deletions.
6 changes: 6 additions & 0 deletions core/src/main/java/org/opensearch/sql/expression/DSL.java
Original file line number Diff line number Diff line change
Expand Up @@ -924,6 +924,12 @@ public static FunctionExpression timestampadd(FunctionProperties functionPropert
return compile(functionProperties, BuiltinFunctionName.TIMESTAMPADD, expressions);
}

public static FunctionExpression timestampdiff(FunctionProperties functionProperties,
Expression... expressions) {
return compile(functionProperties, BuiltinFunctionName.TIMESTAMPDIFF, expressions);
}


public static FunctionExpression utc_date(FunctionProperties functionProperties,
Expression... args) {
return compile(functionProperties, BuiltinFunctionName.UTC_DATE, args);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ public void register(BuiltinFunctionRepository repository) {
repository.register(timediff());
repository.register(timestamp());
repository.register(timestampadd());
repository.register(timestampdiff());
repository.register(utc_date());
repository.register(utc_time());
repository.register(utc_timestamp());
Expand Down Expand Up @@ -899,6 +900,15 @@ private DefaultFunctionResolver timestamp() {
TIMESTAMP, TIMESTAMP, TIMESTAMP));
}

/**
* Adds an interval of time to the provided DATE/DATETIME/TIME/TIMESTAMP/STRING argument.
* The interval of time added is determined by the given first and second arguments.
* The first argument is an interval type, and must be one of the tokens below...
* [MICROSECOND, SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER, YEAR]
* The second argument is the amount of the interval type to be added.
* The third argument is the DATE/DATETIME/TIME/TIMESTAMP/STRING to add to.
* @return The DATETIME representing the summed DATE/DATETIME/TIME/TIMESTAMP and interval.
*/
private DefaultFunctionResolver timestampadd() {
return define(BuiltinFunctionName.TIMESTAMPADD.getName(),
impl(nullMissingHandling(DateTimeFunction::exprTimestampAdd),
Expand All @@ -915,6 +925,35 @@ private DefaultFunctionResolver timestampadd() {
DATETIME, STRING, INTEGER, TIME));
}

/**
* Finds the difference between provided DATE/DATETIME/TIME/TIMESTAMP/STRING arguments.
* The first argument is an interval type, and must be one of the tokens below...
* [MICROSECOND, SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER, YEAR]
* The second argument the DATE/DATETIME/TIME/TIMESTAMP/STRING representing the start time.
* The third argument is the DATE/DATETIME/TIME/TIMESTAMP/STRING representing the end time.
* @return A LONG representing the difference between arguments, using the given interval type.
*/
private DefaultFunctionResolver timestampdiff() {
return define(BuiltinFunctionName.TIMESTAMPDIFF.getName(),
impl(nullMissingHandling(DateTimeFunction::exprTimestampDiff),
DATETIME, STRING, DATETIME, DATETIME),
impl(nullMissingHandling(DateTimeFunction::exprTimestampDiff),
DATETIME, STRING, DATETIME, TIMESTAMP),
impl(nullMissingHandling(DateTimeFunction::exprTimestampDiff),
DATETIME, STRING, TIMESTAMP, DATETIME),
impl(nullMissingHandling(DateTimeFunction::exprTimestampDiff),
DATETIME, STRING, TIMESTAMP, TIMESTAMP),
implWithProperties(
nullMissingHandlingWithProperties(
(functionProperties, part, startTime, endTime) -> exprTimestampDiffForTimeType(
functionProperties,
part,
startTime,
endTime)),
DATETIME, STRING, TIME, TIME)
);
}

/**
* TO_DAYS(STRING/DATE/DATETIME/TIMESTAMP). return the day number of the given date.
*/
Expand Down Expand Up @@ -1871,6 +1910,62 @@ private ExprValue exprTimestampAddForTimeType(Clock clock,
return exprTimestampAdd(partExpr, amountExpr, new ExprDatetimeValue(datetime));
}

private ExprValue getTimeDifference(String part, LocalDateTime startTime, LocalDateTime endTime) {
long returnVal;
switch (part) {
case "MICROSECOND":
returnVal = MICROS.between(startTime, endTime);
break;
case "SECOND":
returnVal = SECONDS.between(startTime, endTime);
break;
case "MINUTE":
returnVal = MINUTES.between(startTime, endTime);
break;
case "HOUR":
returnVal = HOURS.between(startTime, endTime);
break;
case "DAY":
returnVal = DAYS.between(startTime, endTime);
break;
case "WEEK":
returnVal = WEEKS.between(startTime, endTime);
break;
case "MONTH":
returnVal = MONTHS.between(startTime, endTime);
break;
case "QUARTER":
returnVal = MONTHS.between(startTime, endTime) / 3;
break;
case "YEAR":
returnVal = YEARS.between(startTime, endTime);
break;
default:
return ExprNullValue.of();
}
return new ExprLongValue(returnVal);
}

private ExprValue exprTimestampDiff(
ExprValue partExpr,
ExprValue startTimeExpr,
ExprValue endTimeExpr) {
return getTimeDifference(
partExpr.stringValue(),
startTimeExpr.datetimeValue(),
endTimeExpr.datetimeValue());
}

private ExprValue exprTimestampDiffForTimeType(FunctionProperties fp,
ExprValue partExpr,
ExprValue startTimeExpr,
ExprValue endTimeExpr) {
return getTimeDifference(
partExpr.stringValue(),
extractDateTime(startTimeExpr, fp),
extractDateTime(endTimeExpr, fp));
}

/**
* UTC_DATE implementation for ExprValue.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ public enum BuiltinFunctionName {
TIME_TO_SEC(FunctionName.of("time_to_sec")),
TIMESTAMP(FunctionName.of("timestamp")),
TIMESTAMPADD(FunctionName.of("timestampadd")),
TIMESTAMPDIFF(FunctionName.of("timestampdiff")),
TIME_FORMAT(FunctionName.of("time_format")),
TO_DAYS(FunctionName.of("to_days")),
TO_SECONDS(FunctionName.of("to_seconds")),
Expand Down
Loading

0 comments on commit b9a568b

Please sign in to comment.