SQL: non ISO 8601 versions of DAY_OF_WEEK and WEEK_OF_YEAR functions (#36358)

* Renamed DAY_OF_WEEK and WEEK_OF_YEAR functions to their ISO version and
added the same functions with different functionality.
* Rewritten the datetime functions documentation to follow the format of the other
functions documentation pages.
This commit is contained in:
Andrei Stefan 2018-12-12 02:29:02 +02:00 committed by GitHub
parent 51800de2a8
commit de373060fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 1036 additions and 165 deletions

View File

@ -5,92 +5,397 @@
beta[]
* Extract the year from a date (`YEAR`)
[[sql-functions-datetime-day]]
==== `DAY_OF_MONTH`/`DOM`/`DAY`
.Synopsis:
[source, sql]
--------------------------------------------------
DAY_OF_MONTH(date_exp<1>)
--------------------------------------------------
*Input*:
<1> date expression
*Output*: integer
.Description:
Extract the day of the month from a date.
["source","sql",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{sql-specs}/datetime.csv-spec[year]
include-tagged::{sql-specs}/docs.csv-spec[dayOfMonth]
--------------------------------------------------
* Extract the month of the year from a date (`MONTH_OF_YEAR` or `MONTH`)
[[sql-functions-datetime-dow]]
==== `DAY_OF_WEEK`/`DAYOFWEEK`/`DOW`
.Synopsis:
[source, sql]
--------------------------------------------------
DAY_OF_WEEK(date_exp<1>)
--------------------------------------------------
*Input*:
<1> date expression
*Output*: integer
.Description:
Extract the day of the week from a date. Sunday is `1`, Monday is `2`, etc.
["source","sql",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{sql-specs}/datetime.csv-spec[monthOfYear]
include-tagged::{sql-specs}/docs.csv-spec[dayOfWeek]
--------------------------------------------------
* Extract the week of the year from a date (`WEEK_OF_YEAR` or `WEEK`)
[[sql-functions-datetime-doy]]
==== `DAY_OF_YEAR`/`DOY`
.Synopsis:
[source, sql]
--------------------------------------------------
DAY_OF_YEAR(date_exp<1>)
--------------------------------------------------
*Input*:
<1> date expression
*Output*: integer
.Description:
Extract the day of the year from a date.
["source","sql",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{sql-specs}/datetime.csv-spec[weekOfYear]
include-tagged::{sql-specs}/docs.csv-spec[dayOfYear]
--------------------------------------------------
* Extract the day of the year from a date (`DAY_OF_YEAR` or `DOY`)
[[sql-functions-datetime-dayname]]
==== `DAY_NAME`/`DAYNAME`
.Synopsis:
[source, sql]
--------------------------------------------------
DAY_NAME(date_exp<1>)
--------------------------------------------------
*Input*:
<1> date expression
*Output*: string
.Description:
Extract the day of the week from a datetime in text format (`Monday`, `Tuesday`...).
["source","sql",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{sql-specs}/datetime.csv-spec[dayOfYear]
include-tagged::{sql-specs}/docs.csv-spec[dayName]
--------------------------------------------------
* Extract the day of the month from a date (`DAY_OF_MONTH`, `DOM`, or `DAY`)
[[sql-functions-datetime-hour]]
==== `HOUR_OF_DAY`/`HOUR`
.Synopsis:
[source, sql]
--------------------------------------------------
HOUR_OF_DAY(date_exp<1>)
--------------------------------------------------
*Input*:
<1> date expression
*Output*: integer
.Description:
Extract the hour of the day from a date.
["source","sql",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{sql-specs}/datetime.csv-spec[dayOfMonth]
include-tagged::{sql-specs}/docs.csv-spec[hourOfDay]
--------------------------------------------------
* Extract the day of the week from a date (`DAY_OF_WEEK` or `DOW`).
[[sql-functions-datetime-isodow]]
==== `ISO_DAY_OF_WEEK`/`ISODAYOFWEEK`/`ISODOW`/`IDOW`
.Synopsis:
[source, sql]
--------------------------------------------------
ISO_DAY_OF_WEEK(date_exp<1>)
--------------------------------------------------
*Input*:
<1> date expression
*Output*: integer
.Description:
Extract the day of the week from a date, following the https://en.wikipedia.org/wiki/ISO_week_date[ISO 8601 standard].
Monday is `1`, Tuesday is `2`, etc.
["source","sql",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{sql-specs}/datetime.csv-spec[dayOfWeek]
include-tagged::{sql-specs}/docs.csv-spec[isoDayOfWeek]
--------------------------------------------------
* Extract the hour of the day from a date (`HOUR_OF_DAY` or `HOUR`).
Monday is `1`, Tuesday is `2`, etc.
[[sql-functions-datetime-isoweek]]
==== `ISO_WEEK_OF_YEAR`/`ISOWEEKOFYEAR`/`ISOWEEK`/`IWOY`/`IW`
.Synopsis:
[source, sql]
--------------------------------------------------
ISO_WEEK_OF_YEAR(date_exp<1>)
--------------------------------------------------
*Input*:
<1> date expression
*Output*: integer
.Description:
Extract the week of the year from a date, following https://en.wikipedia.org/wiki/ISO_week_date[ISO 8601 standard]. The first week
of a year is the first week with a majority (4 or more) of its days in January.
["source","sql",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{sql-specs}/datetime.csv-spec[hourOfDay]
include-tagged::{sql-specs}/docs.csv-spec[isoWeekOfYear]
--------------------------------------------------
* Extract the minute of the day from a date (`MINUTE_OF_DAY`).
[[sql-functions-datetime-minuteofday]]
==== `MINUTE_OF_DAY`
.Synopsis:
[source, sql]
--------------------------------------------------
MINUTE_OF_DAY(date_exp<1>)
--------------------------------------------------
*Input*:
<1> date expression
*Output*: integer
.Description:
Extract the minute of the day from a date.
["source","sql",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{sql-specs}/datetime.csv-spec[minuteOfDay]
include-tagged::{sql-specs}/docs.csv-spec[minuteOfDay]
--------------------------------------------------
* Extract the minute of the hour from a date (`MINUTE_OF_HOUR`, `MINUTE`).
[[sql-functions-datetime-minute]]
==== `MINUTE_OF_HOUR`/`MINUTE`
.Synopsis:
[source, sql]
--------------------------------------------------
MINUTE_OF_HOUR(date_exp<1>)
--------------------------------------------------
*Input*:
<1> date expression
*Output*: integer
.Description:
Extract the minute of the hour from a date.
["source","sql",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{sql-specs}/datetime.csv-spec[minuteOfHour]
include-tagged::{sql-specs}/docs.csv-spec[minuteOfHour]
--------------------------------------------------
* Extract the second of the minute from a date (`SECOND_OF_MINUTE`, `SECOND`).
[[sql-functions-datetime-month]]
==== `MONTH_OF_YEAR`/`MONTH`
.Synopsis:
[source, sql]
--------------------------------------------------
MONTH(date_exp<1>)
--------------------------------------------------
*Input*:
<1> date expression
*Output*: integer
.Description:
Extract the month of the year from a date.
["source","sql",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{sql-specs}/datetime.csv-spec[secondOfMinute]
include-tagged::{sql-specs}/docs.csv-spec[monthOfYear]
--------------------------------------------------
* Extract
[[sql-functions-datetime-monthname]]
==== `MONTH_NAME`/`MONTHNAME`
As an alternative, one can support `EXTRACT` to extract fields from datetimes.
You can run any <<sql-functions-datetime,datetime function>>
with `EXTRACT(<datetime_function> FROM <expression>)`. So
.Synopsis:
[source, sql]
--------------------------------------------------
MONTH_NAME(date_exp<1>)
--------------------------------------------------
*Input*:
<1> date expression
*Output*: string
.Description:
Extract the month from a datetime in text format (`January`, `February`...).
["source","sql",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{sql-specs}/datetime.csv-spec[extractDayOfYear]
include-tagged::{sql-specs}/docs.csv-spec[monthName]
--------------------------------------------------
[[sql-functions-datetime-second]]
==== `SECOND_OF_MINUTE`/`SECOND`
.Synopsis:
[source, sql]
--------------------------------------------------
SECOND_OF_MINUTE(date_exp<1>)
--------------------------------------------------
*Input*:
<1> date expression
*Output*: integer
.Description:
Extract the second of the minute from a date.
["source","sql",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{sql-specs}/docs.csv-spec[secondOfMinute]
--------------------------------------------------
[[sql-functions-datetime-quarter]]
==== `QUARTER`
.Synopsis:
[source, sql]
--------------------------------------------------
QUARTER(date_exp<1>)
--------------------------------------------------
*Input*:
<1> date expression
*Output*: integer
.Description:
Extract the year quarter the date falls in.
["source","sql",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{sql-specs}/docs.csv-spec[quarter]
--------------------------------------------------
[[sql-functions-datetime-week]]
==== `WEEK_OF_YEAR`/`WEEK`
.Synopsis:
[source, sql]
--------------------------------------------------
WEEK_OF_YEAR(date_exp<1>)
--------------------------------------------------
*Input*:
<1> date expression
*Output*: integer
.Description:
Extract the week of the year from a date.
["source","sql",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{sql-specs}/docs.csv-spec[weekOfYear]
--------------------------------------------------
[[sql-functions-datetime-year]]
==== `YEAR`
.Synopsis:
[source, sql]
--------------------------------------------------
YEAR(date_exp<1>)
--------------------------------------------------
*Input*:
<1> date expression
*Output*: integer
.Description:
Extract the year from a date.
["source","sql",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{sql-specs}/docs.csv-spec[year]
--------------------------------------------------
[[sql-functions-datetime-extract]]
==== `EXTRACT`
.Synopsis:
[source, sql]
--------------------------------------------------
EXTRACT(datetime_function<1> FROM date_exp<2>)
--------------------------------------------------
*Input*:
<1> datetime function name
<2> date expression
*Output*: integer
.Description:
Extract fields from a datetime by specifying the name of a <<sql-functions-datetime,datetime function>>.
The following
["source","sql",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{sql-specs}/docs.csv-spec[extractDayOfYear]
--------------------------------------------------
is the equivalent to
["source","sql",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{sql-specs}/datetime.csv-spec[dayOfYear]
include-tagged::{sql-specs}/docs.csv-spec[dayOfYear]
--------------------------------------------------

View File

@ -78,6 +78,8 @@ public abstract class ShowTestCase extends CliIntegrationTestCase {
assertThat(readLine(), RegexMatcher.matches("\\s*DAY_OF_WEEK\\s*\\|\\s*SCALAR\\s*"));
assertThat(readLine(), RegexMatcher.matches("\\s*DAY_OF_YEAR\\s*\\|\\s*SCALAR\\s*"));
assertThat(readLine(), RegexMatcher.matches("\\s*HOUR_OF_DAY\\s*\\|\\s*SCALAR\\s*"));
assertThat(readLine(), RegexMatcher.matches("\\s*ISODAYOFWEEK\\s*\\|\\s*SCALAR\\s*"));
assertThat(readLine(), RegexMatcher.matches("\\s*ISO_DAY_OF_WEEK\\s*\\|\\s*SCALAR\\s*"));
assertThat(readLine(), RegexMatcher.matches("\\s*MINUTE_OF_DAY\\s*\\|\\s*SCALAR\\s*"));
assertEquals("", readLine());
}

View File

@ -40,6 +40,15 @@ DOW |SCALAR
DOY |SCALAR
HOUR |SCALAR
HOUR_OF_DAY |SCALAR
IDOW |SCALAR
ISODAYOFWEEK |SCALAR
ISODOW |SCALAR
ISOWEEK |SCALAR
ISOWEEKOFYEAR |SCALAR
ISO_DAY_OF_WEEK |SCALAR
ISO_WEEK_OF_YEAR|SCALAR
IW |SCALAR
IWOY |SCALAR
MINUTE |SCALAR
MINUTE_OF_DAY |SCALAR
MINUTE_OF_HOUR |SCALAR
@ -156,6 +165,8 @@ DAY_OF_MONTH |SCALAR
DAY_OF_WEEK |SCALAR
DAY_OF_YEAR |SCALAR
HOUR_OF_DAY |SCALAR
ISODAYOFWEEK |SCALAR
ISO_DAY_OF_WEEK|SCALAR
MINUTE_OF_DAY |SCALAR
;

View File

@ -54,10 +54,10 @@ d:i | l:s
;
//
// Date (in H2 these start at 0 instead of 1...)
// Date
//
dateTimeDayOfWeek
SELECT DAY_OF_WEEK(birth_date) d, last_name l FROM "test_emp" WHERE emp_no < 10010 ORDER BY DAY_OF_WEEK(birth_date);
dateTimeIsoDayOfWeek
SELECT ISO_DAY_OF_WEEK(birth_date) d, last_name l FROM "test_emp" WHERE emp_no < 10010 ORDER BY ISO_DAY_OF_WEEK(birth_date);
d:i | l:s
1 | Preusig
@ -86,10 +86,96 @@ d:i | l:s
110 | Peac
;
weekOfYear
SELECT WEEK(birth_date) week, birth_date FROM test_emp ORDER BY WEEK(birth_date) DESC, birth_date DESC LIMIT 15;
week:i | birth_date:ts
---------------+------------------------
52 |1962-12-29T00:00:00.000Z
52 |1959-12-25T00:00:00.000Z
52 |1952-12-24T00:00:00.000Z
51 |1960-12-17T00:00:00.000Z
50 |1956-12-13T00:00:00.000Z
49 |1959-12-03T00:00:00.000Z
49 |1957-12-03T00:00:00.000Z
48 |1963-11-26T00:00:00.000Z
48 |1962-11-26T00:00:00.000Z
47 |1962-11-19T00:00:00.000Z
46 |1956-11-14T00:00:00.000Z
46 |1952-11-13T00:00:00.000Z
45 |1962-11-07T00:00:00.000Z
45 |1953-11-07T00:00:00.000Z
44 |1961-11-02T00:00:00.000Z
;
weekOfYearWithFilter
SELECT WEEK(birth_date) week, birth_date FROM test_emp WHERE WEEK(birth_date) > 50 OR WEEK(birth_date) < 4 ORDER BY WEEK(birth_date) DESC, birth_date DESC;
week:i | birth_date:ts
---------------+------------------------
52 |1962-12-29T00:00:00.000Z
52 |1959-12-25T00:00:00.000Z
52 |1952-12-24T00:00:00.000Z
51 |1960-12-17T00:00:00.000Z
2 |1965-01-03T00:00:00.000Z
2 |1953-01-07T00:00:00.000Z
;
//
// Aggregate
//
dateTimeAggByIsoDayOfWeekWithFilter
SELECT IDOW(birth_date) day, DAY_NAME(birth_date) name, COUNT(*) c FROM test_emp WHERE IDOW(birth_date) < 6 GROUP BY day, name ORDER BY day desc;
day:i | name:s | c:l
---------------+---------------+---------------
5 |Friday |12
4 |Thursday |15
3 |Wednesday |14
2 |Tuesday |18
1 |Monday |8
;
dateTimeAggByIsoDayOfWeek
SELECT IDOW(birth_date) day, DAY_NAME(birth_date) name, COUNT(*) c FROM test_emp GROUP BY day, name ORDER BY day desc;
day:i | name:s | c:l
---------------+---------------+---------------
7 |Sunday |10
6 |Saturday |13
5 |Friday |12
4 |Thursday |15
3 |Wednesday |14
2 |Tuesday |18
1 |Monday |8
null |null |10
;
dateTimeAggByIsoWeekOfYear
SELECT IW(birth_date) iso_week, WEEK(birth_date) week FROM test_emp WHERE IW(birth_date) < 20 GROUP BY iso_week, week ORDER BY iso_week;
iso_week:i | week:i
---------------+---------------
1 |2
3 |4
4 |4
4 |5
6 |7
7 |7
8 |8
8 |9
9 |9
10 |11
12 |12
14 |14
14 |15
15 |16
16 |16
16 |17
18 |18
;
dateTimeAggByYear
SELECT YEAR(birth_date) AS d, CAST(SUM(emp_no) AS INT) s FROM "test_emp" GROUP BY YEAR(birth_date) ORDER BY YEAR(birth_date) LIMIT 13;
@ -166,112 +252,22 @@ d:i | c:l | s:i
null |10 |100445
;
constantYear
// tag::year
SELECT YEAR(CAST('2018-02-19T10:23:27Z' AS TIMESTAMP)) AS year;
weekOfYearGroupBy
SELECT WEEK(birth_date) week, COUNT(*) c FROM test_emp WHERE MOD(WEEK(birth_date), 4) = 0 GROUP BY week ORDER BY WEEK(birth_date);
year
---------------
2018
// end::year
;
constantMonthOfYear
// tag::monthOfYear
SELECT MONTH_OF_YEAR(CAST('2018-02-19T10:23:27Z' AS TIMESTAMP)) AS month;
month
---------------
2
// end::monthOfYear
;
constantWeekOfYear
// tag::weekOfYear
SELECT WEEK_OF_YEAR(CAST('2018-02-19T10:23:27Z' AS TIMESTAMP)) AS week;
week
---------------
8
// end::weekOfYear
;
constantDayOfYear
// tag::dayOfYear
SELECT DAY_OF_YEAR(CAST('2018-02-19T10:23:27Z' AS TIMESTAMP)) AS day;
day
---------------
50
// end::dayOfYear
;
extractDayOfYear
// tag::extractDayOfYear
SELECT EXTRACT(DAY_OF_YEAR FROM CAST('2018-02-19T10:23:27Z' AS TIMESTAMP)) AS day;
day
---------------
50
// end::extractDayOfYear
;
constantDayOfMonth
// tag::dayOfMonth
SELECT DAY_OF_MONTH(CAST('2018-02-19T10:23:27Z' AS TIMESTAMP)) AS day;
day
---------------
19
// end::dayOfMonth
;
constantDayOfWeek
// tag::dayOfWeek
SELECT DAY_OF_WEEK(CAST('2018-02-19T10:23:27Z' AS TIMESTAMP)) AS day;
day
---------------
1
// end::dayOfWeek
;
constantHourOfDay
// tag::hourOfDay
SELECT HOUR_OF_DAY(CAST('2018-02-19T10:23:27Z' AS TIMESTAMP)) AS hour;
hour
---------------
10
// end::hourOfDay
;
constantMinuteOfDay
// tag::minuteOfDay
SELECT MINUTE_OF_DAY(CAST('2018-02-19T10:23:27Z' AS TIMESTAMP)) AS minute;
minute
---------------
623
// end::minuteOfDay
;
constantMinuteOfHour
// tag::minuteOfHour
SELECT MINUTE_OF_HOUR(CAST('2018-02-19T10:23:27Z' AS TIMESTAMP)) AS minute;
minute
---------------
23
// end::minuteOfHour
;
constantSecondOfMinute
// tag::secondOfMinute
SELECT SECOND_OF_MINUTE(CAST('2018-02-19T10:23:27Z' AS TIMESTAMP)) AS second;
second
---------------
27
// end::secondOfMinute
week:i | c:l
---------------+---------------
4 |3
8 |2
12 |1
16 |3
20 |1
24 |2
28 |3
32 |1
36 |3
40 |4
44 |2
48 |2
52 |3
;

View File

@ -6,6 +6,9 @@
// Time NOT IMPLEMENTED in H2 on TIMESTAMP WITH TIME ZONE - hence why these are moved to CSV
//
// WEEK_OF_YEAR moved to CSV tests, because H2 builds its Calendar with the local Locale, we consider ROOT as the default Locale
// This has implications on the results, which could change given specific locales where the rules for determining the start of a year are different.
//
// Date
//
@ -31,6 +34,9 @@ SELECT DAYNAME(CAST('2018-09-03' AS TIMESTAMP)) day FROM "test_emp" limit 1;
quarterSelect
SELECT QUARTER(hire_date) q, hire_date FROM test_emp ORDER BY hire_date LIMIT 15;
dayOfWeek
SELECT DAY_OF_WEEK(birth_date) day, birth_date FROM test_emp ORDER BY DAY_OF_WEEK(birth_date);
//
// Filter
//
@ -59,6 +65,9 @@ SELECT first_name, last_name FROM "test_emp" WHERE DAYNAME(hire_date) = 'Sunday'
quarterWithFilter
SELECT QUARTER(hire_date) quarter, hire_date FROM test_emp WHERE QUARTER(hire_date) > 2 ORDER BY hire_date LIMIT 15;
dayOfWeekWithFilter
SELECT DAY_OF_WEEK(birth_date) day, birth_date FROM test_emp WHERE DAY_OF_WEEK(birth_date) IN (6,7) ORDER BY DAY_OF_WEEK(birth_date);
//
// Aggregate
//
@ -102,3 +111,6 @@ SELECT CAST(MAX(salary) AS DOUBLE) max_salary, DAYNAME(hire_date) day_name FROM
quarterWithGroupByAndOrderBy
SELECT QUARTER(hire_date) quarter, COUNT(*) hires FROM test_emp GROUP BY QUARTER(hire_date) ORDER BY QUARTER(hire_date);
dayOfWeekGroupBy
SELECT DAY_OF_WEEK(birth_date) day, COUNT(*) c FROM test_emp WHERE DAY_OF_WEEK(birth_date) < 6 GROUP BY day ORDER BY DAY_OF_WEEK(birth_date);

View File

@ -217,6 +217,15 @@ DOW |SCALAR
DOY |SCALAR
HOUR |SCALAR
HOUR_OF_DAY |SCALAR
IDOW |SCALAR
ISODAYOFWEEK |SCALAR
ISODOW |SCALAR
ISOWEEK |SCALAR
ISOWEEKOFYEAR |SCALAR
ISO_DAY_OF_WEEK |SCALAR
ISO_WEEK_OF_YEAR|SCALAR
IW |SCALAR
IWOY |SCALAR
MINUTE |SCALAR
MINUTE_OF_DAY |SCALAR
MINUTE_OF_HOUR |SCALAR
@ -345,6 +354,8 @@ DAY_OF_MONTH |SCALAR
DAY_OF_WEEK |SCALAR
DAY_OF_YEAR |SCALAR
HOUR_OF_DAY |SCALAR
ISODAYOFWEEK |SCALAR
ISO_DAY_OF_WEEK|SCALAR
MINUTE_OF_DAY |SCALAR
// end::showFunctionsWithPattern
@ -1518,6 +1529,11 @@ SELECT TRUNCATE(-345.153, 1) AS trimmed;
// end::mathTruncateWithPositiveParameter
;
///////////////////////////////
//
// Null handling
//
///////////////////////////////
coalesceReturnNonNull
// tag::coalesceReturnNonNull
@ -1686,6 +1702,12 @@ true
// end::nullEqualsCompareTwoNulls
;
///////////////////////////////
//
// System functions
//
///////////////////////////////
// ignored because tests run with a docs-not-worthy cluster name
// at the time of this test being ignored, the cluster name was x-pack_plugin_sql_qa_single-node_integTestCluster
database-Ignore
@ -1709,3 +1731,172 @@ SELECT USER();
elastic
// end::user
;
///////////////////////////////
//
// Date-Time functions
//
///////////////////////////////
constantYear
// tag::year
SELECT YEAR(CAST('2018-02-19T10:23:27Z' AS TIMESTAMP)) AS year;
year
---------------
2018
// end::year
;
constantMonthOfYear
// tag::monthOfYear
SELECT MONTH_OF_YEAR(CAST('2018-02-19T10:23:27Z' AS TIMESTAMP)) AS month;
month
---------------
2
// end::monthOfYear
;
constantIsoWeekOfYear
// tag::isoWeekOfYear
SELECT ISO_WEEK_OF_YEAR(CAST('2018-02-19T10:23:27Z' AS TIMESTAMP)) AS week;
week
---------------
8
// end::isoWeekOfYear
;
// Ignored because of https://github.com/elastic/elasticsearch/issues/33796
constantDayName-Ignore
// tag::dayName
SELECT DAY_NAME(CAST('2018-02-19T10:23:27Z' AS TIMESTAMP)) AS day;
day
---------------
Monday
// end::dayName
;
// Ignored because of https://github.com/elastic/elasticsearch/issues/33796
constantMonthName-Ignore
// tag::monthName
SELECT MONTH_NAME(CAST('2018-02-19T10:23:27Z' AS TIMESTAMP)) AS month;
month
---------------
February
// end::monthName
;
constantDayOfYear
// tag::dayOfYear
SELECT DAY_OF_YEAR(CAST('2018-02-19T10:23:27Z' AS TIMESTAMP)) AS day;
day
---------------
50
// end::dayOfYear
;
extractDayOfYear
// tag::extractDayOfYear
SELECT EXTRACT(DAY_OF_YEAR FROM CAST('2018-02-19T10:23:27Z' AS TIMESTAMP)) AS day;
day
---------------
50
// end::extractDayOfYear
;
constantDayOfMonth
// tag::dayOfMonth
SELECT DAY_OF_MONTH(CAST('2018-02-19T10:23:27Z' AS TIMESTAMP)) AS day;
day
---------------
19
// end::dayOfMonth
;
constantDayOfWeek
// tag::dayOfWeek
SELECT DAY_OF_WEEK(CAST('2018-02-19T10:23:27Z' AS TIMESTAMP)) AS day;
day
---------------
2
// end::dayOfWeek
;
constantIsoDayOfWeek
// tag::isoDayOfWeek
SELECT ISO_DAY_OF_WEEK(CAST('2018-02-19T10:23:27Z' AS TIMESTAMP)) AS day;
day
---------------
1
// end::isoDayOfWeek
;
constantHourOfDay
// tag::hourOfDay
SELECT HOUR_OF_DAY(CAST('2018-02-19T10:23:27Z' AS TIMESTAMP)) AS hour;
hour
---------------
10
// end::hourOfDay
;
constantMinuteOfDay
// tag::minuteOfDay
SELECT MINUTE_OF_DAY(CAST('2018-02-19T10:23:27Z' AS TIMESTAMP)) AS minute;
minute
---------------
623
// end::minuteOfDay
;
constantMinuteOfHour
// tag::minuteOfHour
SELECT MINUTE_OF_HOUR(CAST('2018-02-19T10:23:27Z' AS TIMESTAMP)) AS minute;
minute
---------------
23
// end::minuteOfHour
;
constantSecondOfMinute
// tag::secondOfMinute
SELECT SECOND_OF_MINUTE(CAST('2018-02-19T10:23:27Z' AS TIMESTAMP)) AS second;
second
---------------
27
// end::secondOfMinute
;
constantQuarter
// tag::quarter
SELECT QUARTER(CAST('2018-02-19T10:23:27Z' AS TIMESTAMP)) AS quarter;
quarter
---------------
1
// end::quarter
;
constantWeekOfYear
// tag::weekOfYear
SELECT WEEK(CAST('1988-01-05T09:22:10Z' AS TIMESTAMP)) AS week, ISOWEEK(CAST('1988-01-05T09:22:10Z' AS TIMESTAMP)) AS isoweek;
week | isoweek
---------------+---------------
2 |1
// end::weekOfYear
;

View File

@ -28,6 +28,8 @@ import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.DayOfMont
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.DayOfWeek;
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.DayOfYear;
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.HourOfDay;
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.IsoDayOfWeek;
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.IsoWeekOfYear;
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.MinuteOfDay;
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.MinuteOfHour;
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.MonthName;
@ -151,7 +153,7 @@ public class FunctionRegistry {
def(Skewness.class, Skewness::new, "SKEWNESS"),
def(Kurtosis.class, Kurtosis::new, "KURTOSIS"));
// Scalar functions
// conditional
// Conditional
addToMap(def(Coalesce.class, Coalesce::new, "COALESCE"),
def(IfNull.class, IfNull::new, "IFNULL", "ISNULL", "NVL"),
def(NullIf.class, NullIf::new, "NULLIF"),
@ -163,6 +165,8 @@ public class FunctionRegistry {
def(DayOfWeek.class, DayOfWeek::new, "DAY_OF_WEEK", "DAYOFWEEK", "DOW"),
def(DayOfYear.class, DayOfYear::new, "DAY_OF_YEAR", "DAYOFYEAR", "DOY"),
def(HourOfDay.class, HourOfDay::new, "HOUR_OF_DAY", "HOUR"),
def(IsoDayOfWeek.class, IsoDayOfWeek::new, "ISO_DAY_OF_WEEK", "ISODAYOFWEEK", "ISODOW", "IDOW"),
def(IsoWeekOfYear.class, IsoWeekOfYear::new, "ISO_WEEK_OF_YEAR", "ISOWEEKOFYEAR", "ISOWEEK", "IWOY", "IW"),
def(MinuteOfDay.class, MinuteOfDay::new, "MINUTE_OF_DAY"),
def(MinuteOfHour.class, MinuteOfHour::new, "MINUTE_OF_HOUR", "MINUTE"),
def(MonthName.class, MonthName::new, "MONTH_NAME", "MONTHNAME"),

View File

@ -9,6 +9,7 @@ import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
import org.elasticsearch.common.io.stream.NamedWriteableRegistry.Entry;
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.DateTimeProcessor;
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.NamedDateTimeProcessor;
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.NonIsoDateTimeProcessor;
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.QuarterProcessor;
import org.elasticsearch.xpack.sql.expression.function.scalar.math.BinaryMathProcessor;
import org.elasticsearch.xpack.sql.expression.function.scalar.math.MathProcessor;
@ -78,6 +79,7 @@ public final class Processors {
// datetime
entries.add(new Entry(Processor.class, DateTimeProcessor.NAME, DateTimeProcessor::new));
entries.add(new Entry(Processor.class, NamedDateTimeProcessor.NAME, NamedDateTimeProcessor::new));
entries.add(new Entry(Processor.class, NonIsoDateTimeProcessor.NAME, NonIsoDateTimeProcessor::new));
entries.add(new Entry(Processor.class, QuarterProcessor.NAME, QuarterProcessor::new));
// math
entries.add(new Entry(Processor.class, MathProcessor.NAME, MathProcessor::new));

View File

@ -18,14 +18,14 @@ public class DateTimeProcessor extends BaseDateTimeProcessor {
public enum DateTimeExtractor {
DAY_OF_MONTH(ChronoField.DAY_OF_MONTH),
DAY_OF_WEEK(ChronoField.DAY_OF_WEEK),
ISO_DAY_OF_WEEK(ChronoField.DAY_OF_WEEK),
DAY_OF_YEAR(ChronoField.DAY_OF_YEAR),
HOUR_OF_DAY(ChronoField.HOUR_OF_DAY),
MINUTE_OF_DAY(ChronoField.MINUTE_OF_DAY),
MINUTE_OF_HOUR(ChronoField.MINUTE_OF_HOUR),
MONTH_OF_YEAR(ChronoField.MONTH_OF_YEAR),
SECOND_OF_MINUTE(ChronoField.SECOND_OF_MINUTE),
WEEK_OF_YEAR(ChronoField.ALIGNED_WEEK_OF_YEAR),
ISO_WEEK_OF_YEAR(ChronoField.ALIGNED_WEEK_OF_YEAR),
YEAR(ChronoField.YEAR);
private final ChronoField field;

View File

@ -6,18 +6,19 @@
package org.elasticsearch.xpack.sql.expression.function.scalar.datetime;
import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.DateTimeProcessor.DateTimeExtractor;
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.NonIsoDateTimeProcessor.NonIsoDateTimeExtractor;
import org.elasticsearch.xpack.sql.tree.Location;
import org.elasticsearch.xpack.sql.tree.NodeInfo.NodeCtor2;
import java.util.TimeZone;
/**
* Extract the day of the week from a datetime. 1 is Monday, 2 is Tuesday, etc.
* Extract the day of the week from a datetime in non-ISO format. 1 is Sunday, 2 is Monday, etc.
*/
public class DayOfWeek extends DateTimeFunction {
public class DayOfWeek extends NonIsoDateTimeFunction {
public DayOfWeek(Location location, Expression field, TimeZone timeZone) {
super(location, field, timeZone, DateTimeExtractor.DAY_OF_WEEK);
super(location, field, timeZone, NonIsoDateTimeExtractor.DAY_OF_WEEK);
}
@Override
@ -29,9 +30,4 @@ public class DayOfWeek extends DateTimeFunction {
protected DayOfWeek replaceChild(Expression newChild) {
return new DayOfWeek(location(), newChild, timeZone());
}
@Override
public String dateTimeFormat() {
return "e";
}
}

View File

@ -0,0 +1,37 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.sql.expression.function.scalar.datetime;
import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.DateTimeProcessor.DateTimeExtractor;
import org.elasticsearch.xpack.sql.tree.Location;
import org.elasticsearch.xpack.sql.tree.NodeInfo.NodeCtor2;
import java.util.TimeZone;
/**
* Extract the day of the week (following the ISO standard) from a datetime. 1 is Monday, 2 is Tuesday, etc.
*/
public class IsoDayOfWeek extends DateTimeFunction {
public IsoDayOfWeek(Location location, Expression field, TimeZone timeZone) {
super(location, field, timeZone, DateTimeExtractor.ISO_DAY_OF_WEEK);
}
@Override
protected NodeCtor2<Expression, TimeZone, BaseDateTimeFunction> ctorForInfo() {
return IsoDayOfWeek::new;
}
@Override
protected IsoDayOfWeek replaceChild(Expression newChild) {
return new IsoDayOfWeek(location(), newChild, timeZone());
}
@Override
public String dateTimeFormat() {
return "e";
}
}

View File

@ -0,0 +1,37 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.sql.expression.function.scalar.datetime;
import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.DateTimeProcessor.DateTimeExtractor;
import org.elasticsearch.xpack.sql.tree.Location;
import org.elasticsearch.xpack.sql.tree.NodeInfo.NodeCtor2;
import java.util.TimeZone;
/**
* Extract the week of the year from a datetime following the ISO standard.
*/
public class IsoWeekOfYear extends DateTimeFunction {
public IsoWeekOfYear(Location location, Expression field, TimeZone timeZone) {
super(location, field, timeZone, DateTimeExtractor.ISO_WEEK_OF_YEAR);
}
@Override
protected NodeCtor2<Expression, TimeZone, BaseDateTimeFunction> ctorForInfo() {
return IsoWeekOfYear::new;
}
@Override
protected IsoWeekOfYear replaceChild(Expression newChild) {
return new IsoWeekOfYear(location(), newChild, timeZone());
}
@Override
public String dateTimeFormat() {
return "w";
}
}

View File

@ -0,0 +1,61 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.sql.expression.function.scalar.datetime;
import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.FieldAttribute;
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.NonIsoDateTimeProcessor.NonIsoDateTimeExtractor;
import org.elasticsearch.xpack.sql.expression.gen.processor.Processor;
import org.elasticsearch.xpack.sql.expression.gen.script.ScriptTemplate;
import org.elasticsearch.xpack.sql.tree.Location;
import org.elasticsearch.xpack.sql.type.DataType;
import org.elasticsearch.xpack.sql.util.StringUtils;
import java.time.ZonedDateTime;
import java.util.Locale;
import java.util.TimeZone;
import static java.lang.String.format;
import static org.elasticsearch.xpack.sql.expression.gen.script.ParamsBuilder.paramsBuilder;
/*
* Base class for date/time functions that behave differently in a non-ISO format
*/
abstract class NonIsoDateTimeFunction extends BaseDateTimeFunction {
private final NonIsoDateTimeExtractor extractor;
NonIsoDateTimeFunction(Location location, Expression field, TimeZone timeZone, NonIsoDateTimeExtractor extractor) {
super(location, field, timeZone);
this.extractor = extractor;
}
@Override
protected Object doFold(ZonedDateTime dateTime) {
return extractor.extract(dateTime);
}
@Override
public ScriptTemplate scriptWithField(FieldAttribute field) {
return new ScriptTemplate(
formatTemplate(format(Locale.ROOT, "{sql}.%s(doc[{}].value, {})",
StringUtils.underscoreToLowerCamelCase(extractor.name()))),
paramsBuilder()
.variable(field.name())
.variable(timeZone().getID()).build(),
dataType());
}
@Override
protected Processor makeProcessor() {
return new NonIsoDateTimeProcessor(extractor, timeZone());
}
@Override
public DataType dataType() {
return DataType.INTEGER;
}
}

View File

@ -0,0 +1,112 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.sql.expression.function.scalar.datetime;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoField;
import java.util.Calendar;
import java.util.Locale;
import java.util.Objects;
import java.util.TimeZone;
import java.util.function.Function;
public class NonIsoDateTimeProcessor extends BaseDateTimeProcessor {
public enum NonIsoDateTimeExtractor {
DAY_OF_WEEK(zdt -> {
// by ISO 8601 standard, Monday is the first day of the week and has the value 1
// non-ISO 8601 standard considers Sunday as the first day of the week and value 1
int dayOfWeek = zdt.get(ChronoField.DAY_OF_WEEK) + 1;
return dayOfWeek == 8 ? 1 : dayOfWeek;
}),
WEEK_OF_YEAR(zdt -> {
// by ISO 8601 standard, the first week of a year is the first week with a majority (4 or more) of its days in January.
// Other Locales may have their own standards (see Arabic or Japanese calendars).
LocalDateTime ld = zdt.toLocalDateTime();
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone(zdt.getZone()), Locale.ROOT);
cal.clear();
cal.set(ld.get(ChronoField.YEAR), ld.get(ChronoField.MONTH_OF_YEAR) - 1, ld.get(ChronoField.DAY_OF_MONTH),
ld.get(ChronoField.HOUR_OF_DAY), ld.get(ChronoField.MINUTE_OF_HOUR), ld.get(ChronoField.SECOND_OF_MINUTE));
return cal.get(Calendar.WEEK_OF_YEAR);
});
private final Function<ZonedDateTime, Integer> apply;
NonIsoDateTimeExtractor(Function<ZonedDateTime, Integer> apply) {
this.apply = apply;
}
public final Integer extract(ZonedDateTime dateTime) {
return apply.apply(dateTime);
}
public final Integer extract(ZonedDateTime millis, String tzId) {
return apply.apply(millis.withZoneSameInstant(ZoneId.of(tzId)));
}
}
public static final String NAME = "nidt";
private final NonIsoDateTimeExtractor extractor;
public NonIsoDateTimeProcessor(NonIsoDateTimeExtractor extractor, TimeZone timeZone) {
super(timeZone);
this.extractor = extractor;
}
public NonIsoDateTimeProcessor(StreamInput in) throws IOException {
super(in);
extractor = in.readEnum(NonIsoDateTimeExtractor.class);
}
@Override
public void writeTo(StreamOutput out) throws IOException {
super.writeTo(out);
out.writeEnum(extractor);
}
@Override
public String getWriteableName() {
return NAME;
}
NonIsoDateTimeExtractor extractor() {
return extractor;
}
@Override
public Object doProcess(ZonedDateTime dateTime) {
return extractor.extract(dateTime);
}
@Override
public int hashCode() {
return Objects.hash(extractor, timeZone());
}
@Override
public boolean equals(Object obj) {
if (obj == null || obj.getClass() != getClass()) {
return false;
}
NonIsoDateTimeProcessor other = (NonIsoDateTimeProcessor) obj;
return Objects.equals(extractor, other.extractor)
&& Objects.equals(timeZone(), other.timeZone());
}
@Override
public String toString() {
return extractor.toString();
}
}

View File

@ -6,18 +6,19 @@
package org.elasticsearch.xpack.sql.expression.function.scalar.datetime;
import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.DateTimeProcessor.DateTimeExtractor;
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.NonIsoDateTimeProcessor.NonIsoDateTimeExtractor;
import org.elasticsearch.xpack.sql.tree.Location;
import org.elasticsearch.xpack.sql.tree.NodeInfo.NodeCtor2;
import java.util.TimeZone;
/**
* Extract the week of the year from a datetime.
* Extract the week of the year from a datetime following the non-ISO standard.
*/
public class WeekOfYear extends DateTimeFunction {
public class WeekOfYear extends NonIsoDateTimeFunction {
public WeekOfYear(Location location, Expression field, TimeZone timeZone) {
super(location, field, timeZone, DateTimeExtractor.WEEK_OF_YEAR);
super(location, field, timeZone, NonIsoDateTimeExtractor.WEEK_OF_YEAR);
}
@Override
@ -29,9 +30,4 @@ public class WeekOfYear extends DateTimeFunction {
protected WeekOfYear replaceChild(Expression newChild) {
return new WeekOfYear(location(), newChild, timeZone());
}
@Override
public String dateTimeFormat() {
return "w";
}
}

View File

@ -10,6 +10,7 @@ import org.elasticsearch.script.JodaCompatibleZonedDateTime;
import org.elasticsearch.xpack.sql.SqlIllegalArgumentException;
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.DateTimeFunction;
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.NamedDateTimeProcessor.NameExtractor;
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.NonIsoDateTimeProcessor.NonIsoDateTimeExtractor;
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.QuarterProcessor;
import org.elasticsearch.xpack.sql.expression.function.scalar.math.BinaryMathProcessor.BinaryMathOperation;
import org.elasticsearch.xpack.sql.expression.function.scalar.math.MathProcessor.MathOperation;
@ -314,6 +315,13 @@ public final class InternalSqlScriptUtils {
return NameExtractor.DAY_NAME.extract(asDateTime(dateTime), tzId);
}
public static Integer dayOfWeek(Object dateTime, String tzId) {
if (dateTime == null || tzId == null) {
return null;
}
return NonIsoDateTimeExtractor.DAY_OF_WEEK.extract(asDateTime(dateTime), tzId);
}
public static String monthName(Object dateTime, String tzId) {
if (dateTime == null || tzId == null) {
return null;
@ -328,6 +336,13 @@ public final class InternalSqlScriptUtils {
return QuarterProcessor.quarter(asDateTime(dateTime), tzId);
}
public static Integer weekOfYear(Object dateTime, String tzId) {
if (dateTime == null || tzId == null) {
return null;
}
return NonIsoDateTimeExtractor.WEEK_OF_YEAR.extract(asDateTime(dateTime), tzId);
}
public static ZonedDateTime asDateTime(Object dateTime) {
if (dateTime instanceof JodaCompatibleZonedDateTime) {
return ((JodaCompatibleZonedDateTime) dateTime).getZonedDateTime();

View File

@ -98,8 +98,10 @@ class org.elasticsearch.xpack.sql.expression.function.scalar.whitelist.InternalS
#
Integer dateTimeChrono(Object, String, String)
String dayName(Object, String)
Integer dayOfWeek(Object, String)
String monthName(Object, String)
Integer quarter(Object, String)
Integer weekOfYear(Object, String)
IntervalDayTime intervalDayTime(String, String)
IntervalYearMonth intervalYearMonth(String, String)
ZonedDateTime asDateTime(Object)

View File

@ -163,7 +163,7 @@ public class VerifierErrorMessagesTests extends ESTestCase {
}
public void testMissingExtractSimilarMany() {
assertEquals("1:8: Unknown datetime field [DOP], did you mean any of [DOM, DOW, DOY]?",
assertEquals("1:8: Unknown datetime field [DOP], did you mean any of [DOM, DOW, DOY, IDOW]?",
error("SELECT EXTRACT(DOP FROM date) FROM test"));
}

View File

@ -0,0 +1,92 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.sql.expression.function.scalar.datetime;
import org.elasticsearch.common.io.stream.Writeable.Reader;
import org.elasticsearch.test.AbstractWireSerializingTestCase;
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.NonIsoDateTimeProcessor.NonIsoDateTimeExtractor;
import java.io.IOException;
import java.util.TimeZone;
import static org.elasticsearch.xpack.sql.expression.function.scalar.datetime.DateTimeTestUtils.dateTime;
public class NonIsoDateTimeProcessorTests extends AbstractWireSerializingTestCase<NonIsoDateTimeProcessor> {
private static final TimeZone UTC = TimeZone.getTimeZone("UTC");
public static NonIsoDateTimeProcessor randomNonISODateTimeProcessor() {
return new NonIsoDateTimeProcessor(randomFrom(NonIsoDateTimeExtractor.values()), UTC);
}
@Override
protected NonIsoDateTimeProcessor createTestInstance() {
return randomNonISODateTimeProcessor();
}
@Override
protected Reader<NonIsoDateTimeProcessor> instanceReader() {
return NonIsoDateTimeProcessor::new;
}
@Override
protected NonIsoDateTimeProcessor mutateInstance(NonIsoDateTimeProcessor instance) throws IOException {
NonIsoDateTimeExtractor replaced = randomValueOtherThan(instance.extractor(), () -> randomFrom(NonIsoDateTimeExtractor.values()));
return new NonIsoDateTimeProcessor(replaced, UTC);
}
public void testNonISOWeekOfYearInUTC() {
NonIsoDateTimeProcessor proc = new NonIsoDateTimeProcessor(NonIsoDateTimeExtractor.WEEK_OF_YEAR, UTC);
assertEquals(2, proc.process(dateTime(568372930000L))); //1988-01-05T09:22:10Z[UTC]
assertEquals(6, proc.process(dateTime(981278530000L))); //2001-02-04T09:22:10Z[UTC]
assertEquals(7, proc.process(dateTime(224241730000L))); //1977-02-08T09:22:10Z[UTC]
assertEquals(12, proc.process(dateTime(132744130000L))); //1974-03-17T09:22:10Z[UTC]
assertEquals(17, proc.process(dateTime(230376130000L))); //1977-04-20T09:22:10Z[UTC]
assertEquals(17, proc.process(dateTime(766833730000L))); //1994-04-20T09:22:10Z[UTC]
assertEquals(29, proc.process(dateTime(79780930000L))); //1972-07-12T09:22:10Z[UTC]
assertEquals(33, proc.process(dateTime(902913730000L))); //1998-08-12T09:22:10Z[UTC]
}
public void testNonISOWeekOfYearInNonUTCTimeZone() {
NonIsoDateTimeProcessor proc = new NonIsoDateTimeProcessor(NonIsoDateTimeExtractor.WEEK_OF_YEAR, TimeZone.getTimeZone("GMT-10:00"));
assertEquals(2, proc.process(dateTime(568372930000L)));
assertEquals(5, proc.process(dateTime(981278530000L)));
assertEquals(7, proc.process(dateTime(224241730000L)));
assertEquals(11, proc.process(dateTime(132744130000L)));
assertEquals(17, proc.process(dateTime(230376130000L)));
assertEquals(17, proc.process(dateTime(766833730000L)));
assertEquals(29, proc.process(dateTime(79780930000L)));
assertEquals(33, proc.process(dateTime(902913730000L)));
}
public void testNonISODayOfWeekInUTC() {
NonIsoDateTimeProcessor proc = new NonIsoDateTimeProcessor(NonIsoDateTimeExtractor.DAY_OF_WEEK, UTC);
assertEquals(3, proc.process(dateTime(568372930000L))); //1988-01-05T09:22:10Z[UTC]
assertEquals(1, proc.process(dateTime(981278530000L))); //2001-02-04T09:22:10Z[UTC]
assertEquals(3, proc.process(dateTime(224241730000L))); //1977-02-08T09:22:10Z[UTC]
assertEquals(1, proc.process(dateTime(132744130000L))); //1974-03-17T09:22:10Z[UTC]
assertEquals(4, proc.process(dateTime(230376130000L))); //1977-04-20T09:22:10Z[UTC]
assertEquals(4, proc.process(dateTime(766833730000L))); //1994-04-20T09:22:10Z[UTC]
assertEquals(7, proc.process(dateTime(333451330000L))); //1980-07-26T09:22:10Z[UTC]
assertEquals(6, proc.process(dateTime(874660930000L))); //1997-09-19T09:22:10Z[UTC]
}
public void testNonISODayOfWeekInNonUTCTimeZone() {
NonIsoDateTimeProcessor proc = new NonIsoDateTimeProcessor(NonIsoDateTimeExtractor.DAY_OF_WEEK, TimeZone.getTimeZone("GMT-10:00"));
assertEquals(2, proc.process(dateTime(568372930000L)));
assertEquals(7, proc.process(dateTime(981278530000L)));
assertEquals(2, proc.process(dateTime(224241730000L)));
assertEquals(7, proc.process(dateTime(132744130000L)));
assertEquals(3, proc.process(dateTime(230376130000L)));
assertEquals(3, proc.process(dateTime(766833730000L)));
assertEquals(6, proc.process(dateTime(333451330000L)));
assertEquals(5, proc.process(dateTime(874660930000L)));
}
}

View File

@ -23,7 +23,7 @@ import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.DayName;
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.DayOfMonth;
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.DayOfYear;
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.MonthOfYear;
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.WeekOfYear;
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.IsoWeekOfYear;
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.Year;
import org.elasticsearch.xpack.sql.expression.function.scalar.math.ACos;
import org.elasticsearch.xpack.sql.expression.function.scalar.math.ASin;
@ -333,9 +333,9 @@ public class OptimizerTests extends ESTestCase {
assertEquals(1, foldFunction(new MonthOfYear(EMPTY, cast, UTC)));
assertEquals(19, foldFunction(new DayOfMonth(EMPTY, cast, UTC)));
assertEquals(19, foldFunction(new DayOfYear(EMPTY, cast, UTC)));
assertEquals(3, foldFunction(new WeekOfYear(EMPTY, cast, UTC)));
assertEquals(3, foldFunction(new IsoWeekOfYear(EMPTY, cast, UTC)));
assertNull(foldFunction(
new WeekOfYear(EMPTY, new Literal(EMPTY, null, DataType.NULL), UTC)));
new IsoWeekOfYear(EMPTY, new Literal(EMPTY, null, DataType.NULL), UTC)));
}
public void testConstantFoldingIn() {