Skip to content

Commit 3d0a969

Browse files
authored
Add support for window names in WindowExpr (#259)
1 parent 4a3c96e commit 3d0a969

23 files changed

Lines changed: 781 additions & 0 deletions

parser/ast.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4810,6 +4810,7 @@ func (l *LimitByClause) Accept(visitor ASTVisitor) error {
48104810
type WindowExpr struct {
48114811
LeftParenPos Pos
48124812
RightParenPos Pos
4813+
WindowName *Ident
48134814
PartitionBy *PartitionByClause
48144815
OrderBy *OrderByClause
48154816
Frame *WindowFrameClause
@@ -4826,6 +4827,11 @@ func (w *WindowExpr) End() Pos {
48264827
func (w *WindowExpr) Accept(visitor ASTVisitor) error {
48274828
visitor.Enter(w)
48284829
defer visitor.Leave(w)
4830+
if w.WindowName != nil {
4831+
if err := w.WindowName.Accept(visitor); err != nil {
4832+
return err
4833+
}
4834+
}
48294835
if w.PartitionBy != nil {
48304836
if err := w.PartitionBy.Accept(visitor); err != nil {
48314837
return err

parser/format.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2755,7 +2755,14 @@ func (w *WindowClause) FormatSQL(formatter *Formatter) {
27552755
func (w *WindowExpr) FormatSQL(formatter *Formatter) {
27562756
formatter.WriteByte('(')
27572757
hasPart := false
2758+
if w.WindowName != nil {
2759+
formatter.WriteExpr(w.WindowName)
2760+
hasPart = true
2761+
}
27582762
if w.PartitionBy != nil {
2763+
if hasPart {
2764+
formatter.WriteByte(whitespace)
2765+
}
27592766
formatter.WriteExpr(w.PartitionBy)
27602767
hasPart = true
27612768
}

parser/parser_query.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,14 @@ func (p *Parser) parseWindowCondition(pos Pos) (*WindowExpr, error) {
824824
if err := p.expectTokenKind(TokenKindLParen); err != nil {
825825
return nil, err
826826
}
827+
var windowName *Ident
828+
if p.canParseWindowNameInParens() {
829+
var err error
830+
windowName, err = p.parseIdent()
831+
if err != nil {
832+
return nil, err
833+
}
834+
}
827835
partitionBy, err := p.tryParsePartitionByClause(pos)
828836
if err != nil {
829837
return nil, err
@@ -843,12 +851,41 @@ func (p *Parser) parseWindowCondition(pos Pos) (*WindowExpr, error) {
843851
return &WindowExpr{
844852
LeftParenPos: pos,
845853
RightParenPos: rightParenPos,
854+
WindowName: windowName,
846855
PartitionBy: partitionBy,
847856
OrderBy: orderBy,
848857
Frame: frame,
849858
}, nil
850859
}
851860

861+
func (p *Parser) canParseWindowNameInParens() bool {
862+
if !p.matchTokenKind(TokenKindIdent) {
863+
return false
864+
}
865+
if !p.matchTokenKind(TokenKindKeyword) {
866+
return true
867+
}
868+
869+
savedState := p.lexer.saveState()
870+
defer p.lexer.restoreState(savedState)
871+
872+
switch {
873+
case p.matchKeyword(KeywordPartition), p.matchKeyword(KeywordOrder):
874+
_ = p.lexer.consumeToken()
875+
return !p.matchKeyword(KeywordBy)
876+
case p.matchKeyword(KeywordRows), p.matchKeyword(KeywordRange):
877+
_ = p.lexer.consumeToken()
878+
return !p.matchKeyword(KeywordBetween) &&
879+
!p.matchKeyword(KeywordCurrent) &&
880+
!p.matchKeyword(KeywordUnbounded) &&
881+
!p.matchTokenKind(TokenKindInt) &&
882+
!p.matchTokenKind(TokenKindLBrace) &&
883+
!p.matchKeyword(KeywordInterval)
884+
default:
885+
return true
886+
}
887+
}
888+
852889
func (p *Parser) parseWindowClause(pos Pos) (*WindowClause, error) {
853890
if err := p.expectKeyword(KeywordWindow); err != nil {
854891
return nil, err

parser/testdata/ddl/output/create_materialized_view_with_empty_table_schema.sql.golden.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@
307307
"OverExpr": {
308308
"LeftParenPos": 306,
309309
"RightParenPos": 347,
310+
"WindowName": null,
310311
"PartitionBy": {
311312
"PartitionPos": 306,
312313
"Expr": {
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
-- Origin SQL:
2+
SELECT sum(x) OVER (order) AS sum_over_order
3+
FROM t
4+
WINDOW order AS (PARTITION BY team ORDER BY ts);
5+
6+
7+
-- Beautify SQL:
8+
SELECT
9+
sum(x) OVER (order) AS sum_over_order
10+
FROM
11+
t
12+
WINDOW order AS (PARTITION BY team ORDER BY
13+
ts);
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
-- Origin SQL:
2+
SELECT sum(x) OVER (w) AS sum_over_w
3+
FROM t
4+
WINDOW w AS (PARTITION BY y ORDER BY x);
5+
6+
7+
-- Beautify SQL:
8+
SELECT
9+
sum(x) OVER (w) AS sum_over_w
10+
FROM
11+
t
12+
WINDOW w AS (PARTITION BY y ORDER BY
13+
x);
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
-- Origin SQL:
2+
SELECT sum(x) OVER (w1 ORDER BY ts ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS rolling_sum,
3+
avg(x) OVER (w2) AS avg_over_w2
4+
FROM t
5+
WINDOW w1 AS (PARTITION BY team),
6+
w2 AS (w1 ORDER BY ts ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW);
7+
8+
9+
-- Beautify SQL:
10+
SELECT
11+
sum(x) OVER (w1 ORDER BY
12+
ts ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS rolling_sum,
13+
avg(x) OVER (w2) AS avg_over_w2
14+
FROM
15+
t
16+
WINDOW w1 AS (PARTITION BY team), w2 AS (w1 ORDER BY
17+
ts ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW);
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
-- Origin SQL:
2+
SELECT sum(x) OVER (order) AS sum_over_order
3+
FROM t
4+
WINDOW order AS (PARTITION BY team ORDER BY ts);
5+
6+
7+
-- Format SQL:
8+
SELECT sum(x) OVER (order) AS sum_over_order FROM t WINDOW order AS (PARTITION BY team ORDER BY ts);
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
-- Origin SQL:
2+
SELECT sum(x) OVER (w) AS sum_over_w
3+
FROM t
4+
WINDOW w AS (PARTITION BY y ORDER BY x);
5+
6+
7+
-- Format SQL:
8+
SELECT sum(x) OVER (w) AS sum_over_w FROM t WINDOW w AS (PARTITION BY y ORDER BY x);
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
-- Origin SQL:
2+
SELECT sum(x) OVER (w1 ORDER BY ts ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS rolling_sum,
3+
avg(x) OVER (w2) AS avg_over_w2
4+
FROM t
5+
WINDOW w1 AS (PARTITION BY team),
6+
w2 AS (w1 ORDER BY ts ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW);
7+
8+
9+
-- Format SQL:
10+
SELECT sum(x) OVER (w1 ORDER BY ts ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS rolling_sum, avg(x) OVER (w2) AS avg_over_w2 FROM t WINDOW w1 AS (PARTITION BY team), w2 AS (w1 ORDER BY ts ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW);

0 commit comments

Comments
 (0)