[PostgreSQL] Over clause support
This commit is contained in:
@@ -1384,15 +1384,29 @@ frame_clause
|
||||
: (RANGE | ROWS) frame_start
|
||||
| (RANGE | ROWS) BETWEEN frame_start AND frame_end
|
||||
;
|
||||
|
||||
|
||||
window_definition_list
|
||||
: window_definition (COMMA window_definition)*
|
||||
;
|
||||
|
||||
window_definition
|
||||
: window_name
|
||||
| PARTITION BY expr (COMMA expr)*
|
||||
| order_by_clause
|
||||
: window_name AS window_specification
|
||||
;
|
||||
|
||||
window_clause
|
||||
: WINDOW window_name AS OPEN_PAREN window_definition CLOSE_PAREN
|
||||
: WINDOW window_definition_list
|
||||
;
|
||||
|
||||
window_specification
|
||||
: OPEN_PAREN window_name? partition_clause? order_by_clause? frame_clause? CLOSE_PAREN
|
||||
;
|
||||
|
||||
partition_clause
|
||||
: PARTITION BY expr (COMMA expr)*
|
||||
;
|
||||
|
||||
over_clause
|
||||
: OVER (window_specification | window_name)
|
||||
;
|
||||
|
||||
combine_clause
|
||||
@@ -1482,7 +1496,7 @@ expr
|
||||
| expr op=IS (bool_expr | NULL | NOT NULL)
|
||||
| expr IS NOT? DISTINCT FROM expr
|
||||
| op=(NOT | ALL ) expr
|
||||
| func_call
|
||||
| func_call over_clause?
|
||||
| identifier
|
||||
| CAST OPEN_PAREN expr AS data_type CLOSE_PAREN
|
||||
| correlation_name DOT column_name
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2460,6 +2460,18 @@ public class PostgreSqlParserBaseListener implements PostgreSqlParserListener {
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitFrame_clause(PostgreSqlParser.Frame_clauseContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterWindow_definition_list(PostgreSqlParser.Window_definition_listContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitWindow_definition_list(PostgreSqlParser.Window_definition_listContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
@@ -2484,6 +2496,42 @@ public class PostgreSqlParserBaseListener implements PostgreSqlParserListener {
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitWindow_clause(PostgreSqlParser.Window_clauseContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterWindow_specification(PostgreSqlParser.Window_specificationContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitWindow_specification(PostgreSqlParser.Window_specificationContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterPartition_clause(PostgreSqlParser.Partition_clauseContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitPartition_clause(PostgreSqlParser.Partition_clauseContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterOver_clause(PostgreSqlParser.Over_clauseContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitOver_clause(PostgreSqlParser.Over_clauseContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
|
||||
@@ -2047,6 +2047,16 @@ public interface PostgreSqlParserListener extends ParseTreeListener {
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitFrame_clause(PostgreSqlParser.Frame_clauseContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link PostgreSqlParser#window_definition_list}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterWindow_definition_list(PostgreSqlParser.Window_definition_listContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link PostgreSqlParser#window_definition_list}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitWindow_definition_list(PostgreSqlParser.Window_definition_listContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link PostgreSqlParser#window_definition}.
|
||||
* @param ctx the parse tree
|
||||
@@ -2067,6 +2077,36 @@ public interface PostgreSqlParserListener extends ParseTreeListener {
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitWindow_clause(PostgreSqlParser.Window_clauseContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link PostgreSqlParser#window_specification}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterWindow_specification(PostgreSqlParser.Window_specificationContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link PostgreSqlParser#window_specification}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitWindow_specification(PostgreSqlParser.Window_specificationContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link PostgreSqlParser#partition_clause}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterPartition_clause(PostgreSqlParser.Partition_clauseContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link PostgreSqlParser#partition_clause}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitPartition_clause(PostgreSqlParser.Partition_clauseContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link PostgreSqlParser#over_clause}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterOver_clause(PostgreSqlParser.Over_clauseContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link PostgreSqlParser#over_clause}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitOver_clause(PostgreSqlParser.Over_clauseContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link PostgreSqlParser#combine_clause}.
|
||||
* @param ctx the parse tree
|
||||
|
||||
@@ -208,4 +208,81 @@ public class PostgreSqlSemanticTokensTest {
|
||||
assertThat(tokens.get(9)).isEqualTo(new SemanticTokenData(53, 54, "operator", new String[0]));
|
||||
assertThat(tokens.get(10)).isEqualTo(new SemanticTokenData(54, 55, "parameter", new String[0]));
|
||||
}
|
||||
|
||||
@Test
|
||||
void over_clause_1() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT depname, empno, salary, avg(salary) OVER (PARTITION BY depname) FROM empsalary;\n"
|
||||
+ "", 0);
|
||||
assertThat(tokens.size()).isEqualTo(20);
|
||||
}
|
||||
|
||||
@Test
|
||||
void over_clause_2() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("""
|
||||
SELECT depname, empno, salary,
|
||||
rank() OVER (PARTITION BY depname ORDER BY salary DESC)
|
||||
FROM empsalary;
|
||||
""", 0);
|
||||
assertThat(tokens.size()).isEqualTo(23);
|
||||
}
|
||||
|
||||
@Test
|
||||
void over_clause_3() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT salary, sum(salary) OVER () FROM empsalary;"
|
||||
+ "", 0);
|
||||
assertThat(tokens.size()).isEqualTo(13);
|
||||
}
|
||||
|
||||
@Test
|
||||
void over_clause_4() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("SELECT salary, sum(salary) OVER (ORDER BY salary) FROM empsalary;"
|
||||
+ "", 0);
|
||||
assertThat(tokens.size()).isEqualTo(16);
|
||||
}
|
||||
|
||||
@Test
|
||||
void over_clause_5() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("""
|
||||
SELECT depname, empno, salary, enroll_date
|
||||
FROM
|
||||
(SELECT depname, empno, salary, enroll_date,
|
||||
rank() OVER (PARTITION BY depname ORDER BY salary DESC, empno) AS pos
|
||||
FROM empsalary
|
||||
) AS ss
|
||||
WHERE pos < 3;
|
||||
""", 0);
|
||||
assertThat(tokens.size()).isEqualTo(46);
|
||||
}
|
||||
|
||||
@Test
|
||||
void over_clause_6() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("""
|
||||
SELECT sum(salary) OVER w, avg(salary) OVER w
|
||||
FROM empsalary
|
||||
WINDOW w AS (PARTITION BY depname ORDER BY salary DESC);
|
||||
""", 0);
|
||||
assertThat(tokens.size()).isEqualTo(29);
|
||||
}
|
||||
|
||||
@Test
|
||||
void over_clause_7() {
|
||||
List<SemanticTokenData> tokens = provider.computeTokens("""
|
||||
WITH cte AS (
|
||||
SELECT
|
||||
q.*,
|
||||
ROW_NUMBER() OVER (PARTITION BY q.database_id ORDER BY q.order_id) AS rn
|
||||
FROM
|
||||
SAMPLE_TABLE AS q
|
||||
WHERE
|
||||
q.status IN (0, 1, 5, 10)
|
||||
)
|
||||
SELECT *
|
||||
FROM cte
|
||||
WHERE
|
||||
(rn = 1 OR status = 10)
|
||||
AND (scenario = 11 OR scenario = 8)
|
||||
ORDER BY status DESC
|
||||
""", 0);
|
||||
assertThat(tokens.size()).isEqualTo(74);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user