olivrlee commented on code in PR #3054:
URL: https://github.com/apache/calcite/pull/3054#discussion_r1092267880
##########
core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java:
##########
@@ -2650,6 +2696,200 @@ public static int unixDate(int v) {
return v;
}
+ /** SQL {@code DATE(year, month, day)} function. */
+ public static int date(int year, int month, int day) {
+ // Calcite represents dates as Unix integers (days since epoch).
+ return (int) LocalDate.of(year, month, day).toEpochDay();
+ }
+
+ /** SQL {@code DATE(TIMESTAMP)} and
+ * {@code DATE(TIMESTAMP WITH LOCAL TIME ZONE)} functions. */
+ public static int date(long timestampMillis) {
+ // Calcite represents dates as Unix integers (days since epoch).
+ // Unix time ignores leap seconds; every day has the exact same number of
+ // milliseconds. BigQuery TIMESTAMP and DATETIME values (Calcite TIMESTAMP
+ // WITH LOCAL TIME ZONE and TIMESTAMP, respectively) are represented
+ // internally as milliseconds since epoch (or epoch UTC).
+ return (int) (timestampMillis / DateTimeUtils.MILLIS_PER_DAY);
+ }
+
+ /** SQL {@code DATE(TIMESTAMP WITH LOCAL TIME, timeZone)} function. */
+ public static int date(long timestampMillis, String timeZone) {
+ // Calcite represents dates as Unix integers (days since epoch).
+ return (int)
OffsetDateTime.ofInstant(Instant.ofEpochMilli(timestampMillis),
+ ZoneId.of(timeZone))
+ .toLocalDate()
+ .toEpochDay();
+ }
+
+ /** SQL {@code DATETIME(<year>, <month>, <day>, <hour>, <minute>, <second>)}
+ * function. */
+ public static long datetime(int year, int month, int day, int hour,
+ int minute, int second) {
+ // BigQuery's DATETIME function returns a Calcite TIMESTAMP,
+ // represented internally as milliseconds since epoch UTC.
+ return LocalDateTime.of(year, month, day, hour, minute, second)
+ .toEpochSecond(ZoneOffset.UTC)
+ * DateTimeUtils.MILLIS_PER_SECOND;
+ }
+
+ /** SQL {@code DATETIME(DATE)} function; returns a Calcite TIMESTAMP. */
+ public static long datetime(int daysSinceEpoch) {
+ // BigQuery's DATETIME function returns a Calcite TIMESTAMP,
+ // represented internally as milliseconds since epoch.
+ return daysSinceEpoch * DateTimeUtils.MILLIS_PER_DAY;
+ }
+
+ /** SQL {@code DATETIME(DATE, TIME)} function; returns a Calcite TIMESTAMP.
*/
+ public static long datetime(int daysSinceEpoch, int millisSinceMidnight) {
+ // BigQuery's DATETIME function returns a Calcite TIMESTAMP,
+ // represented internally as milliseconds since epoch UTC.
+ return daysSinceEpoch * DateTimeUtils.MILLIS_PER_DAY + millisSinceMidnight;
+ }
+
+ /** SQL {@code DATETIME(TIMESTAMP WITH LOCAL TIME ZONE)} function;
+ * returns a Calcite TIMESTAMP. */
+ public static long datetime(long millisSinceEpoch) {
+ // BigQuery TIMESTAMP and DATETIME values (Calcite TIMESTAMP WITH LOCAL
TIME
+ // ZONE and TIMESTAMP, respectively) are represented internally as
+ // milliseconds since epoch (or epoch UTC).
+ return millisSinceEpoch;
+ }
+
+ /** SQL {@code DATETIME(TIMESTAMP, timeZone)} function;
+ * returns a Calcite TIMESTAMP. */
+ public static long datetime(long millisSinceEpoch, String timeZone) {
+ // BigQuery TIMESTAMP and DATETIME values (Calcite TIMESTAMP WITH LOCAL
TIME
+ // ZONE and TIMESTAMP, respectively) are represented internally as
+ // milliseconds since epoch (or epoch UTC).
+ return OffsetDateTime.ofInstant(Instant.ofEpochMilli(millisSinceEpoch),
+ ZoneId.of(timeZone))
+ .atZoneSimilarLocal(ZoneId.of("UTC"))
+ .toInstant()
+ .toEpochMilli();
+ }
+
+ /** SQL {@code TIMESTAMP(<string>)} function. */
+ public static long timestamp(String expression) {
+ // Calcite represents TIMESTAMP WITH LOCAL TIME ZONE as Unix integers
+ // (milliseconds since epoch).
+ return
parseBigQueryTimestampLiteral(expression).toInstant().toEpochMilli();
+ }
+
+ /** SQL {@code TIMESTAMP(<string>, <timeZone>)} function. */
+ public static long timestamp(String expression, String timeZone) {
+ // Calcite represents TIMESTAMP WITH LOCAL TIME ZONE as Unix integers
+ // (milliseconds since epoch).
+ return parseBigQueryTimestampLiteral(expression)
+ .atZoneSimilarLocal(ZoneId.of(timeZone))
+ .toInstant()
+ .toEpochMilli();
+ }
+
+ private static OffsetDateTime parseBigQueryTimestampLiteral(String
expression) {
+ // First try to parse with an offset, otherwise parse as a local and assume
+ // UTC ("no offset").
+ try {
+ return OffsetDateTime
+ .parse(expression, BIG_QUERY_TIMESTAMP_LITERAL_FORMATTER);
+ } catch (DateTimeParseException e) {
+ try {
+ if (IS_JDK_8) {
+ // JDK 8 has a bug that prevents matching offsets like "+00" but can
+ // match "+00:00".
+ if (expression.endsWith("+00")) {
Review Comment:
Would it be `[-+][0-9]?[0-9]` so we prevent `+000`?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]