Skip to content

Commit c118305

Browse files
committed
initial commit
1 parent a5a7588 commit c118305

15 files changed

Lines changed: 981 additions & 6 deletions

File tree

common/utils/src/main/resources/error/error-conditions.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5714,6 +5714,18 @@
57145714
],
57155715
"sqlState" : "38000"
57165716
},
5717+
"QUALIFY_AGGREGATE_NOT_ALLOWED" : {
5718+
"message" : [
5719+
"Aggregate functions are not supported in QUALIFY: <aggregateExpr>."
5720+
],
5721+
"sqlState" : "42903"
5722+
},
5723+
"QUALIFY_REQUIRES_WINDOW_FUNCTION" : {
5724+
"message" : [
5725+
"The QUALIFY clause requires at least one window function in the current SELECT list or the QUALIFY condition."
5726+
],
5727+
"sqlState" : "42903"
5728+
},
57175729
"RECURSION_LEVEL_LIMIT_EXCEEDED" : {
57185730
"message" : [
57195731
"Recursion level limit <levelLimit> reached but query has not exhausted, try increasing it like 'WITH RECURSIVE t(col) MAX RECURSION LEVEL 200'."
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
---
2+
layout: global
3+
title: QUALIFY Clause
4+
displayTitle: QUALIFY Clause
5+
license: |
6+
Licensed to the Apache Software Foundation (ASF) under one or more
7+
contributor license agreements. See the NOTICE file distributed with
8+
this work for additional information regarding copyright ownership.
9+
The ASF licenses this file to You under the Apache License, Version 2.0
10+
(the "License"); you may not use this file except in compliance with
11+
the License. You may obtain a copy of the License at
12+
13+
http://www.apache.org/licenses/LICENSE-2.0
14+
15+
Unless required by applicable law or agreed to in writing, software
16+
distributed under the License is distributed on an "AS IS" BASIS,
17+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18+
See the License for the specific language governing permissions and
19+
limitations under the License.
20+
---
21+
22+
### Description
23+
24+
The `QUALIFY` clause filters rows after window functions have been evaluated.
25+
It can refer to window functions in the `SELECT` list by alias, or define window
26+
functions directly in the `QUALIFY` condition.
27+
28+
### Syntax
29+
30+
```sql
31+
QUALIFY boolean_expression
32+
```
33+
34+
### Parameters
35+
36+
* **boolean_expression**
37+
38+
Specifies any expression that evaluates to a result type `boolean`. Two or
39+
more expressions may be combined together using the logical
40+
operators ( `AND`, `OR` ).
41+
42+
**Note**
43+
44+
The current query's `SELECT` list or the `QUALIFY` condition must contain at least
45+
one window function. Aggregate functions are not allowed in the `QUALIFY` condition.
46+
47+
### Examples
48+
49+
```sql
50+
CREATE TABLE dealer (id INT, city STRING, car_model STRING, quantity INT);
51+
INSERT INTO dealer VALUES
52+
(100, 'Fremont', 'Honda Civic', 10),
53+
(100, 'Fremont', 'Honda Accord', 15),
54+
(100, 'Fremont', 'Honda CRV', 7),
55+
(200, 'Dublin', 'Honda Civic', 20),
56+
(200, 'Dublin', 'Honda Accord', 10),
57+
(200, 'Dublin', 'Honda CRV', 3),
58+
(300, 'San Jose', 'Honda Civic', 5),
59+
(300, 'San Jose', 'Honda Accord', 8);
60+
61+
-- `QUALIFY` clause referring to a window function in the `SELECT` list by alias.
62+
SELECT city, car_model, RANK() OVER (PARTITION BY car_model ORDER BY quantity) AS rank
63+
FROM dealer
64+
QUALIFY rank = 1;
65+
+--------+------------+----+
66+
| city| car_model|rank|
67+
+--------+------------+----+
68+
|San Jose|Honda Accord| 1|
69+
| Dublin| Honda CRV| 1|
70+
|San Jose| Honda Civic| 1|
71+
+--------+------------+----+
72+
73+
-- `QUALIFY` clause with a window function directly in the predicate.
74+
SELECT city, car_model
75+
FROM dealer
76+
QUALIFY RANK() OVER (PARTITION BY car_model ORDER BY quantity) = 1;
77+
+--------+------------+
78+
| city| car_model|
79+
+--------+------------+
80+
|San Jose|Honda Accord|
81+
| Dublin| Honda CRV|
82+
|San Jose| Honda Civic|
83+
+--------+------------+
84+
```
85+
86+
### Related Statements
87+
88+
* [SELECT Main](sql-ref-syntax-qry-select.html)
89+
* [WHERE Clause](sql-ref-syntax-qry-select-where.html)
90+
* [GROUP BY Clause](sql-ref-syntax-qry-select-groupby.html)
91+
* [HAVING Clause](sql-ref-syntax-qry-select-having.html)
92+
* [WINDOW Clause](sql-ref-syntax-qry-select-window.html)
93+
* [ORDER BY Clause](sql-ref-syntax-qry-select-orderby.html)
94+
* [SORT BY Clause](sql-ref-syntax-qry-select-sortby.html)
95+
* [CLUSTER BY Clause](sql-ref-syntax-qry-select-clusterby.html)
96+
* [DISTRIBUTE BY Clause](sql-ref-syntax-qry-select-distribute-by.html)
97+
* [LIMIT Clause](sql-ref-syntax-qry-select-limit.html)
98+
* [OFFSET Clause](sql-ref-syntax-qry-select-offset.html)

docs/sql-ref-syntax-qry-select.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ SELECT [ hints , ... ] [ ALL | DISTINCT ] { [ [ named_expression | regex_column_
4949
[ WHERE boolean_expression ]
5050
[ GROUP BY expression [ , ... ] ]
5151
[ HAVING boolean_expression ]
52+
[ WINDOW clause ]
53+
[ QUALIFY boolean_expression ]
5254
```
5355

5456
### Parameters
@@ -122,6 +124,12 @@ SELECT [ hints , ... ] [ ALL | DISTINCT ] { [ [ named_expression | regex_column_
122124
filter rows after the grouping is performed. If HAVING is specified without GROUP BY, it indicates a GROUP BY
123125
without grouping expressions (global aggregate).
124126

127+
* **QUALIFY**
128+
129+
Filters rows after window functions have been evaluated. The current `SELECT` list or the
130+
`QUALIFY` condition must contain at least one window function, and aggregate functions are
131+
not allowed inside the `QUALIFY` condition.
132+
125133
* **ORDER BY**
126134

127135
Specifies an ordering of the rows of the complete result set of the query. The output rows are ordered

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,7 @@ PROCEDURE: 'PROCEDURE';
399399
PROCEDURES: 'PROCEDURES';
400400
PROPERTIES: 'PROPERTIES';
401401
PURGE: 'PURGE';
402+
QUALIFY: 'QUALIFY';
402403
QUARTER: 'QUARTER';
403404
QUERY: 'QUERY';
404405
RANGE: 'RANGE';

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -795,6 +795,7 @@ fromStatementBody
795795
aggregationClause?
796796
havingClause?
797797
windowClause?
798+
qualifyClause?
798799
queryOrganization
799800
;
800801

@@ -812,7 +813,8 @@ querySpecification
812813
whereClause?
813814
aggregationClause?
814815
havingClause?
815-
windowClause? #regularQuerySpecification
816+
windowClause?
817+
qualifyClause? #regularQuerySpecification
816818
;
817819

818820
transformClause
@@ -883,6 +885,10 @@ havingClause
883885
: HAVING booleanExpression
884886
;
885887

888+
qualifyClause
889+
: QUALIFY booleanExpression
890+
;
891+
886892
hint
887893
: HENT_START hintStatements+=hintStatement (COMMA? hintStatements+=hintStatement)* HENT_END
888894
;
@@ -2118,6 +2124,7 @@ ansiNonReserved
21182124
| PROCEDURES
21192125
| PROPERTIES
21202126
| PURGE
2127+
| QUALIFY
21212128
| QUARTER
21222129
| QUERY
21232130
| RANGE
@@ -2530,6 +2537,7 @@ nonReserved
25302537
| PROCEDURES
25312538
| PROPERTIES
25322539
| PURGE
2540+
| QUALIFY
25332541
| QUARTER
25342542
| QUERY
25352543
| RANGE

0 commit comments

Comments
 (0)