Skip to content

Commit a1a4db3

Browse files
committed
Add support for date extract
1 parent 98909c3 commit a1a4db3

File tree

5 files changed

+128
-1
lines changed

5 files changed

+128
-1
lines changed

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,6 +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
595596
;
596597

597598
constant
@@ -739,6 +740,7 @@ nonReserved
739740
| VIEW | REPLACE
740741
| IF
741742
| POSITION
743+
| EXTRACT | YEAR | QUARTER | MONTH | WEEK | DAY | HOUR | MINUTE | SECOND
742744
| NO | DATA
743745
| START | TRANSACTION | COMMIT | ROLLBACK | IGNORE
744746
| SORT | CLUSTER | DISTRIBUTE | UNSET | TBLPROPERTIES | SKEWED | STORED | DIRECTORIES | LOCATION
@@ -878,6 +880,15 @@ TRAILING: 'TRAILING';
878880

879881
IF: 'IF';
880882
POSITION: 'POSITION';
883+
EXTRACT: 'EXTRACT';
884+
YEAR: 'YEAR';
885+
QUARTER: 'QUARTER';
886+
MONTH: 'MONTH';
887+
WEEK: 'WEEK';
888+
DAY: 'DAY';
889+
HOUR: 'HOUR';
890+
MINUTE: 'MINUTE';
891+
SECOND: 'SECOND';
881892

882893
EQ : '=' | '==';
883894
NSEQ: '<=>';

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1206,6 +1206,30 @@ class AstBuilder(conf: SQLConf) extends SqlBaseBaseVisitor[AnyRef] with Logging
12061206
new StringLocate(expression(ctx.substr), expression(ctx.str))
12071207
}
12081208

1209+
/**
1210+
* Create a Extract expression.
1211+
*/
1212+
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))
1230+
}
1231+
}
1232+
12091233
/**
12101234
* Create a (windowed) Function expression.
12111235
*/

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ class TableIdentifierParserSuite extends SparkFunSuite {
5151
"rollup", "row", "rows", "set", "smallint", "table", "timestamp", "to", "trigger",
5252
"true", "truncate", "update", "user", "values", "with", "regexp", "rlike",
5353
"bigint", "binary", "boolean", "current_date", "current_timestamp", "date", "double", "float",
54-
"int", "smallint", "timestamp", "at", "position", "both", "leading", "trailing")
54+
"int", "smallint", "timestamp", "at", "position", "both", "leading", "trailing",
55+
"extract", "year", "quarter", "month", "week", "day", "hour", "minute", "second")
5556

5657
val hiveStrictNonReservedKeyword = Seq("anti", "full", "inner", "left", "semi", "right",
5758
"natural", "union", "intersect", "except", "database", "on", "join", "cross", "select", "from",
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
CREATE TEMPORARY VIEW t AS select '2011-05-06 07:08:09.1234567' as c;
2+
3+
select extract(year from c) from t;
4+
5+
select extract(quarter from c) from t;
6+
7+
select extract(month from c) from t;
8+
9+
select extract(week from c) from t;
10+
11+
select extract(day from c) from t;
12+
13+
select extract(hour from c) from t;
14+
15+
select extract(minute from c) from t;
16+
17+
select extract(second from c) from t;
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
-- Automatically generated by SQLQueryTestSuite
2+
-- Number of queries: 9
3+
4+
5+
-- !query 0
6+
CREATE TEMPORARY VIEW t AS select '2011-05-06 07:08:09.1234567' as c
7+
-- !query 0 schema
8+
struct<>
9+
-- !query 0 output
10+
11+
12+
13+
-- !query 1
14+
select extract(year from c) from t
15+
-- !query 1 schema
16+
struct<year(CAST(c AS DATE)):int>
17+
-- !query 1 output
18+
2011
19+
20+
21+
-- !query 2
22+
select extract(quarter from c) from t
23+
-- !query 2 schema
24+
struct<quarter(CAST(c AS DATE)):int>
25+
-- !query 2 output
26+
2
27+
28+
29+
-- !query 3
30+
select extract(month from c) from t
31+
-- !query 3 schema
32+
struct<month(CAST(c AS DATE)):int>
33+
-- !query 3 output
34+
5
35+
36+
37+
-- !query 4
38+
select extract(week from c) from t
39+
-- !query 4 schema
40+
struct<weekofyear(CAST(c AS DATE)):int>
41+
-- !query 4 output
42+
18
43+
44+
45+
-- !query 5
46+
select extract(day from c) from t
47+
-- !query 5 schema
48+
struct<dayofmonth(CAST(c AS DATE)):int>
49+
-- !query 5 output
50+
6
51+
52+
53+
-- !query 6
54+
select extract(hour from c) from t
55+
-- !query 6 schema
56+
struct<hour(CAST(c AS TIMESTAMP)):int>
57+
-- !query 6 output
58+
7
59+
60+
61+
-- !query 7
62+
select extract(minute from c) from t
63+
-- !query 7 schema
64+
struct<minute(CAST(c AS TIMESTAMP)):int>
65+
-- !query 7 output
66+
8
67+
68+
69+
-- !query 8
70+
select extract(second from c) from t
71+
-- !query 8 schema
72+
struct<second(CAST(c AS TIMESTAMP)):int>
73+
-- !query 8 output
74+
9

0 commit comments

Comments
 (0)