Skip to content
Merged
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 @@ -389,6 +389,10 @@ public static FunctionExpression week(Expression... expressions) {
return compile(BuiltinFunctionName.WEEK, expressions);
}

public static FunctionExpression week_of_year(Expression... expressions) {
return compile(BuiltinFunctionName.WEEK_OF_YEAR, expressions);
}

public static FunctionExpression year(Expression... expressions) {
return compile(BuiltinFunctionName.YEAR, expressions);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@ public void register(BuiltinFunctionRepository repository) {
repository.register(date_format());
repository.register(to_days());
repository.register(unix_timestamp());
repository.register(week());
repository.register(week(BuiltinFunctionName.WEEK));
repository.register(week(BuiltinFunctionName.WEEK_OF_YEAR));
repository.register(year());
}

Expand Down Expand Up @@ -548,8 +549,8 @@ private DefaultFunctionResolver unix_timestamp() {
/**
* WEEK(DATE[,mode]). return the week number for date.
*/
private DefaultFunctionResolver week() {
return define(BuiltinFunctionName.WEEK.getName(),
private DefaultFunctionResolver week(BuiltinFunctionName week) {
return define(week.getName(),
impl(nullMissingHandling(DateTimeFunction::exprWeekWithoutMode), INTEGER, DATE),
impl(nullMissingHandling(DateTimeFunction::exprWeekWithoutMode), INTEGER, DATETIME),
impl(nullMissingHandling(DateTimeFunction::exprWeekWithoutMode), INTEGER, TIMESTAMP),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ public enum BuiltinFunctionName {
TO_DAYS(FunctionName.of("to_days")),
UNIX_TIMESTAMP(FunctionName.of("unix_timestamp")),
WEEK(FunctionName.of("week")),
WEEK_OF_YEAR(FunctionName.of("week_of_year")),
YEAR(FunctionName.of("year")),
// `now`-like functions
NOW(FunctionName.of("now")),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -949,6 +949,93 @@ public void modeInUnsupportedFormat() {
exception.getMessage());
}

private void testWeekOfYear(String date, int mode, int expectedResult) {
FunctionExpression expression = DSL
.week_of_year(DSL.literal(new ExprDateValue(date)), DSL.literal(mode));
assertEquals(INTEGER, expression.type());
assertEquals(String.format("week_of_year(DATE '%s', %d)", date, mode), expression.toString());
assertEquals(integerValue(expectedResult), eval(expression));
}

private void testNullMissingWeekOfYear(ExprCoreType date) {
when(nullRef.type()).thenReturn(date);
when(missingRef.type()).thenReturn(date);
assertEquals(nullValue(), eval(DSL.week_of_year(nullRef)));
assertEquals(missingValue(), eval(DSL.week_of_year(missingRef)));
}

@Test
public void invalid_week_of_year() {
testNullMissingWeekOfYear(DATE);
testNullMissingWeekOfYear(DATETIME);
testNullMissingWeekOfYear(TIMESTAMP);
testNullMissingWeekOfYear(STRING);

when(nullRef.type()).thenReturn(INTEGER);
when(missingRef.type()).thenReturn(INTEGER);
assertEquals(nullValue(), eval(DSL.week_of_year(DSL.literal("2019-01-05"), nullRef)));
assertEquals(missingValue(), eval(DSL.week_of_year(DSL.literal("2019-01-05"), missingRef)));

when(nullRef.type()).thenReturn(DATE);
when(missingRef.type()).thenReturn(INTEGER);
assertEquals(missingValue(), eval(DSL.week_of_year(nullRef, missingRef)));
}

@Test
public void week_of_year() {
testNullMissingWeekOfYear(DATE);
testNullMissingWeekOfYear(DATETIME);
testNullMissingWeekOfYear(TIMESTAMP);
testNullMissingWeekOfYear(STRING);

FunctionExpression expression = DSL
.week_of_year(DSL.literal(new ExprTimestampValue("2019-01-05 01:02:03")));
assertEquals(INTEGER, expression.type());
assertEquals("week_of_year(TIMESTAMP '2019-01-05 01:02:03')", expression.toString());
assertEquals(integerValue(0), eval(expression));

expression = DSL.week_of_year(DSL.literal("2019-01-05"));
assertEquals(INTEGER, expression.type());
assertEquals("week_of_year(\"2019-01-05\")", expression.toString());
assertEquals(integerValue(0), eval(expression));

expression = DSL.week_of_year(DSL.literal("2019-01-05 00:01:00"));
assertEquals(INTEGER, expression.type());
assertEquals("week_of_year(\"2019-01-05 00:01:00\")", expression.toString());
assertEquals(integerValue(0), eval(expression));

testWeekOfYear("2019-01-05", 0, 0);
testWeekOfYear("2019-01-05", 1, 1);
testWeekOfYear("2019-01-05", 2, 52);
testWeekOfYear("2019-01-05", 3, 1);
testWeekOfYear("2019-01-05", 4, 1);
testWeekOfYear("2019-01-05", 5, 0);
testWeekOfYear("2019-01-05", 6, 1);
testWeekOfYear("2019-01-05", 7, 53);

testWeekOfYear("2019-01-06", 0, 1);
testWeekOfYear("2019-01-06", 1, 1);
testWeekOfYear("2019-01-06", 2, 1);
testWeekOfYear("2019-01-06", 3, 1);
testWeekOfYear("2019-01-06", 4, 2);
testWeekOfYear("2019-01-06", 5, 0);
testWeekOfYear("2019-01-06", 6, 2);
testWeekOfYear("2019-01-06", 7, 53);

testWeekOfYear("2019-01-07", 0, 1);
testWeekOfYear("2019-01-07", 1, 2);
testWeekOfYear("2019-01-07", 2, 1);
testWeekOfYear("2019-01-07", 3, 2);
testWeekOfYear("2019-01-07", 4, 2);
testWeekOfYear("2019-01-07", 5, 1);
testWeekOfYear("2019-01-07", 6, 2);
testWeekOfYear("2019-01-07", 7, 1);

testWeekOfYear("2000-01-01", 0, 0);
testWeekOfYear("2000-01-01", 2, 52);
testWeekOfYear("1999-12-31", 0, 52);
}

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

Usage: week(date[, mode]) returns the week number for date. If the mode argument is omitted, the default mode 0 is used.
The function week_of_year is also provided as an alternate syntax.

.. list-table:: The following table describes how the mode argument works.
:widths: 25 50 25 75
Expand Down Expand Up @@ -2116,6 +2117,14 @@ Example::
| 7 | 8 |
+----------------------------+-------------------------------+

>od SELECT WEEK_OF_YEAR(DATE('2008-02-20')), WEEK_OF_YEAR(DATE('2008-02-20'), 1)
fetched rows / total rows = 1/1
+------------------------------------+---------------------------------------+
| WEEK_OF_YEAR(DATE('2008-02-20')) | WEEK_OF_YEAR(DATE('2008-02-20'), 1) |
|------------------------------------|---------------------------------------|
| 7 | 8 |
+------------------------------------+---------------------------------------+


YEAR
----
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,19 @@ public void testWeek() throws IOException {
week("2000-01-01", 2, 52);
}

@Test
public void testWeek_Of_Year() throws IOException {
JSONObject result = executeQuery("select week_of_year(date('2008-02-20'))");
verifySchema(result, schema("week_of_year(date('2008-02-20'))", null, "integer"));
verifyDataRows(result, rows(7));

week("2008-02-20", 0, 7);
week("2008-02-20", 1, 8);
week("2008-12-31", 1, 53);
week("2000-01-01", 0, 0);
week("2000-01-01", 2, 52);
}

void verifyDateFormat(String date, String type, String format, String formatted) throws IOException {
String query = String.format("date_format(%s('%s'), '%s')", type, date, format);
JSONObject result = executeQuery("select " + query);
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 @@ -397,7 +397,7 @@ dateTimeFunctionName
| DATETIME | DAY | DAYNAME | DAYOFMONTH | DAYOFWEEK | DAYOFYEAR | 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
| TIMESTAMP | TO_DAYS | UNIX_TIMESTAMP | WEEK | WEEK_OF_YEAR | YEAR
;

// Functions which value could be cached in scope of a single query
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,13 @@ 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_week_of_year_functions() {
assertNotNull(parser.parse("SELECT week('2022-11-18')"));
assertNotNull(parser.parse("SELECT week_of_year('2022-11-18')"));
}

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