Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Day_Of_Year Function To OpenSearch #173

Merged
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 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 @@ -325,6 +325,10 @@ public static FunctionExpression dayofyear(Expression... expressions) {
return compile(BuiltinFunctionName.DAYOFYEAR, expressions);
}

public static FunctionExpression day_of_year(Expression... expressions) {
return compile(BuiltinFunctionName.DAY_OF_YEAR, expressions);
}

public static FunctionExpression from_days(Expression... expressions) {
return compile(BuiltinFunctionName.FROM_DAYS, expressions);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ public void register(BuiltinFunctionRepository repository) {
repository.register(dayName());
repository.register(dayOfMonth());
repository.register(dayOfWeek());
repository.register(dayOfYear());
repository.register(dayOfYear(BuiltinFunctionName.DAYOFYEAR));
repository.register(dayOfYear(BuiltinFunctionName.DAY_OF_YEAR));
repository.register(from_days());
repository.register(from_unixtime());
repository.register(hour());
Expand Down Expand Up @@ -319,8 +320,8 @@ private DefaultFunctionResolver dayOfWeek() {
* DAYOFYEAR(STRING/DATE/DATETIME/TIMESTAMP).
* return the day of the year for date (1-366).
*/
private DefaultFunctionResolver dayOfYear() {
return define(BuiltinFunctionName.DAYOFYEAR.getName(),
private DefaultFunctionResolver dayOfYear(BuiltinFunctionName dayOfYear) {
return define(dayOfYear.getName(),
Yury-Fridlyand marked this conversation as resolved.
Show resolved Hide resolved
impl(nullMissingHandling(DateTimeFunction::exprDayOfYear), INTEGER, DATE),
impl(nullMissingHandling(DateTimeFunction::exprDayOfYear), INTEGER, DATETIME),
impl(nullMissingHandling(DateTimeFunction::exprDayOfYear), INTEGER, TIMESTAMP),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ public enum BuiltinFunctionName {
DAYOFMONTH(FunctionName.of("dayofmonth")),
DAYOFWEEK(FunctionName.of("dayofweek")),
DAYOFYEAR(FunctionName.of("dayofyear")),
DAY_OF_YEAR(FunctionName.of("day_of_year")),
FROM_DAYS(FunctionName.of("from_days")),
FROM_UNIXTIME(FunctionName.of("from_unixtime")),
HOUR(FunctionName.of("hour")),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.when;
import static org.opensearch.sql.data.model.ExprValueUtils.integerValue;
import static org.opensearch.sql.data.model.ExprValueUtils.longValue;
Expand Down Expand Up @@ -479,6 +480,76 @@ public void dayOfYear() {
assertEquals(integerValue(220), eval(expression));
}

public void test_day_of_year(String date, int dayOfYear) {
FunctionExpression expression = DSL.day_of_year(DSL.literal(new ExprDateValue(date)));
assertEquals(INTEGER, expression.type());
assertEquals(integerValue(dayOfYear), eval(expression));
}

@Test
public void day_Of_Year() {
lenient().when(nullRef.valueOf(env)).thenReturn(nullValue());
lenient().when(missingRef.valueOf(env)).thenReturn(missingValue());

FunctionExpression expression = DSL.day_of_year(DSL.literal(new ExprDateValue("2020-08-07")));
assertEquals(INTEGER, expression.type());
assertEquals("day_of_year(DATE '2020-08-07')", expression.toString());
assertEquals(integerValue(220), eval(expression));

expression = DSL.day_of_year(DSL.literal("2020-08-07"));
assertEquals(INTEGER, expression.type());
assertEquals("day_of_year(\"2020-08-07\")", expression.toString());
assertEquals(integerValue(220), eval(expression));

expression = DSL.day_of_year(DSL.literal("2020-08-07 01:02:03"));
acarbonetto marked this conversation as resolved.
Show resolved Hide resolved
assertEquals(INTEGER, expression.type());
assertEquals("day_of_year(\"2020-08-07 01:02:03\")", expression.toString());
assertEquals(integerValue(220), eval(expression));

//28th of Feb
test_day_of_year("2020-02-28", 59);

//29th of Feb during leap year
test_day_of_year("2020-02-29 23:59:59", 60);
test_day_of_year("2020-02-29", 60);
GabeFernandez310 marked this conversation as resolved.
Show resolved Hide resolved

//1st of March during leap year
test_day_of_year("2020-03-01 00:00:00", 61);
test_day_of_year("2020-03-01", 61);

//1st of March during non leap year
test_day_of_year("2019-03-01", 60);

//31st of December during leap year (should be 366)
test_day_of_year("2020-12-31", 366);

//Year 1200
test_day_of_year("1200-02-28", 59);

//Year 4000
test_day_of_year("4000-02-28", 59);
}

public void test_invalid_day_of_year(String date) {
FunctionExpression expression = DSL.day_of_year(DSL.literal(new ExprDateValue(date)));
eval(expression);
}

@Test
public void invalid_day_of_year() {
when(nullRef.type()).thenReturn(DATE);
when(missingRef.type()).thenReturn(DATE);
assertEquals(nullValue(), eval(DSL.day_of_year(nullRef)));
assertEquals(missingValue(), eval(DSL.day_of_year(missingRef)));

//29th of Feb non-leapyear
assertThrows(SemanticCheckException.class, () -> test_invalid_day_of_year("2019-02-29"));
//13th month
assertThrows(SemanticCheckException.class, () -> test_invalid_day_of_year("2019-13-15"));
//incorrect format for type
assertThrows(SemanticCheckException.class, () -> test_invalid_day_of_year("asdfasdfasdf"));
}

@Test
public void from_days() {
when(nullRef.type()).thenReturn(LONG);
Expand Down
57 changes: 57 additions & 0 deletions docs/user/dql/functions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1443,6 +1443,7 @@ Description
>>>>>>>>>>>

Usage: dayofyear(date) returns the day of the year for date, in the range 1 to 366.
The function `day_of_year`_ is also provided as an alias.

Argument type: STRING/DATE/DATETIME/TIMESTAMP

Expand All @@ -1458,6 +1459,62 @@ Example::
| 239 |
+---------------------------------+

os> SELECT DAYOFYEAR(DATETIME('2020-08-26 00:00:00'))
fetched rows / total rows = 1/1
+----------------------------------------------+
| DAYOFYEAR(DATETIME('2020-08-26 00:00:00')) |
|----------------------------------------------|
| 239 |
+----------------------------------------------+

os> SELECT DAYOFYEAR(DATE('2020-08-26 00:00:00'))
fetched rows / total rows = 1/1
+-----------------------------------------------+
| DAYOFYEAR(TIMESTAMP('2020-08-26 00:00:00')) |
|-----------------------------------------------|
| 239 |
+-----------------------------------------------+


DAY_OF_YEAR
---------

Description
>>>>>>>>>>>

This function is an alias to the `dayofyear`_ function

Argument type: STRING/DATE/DATETIME/TIMESTAMP

Return type: INTEGER

Example::

os> SELECT DAY_OF_YEAR(DATE('2020-08-26'))
fetched rows / total rows = 1/1
+-----------------------------------+
| DAY_OF_YEAR(DATE('2020-08-26')) |
|-----------------------------------|
| 239 |
+-----------------------------------+

MitchellGale marked this conversation as resolved.
Show resolved Hide resolved
os> SELECT DAY_OF_YEAR(DATETIME('2020-08-26 00:00:00'))
fetched rows / total rows = 1/1
+------------------------------------------------+
| DAY_OF_YEAR(DATETIME('2020-08-26 00:00:00')) |
|------------------------------------------------|
| 239 |
+------------------------------------------------+

os> SELECT DAY_OF_YEAR(DATE('2020-08-26 00:00:00'))
fetched rows / total rows = 1/1
+-------------------------------------------------+
| DAY_OF_YEAR(TIMESTAMP('2020-08-26 00:00:00')) |
|-------------------------------------------------|
| 239 |
+-------------------------------------------------+



FROM_DAYS
---------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,25 @@ public void testDayOfYear() throws IOException {
verifyDataRows(result, rows(260));
}

@Test
public void testDayOfYearWithUnderscores() throws IOException {
JSONObject result = executeQuery("select day_of_year(date('2020-09-16'))");
verifySchema(result, schema("day_of_year(date('2020-09-16'))", null, "integer"));
verifyDataRows(result, rows(260));

result = executeQuery("select day_of_year(datetime('2020-09-16 00:00:00'))");
verifySchema(result, schema("day_of_year(datetime('2020-09-16 00:00:00'))", null, "integer"));
verifyDataRows(result, rows(260));

result = executeQuery("select day_of_year(timestamp('2020-09-16 00:00:00'))");
verifySchema(result, schema("day_of_year(timestamp('2020-09-16 00:00:00'))", null, "integer"));
verifyDataRows(result, rows(260));

result = executeQuery("select day_of_year('2020-09-16')");
verifySchema(result, schema("day_of_year('2020-09-16')", null, "integer"));
verifyDataRows(result, rows(260));
}
Yury-Fridlyand marked this conversation as resolved.
Show resolved Hide resolved

@Test
public void testFromDays() throws IOException {
JSONObject result = executeQuery("select from_days(738049)");
Expand Down
2 changes: 1 addition & 1 deletion sql/src/main/antlr/OpenSearchSQLParser.g4
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ trigonometricFunctionName

dateTimeFunctionName
: ADDDATE | CONVERT_TZ | DATE | DATE_ADD | DATE_FORMAT | DATE_SUB
| DATETIME | DAY | DAYNAME | DAYOFMONTH | DAYOFWEEK | DAYOFYEAR | FROM_DAYS | FROM_UNIXTIME
| DATETIME | DAY | DAYNAME | DAYOFMONTH | DAYOFWEEK | DAYOFYEAR | DAY_OF_YEAR | FROM_DAYS | FROM_UNIXTIME
| HOUR | MAKEDATE | MAKETIME | MICROSECOND | MINUTE | MONTH | MONTHNAME | PERIOD_ADD
| PERIOD_DIFF | QUARTER | SECOND | SUBDATE | SYSDATE | TIME | TIME_TO_SEC
| TIMESTAMP | TO_DAYS | UNIX_TIMESTAMP | WEEK | YEAR
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,12 @@ public void can_parse_now_like_functions(String name, Boolean hasFsp, Boolean ha
assertNotNull(parser.parse("SELECT id FROM test WHERE " + String.join(" AND ", calls)));
}

@Test
public void can_parse_dayofyear_functions() {
assertNotNull(parser.parse("SELECT dayofyear('2022-11-18')"));
assertNotNull(parser.parse("SELECT day_of_year('2022-11-18')"));
}

@Test
public void can_parse_multi_match_relevance_function() {
assertNotNull(parser.parse(
Expand Down