From 65c34acb666fec0c6e0e0d77346151052b06ccd7 Mon Sep 17 00:00:00 2001 From: MitchellGale-BitQuill Date: Thu, 13 Oct 2022 01:00:53 -0700 Subject: [PATCH 01/18] Added test cases and support for strict date validation. Added ability to parse time out of datetime or date out of datetime. Signed-off-by: MitchellGale-BitQuill --- .../sql/data/model/ExprDateValue.java | 4 +++- .../sql/data/model/ExprTimeValue.java | 7 +++--- .../sql/utils/DateTimeFormatters.java | 16 +++++++++++-- .../datetime/DateTimeFunctionTest.java | 10 ++++++++ docs/user/dql/functions.rst | 24 +++++++++---------- docs/user/ppl/functions/datetime.rst | 24 +++++++++---------- 6 files changed, 55 insertions(+), 30 deletions(-) diff --git a/core/src/main/java/org/opensearch/sql/data/model/ExprDateValue.java b/core/src/main/java/org/opensearch/sql/data/model/ExprDateValue.java index 09b2e56b44..7617e156ba 100644 --- a/core/src/main/java/org/opensearch/sql/data/model/ExprDateValue.java +++ b/core/src/main/java/org/opensearch/sql/data/model/ExprDateValue.java @@ -6,6 +6,8 @@ package org.opensearch.sql.data.model; +import static org.opensearch.sql.utils.DateTimeFormatters.DATE_TIME_FORMATTER_VARIABLE_NANOS_OPTIONAL; + import com.google.common.base.Objects; import java.time.Instant; import java.time.LocalDate; @@ -33,7 +35,7 @@ public class ExprDateValue extends AbstractExprValue { */ public ExprDateValue(String date) { try { - this.date = LocalDate.parse(date); + this.date = LocalDate.parse(date, DATE_TIME_FORMATTER_VARIABLE_NANOS_OPTIONAL); } catch (DateTimeParseException e) { throw new SemanticCheckException(String.format("date:%s in unsupported format, please use " + "yyyy-MM-dd", date)); diff --git a/core/src/main/java/org/opensearch/sql/data/model/ExprTimeValue.java b/core/src/main/java/org/opensearch/sql/data/model/ExprTimeValue.java index 9c5f5c5d55..aa3d17146a 100644 --- a/core/src/main/java/org/opensearch/sql/data/model/ExprTimeValue.java +++ b/core/src/main/java/org/opensearch/sql/data/model/ExprTimeValue.java @@ -6,7 +6,7 @@ package org.opensearch.sql.data.model; -import static org.opensearch.sql.utils.DateTimeFormatters.TIME_FORMATTER_VARIABLE_NANOS; +import static org.opensearch.sql.utils.DateTimeFormatters.DATE_TIME_FORMATTER_VARIABLE_NANOS_OPTIONAL; import java.time.LocalTime; import java.time.format.DateTimeFormatter; @@ -22,14 +22,15 @@ */ @RequiredArgsConstructor public class ExprTimeValue extends AbstractExprValue { + private final LocalTime time; /** - * Constructor. + * Constructor of ExprTimeValue. */ public ExprTimeValue(String time) { try { - this.time = LocalTime.parse(time, TIME_FORMATTER_VARIABLE_NANOS); + this.time = LocalTime.parse(time, DATE_TIME_FORMATTER_VARIABLE_NANOS_OPTIONAL); } catch (DateTimeParseException e) { throw new SemanticCheckException(String.format("time:%s in unsupported format, please use " + "HH:mm:ss[.SSSSSSSSS]", time)); diff --git a/core/src/main/java/org/opensearch/sql/utils/DateTimeFormatters.java b/core/src/main/java/org/opensearch/sql/utils/DateTimeFormatters.java index 2efdbb3755..0e1473868f 100644 --- a/core/src/main/java/org/opensearch/sql/utils/DateTimeFormatters.java +++ b/core/src/main/java/org/opensearch/sql/utils/DateTimeFormatters.java @@ -113,13 +113,25 @@ public class DateTimeFormatters { public static final DateTimeFormatter DATE_TIME_FORMATTER_VARIABLE_NANOS = new DateTimeFormatterBuilder() - .appendPattern("yyyy-MM-dd HH:mm:ss") + .appendPattern("uuuu-MM-dd HH:mm:ss") .appendFraction( ChronoField.NANO_OF_SECOND, MIN_FRACTION_SECONDS, MAX_FRACTION_SECONDS, true) - .toFormatter(Locale.ROOT); + .toFormatter(Locale.ROOT) + .withResolverStyle(ResolverStyle.STRICT); + + public static final DateTimeFormatter DATE_TIME_FORMATTER_VARIABLE_NANOS_OPTIONAL = + new DateTimeFormatterBuilder() + .appendPattern("[uuuu-MM-dd HH:mm:ss][HH:mm:ss][uuuu-MM-dd]") + .appendFraction( + ChronoField.NANO_OF_SECOND, + MIN_FRACTION_SECONDS, + MAX_FRACTION_SECONDS, + true) + .toFormatter(Locale.ROOT) + .withResolverStyle(ResolverStyle.STRICT); public static final DateTimeFormatter TIME_FORMATTER_VARIABLE_NANOS = new DateTimeFormatterBuilder() 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 79efa2a015..75f44bbd5e 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 @@ -240,6 +240,11 @@ public void date() { assertEquals(DATE, expr.type()); assertEquals(new ExprDateValue("2020-08-17"), eval(expr)); assertEquals("date(DATE '2020-08-17')", expr.toString()); + + expr = dsl.date(DSL.literal(new ExprDateValue("2020-08-17 12:12:00"))); + assertEquals(DATE, expr.type()); + assertEquals(new ExprDateValue("2020-08-17 12:12:00"), eval(expr)); + assertEquals("date(DATE '2020-08-17')", expr.toString()); } @Test @@ -795,6 +800,11 @@ public void time() { assertEquals(TIME, expr.type()); assertEquals(new ExprTimeValue("01:01:01"), eval(expr)); assertEquals("time(TIME '01:01:01')", expr.toString()); + + expr = dsl.time(DSL.literal(new ExprTimeValue("2020-01-02 01:01:01"))); + assertEquals(TIME, expr.type()); + assertEquals(new ExprTimeValue("2020-01-02 01:01:01"), eval(expr)); + assertEquals("time(TIME '01:01:01')", expr.toString()); } @Test diff --git a/docs/user/dql/functions.rst b/docs/user/dql/functions.rst index 7f02e947a4..73d9c16bd1 100644 --- a/docs/user/dql/functions.rst +++ b/docs/user/dql/functions.rst @@ -1076,13 +1076,13 @@ Return type: DATE Example:: - >od SELECT DATE('2020-08-26'), DATE(TIMESTAMP('2020-08-26 13:49:00')) + os> SELECT DATE('2020-08-26'), DATE(TIMESTAMP('2020-08-26 13:49:00')), DATE('2020-08-26 13:49:00') fetched rows / total rows = 1/1 - +----------------------+------------------------------------------+ - | DATE('2020-08-26') | DATE(TIMESTAMP('2020-08-26 13:49:00')) | - |----------------------+------------------------------------------| - | DATE '2020-08-26' | DATE '2020-08-26' | - +----------------------+------------------------------------------+ + +----------------------+------------------------------------------+-------------------------------+ + | DATE('2020-08-26') | DATE(TIMESTAMP('2020-08-26 13:49:00')) | DATE('2020-08-26 13:49:00') | + |----------------------+------------------------------------------+-------------------------------| + | 2020-08-26 | 2020-08-26 | 2020-08-26 | + +----------------------+------------------------------------------+-------------------------------+ DATETIME @@ -1880,13 +1880,13 @@ Return type: TIME Example:: - >od SELECT TIME('13:49:00'), TIME(TIMESTAMP('2020-08-26 13:49:00')) + os> SELECT TIME('13:49:00'), TIME(TIMESTAMP('2020-08-26 13:49:00')), TIME('2020-08-26 13:49:00') fetched rows / total rows = 1/1 - +--------------------+------------------------------------------+ - | TIME('13:49:00') | TIME(TIMESTAMP('2020-08-26 13:49:00')) | - |--------------------+------------------------------------------| - | TIME '13:49:00' | TIME '13:49:00' | - +--------------------+------------------------------------------+ + +--------------------+------------------------------------------+-------------------------------+ + | TIME('13:49:00') | TIME(TIMESTAMP('2020-08-26 13:49:00')) | TIME('2020-08-26 13:49:00') | + |--------------------+------------------------------------------+-------------------------------| + | 13:49:00 | 13:49:00 | 13:49:00 | + +--------------------+------------------------------------------+-------------------------------+ TIME_TO_SEC diff --git a/docs/user/ppl/functions/datetime.rst b/docs/user/ppl/functions/datetime.rst index e6ff88d2a8..63408d427e 100644 --- a/docs/user/ppl/functions/datetime.rst +++ b/docs/user/ppl/functions/datetime.rst @@ -291,13 +291,13 @@ Return type: DATE Example:: - >od source=people | eval `DATE('2020-08-26')` = DATE('2020-08-26'), `DATE(TIMESTAMP('2020-08-26 13:49:00'))` = DATE(TIMESTAMP('2020-08-26 13:49:00')) | fields `DATE('2020-08-26')`, `DATE(TIMESTAMP('2020-08-26 13:49:00'))` + os> source=people | eval `DATE('2020-08-26')` = DATE('2020-08-26'), `DATE(TIMESTAMP('2020-08-26 13:49:00'))` = DATE(TIMESTAMP('2020-08-26 13:49:00')), `DATE('2020-08-26 13:49:00')` = DATE('2020-08-26 13:49:00') | fields `DATE('2020-08-26')`, `DATE(TIMESTAMP('2020-08-26 13:49:00'))`, `DATE('2020-08-26 13:49:00')` fetched rows / total rows = 1/1 - +----------------------+------------------------------------------+ - | DATE('2020-08-26') | DATE(TIMESTAMP('2020-08-26 13:49:00')) | - |----------------------+------------------------------------------| - | DATE '2020-08-26' | DATE '2020-08-26' | - +----------------------+------------------------------------------+ + +----------------------+------------------------------------------+-------------------------------+ + | DATE('2020-08-26') | DATE(TIMESTAMP('2020-08-26 13:49:00')) | DATE('2020-08-26 13:49:00') | + |----------------------+------------------------------------------+-------------------------------| + | 2020-08-26 | 2020-08-26 | 2020-08-26 | + +----------------------+------------------------------------------+-------------------------------+ DATE_ADD @@ -1052,13 +1052,13 @@ Return type: TIME Example:: - >od source=people | eval `TIME('13:49:00')` = TIME('13:49:00'), `TIME(TIMESTAMP('2020-08-26 13:49:00'))` = TIME(TIMESTAMP('2020-08-26 13:49:00')) | fields `TIME('13:49:00')`, `TIME(TIMESTAMP('2020-08-26 13:49:00'))` + >od source=people | eval `TIME('13:49:00')` = TIME('13:49:00'), `TIME(TIMESTAMP('2020-08-26 13:49:00'))` = TIME(TIMESTAMP('2020-08-26 13:49:00')), `TIME('2020-08-26 13:49:00')` = TIME('2020-08-26 13:49:00') | fields `TIME('13:49:00')`, `TIME(TIMESTAMP('2020-08-26 13:49:00'))`, `TIME('2020-08-26 13:49:00')` fetched rows / total rows = 1/1 - +--------------------+------------------------------------------+ - | TIME('13:49:00') | TIME(TIMESTAMP('2020-08-26 13:49:00')) | - |--------------------+------------------------------------------| - | TIME '13:49:00' | TIME '13:49:00' | - +--------------------+------------------------------------------+ + +--------------------+------------------------------------------+-------------------------------+ + | TIME('13:49:00') | TIME(TIMESTAMP('2020-08-26 13:49:00')) | TIME('2020-08-26 13:49:00') | + |--------------------+------------------------------------------+-------------------------------| + | 13:49:00 | 13:49:00 | 13:49:00 | + +--------------------+------------------------------------------+-------------------------------+ TIME_TO_SEC From 4a4e4252fd1bee89861b23f7a627148231fdff27 Mon Sep 17 00:00:00 2001 From: Yury-Fridlyand Date: Wed, 12 Oct 2022 19:16:32 -0700 Subject: [PATCH 02/18] Update `ExprTimeValue` by `datetimeValue` and other interfaces. Add corresponding tests. Signed-off-by: Yury-Fridlyand --- .../sql/data/model/ExprTimeValue.java | 20 +++++++++++++++++++ .../sql/data/model/DateTimeValueTest.java | 4 ++++ 2 files changed, 24 insertions(+) diff --git a/core/src/main/java/org/opensearch/sql/data/model/ExprTimeValue.java b/core/src/main/java/org/opensearch/sql/data/model/ExprTimeValue.java index aa3d17146a..1d6c81c7e1 100644 --- a/core/src/main/java/org/opensearch/sql/data/model/ExprTimeValue.java +++ b/core/src/main/java/org/opensearch/sql/data/model/ExprTimeValue.java @@ -8,7 +8,12 @@ import static org.opensearch.sql.utils.DateTimeFormatters.DATE_TIME_FORMATTER_VARIABLE_NANOS_OPTIONAL; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; import java.time.LocalTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; import java.util.Objects; @@ -52,6 +57,21 @@ public LocalTime timeValue() { return time; } + @Override + public LocalDate dateValue() { + return LocalDate.now(); + } + + @Override + public LocalDateTime datetimeValue() { + return LocalDateTime.of(dateValue(), timeValue()); + } + + @Override + public Instant timestampValue() { + return ZonedDateTime.of(dateValue(), timeValue(), ZoneId.systemDefault()).toInstant(); + } + @Override public String toString() { return String.format("TIME '%s'", value()); diff --git a/core/src/test/java/org/opensearch/sql/data/model/DateTimeValueTest.java b/core/src/test/java/org/opensearch/sql/data/model/DateTimeValueTest.java index 3a7df17d90..9a1d92f5e0 100644 --- a/core/src/test/java/org/opensearch/sql/data/model/DateTimeValueTest.java +++ b/core/src/test/java/org/opensearch/sql/data/model/DateTimeValueTest.java @@ -31,6 +31,10 @@ public void timeValueInterfaceTest() { assertEquals(TIME, timeValue.type()); assertEquals(LocalTime.parse("01:01:01"), timeValue.timeValue()); + assertEquals(LocalDate.now(), timeValue.dateValue()); + assertEquals(LocalDate.now().atTime(1, 1, 1), timeValue.datetimeValue()); + assertEquals(ZonedDateTime.of(LocalTime.parse("01:01:01").atDate(LocalDate.now()), + ZoneId.systemDefault()).toInstant(), timeValue.timestampValue()); assertEquals("01:01:01", timeValue.value()); assertEquals("TIME '01:01:01'", timeValue.toString()); assertThrows(ExpressionEvaluationException.class, () -> integerValue(1).timeValue(), From da22234f08d08bee9a76b81d234f687e882d806b Mon Sep 17 00:00:00 2001 From: Yury-Fridlyand Date: Wed, 12 Oct 2022 19:16:32 -0700 Subject: [PATCH 03/18] core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunction.java Signed-off-by: MitchellGale-BitQuill --- .../sql/expression/datetime/DateTimeFunction.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) 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 84716a425a..9e65ee1ee8 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 @@ -55,6 +55,7 @@ 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; @@ -651,7 +652,11 @@ private ExprValue exprConvertTZ(ExprValue startingDateTime, ExprValue fromTz, Ex */ private ExprValue exprDate(ExprValue exprValue) { if (exprValue instanceof ExprStringValue) { - return new ExprDateValue(exprValue.stringValue()); + try { + return new ExprDateValue(exprValue.stringValue()); + } catch (SemanticCheckException e) { + return ExprNullValue.of(); + } } else { return new ExprDateValue(exprValue.dateValue()); } @@ -944,6 +949,7 @@ private ExprValue exprSubDateInterval(ExprValue date, ExprValue expr) { */ private ExprValue exprTime(ExprValue exprValue) { if (exprValue instanceof ExprStringValue) { + //try catch return new ExprTimeValue(exprValue.stringValue()); } else { return new ExprTimeValue(exprValue.timeValue()); From e42134952915e1c98473f6a8cb2aab55c7aa7a28 Mon Sep 17 00:00:00 2001 From: Yury-Fridlyand Date: Thu, 13 Oct 2022 17:58:01 -0700 Subject: [PATCH 04/18] Fix conversion to timestamp. Signed-off-by: Yury-Fridlyand --- .../java/org/opensearch/sql/data/model/ExprDateValue.java | 2 +- .../java/org/opensearch/sql/data/model/ExprTimeValue.java | 2 +- .../java/org/opensearch/sql/data/model/DateTimeValueTest.java | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/opensearch/sql/data/model/ExprDateValue.java b/core/src/main/java/org/opensearch/sql/data/model/ExprDateValue.java index 7617e156ba..5aeebc9297 100644 --- a/core/src/main/java/org/opensearch/sql/data/model/ExprDateValue.java +++ b/core/src/main/java/org/opensearch/sql/data/model/ExprDateValue.java @@ -69,7 +69,7 @@ public LocalDateTime datetimeValue() { @Override public Instant timestampValue() { - return ZonedDateTime.of(date, timeValue(), ZoneId.systemDefault()).toInstant(); + return ZonedDateTime.of(date, timeValue(), ZoneId.of("UTC")).toInstant(); } @Override diff --git a/core/src/main/java/org/opensearch/sql/data/model/ExprTimeValue.java b/core/src/main/java/org/opensearch/sql/data/model/ExprTimeValue.java index 1d6c81c7e1..5c7e9c58e8 100644 --- a/core/src/main/java/org/opensearch/sql/data/model/ExprTimeValue.java +++ b/core/src/main/java/org/opensearch/sql/data/model/ExprTimeValue.java @@ -69,7 +69,7 @@ public LocalDateTime datetimeValue() { @Override public Instant timestampValue() { - return ZonedDateTime.of(dateValue(), timeValue(), ZoneId.systemDefault()).toInstant(); + return ZonedDateTime.of(dateValue(), timeValue(), ZoneId.of("UTC")).toInstant(); } @Override diff --git a/core/src/test/java/org/opensearch/sql/data/model/DateTimeValueTest.java b/core/src/test/java/org/opensearch/sql/data/model/DateTimeValueTest.java index 9a1d92f5e0..ca6a09a30c 100644 --- a/core/src/test/java/org/opensearch/sql/data/model/DateTimeValueTest.java +++ b/core/src/test/java/org/opensearch/sql/data/model/DateTimeValueTest.java @@ -34,7 +34,7 @@ public void timeValueInterfaceTest() { assertEquals(LocalDate.now(), timeValue.dateValue()); assertEquals(LocalDate.now().atTime(1, 1, 1), timeValue.datetimeValue()); assertEquals(ZonedDateTime.of(LocalTime.parse("01:01:01").atDate(LocalDate.now()), - ZoneId.systemDefault()).toInstant(), timeValue.timestampValue()); + ZoneId.of("UTC")).toInstant(), timeValue.timestampValue()); assertEquals("01:01:01", timeValue.value()); assertEquals("TIME '01:01:01'", timeValue.toString()); assertThrows(ExpressionEvaluationException.class, () -> integerValue(1).timeValue(), @@ -65,7 +65,7 @@ public void dateValueInterfaceTest() { assertEquals(LocalTime.parse("00:00:00"), dateValue.timeValue()); assertEquals(LocalDateTime.parse("2012-07-07T00:00:00"), dateValue.datetimeValue()); assertEquals(ZonedDateTime.of(LocalDateTime.parse("2012-07-07T00:00:00"), - ZoneId.systemDefault()).toInstant(), dateValue.timestampValue()); + ZoneId.of("UTC")).toInstant(), dateValue.timestampValue()); ExpressionEvaluationException exception = assertThrows(ExpressionEvaluationException.class, () -> integerValue(1).dateValue()); assertEquals("invalid to get dateValue from value of type INTEGER", From 26c1165b0aef1b26a53cbc1feb89261a7e27963c Mon Sep 17 00:00:00 2001 From: MitchellGale-BitQuill Date: Mon, 17 Oct 2022 09:52:05 -0700 Subject: [PATCH 05/18] Added try catch to return null for invalid date in DATE Signed-off-by: MitchellGale-BitQuill --- .../sql/expression/datetime/DateTimeFunction.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 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 9e65ee1ee8..ec1c4b86e1 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 @@ -949,8 +949,11 @@ private ExprValue exprSubDateInterval(ExprValue date, ExprValue expr) { */ private ExprValue exprTime(ExprValue exprValue) { if (exprValue instanceof ExprStringValue) { - //try catch - return new ExprTimeValue(exprValue.stringValue()); + try { + return new ExprTimeValue(exprValue.stringValue()); + } catch (SemanticCheckException e) { + return ExprNullValue.of(); + } } else { return new ExprTimeValue(exprValue.timeValue()); } From be3ea22519e49ad62a22c259335aac59d9d508f4 Mon Sep 17 00:00:00 2001 From: MitchellGale-BitQuill Date: Mon, 17 Oct 2022 12:00:48 -0700 Subject: [PATCH 06/18] Added null test for TIME and DATE Signed-off-by: MitchellGale-BitQuill --- .../sql/expression/datetime/DateTimeFunctionTest.java | 6 ++++++ 1 file changed, 6 insertions(+) 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 75f44bbd5e..e4e0ed979f 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 @@ -245,6 +245,9 @@ public void date() { assertEquals(DATE, expr.type()); assertEquals(new ExprDateValue("2020-08-17 12:12:00"), eval(expr)); assertEquals("date(DATE '2020-08-17')", expr.toString()); + + expr = dsl.date(DSL.literal("2020-02-30")); + assertEquals(nullValue(), expr.valueOf(null)); } @Test @@ -805,6 +808,9 @@ public void time() { assertEquals(TIME, expr.type()); assertEquals(new ExprTimeValue("2020-01-02 01:01:01"), eval(expr)); assertEquals("time(TIME '01:01:01')", expr.toString()); + + expr = dsl.time(DSL.literal("01:01:01:01")); + assertEquals(nullValue(), expr.valueOf(null)); } @Test From 4f7edd102657f9a7b51a4e4868077daccf0e8d4a Mon Sep 17 00:00:00 2001 From: MitchellGale-BitQuill Date: Mon, 17 Oct 2022 15:04:23 -0700 Subject: [PATCH 07/18] Added exprDate to accept time. Signed-off-by: MitchellGale-BitQuill --- .../opensearch/sql/expression/datetime/DateTimeFunction.java | 4 ++++ 1 file changed, 4 insertions(+) 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 ec1c4b86e1..de70242dd6 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 @@ -246,6 +246,7 @@ private DefaultFunctionResolver date() { return define(BuiltinFunctionName.DATE.getName(), impl(nullMissingHandling(DateTimeFunction::exprDate), DATE, STRING), impl(nullMissingHandling(DateTimeFunction::exprDate), DATE, DATE), + impl(nullMissingHandling(DateTimeFunction::exprDate), DATE, TIME), impl(nullMissingHandling(DateTimeFunction::exprDate), DATE, DATETIME), impl(nullMissingHandling(DateTimeFunction::exprDate), DATE, TIMESTAMP)); } @@ -651,6 +652,9 @@ private ExprValue exprConvertTZ(ExprValue startingDateTime, ExprValue fromTz, Ex * @return ExprValue. */ private ExprValue exprDate(ExprValue exprValue) { + if (exprValue.type() == TIME) { + return new ExprDateValue(LocalDate.now()); + } if (exprValue instanceof ExprStringValue) { try { return new ExprDateValue(exprValue.stringValue()); From a00863c8814f915d690e09a4baa2eef888bc454b Mon Sep 17 00:00:00 2001 From: MitchellGale-BitQuill Date: Tue, 18 Oct 2022 10:15:25 -0700 Subject: [PATCH 08/18] Accept date time for time and date Signed-off-by: MitchellGale-BitQuill --- .../sql/data/model/ExprDateValue.java | 4 +++- .../sql/data/model/ExprTimeValue.java | 6 +++-- .../sql/utils/DateTimeFormatters.java | 22 +++++++++++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/opensearch/sql/data/model/ExprDateValue.java b/core/src/main/java/org/opensearch/sql/data/model/ExprDateValue.java index 5aeebc9297..ab8ed0e2fe 100644 --- a/core/src/main/java/org/opensearch/sql/data/model/ExprDateValue.java +++ b/core/src/main/java/org/opensearch/sql/data/model/ExprDateValue.java @@ -6,6 +6,7 @@ package org.opensearch.sql.data.model; +import static org.opensearch.sql.utils.DateTimeFormatters.DATE_FORMATTER_VARIABLE_NANOS_OPTIONAL; import static org.opensearch.sql.utils.DateTimeFormatters.DATE_TIME_FORMATTER_VARIABLE_NANOS_OPTIONAL; import com.google.common.base.Objects; @@ -28,6 +29,7 @@ @RequiredArgsConstructor public class ExprDateValue extends AbstractExprValue { + //private static final DateTimeFormatter DATE_FORMATTER_VARIABLE_NANOS_OPTIONAL = ; private final LocalDate date; /** @@ -35,7 +37,7 @@ public class ExprDateValue extends AbstractExprValue { */ public ExprDateValue(String date) { try { - this.date = LocalDate.parse(date, DATE_TIME_FORMATTER_VARIABLE_NANOS_OPTIONAL); + this.date = LocalDate.parse(date, DATE_FORMATTER_VARIABLE_NANOS_OPTIONAL); } catch (DateTimeParseException e) { throw new SemanticCheckException(String.format("date:%s in unsupported format, please use " + "yyyy-MM-dd", date)); diff --git a/core/src/main/java/org/opensearch/sql/data/model/ExprTimeValue.java b/core/src/main/java/org/opensearch/sql/data/model/ExprTimeValue.java index 5c7e9c58e8..a389a5dd34 100644 --- a/core/src/main/java/org/opensearch/sql/data/model/ExprTimeValue.java +++ b/core/src/main/java/org/opensearch/sql/data/model/ExprTimeValue.java @@ -6,7 +6,9 @@ package org.opensearch.sql.data.model; +import static java.time.format.DateTimeFormatter.ISO_LOCAL_TIME; import static org.opensearch.sql.utils.DateTimeFormatters.DATE_TIME_FORMATTER_VARIABLE_NANOS_OPTIONAL; +import static org.opensearch.sql.utils.DateTimeFormatters.TIME_FORMATTER_VARIABLE_NANOS_OPTIONAL; import java.time.Instant; import java.time.LocalDate; @@ -35,7 +37,7 @@ public class ExprTimeValue extends AbstractExprValue { */ public ExprTimeValue(String time) { try { - this.time = LocalTime.parse(time, DATE_TIME_FORMATTER_VARIABLE_NANOS_OPTIONAL); + this.time = LocalTime.parse(time, TIME_FORMATTER_VARIABLE_NANOS_OPTIONAL); } catch (DateTimeParseException e) { throw new SemanticCheckException(String.format("time:%s in unsupported format, please use " + "HH:mm:ss[.SSSSSSSSS]", time)); @@ -44,7 +46,7 @@ public ExprTimeValue(String time) { @Override public String value() { - return DateTimeFormatter.ISO_LOCAL_TIME.format(time); + return ISO_LOCAL_TIME.format(time); } @Override diff --git a/core/src/main/java/org/opensearch/sql/utils/DateTimeFormatters.java b/core/src/main/java/org/opensearch/sql/utils/DateTimeFormatters.java index 0e1473868f..56e9bf1de4 100644 --- a/core/src/main/java/org/opensearch/sql/utils/DateTimeFormatters.java +++ b/core/src/main/java/org/opensearch/sql/utils/DateTimeFormatters.java @@ -133,6 +133,28 @@ public class DateTimeFormatters { .toFormatter(Locale.ROOT) .withResolverStyle(ResolverStyle.STRICT); + public static final DateTimeFormatter DATE_FORMATTER_VARIABLE_NANOS_OPTIONAL = + new DateTimeFormatterBuilder() + .appendPattern("[uu:MM:dd][uuuu-MM-dd HH:mm:ss][uuuu-MM-dd]") + .appendFraction( + ChronoField.NANO_OF_SECOND, + MIN_FRACTION_SECONDS, + MAX_FRACTION_SECONDS, + true) + .toFormatter(Locale.ROOT) + .withResolverStyle(ResolverStyle.STRICT); + + public static final DateTimeFormatter TIME_FORMATTER_VARIABLE_NANOS_OPTIONAL = + new DateTimeFormatterBuilder() + .appendPattern("[uuuu-MM-dd HH:mm:ss][HH:mm:ss]") + .appendFraction( + ChronoField.NANO_OF_SECOND, + MIN_FRACTION_SECONDS, + MAX_FRACTION_SECONDS, + true) + .toFormatter(Locale.ROOT) + .withResolverStyle(ResolverStyle.STRICT); + public static final DateTimeFormatter TIME_FORMATTER_VARIABLE_NANOS = new DateTimeFormatterBuilder() .appendPattern("HH:mm:ss") From 99c98b0a278c090ee37a8a4db93cb7ef3af37444 Mon Sep 17 00:00:00 2001 From: MitchellGale-BitQuill Date: Wed, 19 Oct 2022 09:07:34 -0700 Subject: [PATCH 09/18] Adding coverage Signed-off-by: MitchellGale-BitQuill --- .../sql/expression/datetime/DateTimeFunctionTest.java | 3 +++ 1 file changed, 3 insertions(+) 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 e4e0ed979f..6daf02c4a3 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 @@ -246,6 +246,9 @@ public void date() { assertEquals(new ExprDateValue("2020-08-17 12:12:00"), eval(expr)); assertEquals("date(DATE '2020-08-17')", expr.toString()); + expr = dsl.date(dsl.time(DSL.literal("12:12:00"))); + assertEquals(DATE, expr.type()); + expr = dsl.date(DSL.literal("2020-02-30")); assertEquals(nullValue(), expr.valueOf(null)); } From f9e38e96f9c7542535df07fa4e8ac46acddac408 Mon Sep 17 00:00:00 2001 From: MitchellGale-BitQuill Date: Wed, 19 Oct 2022 13:28:13 -0700 Subject: [PATCH 10/18] Fixed code coverage for time passed to date function case. Signed-off-by: MitchellGale-BitQuill --- .../sql/expression/datetime/DateTimeFunctionTest.java | 3 +++ 1 file changed, 3 insertions(+) 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 6daf02c4a3..9e2eaab5a9 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 @@ -24,6 +24,7 @@ import static org.opensearch.sql.data.type.ExprCoreType.TIMESTAMP; import com.google.common.collect.ImmutableList; +import java.time.LocalDate; import java.util.List; import lombok.AllArgsConstructor; import org.junit.jupiter.api.BeforeEach; @@ -248,6 +249,8 @@ public void date() { expr = dsl.date(dsl.time(DSL.literal("12:12:00"))); assertEquals(DATE, expr.type()); + assertEquals(new ExprDateValue(LocalDate.now()), expr.valueOf(null)); + expr = dsl.date(DSL.literal("2020-02-30")); assertEquals(nullValue(), expr.valueOf(null)); From 2016222f524af6c2edd56afa940a53181efd3b1c Mon Sep 17 00:00:00 2001 From: MitchellGale-BitQuill Date: Wed, 19 Oct 2022 15:52:35 -0700 Subject: [PATCH 11/18] Adding more test cases for datetime and milliseconds for DATE and TIME functions. Signed-off-by: MitchellGale-BitQuill --- .../opensearch/sql/data/model/ExprDateValue.java | 3 +-- .../opensearch/sql/data/model/ExprTimeValue.java | 2 +- .../sql/expression/datetime/DateTimeFunction.java | 3 +++ .../opensearch/sql/utils/DateTimeFormatters.java | 2 +- .../expression/datetime/DateTimeFunctionTest.java | 14 +++++++++++--- 5 files changed, 17 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/org/opensearch/sql/data/model/ExprDateValue.java b/core/src/main/java/org/opensearch/sql/data/model/ExprDateValue.java index ab8ed0e2fe..4e02dd6678 100644 --- a/core/src/main/java/org/opensearch/sql/data/model/ExprDateValue.java +++ b/core/src/main/java/org/opensearch/sql/data/model/ExprDateValue.java @@ -29,7 +29,6 @@ @RequiredArgsConstructor public class ExprDateValue extends AbstractExprValue { - //private static final DateTimeFormatter DATE_FORMATTER_VARIABLE_NANOS_OPTIONAL = ; private final LocalDate date; /** @@ -37,7 +36,7 @@ public class ExprDateValue extends AbstractExprValue { */ public ExprDateValue(String date) { try { - this.date = LocalDate.parse(date, DATE_FORMATTER_VARIABLE_NANOS_OPTIONAL); + this.date = LocalDate.parse(date, DATE_TIME_FORMATTER_VARIABLE_NANOS_OPTIONAL); } catch (DateTimeParseException e) { throw new SemanticCheckException(String.format("date:%s in unsupported format, please use " + "yyyy-MM-dd", date)); diff --git a/core/src/main/java/org/opensearch/sql/data/model/ExprTimeValue.java b/core/src/main/java/org/opensearch/sql/data/model/ExprTimeValue.java index a389a5dd34..3123aaacdc 100644 --- a/core/src/main/java/org/opensearch/sql/data/model/ExprTimeValue.java +++ b/core/src/main/java/org/opensearch/sql/data/model/ExprTimeValue.java @@ -37,7 +37,7 @@ public class ExprTimeValue extends AbstractExprValue { */ public ExprTimeValue(String time) { try { - this.time = LocalTime.parse(time, TIME_FORMATTER_VARIABLE_NANOS_OPTIONAL); + this.time = LocalTime.parse(time, DATE_TIME_FORMATTER_VARIABLE_NANOS_OPTIONAL); } catch (DateTimeParseException e) { throw new SemanticCheckException(String.format("time:%s in unsupported format, please use " + "HH:mm:ss[.SSSSSSSSS]", time)); 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 de70242dd6..87ed7a2922 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 @@ -952,6 +952,9 @@ private ExprValue exprSubDateInterval(ExprValue date, ExprValue expr) { * @return ExprValue. */ private ExprValue exprTime(ExprValue exprValue) { + if (exprValue.type() == DATE) { + return new ExprTimeValue("00:00:00"); + } if (exprValue instanceof ExprStringValue) { try { return new ExprTimeValue(exprValue.stringValue()); diff --git a/core/src/main/java/org/opensearch/sql/utils/DateTimeFormatters.java b/core/src/main/java/org/opensearch/sql/utils/DateTimeFormatters.java index 56e9bf1de4..cb9dc66f68 100644 --- a/core/src/main/java/org/opensearch/sql/utils/DateTimeFormatters.java +++ b/core/src/main/java/org/opensearch/sql/utils/DateTimeFormatters.java @@ -135,7 +135,7 @@ public class DateTimeFormatters { public static final DateTimeFormatter DATE_FORMATTER_VARIABLE_NANOS_OPTIONAL = new DateTimeFormatterBuilder() - .appendPattern("[uu:MM:dd][uuuu-MM-dd HH:mm:ss][uuuu-MM-dd]") + .appendPattern("[uuuu-MM-dd][HH:mm:ss][uuuu-MM-dd HH:mm:ss]") .appendFraction( ChronoField.NANO_OF_SECOND, MIN_FRACTION_SECONDS, 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 9e2eaab5a9..7cfb7a372a 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 @@ -251,7 +251,6 @@ public void date() { assertEquals(DATE, expr.type()); assertEquals(new ExprDateValue(LocalDate.now()), expr.valueOf(null)); - expr = dsl.date(DSL.literal("2020-02-30")); assertEquals(nullValue(), expr.valueOf(null)); } @@ -810,11 +809,20 @@ public void time() { assertEquals(new ExprTimeValue("01:01:01"), eval(expr)); assertEquals("time(TIME '01:01:01')", expr.toString()); - expr = dsl.time(DSL.literal(new ExprTimeValue("2020-01-02 01:01:01"))); + expr = dsl.time(DSL.literal(new ExprTimeValue("2019-04-19 01:01:01"))); assertEquals(TIME, expr.type()); - assertEquals(new ExprTimeValue("2020-01-02 01:01:01"), eval(expr)); + assertEquals(new ExprTimeValue("2019-04-19 01:01:01"), eval(expr)); assertEquals("time(TIME '01:01:01')", expr.toString()); + expr = dsl.time(DSL.literal(new ExprTimeValue("01:01:01.0123"))); + assertEquals(TIME, expr.type()); + assertEquals(new ExprTimeValue("01:01:01.0123"), eval(expr)); + assertEquals("time(TIME '01:01:01.0123')", expr.toString()); + + expr = dsl.time(dsl.date(DSL.literal("2020-01-02"))); + assertEquals(TIME, expr.type()); + assertEquals(new ExprTimeValue("00:00:00"), expr.valueOf(null)); + expr = dsl.time(DSL.literal("01:01:01:01")); assertEquals(nullValue(), expr.valueOf(null)); } From 4c0928d6c90da35275f8b47cba1f5cca32ff1a6e Mon Sep 17 00:00:00 2001 From: MitchellGale-BitQuill Date: Wed, 19 Oct 2022 16:20:23 -0700 Subject: [PATCH 12/18] Removed unused imports. Signed-off-by: MitchellGale-BitQuill --- .../main/java/org/opensearch/sql/data/model/ExprDateValue.java | 1 - .../main/java/org/opensearch/sql/data/model/ExprTimeValue.java | 2 -- 2 files changed, 3 deletions(-) diff --git a/core/src/main/java/org/opensearch/sql/data/model/ExprDateValue.java b/core/src/main/java/org/opensearch/sql/data/model/ExprDateValue.java index 4e02dd6678..5aeebc9297 100644 --- a/core/src/main/java/org/opensearch/sql/data/model/ExprDateValue.java +++ b/core/src/main/java/org/opensearch/sql/data/model/ExprDateValue.java @@ -6,7 +6,6 @@ package org.opensearch.sql.data.model; -import static org.opensearch.sql.utils.DateTimeFormatters.DATE_FORMATTER_VARIABLE_NANOS_OPTIONAL; import static org.opensearch.sql.utils.DateTimeFormatters.DATE_TIME_FORMATTER_VARIABLE_NANOS_OPTIONAL; import com.google.common.base.Objects; diff --git a/core/src/main/java/org/opensearch/sql/data/model/ExprTimeValue.java b/core/src/main/java/org/opensearch/sql/data/model/ExprTimeValue.java index 3123aaacdc..fdbe7532f0 100644 --- a/core/src/main/java/org/opensearch/sql/data/model/ExprTimeValue.java +++ b/core/src/main/java/org/opensearch/sql/data/model/ExprTimeValue.java @@ -8,7 +8,6 @@ import static java.time.format.DateTimeFormatter.ISO_LOCAL_TIME; import static org.opensearch.sql.utils.DateTimeFormatters.DATE_TIME_FORMATTER_VARIABLE_NANOS_OPTIONAL; -import static org.opensearch.sql.utils.DateTimeFormatters.TIME_FORMATTER_VARIABLE_NANOS_OPTIONAL; import java.time.Instant; import java.time.LocalDate; @@ -16,7 +15,6 @@ import java.time.LocalTime; import java.time.ZoneId; import java.time.ZonedDateTime; -import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; import java.util.Objects; import lombok.RequiredArgsConstructor; From 95c5e5cb625f571ce2a76bac131a4b09f346f4b2 Mon Sep 17 00:00:00 2001 From: MitchellGale-BitQuill Date: Wed, 19 Oct 2022 17:07:30 -0700 Subject: [PATCH 13/18] Removed unused DATETIMEFORMATTERS. Signed-off-by: MitchellGale-BitQuill --- .../sql/utils/DateTimeFormatters.java | 32 ------------------- 1 file changed, 32 deletions(-) diff --git a/core/src/main/java/org/opensearch/sql/utils/DateTimeFormatters.java b/core/src/main/java/org/opensearch/sql/utils/DateTimeFormatters.java index cb9dc66f68..53aa479115 100644 --- a/core/src/main/java/org/opensearch/sql/utils/DateTimeFormatters.java +++ b/core/src/main/java/org/opensearch/sql/utils/DateTimeFormatters.java @@ -133,38 +133,6 @@ public class DateTimeFormatters { .toFormatter(Locale.ROOT) .withResolverStyle(ResolverStyle.STRICT); - public static final DateTimeFormatter DATE_FORMATTER_VARIABLE_NANOS_OPTIONAL = - new DateTimeFormatterBuilder() - .appendPattern("[uuuu-MM-dd][HH:mm:ss][uuuu-MM-dd HH:mm:ss]") - .appendFraction( - ChronoField.NANO_OF_SECOND, - MIN_FRACTION_SECONDS, - MAX_FRACTION_SECONDS, - true) - .toFormatter(Locale.ROOT) - .withResolverStyle(ResolverStyle.STRICT); - - public static final DateTimeFormatter TIME_FORMATTER_VARIABLE_NANOS_OPTIONAL = - new DateTimeFormatterBuilder() - .appendPattern("[uuuu-MM-dd HH:mm:ss][HH:mm:ss]") - .appendFraction( - ChronoField.NANO_OF_SECOND, - MIN_FRACTION_SECONDS, - MAX_FRACTION_SECONDS, - true) - .toFormatter(Locale.ROOT) - .withResolverStyle(ResolverStyle.STRICT); - - public static final DateTimeFormatter TIME_FORMATTER_VARIABLE_NANOS = - new DateTimeFormatterBuilder() - .appendPattern("HH:mm:ss") - .appendFraction( - ChronoField.NANO_OF_SECOND, - MIN_FRACTION_SECONDS, - MAX_FRACTION_SECONDS, - true) - .toFormatter(); - // YYMMDD public static final DateTimeFormatter DATE_FORMATTER_SHORT_YEAR = new DateTimeFormatterBuilder() From 61289bbecd5557b83c533d18056ffcfcaf85ef5c Mon Sep 17 00:00:00 2001 From: MitchellGale-BitQuill Date: Tue, 25 Oct 2022 10:54:08 -0700 Subject: [PATCH 14/18] Added support for HH:mm for time/datetime inputs. Removed call for local time now. Signed-off-by: MitchellGale-BitQuill --- .../sql/expression/datetime/DateTimeFunction.java | 4 ---- .../opensearch/sql/utils/DateTimeFormatters.java | 2 +- .../expression/datetime/DateTimeFunctionTest.java | 15 +++++++++++++-- 3 files changed, 14 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 87ed7a2922..17aa76557f 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 @@ -246,7 +246,6 @@ private DefaultFunctionResolver date() { return define(BuiltinFunctionName.DATE.getName(), impl(nullMissingHandling(DateTimeFunction::exprDate), DATE, STRING), impl(nullMissingHandling(DateTimeFunction::exprDate), DATE, DATE), - impl(nullMissingHandling(DateTimeFunction::exprDate), DATE, TIME), impl(nullMissingHandling(DateTimeFunction::exprDate), DATE, DATETIME), impl(nullMissingHandling(DateTimeFunction::exprDate), DATE, TIMESTAMP)); } @@ -652,9 +651,6 @@ private ExprValue exprConvertTZ(ExprValue startingDateTime, ExprValue fromTz, Ex * @return ExprValue. */ private ExprValue exprDate(ExprValue exprValue) { - if (exprValue.type() == TIME) { - return new ExprDateValue(LocalDate.now()); - } if (exprValue instanceof ExprStringValue) { try { return new ExprDateValue(exprValue.stringValue()); diff --git a/core/src/main/java/org/opensearch/sql/utils/DateTimeFormatters.java b/core/src/main/java/org/opensearch/sql/utils/DateTimeFormatters.java index 53aa479115..2556aed8d8 100644 --- a/core/src/main/java/org/opensearch/sql/utils/DateTimeFormatters.java +++ b/core/src/main/java/org/opensearch/sql/utils/DateTimeFormatters.java @@ -124,7 +124,7 @@ public class DateTimeFormatters { public static final DateTimeFormatter DATE_TIME_FORMATTER_VARIABLE_NANOS_OPTIONAL = new DateTimeFormatterBuilder() - .appendPattern("[uuuu-MM-dd HH:mm:ss][HH:mm:ss][uuuu-MM-dd]") + .appendPattern("[uuuu-MM-dd HH:mm:ss][uuuu-MM-dd HH:mm][HH:mm:ss][HH:mm][uuuu-MM-dd]") .appendFraction( ChronoField.NANO_OF_SECOND, MIN_FRACTION_SECONDS, 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 7cfb7a372a..9e8f31aa71 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 @@ -247,9 +247,10 @@ public void date() { assertEquals(new ExprDateValue("2020-08-17 12:12:00"), eval(expr)); assertEquals("date(DATE '2020-08-17')", expr.toString()); - expr = dsl.date(dsl.time(DSL.literal("12:12:00"))); + expr = dsl.date(DSL.literal(new ExprDateValue("2020-08-17 12:12"))); assertEquals(DATE, expr.type()); - assertEquals(new ExprDateValue(LocalDate.now()), expr.valueOf(null)); + assertEquals(new ExprDateValue("2020-08-17 12:12"), eval(expr)); + assertEquals("date(DATE '2020-08-17')", expr.toString()); expr = dsl.date(DSL.literal("2020-02-30")); assertEquals(nullValue(), expr.valueOf(null)); @@ -809,11 +810,21 @@ public void time() { assertEquals(new ExprTimeValue("01:01:01"), eval(expr)); assertEquals("time(TIME '01:01:01')", expr.toString()); + expr = dsl.time(DSL.literal(new ExprTimeValue("01:01"))); + assertEquals(TIME, expr.type()); + assertEquals(new ExprTimeValue("01:01"), eval(expr)); + assertEquals("time(TIME '01:01')", expr.toString()); + expr = dsl.time(DSL.literal(new ExprTimeValue("2019-04-19 01:01:01"))); assertEquals(TIME, expr.type()); assertEquals(new ExprTimeValue("2019-04-19 01:01:01"), eval(expr)); assertEquals("time(TIME '01:01:01')", expr.toString()); + expr = dsl.time(DSL.literal(new ExprTimeValue("2019-04-19 01:01"))); + assertEquals(TIME, expr.type()); + assertEquals(new ExprTimeValue("2019-04-19 01:01"), eval(expr)); + assertEquals("time(TIME '01:01')", expr.toString()); + expr = dsl.time(DSL.literal(new ExprTimeValue("01:01:01.0123"))); assertEquals(TIME, expr.type()); assertEquals(new ExprTimeValue("01:01:01.0123"), eval(expr)); From 310f653a46d9bff790a99882aaf954da0c6df4a0 Mon Sep 17 00:00:00 2001 From: MitchellGale-BitQuill Date: Thu, 27 Oct 2022 10:50:51 -0700 Subject: [PATCH 15/18] Added more doc tests. Signed-off-by: MitchellGale-BitQuill --- .../datetime/DateTimeFunctionTest.java | 4 +- docs/user/dql/functions.rst | 24 ++--- docs/user/ppl/functions/datetime.rst | 88 ++++++++++++++++--- 3 files changed, 90 insertions(+), 26 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 9e8f31aa71..aa7b342b16 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 @@ -813,7 +813,7 @@ public void time() { expr = dsl.time(DSL.literal(new ExprTimeValue("01:01"))); assertEquals(TIME, expr.type()); assertEquals(new ExprTimeValue("01:01"), eval(expr)); - assertEquals("time(TIME '01:01')", expr.toString()); + assertEquals("time(TIME '01:01:00')", expr.toString()); expr = dsl.time(DSL.literal(new ExprTimeValue("2019-04-19 01:01:01"))); assertEquals(TIME, expr.type()); @@ -823,7 +823,7 @@ public void time() { expr = dsl.time(DSL.literal(new ExprTimeValue("2019-04-19 01:01"))); assertEquals(TIME, expr.type()); assertEquals(new ExprTimeValue("2019-04-19 01:01"), eval(expr)); - assertEquals("time(TIME '01:01')", expr.toString()); + assertEquals("time(TIME '01:01:00')", expr.toString()); expr = dsl.time(DSL.literal(new ExprTimeValue("01:01:01.0123"))); assertEquals(TIME, expr.type()); diff --git a/docs/user/dql/functions.rst b/docs/user/dql/functions.rst index 73d9c16bd1..7d003a2262 100644 --- a/docs/user/dql/functions.rst +++ b/docs/user/dql/functions.rst @@ -1076,13 +1076,13 @@ Return type: DATE Example:: - os> SELECT DATE('2020-08-26'), DATE(TIMESTAMP('2020-08-26 13:49:00')), DATE('2020-08-26 13:49:00') + os> SELECT DATE('2020-08-26'), DATE(TIMESTAMP('2020-08-26 13:49:00')), DATE('2020-08-26 13:49:00'), DATE('2020-08-26 13:49') fetched rows / total rows = 1/1 - +----------------------+------------------------------------------+-------------------------------+ - | DATE('2020-08-26') | DATE(TIMESTAMP('2020-08-26 13:49:00')) | DATE('2020-08-26 13:49:00') | - |----------------------+------------------------------------------+-------------------------------| - | 2020-08-26 | 2020-08-26 | 2020-08-26 | - +----------------------+------------------------------------------+-------------------------------+ + +----------------------+------------------------------------------+-------------------------------+----------------------------+ + | DATE('2020-08-26') | DATE(TIMESTAMP('2020-08-26 13:49:00')) | DATE('2020-08-26 13:49:00') | DATE('2020-08-26 13:49') | + |----------------------+------------------------------------------+-------------------------------+----------------------------| + | 2020-08-26 | 2020-08-26 | 2020-08-26 | 2020-08-26 | + +----------------------+------------------------------------------+-------------------------------+----------------------------+ DATETIME @@ -1880,13 +1880,13 @@ Return type: TIME Example:: - os> SELECT TIME('13:49:00'), TIME(TIMESTAMP('2020-08-26 13:49:00')), TIME('2020-08-26 13:49:00') + os> SELECT TIME('13:49:00'), TIME('13:49'), TIME(TIMESTAMP('2020-08-26 13:49:00')), TIME('2020-08-26 13:49:00') fetched rows / total rows = 1/1 - +--------------------+------------------------------------------+-------------------------------+ - | TIME('13:49:00') | TIME(TIMESTAMP('2020-08-26 13:49:00')) | TIME('2020-08-26 13:49:00') | - |--------------------+------------------------------------------+-------------------------------| - | 13:49:00 | 13:49:00 | 13:49:00 | - +--------------------+------------------------------------------+-------------------------------+ + +--------------------+-----------------+------------------------------------------+-------------------------------+ + | TIME('13:49:00') | TIME('13:49') | TIME(TIMESTAMP('2020-08-26 13:49:00')) | TIME('2020-08-26 13:49:00') | + |--------------------+-----------------+------------------------------------------+-------------------------------| + | 13:49:00 | 13:49:00 | 13:49:00 | 13:49:00 | + +--------------------+-----------------+------------------------------------------+-------------------------------+ TIME_TO_SEC diff --git a/docs/user/ppl/functions/datetime.rst b/docs/user/ppl/functions/datetime.rst index 63408d427e..86a7cd1403 100644 --- a/docs/user/ppl/functions/datetime.rst +++ b/docs/user/ppl/functions/datetime.rst @@ -291,13 +291,45 @@ Return type: DATE Example:: - os> source=people | eval `DATE('2020-08-26')` = DATE('2020-08-26'), `DATE(TIMESTAMP('2020-08-26 13:49:00'))` = DATE(TIMESTAMP('2020-08-26 13:49:00')), `DATE('2020-08-26 13:49:00')` = DATE('2020-08-26 13:49:00') | fields `DATE('2020-08-26')`, `DATE(TIMESTAMP('2020-08-26 13:49:00'))`, `DATE('2020-08-26 13:49:00')` + os> source=people | eval `DATE('2020-08-26')` = DATE('2020-08-26') | fields `DATE('2020-08-26')` fetched rows / total rows = 1/1 - +----------------------+------------------------------------------+-------------------------------+ - | DATE('2020-08-26') | DATE(TIMESTAMP('2020-08-26 13:49:00')) | DATE('2020-08-26 13:49:00') | - |----------------------+------------------------------------------+-------------------------------| - | 2020-08-26 | 2020-08-26 | 2020-08-26 | - +----------------------+------------------------------------------+-------------------------------+ + +----------------------+ + | DATE('2020-08-26') | + |----------------------| + | 2020-08-26 | + +----------------------+ + + os> source=people | eval `DATE(TIMESTAMP('2020-08-26 13:49:00'))` = DATE(TIMESTAMP('2020-08-26 13:49:00')) | fields `DATE(TIMESTAMP('2020-08-26 13:49:00'))` + fetched rows / total rows = 1/1 + +------------------------------------------+ + | DATE(TIMESTAMP('2020-08-26 13:49:00')) | + |------------------------------------------| + | 2020-08-26 | + +------------------------------------------+ + + os> source=people | eval `DATE('2020-08-26 13:49')` = DATE('2020-08-26 13:49') | fields `DATE('2020-08-26 13:49')` + fetched rows / total rows = 1/1 + +----------------------------+ + | DATE('2020-08-26 13:49') | + |----------------------------| + | 2020-08-26 | + +----------------------------+ + + os> source=people | eval `DATE('2020-08-26 13:49')` = DATE('2020-08-26 13:49') | fields `DATE('2020-08-26 13:49')` + fetched rows / total rows = 1/1 + +----------------------------+ + | DATE('2020-08-26 13:49') | + |----------------------------| + | 2020-08-26 | + +----------------------------+ + + os> source=people | eval `DATE('2020-02-30 13:49')` = DATE('2020-02-30 13:49') | fields `DATE('2020-02-30 13:49')` + fetched rows / total rows = 1/1 + +----------------------------+ + | DATE('2020-02-30 13:49') | + |----------------------------| + | null | + +----------------------------+ DATE_ADD @@ -1052,13 +1084,45 @@ Return type: TIME Example:: - >od source=people | eval `TIME('13:49:00')` = TIME('13:49:00'), `TIME(TIMESTAMP('2020-08-26 13:49:00'))` = TIME(TIMESTAMP('2020-08-26 13:49:00')), `TIME('2020-08-26 13:49:00')` = TIME('2020-08-26 13:49:00') | fields `TIME('13:49:00')`, `TIME(TIMESTAMP('2020-08-26 13:49:00'))`, `TIME('2020-08-26 13:49:00')` + os> source=people | eval `TIME('13:49:00')` = TIME('13:49:00') | fields `TIME('13:49:00')` fetched rows / total rows = 1/1 - +--------------------+------------------------------------------+-------------------------------+ - | TIME('13:49:00') | TIME(TIMESTAMP('2020-08-26 13:49:00')) | TIME('2020-08-26 13:49:00') | - |--------------------+------------------------------------------+-------------------------------| - | 13:49:00 | 13:49:00 | 13:49:00 | - +--------------------+------------------------------------------+-------------------------------+ + +--------------------+ + | TIME('13:49:00') | + |--------------------| + | 13:49:00 | + +--------------------+ + + os> source=people | eval `TIME('13:49')` = TIME('13:49') | fields `TIME('13:49')` + fetched rows / total rows = 1/1 + +-----------------+ + | TIME('13:49') | + |-----------------| + | 13:49:00 | + +-----------------+ + + os> source=people | eval `TIME('2020-08-26 13:49:00')` = TIME('2020-08-26 13:49:00') | fields `TIME('2020-08-26 13:49:00')` + fetched rows / total rows = 1/1 + +-------------------------------+ + | TIME('2020-08-26 13:49:00') | + |-------------------------------| + | 13:49:00 | + +-------------------------------+ + + os> source=people | eval `TIME('2020-08-26 13:49')` = TIME('2020-08-26 13:49') | fields `TIME('2020-08-26 13:49')` + fetched rows / total rows = 1/1 + +----------------------------+ + | TIME('2020-08-26 13:49') | + |----------------------------| + | 13:49:00 | + +----------------------------+ + + os> source=people | eval `TIME('2020-02-30 13:49')` = TIME('2020-02-30 13:49') | fields `TIME('2020-02-30 13:49')` + fetched rows / total rows = 1/1 + +----------------------------+ + | TIME('2020-02-30 13:49') | + |----------------------------| + | null | + +----------------------------+ TIME_TO_SEC From 484b28c5d18cc65e8426bfcc0e72be85528e6691 Mon Sep 17 00:00:00 2001 From: MitchellGale-BitQuill Date: Fri, 28 Oct 2022 10:26:51 -0700 Subject: [PATCH 16/18] Removed blocks from cherry-picked PR. Signed-off-by: MitchellGale-BitQuill --- .../opensearch/sql/data/model/ExprTimeValue.java | 15 --------------- .../sql/data/model/DateTimeValueTest.java | 6 +----- 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/core/src/main/java/org/opensearch/sql/data/model/ExprTimeValue.java b/core/src/main/java/org/opensearch/sql/data/model/ExprTimeValue.java index fdbe7532f0..6cc4021d2e 100644 --- a/core/src/main/java/org/opensearch/sql/data/model/ExprTimeValue.java +++ b/core/src/main/java/org/opensearch/sql/data/model/ExprTimeValue.java @@ -57,21 +57,6 @@ public LocalTime timeValue() { return time; } - @Override - public LocalDate dateValue() { - return LocalDate.now(); - } - - @Override - public LocalDateTime datetimeValue() { - return LocalDateTime.of(dateValue(), timeValue()); - } - - @Override - public Instant timestampValue() { - return ZonedDateTime.of(dateValue(), timeValue(), ZoneId.of("UTC")).toInstant(); - } - @Override public String toString() { return String.format("TIME '%s'", value()); diff --git a/core/src/test/java/org/opensearch/sql/data/model/DateTimeValueTest.java b/core/src/test/java/org/opensearch/sql/data/model/DateTimeValueTest.java index ca6a09a30c..3a7df17d90 100644 --- a/core/src/test/java/org/opensearch/sql/data/model/DateTimeValueTest.java +++ b/core/src/test/java/org/opensearch/sql/data/model/DateTimeValueTest.java @@ -31,10 +31,6 @@ public void timeValueInterfaceTest() { assertEquals(TIME, timeValue.type()); assertEquals(LocalTime.parse("01:01:01"), timeValue.timeValue()); - assertEquals(LocalDate.now(), timeValue.dateValue()); - assertEquals(LocalDate.now().atTime(1, 1, 1), timeValue.datetimeValue()); - assertEquals(ZonedDateTime.of(LocalTime.parse("01:01:01").atDate(LocalDate.now()), - ZoneId.of("UTC")).toInstant(), timeValue.timestampValue()); assertEquals("01:01:01", timeValue.value()); assertEquals("TIME '01:01:01'", timeValue.toString()); assertThrows(ExpressionEvaluationException.class, () -> integerValue(1).timeValue(), @@ -65,7 +61,7 @@ public void dateValueInterfaceTest() { assertEquals(LocalTime.parse("00:00:00"), dateValue.timeValue()); assertEquals(LocalDateTime.parse("2012-07-07T00:00:00"), dateValue.datetimeValue()); assertEquals(ZonedDateTime.of(LocalDateTime.parse("2012-07-07T00:00:00"), - ZoneId.of("UTC")).toInstant(), dateValue.timestampValue()); + ZoneId.systemDefault()).toInstant(), dateValue.timestampValue()); ExpressionEvaluationException exception = assertThrows(ExpressionEvaluationException.class, () -> integerValue(1).dateValue()); assertEquals("invalid to get dateValue from value of type INTEGER", From 157059fa8fa1a40a0276af943e2864fc988e90f2 Mon Sep 17 00:00:00 2001 From: MitchellGale-BitQuill Date: Fri, 28 Oct 2022 13:23:09 -0700 Subject: [PATCH 17/18] Reverted change in ExprDateTimeValue Signed-off-by: MitchellGale-BitQuill --- .../java/org/opensearch/sql/data/model/ExprDatetimeValue.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/org/opensearch/sql/data/model/ExprDatetimeValue.java b/core/src/main/java/org/opensearch/sql/data/model/ExprDatetimeValue.java index f5f80f133f..e20dbf14a2 100644 --- a/core/src/main/java/org/opensearch/sql/data/model/ExprDatetimeValue.java +++ b/core/src/main/java/org/opensearch/sql/data/model/ExprDatetimeValue.java @@ -71,7 +71,7 @@ public LocalTime timeValue() { @Override public Instant timestampValue() { - return ZonedDateTime.of(datetime, ZoneId.of("UTC")).toInstant(); + return ZonedDateTime.of(datetime, ZoneId.systemDefault()).toInstant(); } @Override From 77bd46e17ed10c96d82e5700f6ec2aaff0bff06b Mon Sep 17 00:00:00 2001 From: MitchellGale-BitQuill Date: Fri, 28 Oct 2022 13:37:48 -0700 Subject: [PATCH 18/18] Reverted reverted changes in ExprDateTimeValue. Reverted change in ExprDateValue.java for timestampValue to use systemDefault instead of UTC time. Signed-off-by: MitchellGale-BitQuill --- .../main/java/org/opensearch/sql/data/model/ExprDateValue.java | 2 +- .../java/org/opensearch/sql/data/model/ExprDatetimeValue.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/opensearch/sql/data/model/ExprDateValue.java b/core/src/main/java/org/opensearch/sql/data/model/ExprDateValue.java index 5aeebc9297..7617e156ba 100644 --- a/core/src/main/java/org/opensearch/sql/data/model/ExprDateValue.java +++ b/core/src/main/java/org/opensearch/sql/data/model/ExprDateValue.java @@ -69,7 +69,7 @@ public LocalDateTime datetimeValue() { @Override public Instant timestampValue() { - return ZonedDateTime.of(date, timeValue(), ZoneId.of("UTC")).toInstant(); + return ZonedDateTime.of(date, timeValue(), ZoneId.systemDefault()).toInstant(); } @Override diff --git a/core/src/main/java/org/opensearch/sql/data/model/ExprDatetimeValue.java b/core/src/main/java/org/opensearch/sql/data/model/ExprDatetimeValue.java index e20dbf14a2..f5f80f133f 100644 --- a/core/src/main/java/org/opensearch/sql/data/model/ExprDatetimeValue.java +++ b/core/src/main/java/org/opensearch/sql/data/model/ExprDatetimeValue.java @@ -71,7 +71,7 @@ public LocalTime timeValue() { @Override public Instant timestampValue() { - return ZonedDateTime.of(datetime, ZoneId.systemDefault()).toInstant(); + return ZonedDateTime.of(datetime, ZoneId.of("UTC")).toInstant(); } @Override