-
Notifications
You must be signed in to change notification settings - Fork 153
Add datetime functions #3473
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
Add datetime functions #3473
Changes from all commits
7f1eba4
86f1b9c
7d46cbc
ce264dd
06a7b65
25d7d51
6cc2452
7ff8a1c
19e11d6
25867df
65fd487
7274a05
6ccfd97
f6120dc
4fa915d
99b33cd
0b28fab
651db98
706f9b0
8c0dd3b
d0f4f38
2f29ab7
8fc4b39
6eb9204
5b75398
61deedf
60a2807
85798af
f4c08cf
02be4c4
6ca160d
a359112
0e8e5be
8338a58
6849035
cbd95d6
345de93
e5a347d
03e0726
b8a8667
c78f6ca
d8201da
5f72f21
40d4caa
2962942
c94657c
6711b82
b8509d2
6379d34
c3eb8ff
4b32722
ee9f704
7a8674d
40b166c
6f3545a
272afbb
ae42653
8e04bde
8a45c36
9db5a08
1d136e0
f076847
a162bb0
e5e5124
bfff6b3
0ecdc06
1224781
4c523c8
efb83bb
d1d2c4a
7931b3d
4727402
752b634
e7c36f3
91a51ce
b520503
b16d8e1
776e408
d73f510
73d2727
9b229d9
0cd7d58
6cfe963
f9073ad
4724128
725b595
20415db
1bf217c
b40435a
f8c7501
2c2d0d3
e7e3cf4
3eb36b7
7eb540a
72ca8a2
d3e05aa
774891b
6d91bd8
ce6b691
ea9fc40
c72a975
d5aa8fd
4750729
0d6995c
0021744
09406ef
748e1e2
a8a924f
cf12ef8
dfa600e
aad9d0e
99489b4
98ef3ca
ec6eeed
7b720bf
b79b3d9
04064d6
a04f729
227be36
9a5eeb6
a4f477b
59b4817
c89b38b
86f1538
238d375
a9dc42b
7930930
dd803e0
609c817
c0b0c11
59a7b74
c50dbc3
886b4de
16db26e
2d53d29
ec52051
9d1d666
bd7914a
ec6d5f2
c5762e1
c13b6de
b12abcf
ca97938
b37242a
5362cfe
88300e8
1d88fbe
21e54f4
7ac30af
4a62a4f
d5a64af
5bf9f17
ec643d5
366d1d7
41f24af
5dfbf77
a8fcf9e
3144c00
878635a
8eb5776
e392550
67ca837
957a6a0
04ae1d0
2d63193
f7a8b83
d6a94f8
ae23433
b58fce5
c03c5fb
c1cdbed
11839a1
5b6ef9e
e8d4b36
563ecf4
b42b671
0ecb578
c1f6e05
942eb42
519151c
e73529c
077141f
777302f
2a75227
b076969
d488a0c
4c70c95
62cb0c0
eee5d53
6bf2e4c
b8c3dda
4cc10f6
337c2b9
01a2dde
38fef3b
368ac70
8a190cd
cf30e05
3e1774c
0c7d247
7fd66ef
19d3cc8
5e46c17
b0eb105
8607d98
ed105bb
61246d8
f1d1453
8a88ef9
720b0e7
a82dc58
b922857
3469557
e9165fd
d413bdb
b80ea40
8ae7d16
30941ee
a1e20ad
c686197
d510c84
9d8e849
508fef8
345beca
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package org.opensearch.sql.calcite.udf.datetimeUDF; | ||
|
||
import org.opensearch.sql.calcite.udf.UserDefinedFunction; | ||
import org.opensearch.sql.calcite.utils.UserDefinedFunctionUtils; | ||
import org.opensearch.sql.data.model.ExprStringValue; | ||
import org.opensearch.sql.data.model.ExprValue; | ||
import org.opensearch.sql.expression.datetime.DateTimeFunctions; | ||
|
||
public class ConvertTZFunction implements UserDefinedFunction { | ||
@Override | ||
public Object eval(Object... args) { | ||
|
||
if (UserDefinedFunctionUtils.containsNull(args)) { | ||
return null; | ||
} | ||
|
||
Object argTimestamp = args[0]; | ||
Object fromTz = args[1]; | ||
Object toTz = args[2]; | ||
ExprValue datetimeExpr = | ||
DateTimeFunctions.exprConvertTZ( | ||
new ExprStringValue(argTimestamp.toString()), | ||
new ExprStringValue(fromTz.toString()), | ||
new ExprStringValue(toTz.toString())); | ||
|
||
return datetimeExpr.valueForCalcite(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package org.opensearch.sql.calcite.udf.datetimeUDF; | ||
|
||
import static org.opensearch.sql.calcite.utils.UserDefinedFunctionUtils.*; | ||
import static org.opensearch.sql.calcite.utils.datetime.DateTimeApplyUtils.convertToTemporalAmount; | ||
import static org.opensearch.sql.calcite.utils.datetime.DateTimeApplyUtils.transferInputToExprValue; | ||
|
||
import org.apache.calcite.avatica.util.TimeUnit; | ||
import org.apache.calcite.rel.type.RelDataType; | ||
import org.apache.calcite.sql.type.SqlReturnTypeInference; | ||
import org.apache.calcite.sql.type.SqlTypeName; | ||
import org.opensearch.sql.calcite.udf.UserDefinedFunction; | ||
import org.opensearch.sql.calcite.utils.UserDefinedFunctionUtils; | ||
import org.opensearch.sql.data.model.ExprDateValue; | ||
import org.opensearch.sql.data.model.ExprValue; | ||
import org.opensearch.sql.expression.datetime.DateTimeFunctions; | ||
import org.opensearch.sql.expression.function.FunctionProperties; | ||
|
||
public class DateAddSubFunction implements UserDefinedFunction { | ||
@Override | ||
public Object eval(Object... args) { | ||
|
||
if (UserDefinedFunctionUtils.containsNull(args)) { | ||
return null; | ||
} | ||
|
||
TimeUnit unit = (TimeUnit) args[0]; | ||
long interval = ((Number) args[1]).longValue(); | ||
Object argBase = args[2]; | ||
SqlTypeName sqlTypeName = (SqlTypeName) args[3]; | ||
boolean isAdd = (Boolean) args[4]; | ||
SqlTypeName returnSqlType = (SqlTypeName) args[5]; | ||
ExprValue base = transferInputToExprValue(argBase, sqlTypeName); | ||
FunctionProperties restored = restoreFunctionProperties(args[args.length - 1]); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This properties should be set when constructing the function and I think it supports pass in FunctionProperties directly, please add a TODO here to make change in the future. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Got it. Add in function restoreFunctionProperties |
||
ExprValue resultDatetime = | ||
DateTimeFunctions.exprDateApplyInterval( | ||
restored, base, convertToTemporalAmount(interval, unit), isAdd); | ||
if (returnSqlType == SqlTypeName.TIMESTAMP) { | ||
return resultDatetime.valueForCalcite(); | ||
} else { | ||
return new ExprDateValue(resultDatetime.dateValue()).valueForCalcite(); | ||
} | ||
} | ||
|
||
public static SqlReturnTypeInference getReturnTypeForAddOrSubDate() { | ||
return opBinding -> { | ||
RelDataType operandType0 = opBinding.getOperandType(6); | ||
SqlTypeName typeName = operandType0.getSqlTypeName(); | ||
if (typeName == SqlTypeName.TIMESTAMP) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In which case will we use SqlTypeName.TIMESTAMP? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above. |
||
return nullableTimestampUDT; | ||
} else if (typeName == SqlTypeName.DATE) { | ||
return nullableDateUDT; | ||
} | ||
return opBinding.getTypeFactory().createSqlType(typeName); | ||
}; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package org.opensearch.sql.calcite.udf.datetimeUDF; | ||
|
||
import static org.opensearch.sql.calcite.utils.OpenSearchTypeFactory.convertSqlTypeNameToExprType; | ||
import static org.opensearch.sql.calcite.utils.UserDefinedFunctionUtils.restoreFunctionProperties; | ||
import static org.opensearch.sql.data.model.ExprValueUtils.fromObjectValue; | ||
|
||
import org.apache.calcite.sql.type.SqlTypeName; | ||
import org.opensearch.sql.calcite.udf.UserDefinedFunction; | ||
import org.opensearch.sql.calcite.utils.UserDefinedFunctionUtils; | ||
import org.opensearch.sql.data.model.ExprValue; | ||
import org.opensearch.sql.expression.datetime.DateTimeFunctions; | ||
import org.opensearch.sql.expression.function.FunctionProperties; | ||
|
||
/** | ||
* Calculates the difference of date parts of given values. If the first argument is time, today's | ||
* date is used. | ||
* | ||
* <p>(DATE/TIMESTAMP/TIME, DATE/TIMESTAMP/TIME) -> LONG | ||
*/ | ||
public class DateDiffFunction implements UserDefinedFunction { | ||
@Override | ||
public Object eval(Object... args) { | ||
if (UserDefinedFunctionUtils.containsNull(args)) { | ||
return null; | ||
} | ||
FunctionProperties restored = restoreFunctionProperties(args[args.length - 1]); | ||
SqlTypeName sqlTypeName1 = (SqlTypeName) args[1]; | ||
SqlTypeName sqlTypeName2 = (SqlTypeName) args[3]; | ||
ExprValue diffResult = | ||
DateTimeFunctions.exprDateDiff( | ||
restored, | ||
fromObjectValue(args[0], convertSqlTypeNameToExprType(sqlTypeName1)), | ||
fromObjectValue(args[2], convertSqlTypeNameToExprType(sqlTypeName2))); | ||
return diffResult.longValue(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package org.opensearch.sql.calcite.udf.datetimeUDF; | ||
|
||
import static org.opensearch.sql.calcite.utils.UserDefinedFunctionUtils.restoreFunctionProperties; | ||
import static org.opensearch.sql.calcite.utils.datetime.DateTimeApplyUtils.transferInputToExprValue; | ||
import static org.opensearch.sql.expression.datetime.DateTimeFormatterUtil.getFormattedDate; | ||
import static org.opensearch.sql.expression.datetime.DateTimeFormatterUtil.getFormattedDateOfToday; | ||
|
||
import org.apache.calcite.sql.type.SqlTypeName; | ||
import org.opensearch.sql.calcite.udf.UserDefinedFunction; | ||
import org.opensearch.sql.calcite.utils.UserDefinedFunctionUtils; | ||
import org.opensearch.sql.data.model.ExprStringValue; | ||
import org.opensearch.sql.data.model.ExprValue; | ||
import org.opensearch.sql.expression.function.FunctionProperties; | ||
|
||
public class DateFormatFunction implements UserDefinedFunction { | ||
@Override | ||
public Object eval(Object... args) { | ||
if (UserDefinedFunctionUtils.containsNull(args)) { | ||
return null; | ||
} | ||
Object argDatetime = args[0]; | ||
Object argDatetimeType = args[1]; | ||
Object argFormat = args[2]; | ||
FunctionProperties restored = restoreFunctionProperties(args[args.length - 1]); | ||
ExprValue candidateValue = transferInputToExprValue(argDatetime, (SqlTypeName) argDatetimeType); | ||
if (argDatetimeType == SqlTypeName.TIME) { | ||
return getFormattedDateOfToday( | ||
new ExprStringValue(argFormat.toString()), | ||
candidateValue, | ||
restored.getQueryStartClock()) | ||
.stringValue(); | ||
} | ||
return getFormattedDate(candidateValue, new ExprStringValue(argFormat.toString())) | ||
.stringValue(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package org.opensearch.sql.calcite.udf.datetimeUDF; | ||
|
||
import static org.opensearch.sql.calcite.utils.UserDefinedFunctionUtils.restoreFunctionProperties; | ||
import static org.opensearch.sql.calcite.utils.datetime.DateTimeApplyUtils.transferInputToExprValue; | ||
import static org.opensearch.sql.expression.datetime.DateTimeFunctions.exprDate; | ||
|
||
import org.apache.calcite.sql.type.SqlTypeName; | ||
import org.opensearch.sql.calcite.udf.UserDefinedFunction; | ||
import org.opensearch.sql.calcite.utils.UserDefinedFunctionUtils; | ||
import org.opensearch.sql.data.model.ExprDateValue; | ||
import org.opensearch.sql.data.model.ExprTimeValue; | ||
import org.opensearch.sql.data.model.ExprValue; | ||
import org.opensearch.sql.expression.function.FunctionProperties; | ||
|
||
public class DateFunction implements UserDefinedFunction { | ||
|
||
@Override | ||
public Object eval(Object... args) { | ||
if (UserDefinedFunctionUtils.containsNull(args)) { | ||
return null; | ||
} | ||
FunctionProperties restored = restoreFunctionProperties(args[args.length - 1]); | ||
ExprValue candidate = transferInputToExprValue(args[0], (SqlTypeName) args[1]); | ||
if ((SqlTypeName) args[1] == SqlTypeName.TIME) { | ||
return new ExprDateValue(((ExprTimeValue) candidate).dateValue(restored)).valueForCalcite(); | ||
} | ||
return exprDate(candidate).valueForCalcite(); | ||
} | ||
} |
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 using SqlTypeName here? I think sql type is a subset of all types we use and date, time, timestamp of Sql type is no longer used by us after introducing UDT
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.
For our current UDF, all time/timestamp/time input would be the UDT. So we directly transfer the type to corresponding sqltypetime that we can call
fromObjectValue
easily. See functiontransferDateRelatedTimeName
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.
These UDT's real SqlType is VARCHAR, the more appropriate way is pass in the RelDataType here and get the correct exprtype by using
ExprUDT.getExprCoreType
.It works here because we have a incorrect mapping in
convertSqlTypeNameToExprType
(the mapping of time,timestamp,date will never be used since they are blocked now by the previous logic of handling UDT), and you pass inSqlTypeName.TIMESTAMP
directly from the place where you call this funciton.