Skip to content

Commit

Permalink
Add WeekOfYear Function To OpenSearch (opensearch-project#1345)
Browse files Browse the repository at this point in the history
Added WeekOfYear As An Alias To Week Function

Signed-off-by: GabeFernandez310 <[email protected]>
  • Loading branch information
GabeFernandez310 authored Feb 16, 2023
1 parent d9114f5 commit 114e02a
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 28 deletions.
5 changes: 5 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 @@ -439,6 +439,11 @@ public static FunctionExpression week(
return compile(functionProperties, BuiltinFunctionName.WEEK, expressions);
}

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

public static FunctionExpression week_of_year(
FunctionProperties functionProperties, Expression... expressions) {
return compile(functionProperties, BuiltinFunctionName.WEEK_OF_YEAR, expressions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ public void register(BuiltinFunctionRepository repository) {
repository.register(to_days());
repository.register(unix_timestamp());
repository.register(week(BuiltinFunctionName.WEEK));
repository.register(week(BuiltinFunctionName.WEEKOFYEAR));
repository.register(week(BuiltinFunctionName.WEEK_OF_YEAR));
repository.register(year());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ public enum BuiltinFunctionName {
UTC_TIMESTAMP(FunctionName.of("utc_timestamp")),
UNIX_TIMESTAMP(FunctionName.of("unix_timestamp")),
WEEK(FunctionName.of("week")),
WEEKOFYEAR(FunctionName.of("weekofyear")),
WEEK_OF_YEAR(FunctionName.of("week_of_year")),
YEAR(FunctionName.of("year")),
// `now`-like functions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1498,7 +1498,7 @@ private void weekQuery(String date, int mode, int expectedResult) {
assertEquals(integerValue(expectedResult), eval(expression));
}

private void weekOfYearQuery(String date, int mode, int expectedResult) {
private void weekOfYearUnderscoresQuery(String date, int mode, int expectedResult) {
FunctionExpression expression = DSL
.week_of_year(
functionProperties,
Expand All @@ -1508,6 +1508,16 @@ private void weekOfYearQuery(String date, int mode, int expectedResult) {
assertEquals(integerValue(expectedResult), eval(expression));
}

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

private void nullMissingWeekQuery(ExprCoreType date) {
when(nullRef.type()).thenReturn(date);
when(missingRef.type()).thenReturn(date);
Expand Down Expand Up @@ -1581,6 +1591,7 @@ public void testWeek(String date, int mode, int expected) {
lenient().when(missingRef.valueOf(env)).thenReturn(missingValue());
weekQuery(date, mode, expected);
weekOfYearQuery(date, mode, expected);
weekOfYearUnderscoresQuery(date, mode, expected);
}

private void validateStringFormat(
Expand Down Expand Up @@ -1630,6 +1641,9 @@ public void testWeekFormats(
validateStringFormat(
DSL.week_of_year(functionProperties, arg),
String.format("week_of_year(%s)", expectedString), expectedInteger);
validateStringFormat(
DSL.weekofyear(functionProperties, arg),
String.format("weekofyear(%s)", expectedString), expectedInteger);
}

@Test
Expand All @@ -1649,6 +1663,11 @@ public void testWeekOfYearWithTimeType() {
() -> validateStringFormat(
DSL.week_of_year(functionProperties, DSL.literal(new ExprTimeValue("12:23:34"))),
"week_of_year(TIME '12:23:34')",
LocalDate.now(functionProperties.getQueryStartClock()).get(ALIGNED_WEEK_OF_YEAR)),

() -> validateStringFormat(
DSL.weekofyear(functionProperties, DSL.literal(new ExprTimeValue("12:23:34"))),
"weekofyear(TIME '12:23:34')",
LocalDate.now(functionProperties.getQueryStartClock()).get(ALIGNED_WEEK_OF_YEAR))
);
}
Expand Down Expand Up @@ -1705,6 +1724,7 @@ public void testInvalidWeekOfYear() {
nullRef, missingRef)));

assertAll(
//Test for WeekOfYear
//test invalid month
() -> assertThrows(
SemanticCheckException.class,
Expand All @@ -1716,7 +1736,21 @@ public void testInvalidWeekOfYear() {
//test invalid leap year
() -> assertThrows(
SemanticCheckException.class,
() -> weekOfYearQuery("2019-02-29 01:02:03", 0, 0))
() -> weekOfYearQuery("2019-02-29 01:02:03", 0, 0)),

//Test for Week_Of_Year
//test invalid month
() -> assertThrows(
SemanticCheckException.class,
() -> weekOfYearUnderscoresQuery("2019-13-05 01:02:03", 0, 0)),
//test invalid day
() -> assertThrows(
SemanticCheckException.class,
() -> weekOfYearUnderscoresQuery("2019-01-50 01:02:03", 0, 0)),
//test invalid leap year
() -> assertThrows(
SemanticCheckException.class,
() -> weekOfYearUnderscoresQuery("2019-02-29 01:02:03", 0, 0))
);
}

Expand Down
28 changes: 26 additions & 2 deletions docs/user/dql/functions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2570,7 +2570,7 @@ Description

Usage: week(date[, mode]) returns the week number for date. If the mode argument is omitted, the default mode 0 is used.
If an argument of type `TIME` is given, the function will use the current date.
The function `week_of_year` is also provided as an alias.
The functions `weekofyear` and `week_of_year` is also provided as an alias.

.. list-table:: The following table describes how the mode argument works.
:widths: 25 50 25 75
Expand Down Expand Up @@ -2628,7 +2628,7 @@ Example::
+----------------------------+-------------------------------+

WEEK_OF_YEAR
----
------------

Description
>>>>>>>>>>>
Expand All @@ -2651,6 +2651,30 @@ Example::
+------------------------------------+---------------------------------------+


WEEKOFYEAR
----------

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

The weekofyear function is a synonym for the `week`_ function.
If an argument of type `TIME` is given, the function will use the current date.

Argument type: DATE/DATETIME/TIME/TIMESTAMP/STRING

Return type: INTEGER

Example::

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


YEAR
----

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -933,7 +933,7 @@ public void testWeek() throws IOException {
}

@Test
public void testWeekOfYear() throws IOException {
public void testWeekOfYearUnderscores() 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));
Expand All @@ -946,35 +946,43 @@ public void testWeekOfYear() throws IOException {
}

@Test
public void testWeekAlternateSyntaxesReturnTheSameResults() throws IOException {
JSONObject result1 = executeQuery("SELECT week(date('2022-11-22'))");
JSONObject result2 = executeQuery("SELECT week_of_year(date('2022-11-22'))");
verifyDataRows(result1, rows(47));
result1.getJSONArray("datarows").similar(result2.getJSONArray("datarows"));
public void testWeekOfYear() throws IOException {
JSONObject result = executeQuery("select weekofyear(date('2008-02-20'))");
verifySchema(result, schema("weekofyear(date('2008-02-20'))", null, "integer"));
verifyDataRows(result, rows(7));

result1 = executeQuery(String.format(
"SELECT week(CAST(date0 AS date)) FROM %s", TEST_INDEX_CALCS));
result2 = executeQuery(String.format(
"SELECT week_of_year(CAST(date0 AS date)) FROM %s", TEST_INDEX_CALCS));
result1.getJSONArray("datarows").similar(result2.getJSONArray("datarows"));
week("2008-02-20", 0, 7, "weekofyear");
week("2008-02-20", 1, 8, "weekofyear");
week("2008-12-31", 1, 53, "weekofyear");
week("2000-01-01", 0, 0, "weekofyear");
week("2000-01-01", 2, 52, "week_of_year");
}

result1 = executeQuery(String.format(
"SELECT week(datetime(CAST(time0 AS STRING))) FROM %s", TEST_INDEX_CALCS));
result2 = executeQuery(String.format(
"SELECT week_of_year(datetime(CAST(time0 AS STRING))) FROM %s", TEST_INDEX_CALCS));
result1.getJSONArray("datarows").similar(result2.getJSONArray("datarows"));
private void compareWeekResults(String arg, String table) throws IOException {
JSONObject result1 = executeQuery(String.format(
"SELECT week(%s) FROM %s", arg, table));
JSONObject result2 = executeQuery(String.format(
"SELECT week_of_year(%s) FROM %s", arg, table));
JSONObject result3 = executeQuery(String.format(
"SELECT weekofyear(%s) FROM %s", arg, table));

result1 = executeQuery(String.format(
"SELECT week(CAST(time0 AS STRING)) FROM %s", TEST_INDEX_CALCS));
result2 = executeQuery(String.format(
"SELECT week_of_year(CAST(time0 AS STRING)) FROM %s", TEST_INDEX_CALCS));
result1.getJSONArray("datarows").similar(result2.getJSONArray("datarows"));
result1.getJSONArray("datarows").similar(result3.getJSONArray("datarows"));
}

result1 = executeQuery(String.format(
"SELECT week(CAST(datetime0 AS timestamp)) FROM %s", TEST_INDEX_CALCS));
result2 = executeQuery(String.format(
"SELECT week_of_year(CAST(datetime0 AS timestamp)) FROM %s", TEST_INDEX_CALCS));
@Test
public void testWeekAlternateSyntaxesReturnTheSameResults() throws IOException {
JSONObject result1 = executeQuery("SELECT week(date('2022-11-22'))");
JSONObject result2 = executeQuery("SELECT week_of_year(date('2022-11-22'))");
JSONObject result3 = executeQuery("SELECT weekofyear(date('2022-11-22'))");
verifyDataRows(result1, rows(47));
result1.getJSONArray("datarows").similar(result2.getJSONArray("datarows"));
result1.getJSONArray("datarows").similar(result3.getJSONArray("datarows"));

compareWeekResults("CAST(date0 AS date)", TEST_INDEX_CALCS);
compareWeekResults("datetime(CAST(time0 AS STRING))", TEST_INDEX_CALCS);
compareWeekResults("CAST(time0 AS STRING)", TEST_INDEX_CALCS);
compareWeekResults("CAST(datetime0 AS timestamp)", TEST_INDEX_CALCS);
}

void verifyDateFormat(String date, String type, String format, String formatted) throws IOException {
Expand Down
1 change: 1 addition & 0 deletions sql/src/main/antlr/OpenSearchSQLLexer.g4
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ TERMS: 'TERMS';
TOPHITS: 'TOPHITS';
TYPEOF: 'TYPEOF';
WEEK_OF_YEAR: 'WEEK_OF_YEAR';
WEEKOFYEAR: 'WEEKOFYEAR';
WILDCARDQUERY: 'WILDCARDQUERY';
WILDCARD_QUERY: 'WILDCARD_QUERY';

Expand Down
1 change: 1 addition & 0 deletions sql/src/main/antlr/OpenSearchSQLParser.g4
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,7 @@ dateTimeFunctionName
| UNIX_TIMESTAMP
| WEEK
| WEEK_OF_YEAR
| WEEKOFYEAR
| YEAR
;

Expand Down

0 comments on commit 114e02a

Please sign in to comment.