Skip to content

Commit c9d2bc3

Browse files
committed
Add DOW/dayofweek
1 parent a1a4db3 commit c9d2bc3

File tree

5 files changed

+67
-29
lines changed

5 files changed

+67
-29
lines changed

sql/catalyst/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBase.g4

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,7 @@ primaryExpression
592592
| identifier #columnReference
593593
| base=primaryExpression '.' fieldName=identifier #dereference
594594
| '(' expression ')' #parenthesizedExpression
595-
| EXTRACT '(' field=(YEAR | QUARTER | MONTH | WEEK | DAY | HOUR | MINUTE | SECOND) FROM source=valueExpression ')' #extract
595+
| EXTRACT '(' field=identifier FROM source=valueExpression ')' #extract
596596
;
597597

598598
constant
@@ -740,7 +740,7 @@ nonReserved
740740
| VIEW | REPLACE
741741
| IF
742742
| POSITION
743-
| EXTRACT | YEAR | QUARTER | MONTH | WEEK | DAY | HOUR | MINUTE | SECOND
743+
| EXTRACT | YEAR | QUARTER | MONTH | WEEK | DAY | DOW | HOUR | MINUTE | SECOND
744744
| NO | DATA
745745
| START | TRANSACTION | COMMIT | ROLLBACK | IGNORE
746746
| SORT | CLUSTER | DISTRIBUTE | UNSET | TBLPROPERTIES | SKEWED | STORED | DIRECTORIES | LOCATION
@@ -886,6 +886,7 @@ QUARTER: 'QUARTER';
886886
MONTH: 'MONTH';
887887
WEEK: 'WEEK';
888888
DAY: 'DAY';
889+
DOW: 'DOW';
889890
HOUR: 'HOUR';
890891
MINUTE: 'MINUTE';
891892
SECOND: 'SECOND';

sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1210,23 +1210,34 @@ class AstBuilder(conf: SQLConf) extends SqlBaseBaseVisitor[AnyRef] with Logging
12101210
* Create a Extract expression.
12111211
*/
12121212
override def visitExtract(ctx: ExtractContext): Expression = withOrigin(ctx) {
1213-
ctx.field.getType match {
1214-
case SqlBaseParser.YEAR =>
1215-
Year(expression(ctx.source))
1216-
case SqlBaseParser.QUARTER =>
1217-
Quarter(expression(ctx.source))
1218-
case SqlBaseParser.MONTH =>
1219-
Month(expression(ctx.source))
1220-
case SqlBaseParser.WEEK =>
1221-
WeekOfYear(expression(ctx.source))
1222-
case SqlBaseParser.DAY =>
1223-
DayOfMonth(expression(ctx.source))
1224-
case SqlBaseParser.HOUR =>
1225-
Hour(expression(ctx.source))
1226-
case SqlBaseParser.MINUTE =>
1227-
Minute(expression(ctx.source))
1228-
case SqlBaseParser.SECOND =>
1229-
Second(expression(ctx.source))
1213+
val extractType = ctx.field.getText.toUpperCase(Locale.ROOT)
1214+
try {
1215+
extractType match {
1216+
case "YEAR" =>
1217+
Year(expression(ctx.source))
1218+
case "QUARTER" =>
1219+
Quarter(expression(ctx.source))
1220+
case "MONTH" =>
1221+
Month(expression(ctx.source))
1222+
case "WEEK" =>
1223+
WeekOfYear(expression(ctx.source))
1224+
case "DAY" =>
1225+
DayOfMonth(expression(ctx.source))
1226+
case "DOW" =>
1227+
DayOfWeek(expression(ctx.source))
1228+
case "HOUR" =>
1229+
Hour(expression(ctx.source))
1230+
case "MINUTE" =>
1231+
Minute(expression(ctx.source))
1232+
case "SECOND" =>
1233+
Second(expression(ctx.source))
1234+
case other =>
1235+
throw new ParseException(s"Literals of type '$other' are currently not supported.", ctx)
1236+
}
1237+
} catch {
1238+
case e: IllegalArgumentException =>
1239+
val message = Option(e.getMessage).getOrElse(s"Exception parsing $extractType")
1240+
throw new ParseException(message, ctx)
12301241
}
12311242
}
12321243

sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/parser/TableIdentifierParserSuite.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class TableIdentifierParserSuite extends SparkFunSuite {
5252
"true", "truncate", "update", "user", "values", "with", "regexp", "rlike",
5353
"bigint", "binary", "boolean", "current_date", "current_timestamp", "date", "double", "float",
5454
"int", "smallint", "timestamp", "at", "position", "both", "leading", "trailing",
55-
"extract", "year", "quarter", "month", "week", "day", "hour", "minute", "second")
55+
"extract", "year", "quarter", "month", "week", "day", "dow", "hour", "minute", "second")
5656

5757
val hiveStrictNonReservedKeyword = Seq("anti", "full", "inner", "left", "semi", "right",
5858
"natural", "union", "intersect", "except", "database", "on", "join", "cross", "select", "from",

sql/core/src/test/resources/sql-tests/inputs/extract.sql

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,12 @@ select extract(week from c) from t;
1010

1111
select extract(day from c) from t;
1212

13+
select extract(dow from c) from t;
14+
1315
select extract(hour from c) from t;
1416

1517
select extract(minute from c) from t;
1618

1719
select extract(second from c) from t;
20+
21+
select extract(not_supported from c) from t;

sql/core/src/test/resources/sql-tests/results/extract.sql.out

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
-- Automatically generated by SQLQueryTestSuite
2-
-- Number of queries: 9
2+
-- Number of queries: 11
33

44

55
-- !query 0
@@ -51,24 +51,46 @@ struct<dayofmonth(CAST(c AS DATE)):int>
5151

5252

5353
-- !query 6
54-
select extract(hour from c) from t
54+
select extract(dow from c) from t
5555
-- !query 6 schema
56-
struct<hour(CAST(c AS TIMESTAMP)):int>
56+
struct<dayofweek(CAST(c AS DATE)):int>
5757
-- !query 6 output
58-
7
58+
6
5959

6060

6161
-- !query 7
62-
select extract(minute from c) from t
62+
select extract(hour from c) from t
6363
-- !query 7 schema
64-
struct<minute(CAST(c AS TIMESTAMP)):int>
64+
struct<hour(CAST(c AS TIMESTAMP)):int>
6565
-- !query 7 output
66-
8
66+
7
6767

6868

6969
-- !query 8
70-
select extract(second from c) from t
70+
select extract(minute from c) from t
7171
-- !query 8 schema
72-
struct<second(CAST(c AS TIMESTAMP)):int>
72+
struct<minute(CAST(c AS TIMESTAMP)):int>
7373
-- !query 8 output
74+
8
75+
76+
77+
-- !query 9
78+
select extract(second from c) from t
79+
-- !query 9 schema
80+
struct<second(CAST(c AS TIMESTAMP)):int>
81+
-- !query 9 output
7482
9
83+
84+
85+
-- !query 10
86+
select extract(not_supported from c) from t
87+
-- !query 10 schema
88+
struct<>
89+
-- !query 10 output
90+
org.apache.spark.sql.catalyst.parser.ParseException
91+
92+
Literals of type 'NOT_SUPPORTED' are currently not supported.(line 1, pos 7)
93+
94+
== SQL ==
95+
select extract(not_supported from c) from t
96+
-------^^^

0 commit comments

Comments
 (0)