From c4e6c1aca7614c64e34406cd11736f865a230f0c Mon Sep 17 00:00:00 2001 From: GabeFernandez310 Date: Mon, 19 Dec 2022 07:27:05 -0800 Subject: [PATCH 1/8] Added Implementation, Testing, And Docs Signed-off-by: GabeFernandez310 --- .../org/opensearch/sql/expression/DSL.java | 4 ++ .../expression/datetime/DateTimeFunction.java | 8 +-- .../function/BuiltinFunctionName.java | 1 + .../datetime/DateTimeFunctionTest.java | 58 +++++++++++++++++++ docs/user/dql/functions.rst | 52 ++++++++++++++++- .../sql/sql/DateTimeFunctionIT.java | 42 ++++++++++++++ sql/src/main/antlr/OpenSearchSQLParser.g4 | 1 + .../sql/sql/antlr/SQLSyntaxParserTest.java | 6 ++ 8 files changed, 166 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/org/opensearch/sql/expression/DSL.java b/core/src/main/java/org/opensearch/sql/expression/DSL.java index fc425c6c20b..a95932f35a5 100644 --- a/core/src/main/java/org/opensearch/sql/expression/DSL.java +++ b/core/src/main/java/org/opensearch/sql/expression/DSL.java @@ -334,6 +334,10 @@ public static FunctionExpression dayofyear(Expression... expressions) { return compile(FunctionProperties.None, BuiltinFunctionName.DAYOFYEAR, expressions); } + public static FunctionExpression day_of_month(Expression... expressions) { + return compile(FunctionProperties.None, BuiltinFunctionName.DAY_OF_MONTH, expressions); + } + public static FunctionExpression day_of_year(Expression... expressions) { return compile(FunctionProperties.None, BuiltinFunctionName.DAY_OF_YEAR, expressions); } diff --git a/core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunction.java b/core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunction.java index a111f672af1..26d7b2880ef 100644 --- a/core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunction.java +++ b/core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunction.java @@ -57,7 +57,6 @@ import org.opensearch.sql.data.model.ExprValue; import org.opensearch.sql.data.type.ExprCoreType; import org.opensearch.sql.exception.ExpressionEvaluationException; -import org.opensearch.sql.exception.SemanticCheckException; import org.opensearch.sql.expression.function.BuiltinFunctionName; import org.opensearch.sql.expression.function.BuiltinFunctionRepository; import org.opensearch.sql.expression.function.DefaultFunctionResolver; @@ -100,7 +99,8 @@ public void register(BuiltinFunctionRepository repository) { repository.register(date_sub()); repository.register(day()); repository.register(dayName()); - repository.register(dayOfMonth()); + repository.register(dayOfMonth(BuiltinFunctionName.DAYOFMONTH)); + repository.register(dayOfMonth(BuiltinFunctionName.DAY_OF_MONTH)); repository.register(dayOfWeek()); repository.register(dayOfYear(BuiltinFunctionName.DAYOFYEAR)); repository.register(dayOfYear(BuiltinFunctionName.DAY_OF_YEAR)); @@ -336,8 +336,8 @@ private DefaultFunctionResolver dayName() { /** * DAYOFMONTH(STRING/DATE/DATETIME/TIMESTAMP). return the day of the month (1-31). */ - private DefaultFunctionResolver dayOfMonth() { - return define(BuiltinFunctionName.DAYOFMONTH.getName(), + private DefaultFunctionResolver dayOfMonth(BuiltinFunctionName name) { + return define(name.getName(), impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, DATE), impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, DATETIME), impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, TIMESTAMP), diff --git a/core/src/main/java/org/opensearch/sql/expression/function/BuiltinFunctionName.java b/core/src/main/java/org/opensearch/sql/expression/function/BuiltinFunctionName.java index b23c7613d68..1435e8a5568 100644 --- a/core/src/main/java/org/opensearch/sql/expression/function/BuiltinFunctionName.java +++ b/core/src/main/java/org/opensearch/sql/expression/function/BuiltinFunctionName.java @@ -67,6 +67,7 @@ public enum BuiltinFunctionName { DAY(FunctionName.of("day")), DAYNAME(FunctionName.of("dayname")), DAYOFMONTH(FunctionName.of("dayofmonth")), + DAY_OF_MONTH(FunctionName.of("day_of_month")), DAYOFWEEK(FunctionName.of("dayofweek")), DAYOFYEAR(FunctionName.of("dayofyear")), DAY_OF_YEAR(FunctionName.of("day_of_year")), diff --git a/core/src/test/java/org/opensearch/sql/expression/datetime/DateTimeFunctionTest.java b/core/src/test/java/org/opensearch/sql/expression/datetime/DateTimeFunctionTest.java index 092b64d5d75..20119797ad3 100644 --- a/core/src/test/java/org/opensearch/sql/expression/datetime/DateTimeFunctionTest.java +++ b/core/src/test/java/org/opensearch/sql/expression/datetime/DateTimeFunctionTest.java @@ -430,6 +430,64 @@ public void dayOfMonth() { assertEquals(integerValue(8), eval(expression)); } + public void testDayOfMonthWithUnderscores(FunctionExpression dateExpression, int dayOfMonth) { + assertEquals(INTEGER, dateExpression.type()); + assertEquals(integerValue(dayOfMonth), eval(dateExpression)); + } + + @Test + public void dayOfMonthWithUnderscores() { + lenient().when(nullRef.valueOf(env)).thenReturn(nullValue()); + lenient().when(missingRef.valueOf(env)).thenReturn(missingValue()); + + + FunctionExpression expression1 = DSL.dayofmonth(DSL.literal(new ExprDateValue("2020-08-07"))); + FunctionExpression expression2 = DSL.dayofmonth(DSL.literal("2020-07-08")); + + assertAll( + () -> testDayOfMonthWithUnderscores(expression1, 7), + () -> assertEquals("dayofmonth(DATE '2020-08-07')", expression1.toString()), + + () -> testDayOfMonthWithUnderscores(expression2, 8), + () -> assertEquals("dayofmonth(\"2020-07-08\")", expression2.toString()) + + ); + } + + public void testInvalidDayOfMonth(String date) { + FunctionExpression expression = DSL.day_of_month(DSL.literal(new ExprDateValue(date))); + eval(expression); + } + + @Test + public void dayOfMonthWithUnderscoresLeapYear() { + lenient().when(nullRef.valueOf(env)).thenReturn(nullValue()); + lenient().when(missingRef.valueOf(env)).thenReturn(missingValue()); + + //Feb. 29 of a leap year + testDayOfMonthWithUnderscores(DSL.day_of_month(DSL.literal("2020-02-29")), 29); + + //Feb. 29 of a non-leap year + assertThrows(SemanticCheckException.class, () -> testInvalidDayOfMonth("2021-02-29")); + } + + @Test + public void dayOfMonthWithUnderscoresInvalidArguments() { + lenient().when(nullRef.type()).thenReturn(DATE); + lenient().when(missingRef.type()).thenReturn(DATE); + assertEquals(nullValue(), eval(DSL.day_of_month(nullRef))); + assertEquals(missingValue(), eval(DSL.day_of_month(missingRef))); + + //40th day of the month + assertThrows(SemanticCheckException.class, () -> testInvalidDayOfMonth("2021-02-40")); + + //13th month of the year + assertThrows(SemanticCheckException.class, () -> testInvalidDayOfMonth("2021-13-40")); + + //incorrect format + assertThrows(SemanticCheckException.class, () -> testInvalidDayOfMonth("asdfasdfasdf")); + } + @Test public void dayOfWeek() { when(nullRef.type()).thenReturn(DATE); diff --git a/docs/user/dql/functions.rst b/docs/user/dql/functions.rst index 843d6c7e455..bff4975ccba 100644 --- a/docs/user/dql/functions.rst +++ b/docs/user/dql/functions.rst @@ -1365,7 +1365,7 @@ Argument type: STRING/DATE/DATETIME/TIMESTAMP Return type: INTEGER -Synonyms: DAYOFMONTH +Synonyms: `DAYOFMONTH`_, `DAY_OF_MONTH`_ Example:: @@ -1413,7 +1413,7 @@ Argument type: STRING/DATE/DATETIME/TIMESTAMP Return type: INTEGER -Synonyms: DAY +Synonyms: `DAY`_, `DAY_OF_MONTH`_ Example:: @@ -1425,6 +1425,54 @@ Example:: | 26 | +----------------------------------+ +DAY_OF_MONTH +---------- + +Description +>>>>>>>>>>> + +Usage: day_of_month(date) extracts the day of the month for date, in the range 1 to 31. The dates with value 0 such as '0000-00-00' or '2008-00-00' are invalid. + +Argument type: STRING/DATE/DATETIME/TIMESTAMP + +Return type: INTEGER + +Synonyms: `DAY`_, `DAYOFMONTH`_ + +Example:: + + os> SELECT DAY_OF_MONTH('2020-08-26') + fetched rows / total rows = 1/1 + +------------------------------+ + | DAY_OF_MONTH('2020-08-26') | + |------------------------------| + | 26 | + +------------------------------+ + + os> SELECT DAY_OF_MONTH(DATE('2020-08-26')) + fetched rows / total rows = 1/1 + +------------------------------------+ + | DAY_OF_MONTH(DATE('2020-08-26')) | + |------------------------------------| + | 26 | + +------------------------------------+ + + os> SELECT DAY_OF_MONTH(TIMESTAMP('2020-08-26 00:00:00')) + fetched rows / total rows = 1/1 + +--------------------------------------------------+ + | DAY_OF_MONTH(TIMESTAMP('2020-08-26 00:00:00')) | + |--------------------------------------------------| + | 26 | + +--------------------------------------------------+ + + os> SELECT DAY_OF_MONTH(DATETIME('2020-08-26 00:00:00')) + fetched rows / total rows = 1/1 + +-------------------------------------------------+ + | DAY_OF_MONTH(DATETIME('2020-08-26 00:00:00')) | + |-------------------------------------------------| + | 26 | + +-------------------------------------------------+ + DAYOFWEEK --------- diff --git a/integ-test/src/test/java/org/opensearch/sql/sql/DateTimeFunctionIT.java b/integ-test/src/test/java/org/opensearch/sql/sql/DateTimeFunctionIT.java index 3503877d647..fd638911ee0 100644 --- a/integ-test/src/test/java/org/opensearch/sql/sql/DateTimeFunctionIT.java +++ b/integ-test/src/test/java/org/opensearch/sql/sql/DateTimeFunctionIT.java @@ -206,6 +206,48 @@ public void testDayOfMonth() throws IOException { verifyDataRows(result, rows(16)); } + @Test + public void testDayOfMonthWithUnderscores() throws IOException { + JSONObject result = executeQuery("select day_of_month(date('2020-09-16'))"); + verifySchema(result, schema("day_of_month(date('2020-09-16'))", null, "integer")); + verifyDataRows(result, rows(16)); + + result = executeQuery("select day_of_month('2020-09-16')"); + verifySchema(result, schema("day_of_month('2020-09-16')", null, "integer")); + verifyDataRows(result, rows(16)); + } + + @Test + public void testDayOfMonthAliasesReturnTheSameResults() throws IOException { + JSONObject result1 = executeQuery("SELECT dayofmonth(date('2022-11-22'))"); + JSONObject result2 = executeQuery("SELECT day_of_month(date('2022-11-22'))"); + verifyDataRows(result1, rows(22)); + result1.getJSONArray("datarows").similar(result2.getJSONArray("datarows")); + + result1 = executeQuery(String.format( + "SELECT dayofmonth(CAST(date0 AS date)) FROM %s", TEST_INDEX_CALCS)); + result2 = executeQuery(String.format( + "SELECT day_of_month(CAST(date0 AS date)) FROM %s", TEST_INDEX_CALCS)); + result1.getJSONArray("datarows").similar(result2.getJSONArray("datarows")); + + result1 = executeQuery(String.format( + "SELECT dayofmonth(datetime(CAST(time0 AS STRING))) FROM %s", TEST_INDEX_CALCS)); + result2 = executeQuery(String.format( + "SELECT day_of_month(datetime(CAST(time0 AS STRING))) FROM %s", TEST_INDEX_CALCS)); + result1.getJSONArray("datarows").similar(result2.getJSONArray("datarows")); + + result1 = executeQuery(String.format( + "SELECT dayofmonth(CAST(time0 AS STRING)) FROM %s", TEST_INDEX_CALCS)); + result2 = executeQuery(String.format( + "SELECT day_of_month(CAST(time0 AS STRING)) FROM %s", TEST_INDEX_CALCS)); + result1.getJSONArray("datarows").similar(result2.getJSONArray("datarows")); + + result1 = executeQuery(String.format( + "SELECT dayofmonth(CAST(datetime0 AS timestamp)) FROM %s", TEST_INDEX_CALCS)); + result2 = executeQuery(String.format( + "SELECT day_of_month(CAST(datetime0 AS timestamp)) FROM %s", TEST_INDEX_CALCS)); + result1.getJSONArray("datarows").similar(result2.getJSONArray("datarows")); + } @Test public void testDayOfWeek() throws IOException { JSONObject result = executeQuery("select dayofweek(date('2020-09-16'))"); diff --git a/sql/src/main/antlr/OpenSearchSQLParser.g4 b/sql/src/main/antlr/OpenSearchSQLParser.g4 index 47a43362eaa..0943859d397 100644 --- a/sql/src/main/antlr/OpenSearchSQLParser.g4 +++ b/sql/src/main/antlr/OpenSearchSQLParser.g4 @@ -244,6 +244,7 @@ datetimeConstantLiteral : CURRENT_DATE | CURRENT_TIME | CURRENT_TIMESTAMP + | DAY_OF_MONTH | DAY_OF_YEAR | LOCALTIME | LOCALTIMESTAMP diff --git a/sql/src/test/java/org/opensearch/sql/sql/antlr/SQLSyntaxParserTest.java b/sql/src/test/java/org/opensearch/sql/sql/antlr/SQLSyntaxParserTest.java index bfd0f93ec98..67a13cf6e50 100644 --- a/sql/src/test/java/org/opensearch/sql/sql/antlr/SQLSyntaxParserTest.java +++ b/sql/src/test/java/org/opensearch/sql/sql/antlr/SQLSyntaxParserTest.java @@ -197,6 +197,12 @@ public void can_parse_week_of_year_functions() { assertNotNull(parser.parse("SELECT week_of_year('2022-11-18')")); } + @Test + public void can_parse_dayofmonth_functions() { + assertNotNull(parser.parse("SELECT dayofmonth('2022-11-18')")); + assertNotNull(parser.parse("SELECT day_of_month('2022-11-18')")); + } + @Test public void can_parse_dayofyear_functions() { assertNotNull(parser.parse("SELECT dayofyear('2022-11-18')")); From 878a6a152955d3cbbc1a21c85ff2d900a6bc785c Mon Sep 17 00:00:00 2001 From: GabeFernandez310 Date: Wed, 21 Dec 2022 15:04:28 -0800 Subject: [PATCH 2/8] Addressed PR Comments Signed-off-by: GabeFernandez310 --- .../datetime/DateTimeFunctionTest.java | 4 +-- docs/user/dql/functions.rst | 31 ++----------------- sql/src/main/antlr/OpenSearchSQLParser.g4 | 2 +- 3 files changed, 6 insertions(+), 31 deletions(-) diff --git a/core/src/test/java/org/opensearch/sql/expression/datetime/DateTimeFunctionTest.java b/core/src/test/java/org/opensearch/sql/expression/datetime/DateTimeFunctionTest.java index 20119797ad3..7f58f8f2e67 100644 --- a/core/src/test/java/org/opensearch/sql/expression/datetime/DateTimeFunctionTest.java +++ b/core/src/test/java/org/opensearch/sql/expression/datetime/DateTimeFunctionTest.java @@ -430,7 +430,7 @@ public void dayOfMonth() { assertEquals(integerValue(8), eval(expression)); } - public void testDayOfMonthWithUnderscores(FunctionExpression dateExpression, int dayOfMonth) { + private void testDayOfMonthWithUnderscores(FunctionExpression dateExpression, int dayOfMonth) { assertEquals(INTEGER, dateExpression.type()); assertEquals(integerValue(dayOfMonth), eval(dateExpression)); } @@ -454,7 +454,7 @@ public void dayOfMonthWithUnderscores() { ); } - public void testInvalidDayOfMonth(String date) { + private void testInvalidDayOfMonth(String date) { FunctionExpression expression = DSL.day_of_month(DSL.literal(new ExprDateValue(date))); eval(expression); } diff --git a/docs/user/dql/functions.rst b/docs/user/dql/functions.rst index bff4975ccba..6f039411836 100644 --- a/docs/user/dql/functions.rst +++ b/docs/user/dql/functions.rst @@ -1359,7 +1359,7 @@ DAY Description >>>>>>>>>>> -Usage: day(date) extracts the day of the month for date, in the range 1 to 31. The dates with value 0 such as '0000-00-00' or '2008-00-00' are invalid. +Usage: day(date) extracts the day of the month for date, in the range 1 to 31. Argument type: STRING/DATE/DATETIME/TIMESTAMP @@ -1407,7 +1407,7 @@ DAYOFMONTH Description >>>>>>>>>>> -Usage: dayofmonth(date) extracts the day of the month for date, in the range 1 to 31. The dates with value 0 such as '0000-00-00' or '2008-00-00' are invalid. +Usage: dayofmonth(date) extracts the day of the month for date, in the range 1 to 31. Argument type: STRING/DATE/DATETIME/TIMESTAMP @@ -1431,7 +1431,7 @@ DAY_OF_MONTH Description >>>>>>>>>>> -Usage: day_of_month(date) extracts the day of the month for date, in the range 1 to 31. The dates with value 0 such as '0000-00-00' or '2008-00-00' are invalid. +Usage: day_of_month(date) extracts the day of the month for date, in the range 1 to 31. Argument type: STRING/DATE/DATETIME/TIMESTAMP @@ -1449,31 +1449,6 @@ Example:: | 26 | +------------------------------+ - os> SELECT DAY_OF_MONTH(DATE('2020-08-26')) - fetched rows / total rows = 1/1 - +------------------------------------+ - | DAY_OF_MONTH(DATE('2020-08-26')) | - |------------------------------------| - | 26 | - +------------------------------------+ - - os> SELECT DAY_OF_MONTH(TIMESTAMP('2020-08-26 00:00:00')) - fetched rows / total rows = 1/1 - +--------------------------------------------------+ - | DAY_OF_MONTH(TIMESTAMP('2020-08-26 00:00:00')) | - |--------------------------------------------------| - | 26 | - +--------------------------------------------------+ - - os> SELECT DAY_OF_MONTH(DATETIME('2020-08-26 00:00:00')) - fetched rows / total rows = 1/1 - +-------------------------------------------------+ - | DAY_OF_MONTH(DATETIME('2020-08-26 00:00:00')) | - |-------------------------------------------------| - | 26 | - +-------------------------------------------------+ - - DAYOFWEEK --------- diff --git a/sql/src/main/antlr/OpenSearchSQLParser.g4 b/sql/src/main/antlr/OpenSearchSQLParser.g4 index 0943859d397..f9c9f79465c 100644 --- a/sql/src/main/antlr/OpenSearchSQLParser.g4 +++ b/sql/src/main/antlr/OpenSearchSQLParser.g4 @@ -244,7 +244,6 @@ datetimeConstantLiteral : CURRENT_DATE | CURRENT_TIME | CURRENT_TIMESTAMP - | DAY_OF_MONTH | DAY_OF_YEAR | LOCALTIME | LOCALTIMESTAMP @@ -427,6 +426,7 @@ dateTimeFunctionName | DAY | DAYNAME | DAYOFMONTH + | DAY_OF_MONTH | DAYOFWEEK | DAYOFYEAR | FROM_DAYS From 3fabdda1a63cec4818c15e0536c80750b575ebb4 Mon Sep 17 00:00:00 2001 From: GabeFernandez310 Date: Thu, 22 Dec 2022 09:44:54 -0800 Subject: [PATCH 3/8] Added Support For Time Type Signed-off-by: GabeFernandez310 --- .../expression/datetime/DateTimeFunction.java | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunction.java b/core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunction.java index 26d7b2880ef..cfcb0d4b3d4 100644 --- a/core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunction.java +++ b/core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunction.java @@ -6,6 +6,7 @@ package org.opensearch.sql.expression.datetime; +import static java.time.temporal.ChronoUnit.DAYS; import static java.time.temporal.ChronoUnit.MONTHS; import static org.opensearch.sql.data.type.ExprCoreType.DATE; import static org.opensearch.sql.data.type.ExprCoreType.DATETIME; @@ -340,8 +341,9 @@ private DefaultFunctionResolver dayOfMonth(BuiltinFunctionName name) { return define(name.getName(), impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, DATE), impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, DATETIME), - impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, TIMESTAMP), - impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, STRING) + impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, STRING), + impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, TIME), + impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, TIMESTAMP) ); } @@ -761,11 +763,16 @@ private ExprValue exprDayName(ExprValue date) { /** * Day of Month implementation for ExprValue. * - * @param date ExprValue of Date/String type. + * @param exprValue ExprValue of Date/Datetime/String/Time/Timestamp type. * @return ExprValue. */ - private ExprValue exprDayOfMonth(ExprValue date) { - return new ExprIntegerValue(date.dateValue().getDayOfMonth()); + private ExprValue exprDayOfMonth(ExprValue exprValue) { + switch ((ExprCoreType) exprValue.type()) { + case TIME: + return new ExprIntegerValue(formatNow(Clock.systemDefaultZone()).getDayOfMonth()); + default: + return new ExprIntegerValue(exprValue.dateValue().getDayOfMonth()); + } } /** From 2334a7ca613752d4a31a514c2834f0bc76593975 Mon Sep 17 00:00:00 2001 From: GabeFernandez310 Date: Thu, 22 Dec 2022 11:26:24 -0800 Subject: [PATCH 4/8] Altered Implementation of Support For Time Type Signed-off-by: GabeFernandez310 --- .../sql/expression/datetime/DateTimeFunction.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunction.java b/core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunction.java index cfcb0d4b3d4..3031b9cb7c4 100644 --- a/core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunction.java +++ b/core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunction.java @@ -339,10 +339,11 @@ private DefaultFunctionResolver dayName() { */ private DefaultFunctionResolver dayOfMonth(BuiltinFunctionName name) { return define(name.getName(), + implWithProperties((functionProperties, arg) + -> DateTimeFunction.dayOfMonthToday(functionProperties.getQueryStartClock()), INTEGER, TIME), impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, DATE), impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, DATETIME), impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, STRING), - impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, TIME), impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, TIMESTAMP) ); } @@ -617,6 +618,10 @@ private DefaultFunctionResolver date_format() { ); } + private ExprValue dayOfMonthToday(Clock clock) { + return new ExprIntegerValue(formatNow(clock).getDayOfMonth()); + } + /** * ADDDATE function implementation for ExprValue. * @@ -767,12 +772,7 @@ private ExprValue exprDayName(ExprValue date) { * @return ExprValue. */ private ExprValue exprDayOfMonth(ExprValue exprValue) { - switch ((ExprCoreType) exprValue.type()) { - case TIME: - return new ExprIntegerValue(formatNow(Clock.systemDefaultZone()).getDayOfMonth()); - default: - return new ExprIntegerValue(exprValue.dateValue().getDayOfMonth()); - } + return new ExprIntegerValue(exprValue.dateValue().getDayOfMonth()); } /** From 9c3614f8a160cf4960c8a4fce519892fb2ffaccb Mon Sep 17 00:00:00 2001 From: GabeFernandez310 Date: Thu, 22 Dec 2022 11:43:27 -0800 Subject: [PATCH 5/8] Added Tests Signed-off-by: GabeFernandez310 --- .../org/opensearch/sql/expression/DSL.java | 8 ++--- .../datetime/DateTimeFunctionTest.java | 31 +++++++++++++------ 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/core/src/main/java/org/opensearch/sql/expression/DSL.java b/core/src/main/java/org/opensearch/sql/expression/DSL.java index a95932f35a5..bc39df00426 100644 --- a/core/src/main/java/org/opensearch/sql/expression/DSL.java +++ b/core/src/main/java/org/opensearch/sql/expression/DSL.java @@ -322,8 +322,8 @@ public static FunctionExpression dayname(Expression... expressions) { return compile(FunctionProperties.None, BuiltinFunctionName.DAYNAME, expressions); } - public static FunctionExpression dayofmonth(Expression... expressions) { - return compile(FunctionProperties.None, BuiltinFunctionName.DAYOFMONTH, expressions); + public static FunctionExpression dayofmonth(FunctionProperties functionProperties, Expression... expressions) { + return compile(functionProperties , BuiltinFunctionName.DAYOFMONTH, expressions); } public static FunctionExpression dayofweek(Expression... expressions) { @@ -334,8 +334,8 @@ public static FunctionExpression dayofyear(Expression... expressions) { return compile(FunctionProperties.None, BuiltinFunctionName.DAYOFYEAR, expressions); } - public static FunctionExpression day_of_month(Expression... expressions) { - return compile(FunctionProperties.None, BuiltinFunctionName.DAY_OF_MONTH, expressions); + public static FunctionExpression day_of_month(FunctionProperties functionProperties, Expression... expressions) { + return compile(functionProperties, BuiltinFunctionName.DAY_OF_MONTH, expressions); } public static FunctionExpression day_of_year(Expression... expressions) { diff --git a/core/src/test/java/org/opensearch/sql/expression/datetime/DateTimeFunctionTest.java b/core/src/test/java/org/opensearch/sql/expression/datetime/DateTimeFunctionTest.java index 7f58f8f2e67..014338bea38 100644 --- a/core/src/test/java/org/opensearch/sql/expression/datetime/DateTimeFunctionTest.java +++ b/core/src/test/java/org/opensearch/sql/expression/datetime/DateTimeFunctionTest.java @@ -416,15 +416,15 @@ public void dayName() { public void dayOfMonth() { when(nullRef.type()).thenReturn(DATE); when(missingRef.type()).thenReturn(DATE); - assertEquals(nullValue(), eval(DSL.dayofmonth(nullRef))); - assertEquals(missingValue(), eval(DSL.dayofmonth(missingRef))); + assertEquals(nullValue(), eval(DSL.dayofmonth(functionProperties, nullRef))); + assertEquals(missingValue(), eval(DSL.dayofmonth(functionProperties, missingRef))); - FunctionExpression expression = DSL.dayofmonth(DSL.literal(new ExprDateValue("2020-08-07"))); + FunctionExpression expression = DSL.dayofmonth(functionProperties, DSL.literal(new ExprDateValue("2020-08-07"))); assertEquals(INTEGER, expression.type()); assertEquals("dayofmonth(DATE '2020-08-07')", expression.toString()); assertEquals(integerValue(7), eval(expression)); - expression = DSL.dayofmonth(DSL.literal("2020-07-08")); + expression = DSL.dayofmonth(functionProperties, DSL.literal("2020-07-08")); assertEquals(INTEGER, expression.type()); assertEquals("dayofmonth(\"2020-07-08\")", expression.toString()); assertEquals(integerValue(8), eval(expression)); @@ -441,8 +441,8 @@ public void dayOfMonthWithUnderscores() { lenient().when(missingRef.valueOf(env)).thenReturn(missingValue()); - FunctionExpression expression1 = DSL.dayofmonth(DSL.literal(new ExprDateValue("2020-08-07"))); - FunctionExpression expression2 = DSL.dayofmonth(DSL.literal("2020-07-08")); + FunctionExpression expression1 = DSL.dayofmonth(functionProperties, DSL.literal(new ExprDateValue("2020-08-07"))); + FunctionExpression expression2 = DSL.dayofmonth(functionProperties, DSL.literal("2020-07-08")); assertAll( () -> testDayOfMonthWithUnderscores(expression1, 7), @@ -454,8 +454,19 @@ public void dayOfMonthWithUnderscores() { ); } + @Test + public void testDayOfMonthWithTimeType() { + lenient().when(nullRef.valueOf(env)).thenReturn(nullValue()); + lenient().when(missingRef.valueOf(env)).thenReturn(missingValue()); + FunctionExpression expression = DSL.day_of_month(functionProperties, DSL.literal(new ExprTimeValue("12:23:34"))); + + assertEquals(INTEGER, eval(expression).type()); + assertEquals(LocalDate.now(functionProperties.getQueryStartClock()).getDayOfMonth(), eval(expression).integerValue()); + assertEquals("day_of_month(TIME '12:23:34')", expression.toString()); + } + private void testInvalidDayOfMonth(String date) { - FunctionExpression expression = DSL.day_of_month(DSL.literal(new ExprDateValue(date))); + FunctionExpression expression = DSL.day_of_month(functionProperties, DSL.literal(new ExprDateValue(date))); eval(expression); } @@ -465,7 +476,7 @@ public void dayOfMonthWithUnderscoresLeapYear() { lenient().when(missingRef.valueOf(env)).thenReturn(missingValue()); //Feb. 29 of a leap year - testDayOfMonthWithUnderscores(DSL.day_of_month(DSL.literal("2020-02-29")), 29); + testDayOfMonthWithUnderscores(DSL.day_of_month(functionProperties, DSL.literal("2020-02-29")), 29); //Feb. 29 of a non-leap year assertThrows(SemanticCheckException.class, () -> testInvalidDayOfMonth("2021-02-29")); @@ -475,8 +486,8 @@ public void dayOfMonthWithUnderscoresLeapYear() { public void dayOfMonthWithUnderscoresInvalidArguments() { lenient().when(nullRef.type()).thenReturn(DATE); lenient().when(missingRef.type()).thenReturn(DATE); - assertEquals(nullValue(), eval(DSL.day_of_month(nullRef))); - assertEquals(missingValue(), eval(DSL.day_of_month(missingRef))); + assertEquals(nullValue(), eval(DSL.day_of_month(functionProperties, nullRef))); + assertEquals(missingValue(), eval(DSL.day_of_month(functionProperties, missingRef))); //40th day of the month assertThrows(SemanticCheckException.class, () -> testInvalidDayOfMonth("2021-02-40")); From 644c9b3997a87c42d401acef3a26a55b51e3456b Mon Sep 17 00:00:00 2001 From: GabeFernandez310 Date: Thu, 22 Dec 2022 13:49:33 -0800 Subject: [PATCH 6/8] Fixed Checkstyle Issues Signed-off-by: GabeFernandez310 --- .../org/opensearch/sql/expression/DSL.java | 10 +++++++--- .../expression/datetime/DateTimeFunction.java | 10 +++++----- .../datetime/DateTimeFunctionTest.java | 19 +++++++++++++------ 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/core/src/main/java/org/opensearch/sql/expression/DSL.java b/core/src/main/java/org/opensearch/sql/expression/DSL.java index bc39df00426..51b66364933 100644 --- a/core/src/main/java/org/opensearch/sql/expression/DSL.java +++ b/core/src/main/java/org/opensearch/sql/expression/DSL.java @@ -322,8 +322,10 @@ public static FunctionExpression dayname(Expression... expressions) { return compile(FunctionProperties.None, BuiltinFunctionName.DAYNAME, expressions); } - public static FunctionExpression dayofmonth(FunctionProperties functionProperties, Expression... expressions) { - return compile(functionProperties , BuiltinFunctionName.DAYOFMONTH, expressions); + public static FunctionExpression dayofmonth( + FunctionProperties functionProperties, + Expression... expressions) { + return compile(functionProperties, BuiltinFunctionName.DAYOFMONTH, expressions); } public static FunctionExpression dayofweek(Expression... expressions) { @@ -334,7 +336,9 @@ public static FunctionExpression dayofyear(Expression... expressions) { return compile(FunctionProperties.None, BuiltinFunctionName.DAYOFYEAR, expressions); } - public static FunctionExpression day_of_month(FunctionProperties functionProperties, Expression... expressions) { + public static FunctionExpression day_of_month( + FunctionProperties functionProperties, + Expression... expressions) { return compile(functionProperties, BuiltinFunctionName.DAY_OF_MONTH, expressions); } diff --git a/core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunction.java b/core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunction.java index 3031b9cb7c4..7a0cfaecd08 100644 --- a/core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunction.java +++ b/core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunction.java @@ -339,8 +339,8 @@ private DefaultFunctionResolver dayName() { */ private DefaultFunctionResolver dayOfMonth(BuiltinFunctionName name) { return define(name.getName(), - implWithProperties((functionProperties, arg) - -> DateTimeFunction.dayOfMonthToday(functionProperties.getQueryStartClock()), INTEGER, TIME), + implWithProperties((functionProperties, arg) -> DateTimeFunction.dayOfMonthToday( + functionProperties.getQueryStartClock()), INTEGER, TIME), impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, DATE), impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, DATETIME), impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, STRING), @@ -768,11 +768,11 @@ private ExprValue exprDayName(ExprValue date) { /** * Day of Month implementation for ExprValue. * - * @param exprValue ExprValue of Date/Datetime/String/Time/Timestamp type. + * @param date ExprValue of Date/Datetime/String/Time/Timestamp type. * @return ExprValue. */ - private ExprValue exprDayOfMonth(ExprValue exprValue) { - return new ExprIntegerValue(exprValue.dateValue().getDayOfMonth()); + private ExprValue exprDayOfMonth(ExprValue date) { + return new ExprIntegerValue(date.dateValue().getDayOfMonth()); } /** diff --git a/core/src/test/java/org/opensearch/sql/expression/datetime/DateTimeFunctionTest.java b/core/src/test/java/org/opensearch/sql/expression/datetime/DateTimeFunctionTest.java index 014338bea38..d1a238f0c5f 100644 --- a/core/src/test/java/org/opensearch/sql/expression/datetime/DateTimeFunctionTest.java +++ b/core/src/test/java/org/opensearch/sql/expression/datetime/DateTimeFunctionTest.java @@ -419,7 +419,8 @@ public void dayOfMonth() { assertEquals(nullValue(), eval(DSL.dayofmonth(functionProperties, nullRef))); assertEquals(missingValue(), eval(DSL.dayofmonth(functionProperties, missingRef))); - FunctionExpression expression = DSL.dayofmonth(functionProperties, DSL.literal(new ExprDateValue("2020-08-07"))); + FunctionExpression expression = DSL.dayofmonth( + functionProperties, DSL.literal(new ExprDateValue("2020-08-07"))); assertEquals(INTEGER, expression.type()); assertEquals("dayofmonth(DATE '2020-08-07')", expression.toString()); assertEquals(integerValue(7), eval(expression)); @@ -441,7 +442,8 @@ public void dayOfMonthWithUnderscores() { lenient().when(missingRef.valueOf(env)).thenReturn(missingValue()); - FunctionExpression expression1 = DSL.dayofmonth(functionProperties, DSL.literal(new ExprDateValue("2020-08-07"))); + FunctionExpression expression1 = DSL.dayofmonth( + functionProperties, DSL.literal(new ExprDateValue("2020-08-07"))); FunctionExpression expression2 = DSL.dayofmonth(functionProperties, DSL.literal("2020-07-08")); assertAll( @@ -458,15 +460,19 @@ public void dayOfMonthWithUnderscores() { public void testDayOfMonthWithTimeType() { lenient().when(nullRef.valueOf(env)).thenReturn(nullValue()); lenient().when(missingRef.valueOf(env)).thenReturn(missingValue()); - FunctionExpression expression = DSL.day_of_month(functionProperties, DSL.literal(new ExprTimeValue("12:23:34"))); + FunctionExpression expression = DSL.day_of_month( + functionProperties, DSL.literal(new ExprTimeValue("12:23:34"))); assertEquals(INTEGER, eval(expression).type()); - assertEquals(LocalDate.now(functionProperties.getQueryStartClock()).getDayOfMonth(), eval(expression).integerValue()); + assertEquals( + LocalDate.now(functionProperties.getQueryStartClock()).getDayOfMonth(), + eval(expression).integerValue()); assertEquals("day_of_month(TIME '12:23:34')", expression.toString()); } private void testInvalidDayOfMonth(String date) { - FunctionExpression expression = DSL.day_of_month(functionProperties, DSL.literal(new ExprDateValue(date))); + FunctionExpression expression = DSL.day_of_month( + functionProperties, DSL.literal(new ExprDateValue(date))); eval(expression); } @@ -476,7 +482,8 @@ public void dayOfMonthWithUnderscoresLeapYear() { lenient().when(missingRef.valueOf(env)).thenReturn(missingValue()); //Feb. 29 of a leap year - testDayOfMonthWithUnderscores(DSL.day_of_month(functionProperties, DSL.literal("2020-02-29")), 29); + testDayOfMonthWithUnderscores(DSL.day_of_month( + functionProperties, DSL.literal("2020-02-29")), 29); //Feb. 29 of a non-leap year assertThrows(SemanticCheckException.class, () -> testInvalidDayOfMonth("2021-02-29")); From 469fbb23ed6003676fa19f98c4c80e838ba3d949 Mon Sep 17 00:00:00 2001 From: GabeFernandez310 Date: Tue, 3 Jan 2023 13:16:37 -0800 Subject: [PATCH 7/8] Addressed PR Comments Signed-off-by: GabeFernandez310 --- .../expression/datetime/DateTimeFunction.java | 7 +++--- .../datetime/DateTimeFunctionTest.java | 24 ++++++++++++------- docs/user/dql/functions.rst | 4 ++-- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunction.java b/core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunction.java index 7a0cfaecd08..11af8f27782 100644 --- a/core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunction.java +++ b/core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunction.java @@ -21,6 +21,7 @@ import static org.opensearch.sql.expression.function.FunctionDSL.impl; import static org.opensearch.sql.expression.function.FunctionDSL.implWithProperties; import static org.opensearch.sql.expression.function.FunctionDSL.nullMissingHandling; +import static org.opensearch.sql.expression.function.FunctionDSL.nullMissingHandlingWithProperties; import static org.opensearch.sql.utils.DateTimeFormatters.DATE_FORMATTER_LONG_YEAR; import static org.opensearch.sql.utils.DateTimeFormatters.DATE_FORMATTER_SHORT_YEAR; import static org.opensearch.sql.utils.DateTimeFormatters.DATE_TIME_FORMATTER_LONG_YEAR; @@ -339,8 +340,8 @@ private DefaultFunctionResolver dayName() { */ private DefaultFunctionResolver dayOfMonth(BuiltinFunctionName name) { return define(name.getName(), - implWithProperties((functionProperties, arg) -> DateTimeFunction.dayOfMonthToday( - functionProperties.getQueryStartClock()), INTEGER, TIME), + implWithProperties(nullMissingHandlingWithProperties((functionProperties, arg) -> DateTimeFunction.dayOfMonthToday( + functionProperties.getQueryStartClock())), INTEGER, TIME), impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, DATE), impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, DATETIME), impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, STRING), @@ -619,7 +620,7 @@ private DefaultFunctionResolver date_format() { } private ExprValue dayOfMonthToday(Clock clock) { - return new ExprIntegerValue(formatNow(clock).getDayOfMonth()); + return new ExprIntegerValue(LocalDateTime.now(clock).getDayOfMonth()); } /** diff --git a/core/src/test/java/org/opensearch/sql/expression/datetime/DateTimeFunctionTest.java b/core/src/test/java/org/opensearch/sql/expression/datetime/DateTimeFunctionTest.java index d1a238f0c5f..6e255053383 100644 --- a/core/src/test/java/org/opensearch/sql/expression/datetime/DateTimeFunctionTest.java +++ b/core/src/test/java/org/opensearch/sql/expression/datetime/DateTimeFunctionTest.java @@ -493,17 +493,25 @@ public void dayOfMonthWithUnderscoresLeapYear() { public void dayOfMonthWithUnderscoresInvalidArguments() { lenient().when(nullRef.type()).thenReturn(DATE); lenient().when(missingRef.type()).thenReturn(DATE); - assertEquals(nullValue(), eval(DSL.day_of_month(functionProperties, nullRef))); - assertEquals(missingValue(), eval(DSL.day_of_month(functionProperties, missingRef))); - //40th day of the month - assertThrows(SemanticCheckException.class, () -> testInvalidDayOfMonth("2021-02-40")); + assertAll( + () -> assertEquals(nullValue(), eval(DSL.day_of_month(functionProperties, nullRef))), + () -> assertEquals( + missingValue(), eval(DSL.day_of_month(functionProperties, missingRef))), + + //40th day of the month + () -> assertThrows( + SemanticCheckException.class, () -> testInvalidDayOfMonth("2021-02-40")), + //13th month of the year + () -> assertThrows( + SemanticCheckException.class, () -> testInvalidDayOfMonth("2021-13-40")), + //incorrect format + () -> assertThrows( + SemanticCheckException.class, () -> testInvalidDayOfMonth("asdfasdfasdf")) + ); + - //13th month of the year - assertThrows(SemanticCheckException.class, () -> testInvalidDayOfMonth("2021-13-40")); - //incorrect format - assertThrows(SemanticCheckException.class, () -> testInvalidDayOfMonth("asdfasdfasdf")); } @Test diff --git a/docs/user/dql/functions.rst b/docs/user/dql/functions.rst index 6f039411836..92ddd9170ff 100644 --- a/docs/user/dql/functions.rst +++ b/docs/user/dql/functions.rst @@ -1426,14 +1426,14 @@ Example:: +----------------------------------+ DAY_OF_MONTH ----------- +------------ Description >>>>>>>>>>> Usage: day_of_month(date) extracts the day of the month for date, in the range 1 to 31. -Argument type: STRING/DATE/DATETIME/TIMESTAMP +Argument type: STRING/DATE/TIME/DATETIME/TIMESTAMP Return type: INTEGER From f533767edfe63e421c56c6ca977b99d3abd204e7 Mon Sep 17 00:00:00 2001 From: GabeFernandez310 Date: Thu, 5 Jan 2023 09:12:12 -0800 Subject: [PATCH 8/8] Fixed Checkstyle Signed-off-by: GabeFernandez310 --- .../opensearch/sql/expression/datetime/DateTimeFunction.java | 5 +++-- .../sql/expression/datetime/DateTimeFunctionTest.java | 5 +---- docs/user/dql/functions.rst | 4 ++-- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunction.java b/core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunction.java index 11af8f27782..651a916b28c 100644 --- a/core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunction.java +++ b/core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunction.java @@ -340,8 +340,9 @@ private DefaultFunctionResolver dayName() { */ private DefaultFunctionResolver dayOfMonth(BuiltinFunctionName name) { return define(name.getName(), - implWithProperties(nullMissingHandlingWithProperties((functionProperties, arg) -> DateTimeFunction.dayOfMonthToday( - functionProperties.getQueryStartClock())), INTEGER, TIME), + implWithProperties(nullMissingHandlingWithProperties( + (functionProperties, arg) -> DateTimeFunction.dayOfMonthToday( + functionProperties.getQueryStartClock())), INTEGER, TIME), impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, DATE), impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, DATETIME), impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, STRING), diff --git a/core/src/test/java/org/opensearch/sql/expression/datetime/DateTimeFunctionTest.java b/core/src/test/java/org/opensearch/sql/expression/datetime/DateTimeFunctionTest.java index 6e255053383..3be327db91a 100644 --- a/core/src/test/java/org/opensearch/sql/expression/datetime/DateTimeFunctionTest.java +++ b/core/src/test/java/org/opensearch/sql/expression/datetime/DateTimeFunctionTest.java @@ -508,10 +508,7 @@ public void dayOfMonthWithUnderscoresInvalidArguments() { //incorrect format () -> assertThrows( SemanticCheckException.class, () -> testInvalidDayOfMonth("asdfasdfasdf")) - ); - - - + ); } @Test diff --git a/docs/user/dql/functions.rst b/docs/user/dql/functions.rst index 92ddd9170ff..8819b05d25e 100644 --- a/docs/user/dql/functions.rst +++ b/docs/user/dql/functions.rst @@ -1361,7 +1361,7 @@ Description Usage: day(date) extracts the day of the month for date, in the range 1 to 31. -Argument type: STRING/DATE/DATETIME/TIMESTAMP +Argument type: STRING/DATE/DATETIME/TIME/TIMESTAMP Return type: INTEGER @@ -1409,7 +1409,7 @@ Description Usage: dayofmonth(date) extracts the day of the month for date, in the range 1 to 31. -Argument type: STRING/DATE/DATETIME/TIMESTAMP +Argument type: STRING/DATE/DATETIME/TIME/TIMESTAMP Return type: INTEGER