-
Notifications
You must be signed in to change notification settings - Fork 141
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
Extend comparison methods to accept different datetime types. (#129) #1196
Extend comparison methods to accept different datetime types. (#129) #1196
Conversation
e3b4e51
to
2f26532
Compare
Codecov Report
@@ Coverage Diff @@
## main #1196 +/- ##
============================================
- Coverage 98.35% 98.35% -0.01%
- Complexity 3604 3617 +13
============================================
Files 344 343 -1
Lines 8933 8927 -6
Branches 562 569 +7
============================================
- Hits 8786 8780 -6
Misses 142 142
Partials 5 5
Flags with carried forward coverage won't be shown. Click here to find out more.
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. |
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.
Sorry to point this out late. I just realized our current implicit cast mechanism may handle this more properly. Its basic idea is to wrap cast function on argument which has different type than resolved argument but compatible. In this way, all functions will cast the argument automatically instead of only comparison operator. Here is the design doc: https://github.com/opensearch-project/sql/blob/main/docs/dev/TypeConversion.md
Code changes in 2 places for test:
- Make
DATE
andTIME
compatible withTIMESTAMP
for our test - Add missing
cast_to_timestamp(date)
function impl
diff --git a/core/src/main/java/org/opensearch/sql/data/type/ExprCoreType.java b/core/src/main/java/org/opensearch/sql/data/type/ExprCoreType.java
index ad2e4259..58a60779 100644
--- a/core/src/main/java/org/opensearch/sql/data/type/ExprCoreType.java
+++ b/core/src/main/java/org/opensearch/sql/data/type/ExprCoreType.java
@@ -55,10 +55,10 @@ public enum ExprCoreType implements ExprType {
* Date.
* Todo. compatible relationship.
*/
- TIMESTAMP(STRING),
DATE(STRING),
TIME(STRING),
DATETIME(STRING),
+ TIMESTAMP(DATE, TIME),
INTERVAL(UNDEFINED),
/**
diff --git a/core/src/main/java/org/opensearch/sql/expression/operator/convert/TypeCastOperator.java b/core/src/main/java/org/opensearch/sql/expression/operator/convert/TypeCastOperator.java
index 8f904bfb..637905a5 100644
--- a/core/src/main/java/org/opensearch/sql/expression/operator/convert/TypeCastOperator.java
+++ b/core/src/main/java/org/opensearch/sql/expression/operator/convert/TypeCastOperator.java
@@ -182,6 +182,8 @@ public class TypeCastOperator {
(v) -> new ExprTimestampValue(v.stringValue())), TIMESTAMP, STRING),
impl(nullMissingHandling(
(v) -> new ExprTimestampValue(v.timestampValue())), TIMESTAMP, DATETIME),
+ impl(nullMissingHandling(
+ (v) -> new ExprTimestampValue(v.timestampValue())), TIMESTAMP, DATE),
impl(nullMissingHandling((v) -> v), TIMESTAMP, TIMESTAMP)
);
}
Here is my test: (Note that the reason it return true is: ExprDateValue.timestampValue()
seems consider timezone and return 2020-09-16 07:00:00
for date value 2020-09-16
. I don't see other issue than this. Please let me know if this can work for you. Thanks!
curl -XPOST "localhost:9200/_plugins/_sql" -H 'Content-Type: application/json' -d'
{
"query": "SELECT DATE('\''2020-09-16'\'') > TIMESTAMP('\''2020-09-16 00:00:00'\'') "
}'
{
"schema": [
{
"name": "DATE('2020-09-16') > TIMESTAMP('2020-09-16 00:00:00')",
"type": "boolean"
}
],
"datarows": [
[
true
]
],
"total": 1,
"size": 1,
"status": 200
}
core/src/main/java/org/opensearch/sql/data/model/ExprValue.java
Outdated
Show resolved
Hide resolved
@dai-chen, thank you for detailed feedback! I'll try to rework it according to you notes.
DATE(STRING),
TIME(STRING),
DATETIME(STRING, DATE, TIME),
TIMESTAMP(STRING, DATE, TIME),
INTERVAL(UNDEFINED), |
* Extend comparison methods to accept different datetime types. Signed-off-by: Yury-Fridlyand <yuryf@bitquilltech.com> Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com>
@dai-chen, diff --git a/opensearch/src/main/java/org/opensearch/sql/opensearch/executor/OpenSearchQueryManager.java b/opensearch/src/main/java/org/opensearch/sql/opensearch/executor/OpenSearc>
index 9c6fcdb82..0b2629562 100644
--- a/opensearch/src/main/java/org/opensearch/sql/opensearch/executor/OpenSearchQueryManager.java
+++ b/opensearch/src/main/java/org/opensearch/sql/opensearch/executor/OpenSearchQueryManager.java
@@ -30,7 +30,12 @@ public class OpenSearchQueryManager implements QueryManager {
@Override
public QueryId submit(AbstractPlan queryPlan) {
- schedule(nodeClient, () -> queryPlan.execute());
+ schedule(nodeClient, () -> {
+ long timeBefore = System.currentTimeMillis();
+ queryPlan.execute();
+ long elapsed = System.currentTimeMillis() - timeBefore;
+ System.out.println(String.format("\u001B[31m===== %d =====\u001B[0m", elapsed));
+ });
return queryPlan.getQueryId();
} Second: diff --git a/opensearch/src/main/java/org/opensearch/sql/opensearch/executor/OpenSearchExecutionEngine.java b/opensearch/src/main/java/org/opensearch/sql/opensearch/executor/OpenSe>
index 9a136a3be..98bffb85c 100644
--- a/opensearch/src/main/java/org/opensearch/sql/opensearch/executor/OpenSearchExecutionEngine.java
+++ b/opensearch/src/main/java/org/opensearch/sql/opensearch/executor/OpenSearchExecutionEngine.java
@@ -41,7 +41,7 @@ public class OpenSearchExecutionEngine implements ExecutionEngine {
() -> {
try {
List<ExprValue> result = new ArrayList<>();
-
+ long timeBefore = System.currentTimeMillis();
context.getSplit().ifPresent(plan::add);
plan.open();
@@ -50,6 +50,8 @@ public class OpenSearchExecutionEngine implements ExecutionEngine {
}
QueryResponse response = new QueryResponse(physicalPlan.schema(), result);
+ long elapsed = System.currentTimeMillis() - timeBefore;
+ System.out.println(String.format("\u001B[31m===== %d =====\u001B[0m", elapsed));
listener.onResponse(response);
} catch (Exception e) {
listener.onFailure(e); Changes I applied: diff --git a/core/src/main/java/org/opensearch/sql/data/type/ExprCoreType.java b/core/src/main/java/org/opensearch/sql/data/type/ExprCoreType.java
index ad2e42596..fc964d205 100644
--- a/core/src/main/java/org/opensearch/sql/data/type/ExprCoreType.java
+++ b/core/src/main/java/org/opensearch/sql/data/type/ExprCoreType.java
@@ -55,10 +55,16 @@ public enum ExprCoreType implements ExprType {
* Date.
* Todo. compatible relationship.
*/
- TIMESTAMP(STRING),
DATE(STRING),
TIME(STRING),
+/*
DATETIME(STRING),
+ TIMESTAMP(STRING),
+//*/
+//*
+ DATETIME(STRING, DATE, TIME),
+ TIMESTAMP(STRING, DATE, TIME, DATETIME),
+//*/
INTERVAL(UNDEFINED),
/**
diff --git a/core/src/main/java/org/opensearch/sql/expression/operator/convert/TypeCastOperator.java b/core/src/main/java/org/opensearch/sql/expression/operator/convert/TypeCastOpe>
index 8f904bfbf..46e178aed 100644
--- a/core/src/main/java/org/opensearch/sql/expression/operator/convert/TypeCastOperator.java
+++ b/core/src/main/java/org/opensearch/sql/expression/operator/convert/TypeCastOperator.java
@@ -19,7 +19,9 @@ import static org.opensearch.sql.data.type.ExprCoreType.STRING;
import static org.opensearch.sql.data.type.ExprCoreType.TIME;
import static org.opensearch.sql.data.type.ExprCoreType.TIMESTAMP;
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 java.util.Arrays;
import java.util.stream.Collectors;
@@ -182,6 +184,12 @@ public class TypeCastOperator {
(v) -> new ExprTimestampValue(v.stringValue())), TIMESTAMP, STRING),
impl(nullMissingHandling(
(v) -> new ExprTimestampValue(v.timestampValue())), TIMESTAMP, DATETIME),
+//*
+ impl(nullMissingHandling(
+ (v) -> new ExprTimestampValue(v.timestampValue())), TIMESTAMP, DATE),
+ implWithProperties(nullMissingHandlingWithProperties(
+ (fp, v) -> new ExprTimestampValue(((ExprTimeValue)v).timestampValue(fp))), TIMESTAMP, TIME),
+//*/
impl(nullMissingHandling((v) -> v), TIMESTAMP, TIMESTAMP)
);
}
@@ -192,6 +200,11 @@ public class TypeCastOperator {
(v) -> new ExprDatetimeValue(v.stringValue())), DATETIME, STRING),
impl(nullMissingHandling(
(v) -> new ExprDatetimeValue(v.datetimeValue())), DATETIME, TIMESTAMP),
+//*
+ implWithProperties(nullMissingHandlingWithProperties(
+ (fp, v) -> new ExprDatetimeValue(((ExprTimeValue)v).datetimeValue(fp))), DATETIME, TIME),
+ impl(nullMissingHandling((v) -> v), DATETIME, DATETIME),
+//*/
impl(nullMissingHandling(
(v) -> new ExprDatetimeValue(v.datetimeValue())), DATETIME, DATE)
);
diff --git a/core/src/main/java/org/opensearch/sql/expression/operator/predicate/BinaryPredicateOperator.java b/core/src/main/java/org/opensearch/sql/expression/operator/predicate/>
index 23547e8d4..5baaa357b 100644
--- a/core/src/main/java/org/opensearch/sql/expression/operator/predicate/BinaryPredicateOperator.java
+++ b/core/src/main/java/org/opensearch/sql/expression/operator/predicate/BinaryPredicateOperator.java
@@ -202,6 +202,13 @@ public class BinaryPredicateOperator {
private static DefaultFunctionResolver compareImpl(
FunctionName function, SerializableBiFunction<Comparable, Comparable, Boolean> comparator) {
return FunctionDSL.define(function,
+//*
+ ExprCoreType.coreTypes().stream()
+ .map(type -> impl(nullMissingHandling(
+ (v1, v2) -> ExprBooleanValue.of(comparator.apply(v1, v2))),
+ BOOLEAN, type, type))
+//*/
+/*
Stream.concat(
ExprCoreType.coreTypes().stream()
.map(type -> impl(nullMissingHandling(
@@ -212,6 +219,7 @@ public class BinaryPredicateOperator {
(fp, v1, v2) -> ExprBooleanValue.of(comparator.apply(
extractDateTime(v1, fp), extractDateTime(v2, fp)))),
BOOLEAN, pair.getLeft(), pair.getRight())))
+//*/
.collect(Collectors.toList()));
} To test I swapped comments by switching SELECT CAST(date0 AS date) AS `date`, CAST(date0 AS date) < now() AS `date < datetime`,
datetime(CAST(time0 AS STRING)) AS `datetime`, datetime(CAST(time0 AS STRING)) < now() AS `datetime < datetime`,
CAST(time1 AS time) AS `time`, CAST(time1 AS time) < now() AS `time < datetime`,
CAST(datetime0 AS timestamp) AS `timestamp`, CAST(datetime0 AS timestamp) < now() AS `timestamp < datetime`
FROM calcs LIMIT 6; (there is only one time measurement point)
select count(*), timestamp > '2018-01-21 05:32:25' from flights group by 2;
select count(*), timestamp > TIME '05:32:25' from flights group by 2;
select count(*), timestamp > DATE '2018-01-21' from flights group by 2;
select count(*), datetime0 > '2004-07-14 08:16:44' from calcs group by 2;
select count(*), datetime0 > TIME '08:16:44' from calcs group by 2;
select count(*), datetime0 > DATE '2004-07-14' from calcs group by 2;
|
@Yury-Fridlyand Thanks for sharing the test result! I'm not sure if the dominant factor is nested lambda evaluation on argument or resolving |
@Yury-Fridlyand I just did some test by JMH which can microbenchmark on fine-grain class level. Here is my branch and test result: https://github.com/dai-chen/sql-1/tree/test-mircro-benchmark. I think the result is acceptable and it would be very close if we ignore time spent on function compile. I did test quick and not sure if I miss anything. We can double check and let me know if any question. Thanks!
|
Great job @dai-chen! Thank you for sharing your test results. |
opensearch-project#1196 (review) * Revert `BinaryPredicateOperator`. * Add automatic cast rules `DATE`/`TIME`/`DATETIME` -> `DATETIME`/TIMESTAMP`. * Update unit tests. Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com>
Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com>
2f26532
to
e86e703
Compare
Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com>
Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com>
3fd3dc7
to
3289103
Compare
Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com>
Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com>
Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com>
Ready for re-review. |
core/src/main/java/org/opensearch/sql/data/type/ExprCoreType.java
Outdated
Show resolved
Hide resolved
Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com>
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.
LGTM. Thanks for the changes!
Since we enhanced CAST operator in this PR, can #853 be linked and closed as well? |
No,
|
You mean with your changes in this PR below,
|
Exactly, grammar fix is required |
I see. Thanks! |
…1196) * Extend comparison methods to accept different datetime types. (#129) * Extend comparison methods to accept different datetime types. Signed-off-by: Yury-Fridlyand <yuryf@bitquilltech.com> Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com> * Typo fix. Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com> * Rework fix according to @dai-chen's comment. #1196 (review) * Revert `BinaryPredicateOperator`. * Add automatic cast rules `DATE`/`TIME`/`DATETIME` -> `DATETIME`/TIMESTAMP`. * Update unit tests. Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com> * Add doctest sample. Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com> * Docs typo fix. Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com> * Minor comments update. Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com> * Doctest typo fix. Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com> * Doctest typo fix. Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com> * Doctest typo fix. Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com> * Modify `ExprCoreType` dependencies. Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com> Signed-off-by: Yury-Fridlyand <yuryf@bitquilltech.com> Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com> (cherry picked from commit a4f8066)
…ime types cast (PR opensearch-project#1196). Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com>
…1196) (#1294) * Extend comparison methods to accept different datetime types. (#129) * Extend comparison methods to accept different datetime types. Signed-off-by: Yury-Fridlyand <yuryf@bitquilltech.com> Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com> * Typo fix. Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com> * Rework fix according to @dai-chen's comment. #1196 (review) * Revert `BinaryPredicateOperator`. * Add automatic cast rules `DATE`/`TIME`/`DATETIME` -> `DATETIME`/TIMESTAMP`. * Update unit tests. Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com> * Add doctest sample. Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com> * Docs typo fix. Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com> * Minor comments update. Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com> * Doctest typo fix. Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com> * Doctest typo fix. Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com> * Doctest typo fix. Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com> * Modify `ExprCoreType` dependencies. Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com> Signed-off-by: Yury-Fridlyand <yuryf@bitquilltech.com> Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com> (cherry picked from commit a4f8066) Co-authored-by: Yury-Fridlyand <yury.fridlyand@improving.com>
* Update `TIMESTAMP` function implementation and signatures. Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com> * Simplify `TIMESTAMP` function implementation by using automatic datetime types cast (PR #1196). Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com> * Checkstyle fix. Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com> --------- Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com>
* Update `TIMESTAMP` function implementation and signatures. Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com> * Simplify `TIMESTAMP` function implementation by using automatic datetime types cast (PR #1196). Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com> * Checkstyle fix. Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com> --------- Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com> (cherry picked from commit ecb9dec)
…1340) * Update `TIMESTAMP` function implementation and signatures. Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com> * Simplify `TIMESTAMP` function implementation by using automatic datetime types cast (PR #1196). Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com> * Checkstyle fix. Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com> --------- Signed-off-by: Yury-Fridlyand <yury.fridlyand@improving.com> (cherry picked from commit ecb9dec) Co-authored-by: Yury-Fridlyand <yury.fridlyand@improving.com>
Signed-off-by: Yury-Fridlyand yuryf@bitquilltech.com
Description
Functions affected:
=
,!=
,>
,<
,<=
>=
.Added automatic cast rules:
This allows to compare values of any of datetime types.
Reverted
Signatures added:
See team review and discussion in Bit-Quill#129.
Test data
Test queries
MySQL
OpenSearch
Issues Resolved
Fix comparison between different datetime data types. #294
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.