-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update DATE_ADD
/ADDDATE
and DATE_SUB
/SUBDATE
functions.
#122
Update DATE_ADD
/ADDDATE
and DATE_SUB
/SUBDATE
functions.
#122
Conversation
This comment was marked as spam.
This comment was marked as spam.
d1dfe33
to
315bc23
Compare
Oops. Do I need to update docs with |
@Yury-Fridlyand could yup update Also SQL Java CI build says there's a failing integration test. |
315bc23
to
c690f52
Compare
"%\\{" | ||
+ "(?<name>" | ||
+ "(?<pattern>[A-z0-9]+)" | ||
+ "(?::(?<subname>[A-z0-9_:;,\\-\\/\\s\\.']+))?" | ||
+ ")" | ||
+ "(?:=(?<definition>" | ||
+ "(?:" | ||
+ "(?:[^{}]+|\\.+)+" | ||
+ ")+" | ||
+ ")" | ||
+ ")?" | ||
+ "\\}"); |
Check failure
Code scanning / CodeQL
Inefficient regular expression
"%\\{" | ||
+ "(?<name>" | ||
+ "(?<pattern>[A-z0-9]+)" | ||
+ "(?::(?<subname>[A-z0-9_:;,\\-\\/\\s\\.']+))?" | ||
+ ")" | ||
+ "(?:=(?<definition>" | ||
+ "(?:" | ||
+ "(?:[^{}]+|\\.+)+" | ||
+ ")+" | ||
+ ")" | ||
+ ")?" | ||
+ "\\}"); |
Check failure
Code scanning / CodeQL
Inefficient regular expression
public class GrokCompiler implements Serializable { | ||
|
||
// We don't want \n and commented line | ||
private static final Pattern patternLinePattern = Pattern.compile("^([A-z0-9_]+)\\s+(.*)$"); |
Check warning
Code scanning / CodeQL
Overly permissive regular expression range
"%\\{" | ||
+ "(?<name>" | ||
+ "(?<pattern>[A-z0-9]+)" | ||
+ "(?::(?<subname>[A-z0-9_:;,\\-\\/\\s\\.']+))?" | ||
+ ")" | ||
+ "(?:=(?<definition>" | ||
+ "(?:" | ||
+ "(?:[^{}]+|\\.+)+" | ||
+ ")+" | ||
+ ")" | ||
+ ")?" | ||
+ "\\}"); |
Check warning
Code scanning / CodeQL
Overly permissive regular expression range
"%\\{" | ||
+ "(?<name>" | ||
+ "(?<pattern>[A-z0-9]+)" | ||
+ "(?::(?<subname>[A-z0-9_:;,\\-\\/\\s\\.']+))?" | ||
+ ")" | ||
+ "(?:=(?<definition>" | ||
+ "(?:" | ||
+ "(?:[^{}]+|\\.+)+" | ||
+ ")+" | ||
+ ")" | ||
+ ")?" | ||
+ "\\}"); |
Check warning
Code scanning / CodeQL
Overly permissive regular expression range
c690f52
to
82f47ac
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
core/src/test/java/org/opensearch/sql/expression/datetime/IntervalClauseTest.java
Show resolved
Hide resolved
core/src/test/java/org/opensearch/sql/expression/datetime/TimeDIffTest.java
Outdated
Show resolved
Hide resolved
integ-test/src/test/java/org/opensearch/sql/sql/DateTimeFunctionIT.java
Outdated
Show resolved
Hide resolved
public void testSubTime() throws IOException { | ||
var result = executeQuery("SELECT" | ||
+ " SUBTIME(DATE('2008-12-12'), DATE('2008-11-15')) AS `'2008-12-12' - 0`," | ||
+ " SUBTIME(TIME('23:59:59'), DATE('2004-01-01')) AS `'23:59:59' - 0`," | ||
+ " SUBTIME(DATE('2004-01-01'), TIME('23:59:59')) AS `'2004-01-01' - '23:59:59'`," | ||
+ " SUBTIME(TIME('10:20:30'), TIME('00:05:42')) AS `'10:20:30' - '00:05:42'`," | ||
+ " SUBTIME(TIMESTAMP('1999-12-31 15:42:13'), DATETIME('1961-04-12 09:07:00')) AS `'15:42:13' - '09:07:00'`"); | ||
verifySchema(result, | ||
schema("SUBTIME(DATE('2008-12-12'), DATE('2008-11-15'))", "'2008-12-12' - 0", "datetime"), | ||
schema("SUBTIME(TIME('23:59:59'), DATE('2004-01-01'))", "'23:59:59' - 0", "time"), | ||
schema("SUBTIME(DATE('2004-01-01'), TIME('23:59:59'))", "'2004-01-01' - '23:59:59'", "datetime"), | ||
schema("SUBTIME(TIME('10:20:30'), TIME('00:05:42'))", "'10:20:30' - '00:05:42'", "time"), | ||
schema("SUBTIME(TIMESTAMP('1999-12-31 15:42:13'), DATETIME('1961-04-12 09:07:00'))", "'15:42:13' - '09:07:00'", "datetime")); | ||
verifyDataRows(result, rows("2008-12-12 00:00:00", "23:59:59", "2003-12-31 00:00:01", "10:14:48", "1999-12-31 06:35:13")); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It'd be a lot easier to understand and debug failures if these test cases were separated.
return new ExprIntervalValue(Duration.ofDays(getIntegerValue(value))); | ||
return new ExprIntervalValue(Period.ofDays(getIntegerValue(value))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why change from Duration to Period?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was required by changes in a4bca4f:
Lines 467 to 483 in a4bca4f
private ExprValue exprAddDateInterval(ExprValue date, ExprValue expr) { | |
var dt = LocalDateTime.MIN; | |
if (date.type() == TIME) { | |
if (expr.intervalValue() instanceof Duration) { | |
return new ExprTimeValue(date.timeValue().plus(expr.intervalValue())); | |
} else { | |
dt = LocalDateTime.of(LocalDate.now(), date.timeValue()); | |
} | |
} else { | |
dt = date.datetimeValue(); | |
} | |
dt = dt.plus(expr.intervalValue()); | |
if (date.type() == DATE && expr.intervalValue() instanceof Period) { | |
return new ExprDateValue(dt.toLocalDate()); | |
} | |
return new ExprDatetimeValue(dt); | |
} |
These changes were mostly reverted, because they add ambiguous function signatures:
Lines 109 to 110 in a4bca4f
impl(nullMissingHandling(DateTimeFunction::exprAddDateInterval), DATETIME, DATE, INTERVAL), | |
impl(nullMissingHandling(DateTimeFunction::exprAddDateInterval), DATE, DATE, INTERVAL), |
returnType, arg1Type, arg2Type
I still want to keep this change regardless of the revert, because this makes INTERVAL
more consistent:
opensearch-project-sql/core/src/main/java/org/opensearch/sql/expression/datetime/IntervalClause.java
Lines 87 to 101 in 2c1e83d
private ExprValue minute(ExprValue value) { | |
return new ExprIntervalValue(Duration.ofMinutes(getLongValue(value))); | |
} | |
private ExprValue hour(ExprValue value) { | |
return new ExprIntervalValue(Duration.ofHours(getLongValue(value))); | |
} | |
private ExprValue day(ExprValue value) { | |
return new ExprIntervalValue(Period.ofDays(getIntegerValue(value))); | |
} | |
private ExprValue week(ExprValue value) { | |
return new ExprIntervalValue(Period.ofWeeks(getIntegerValue(value))); | |
} |
Period
for Date
-like intervals and Duration
for Time
-like intervals
"source=%s | eval f = adddate(TIME('07:40:00'), interval 1 day) | fields f", TEST_INDEX_DATE)); | ||
verifySchema(result, | ||
schema("f", null, "datetime")); | ||
verifySome(result.getJSONArray("datarows"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you use the HEAD
command, could you validate with verifyDataRows
?
82f47ac
to
2c1e83d
Compare
DATE_ADD
/ADDDATE
and DATE_SUB
/SUBDATE
functions.
core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunction.java
Outdated
Show resolved
Hide resolved
* (DATE, LONG) -> DATE | ||
* (STRING/DATETIME/TIMESTAMP, LONG) -> DATETIME | ||
* (DATE/DATETIME/TIMESTAMP/TIME, INTERVAL) -> DATETIME | ||
* TODO: MySQL has these signatures too |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this a TODO? or just a comment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a room for future changes to completely align with MySQL; they depends on other features which are not implemented yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If possible, don't write TODO then.
That will often get caught in checkstyle rules and cause an automatic failure.
* (DATE, LONG) -> DATE | ||
* (STRING/DATETIME/TIMESTAMP, LONG) -> DATETIME | ||
* (DATE/DATETIME/TIMESTAMP/TIME, INTERVAL) -> DATETIME | ||
* TODO: MySQL has these signatures too |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this a TODO, or just a comment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok - just avoid the word TODO since it will catch as a checkstyle warning in some sets
core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunction.java
Outdated
Show resolved
Hide resolved
* (DATE, LONG) -> DATE | ||
* (STRING/DATETIME/TIMESTAMP, LONG) -> DATETIME | ||
* (DATE/DATETIME/TIMESTAMP/TIME, INTERVAL) -> DATETIME | ||
* TODO: MySQL has these signatures too |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If possible, don't write TODO then.
That will often get caught in checkstyle rules and cause an automatic failure.
* (DATE, LONG) -> DATE | ||
* (STRING/DATETIME/TIMESTAMP, LONG) -> DATETIME | ||
* (DATE/DATETIME/TIMESTAMP/TIME, INTERVAL) -> DATETIME | ||
* TODO: MySQL has these signatures too |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok - just avoid the word TODO since it will catch as a checkstyle warning in some sets
core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunction.java
Outdated
Show resolved
Hide resolved
core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunction.java
Outdated
Show resolved
Hide resolved
core/src/main/java/org/opensearch/sql/data/model/ExprDateValue.java
Outdated
Show resolved
Hide resolved
@@ -51,6 +56,21 @@ public LocalTime timeValue() { | |||
return time; | |||
} | |||
|
|||
@Override | |||
public LocalDate dateValue() { | |||
return LocalDate.now(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dateValue()
needs to return the same any time it's called when evaluating a query. Using LocalDate.now()
means that queries like SELECT CAST(TIME(12, 4) AS DATE), CAST(TIME(12, 4) AS DATE)
will produce different results depending on when they are called.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As we discussed, that will be a separate feature.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in b19ea96 after rebase. Include FunctionProperties
feature from opensearch-project#1047.
core/src/main/java/org/opensearch/sql/data/model/ExprTimeValue.java
Outdated
Show resolved
Hide resolved
core/src/test/java/org/opensearch/sql/expression/datetime/DateAddAndAddDateTest.java
Outdated
Show resolved
Hide resolved
|
||
@Test | ||
public void adddate_returns_date_when_args_are_date_and_days() { | ||
var res = adddate(LocalDate.of(1961, 4, 12), 100500); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what's 100500
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
100500 days. Why not?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not clear that it's an arbitrary number. Since it's repeated several times here, I started to wonder if it's in any way meaningful.
var res = subdate(LocalTime.of(21, 0), Duration.ofHours(1).plusMinutes(2)); | ||
assertEquals(DATETIME, res.type()); | ||
assertEquals(LocalTime.of(19, 58).atDate(LocalDate.now()), res.datetimeValue()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will fail if lines 27 and 29 are executed on different sides of midnight.
Line 29 needs to use the "current date value for query".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As we discussed, that will be a separate feature.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in b19ea96 after rebase. Include FunctionProperties
feature from opensearch-project#1047.
var res = date_sub(LocalTime.of(10, 20, 30), | ||
Duration.ofHours(1).plusMinutes(2).plusSeconds(42)); | ||
assertEquals(DATETIME, res.type()); | ||
assertEquals(LocalTime.of(9, 17, 48).atDate(LocalDate.now()), res.datetimeValue()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WIll fail if test is executed around midnight.
Needs to use "current date value for this query"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As we discussed, that will be a separate feature.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in b19ea96 after rebase. Include FunctionProperties
feature from opensearch-project#1047.
Signed-off-by: Yury-Fridlyand <[email protected]>
Signed-off-by: Yury-Fridlyand <[email protected]>
Signed-off-by: Yury-Fridlyand <[email protected]>
a64d6f9
to
b19ea96
Compare
Rebased and updated to include |
DATE_ADD
/ADDDATE
and DATE_SUB
/SUBDATE
functions.DATE_ADD
/ADDDATE
and DATE_SUB
/SUBDATE
functions.
Signed-off-by: Yury-Fridlyand <[email protected]>
* (STRING, INTERVAL) -> STRING | ||
* (DATE, INTERVAL) -> DATE // when interval has no time part | ||
* (TIME, INTERVAL) -> TIME // when interval has no date part | ||
* (STRING, INTERVAL) -> STRING // when argument has date or datetime string, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Duplicate of line 226?
Signed-off-by: Yury-Fridlyand <[email protected]>
core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunction.java
Outdated
Show resolved
Hide resolved
core/src/main/java/org/opensearch/sql/expression/function/FunctionDSL.java
Show resolved
Hide resolved
|
||
@Test | ||
public void adddate_returns_date_when_args_are_date_and_days() { | ||
var res = adddate(LocalDate.of(1961, 4, 12), 100500); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not clear that it's an arbitrary number. Since it's repeated several times here, I started to wonder if it's in any way meaningful.
Signed-off-by: Yury-Fridlyand <[email protected]>
Signed-off-by: Yury-Fridlyand <[email protected]>
@@ -290,10 +290,6 @@ public static FunctionExpression multiply(Expression... expressions) { | |||
return compile(FunctionProperties.None, BuiltinFunctionName.MULTIPLY, expressions); | |||
} | |||
|
|||
public static FunctionExpression adddate(Expression... expressions) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What was the reason for getting rid of all of these functions? Were they simply not used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- They were used in tests only
- I rewrote tests and made new DSL definitions for those functions in
DateTimeTestBase
- These functions require a
FunctionProperties
object as of now, they crash onFunctionProperties.None
@@ -30,7 +30,7 @@ public class ExprTimestampValue extends AbstractExprValue { | |||
/** | |||
* todo. only support UTC now. | |||
*/ | |||
private static final ZoneId ZONE = ZoneId.of("UTC"); | |||
public static final ZoneId ZONE = ZoneId.of("UTC"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe specify that ZONE is UTC_ZONE
?
opensearch-project#1182) * Update `DATE_ADD`/`ADDDATE` and `DATE_SUB`/`SUBDATE` functions. (#122) Signed-off-by: Yury-Fridlyand <[email protected]>
opensearch-project#1182) (opensearch-project#1325) * Update `DATE_ADD`/`ADDDATE` and `DATE_SUB`/`SUBDATE` functions. (#122) Signed-off-by: Yury-Fridlyand <[email protected]> (cherry picked from commit af188a3) Co-authored-by: Yury-Fridlyand <[email protected]>
Signed-off-by: Yury-Fridlyand [email protected]
Description
I referred to MySQL docs and tried to reproduce MySQL v.8.0.30 behavior as a reference.
Rework on
DATE_ADD
/ADDDATE
functions.Changes
Fixes:
TIME
, considering today's date. If argument isDATE
, it interpreted as midnight of thisDATE
.DATETIME
.Future changes (TODOs):
STRING
Removed function
DATE_ADD(date, int)
Left function (matches MySQL):
Update signature list
TIME
STRING
- all datetime types have implicit cast from a string alreadyMore details
DATE_ADD
ADDDATE
Rework on
DATE_SUB
/SUBDATE
functions.Changes
Removed function
DATE_SUB(date, int)
The same fixes and notes as for
DATE_ADD
/ADDDATE
functions.Test queries:
NB: Due to opensearch-project#853 you can't test with
DATETIME
(without code changes), but I tested with itOpenSearch
MySQL
PostgreSQL
Test data
I found that first 6 rows from
date0
,time0
,time1
,datetime0
are good for testing - these columns have different data types in MySQL. In OpenSearch SQL all[date][time]
columns havetimestamp
type, so I useCAST
for clear testing.data
Related issue:
opensearch-project#291
Check List
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.