Skip to content

Commit 5b640ce

Browse files
authored
Fix should allow using the keyword as column name (#148)
1 parent b28003d commit 5b640ce

File tree

4 files changed

+261
-0
lines changed

4 files changed

+261
-0
lines changed

parser/parser_column.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,23 @@ func (p *Parser) peekTokenKind(kind TokenKind) bool {
333333
return token.Kind == kind
334334
}
335335

336+
func (p *Parser) peekKeyword(keyword string) bool {
337+
if p.lexer.isEOF() {
338+
return false
339+
}
340+
token, err := p.lexer.peekToken()
341+
if err != nil || token == nil {
342+
return false
343+
}
344+
return token.Kind == TokenKindKeyword && strings.EqualFold(token.String, keyword)
345+
}
346+
336347
func (p *Parser) parseColumnExpr(pos Pos) (Expr, error) { //nolint:funlen
348+
// Should parse the keyword as an identifier if the keyword is followed by one of comma, `AS`.
349+
// For example: `SELECT 1 as interval GROUP BY interval` is a valid syntax in ClickHouse.
350+
if p.matchTokenKind(TokenKindKeyword) && (p.peekTokenKind(TokenKindComma) || p.peekKeyword(KeywordAs)) {
351+
return p.parseIdent()
352+
}
337353
switch {
338354
case p.matchKeyword(KeywordInterval):
339355
return p.parseColumnExprInterval(pos)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
-- Origin SQL:
2+
SELECT
3+
toStartOfInterval(timestamp, toIntervalMinute(1)) AS interval,
4+
column_name
5+
FROM table
6+
WHERE true
7+
GROUP BY (interval, column_name)
8+
ORDER BY (interval AS i, column_name) ASC
9+
10+
-- Format SQL:
11+
SELECT toStartOfInterval(timestamp, toIntervalMinute(1)) AS interval, column_name FROM table WHERE true GROUP BY (interval, column_name) ORDER BY (interval AS i, column_name) ASC;
Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
[
2+
{
3+
"SelectPos": 0,
4+
"StatementEnd": 181,
5+
"With": null,
6+
"Top": null,
7+
"SelectItems": [
8+
{
9+
"Expr": {
10+
"Name": {
11+
"Name": "toStartOfInterval",
12+
"QuoteType": 1,
13+
"NamePos": 11,
14+
"NameEnd": 28
15+
},
16+
"Params": {
17+
"LeftParenPos": 28,
18+
"RightParenPos": 59,
19+
"Items": {
20+
"ListPos": 29,
21+
"ListEnd": 58,
22+
"HasDistinct": false,
23+
"Items": [
24+
{
25+
"Expr": {
26+
"Name": "timestamp",
27+
"QuoteType": 1,
28+
"NamePos": 29,
29+
"NameEnd": 38
30+
},
31+
"Alias": null
32+
},
33+
{
34+
"Expr": {
35+
"Name": {
36+
"Name": "toIntervalMinute",
37+
"QuoteType": 1,
38+
"NamePos": 40,
39+
"NameEnd": 56
40+
},
41+
"Params": {
42+
"LeftParenPos": 56,
43+
"RightParenPos": 58,
44+
"Items": {
45+
"ListPos": 57,
46+
"ListEnd": 58,
47+
"HasDistinct": false,
48+
"Items": [
49+
{
50+
"Expr": {
51+
"NumPos": 57,
52+
"NumEnd": 58,
53+
"Literal": "1",
54+
"Base": 10
55+
},
56+
"Alias": null
57+
}
58+
]
59+
},
60+
"ColumnArgList": null
61+
}
62+
},
63+
"Alias": null
64+
}
65+
]
66+
},
67+
"ColumnArgList": null
68+
}
69+
},
70+
"Modifiers": [],
71+
"Alias": {
72+
"Name": "interval",
73+
"QuoteType": 1,
74+
"NamePos": 64,
75+
"NameEnd": 72
76+
}
77+
},
78+
{
79+
"Expr": {
80+
"Name": "column_name",
81+
"QuoteType": 1,
82+
"NamePos": 78,
83+
"NameEnd": 89
84+
},
85+
"Modifiers": [],
86+
"Alias": null
87+
}
88+
],
89+
"From": {
90+
"FromPos": 90,
91+
"Expr": {
92+
"Table": {
93+
"TablePos": 95,
94+
"TableEnd": 100,
95+
"Alias": null,
96+
"Expr": {
97+
"Database": null,
98+
"Table": {
99+
"Name": "table",
100+
"QuoteType": 1,
101+
"NamePos": 95,
102+
"NameEnd": 100
103+
}
104+
},
105+
"HasFinal": false
106+
},
107+
"StatementEnd": 100,
108+
"SampleRatio": null,
109+
"HasFinal": false
110+
}
111+
},
112+
"ArrayJoin": null,
113+
"Window": null,
114+
"Prewhere": null,
115+
"Where": {
116+
"WherePos": 101,
117+
"Expr": {
118+
"Name": "true",
119+
"QuoteType": 1,
120+
"NamePos": 107,
121+
"NameEnd": 111
122+
}
123+
},
124+
"GroupBy": {
125+
"GroupByPos": 112,
126+
"AggregateType": "",
127+
"Expr": {
128+
"ListPos": 121,
129+
"ListEnd": 143,
130+
"HasDistinct": false,
131+
"Items": [
132+
{
133+
"Expr": {
134+
"LeftParenPos": 121,
135+
"RightParenPos": 143,
136+
"Items": {
137+
"ListPos": 122,
138+
"ListEnd": 143,
139+
"HasDistinct": false,
140+
"Items": [
141+
{
142+
"Expr": {
143+
"Name": "interval",
144+
"QuoteType": 1,
145+
"NamePos": 122,
146+
"NameEnd": 130
147+
},
148+
"Alias": null
149+
},
150+
{
151+
"Expr": {
152+
"Name": "column_name",
153+
"QuoteType": 1,
154+
"NamePos": 132,
155+
"NameEnd": 143
156+
},
157+
"Alias": null
158+
}
159+
]
160+
},
161+
"ColumnArgList": null
162+
},
163+
"Alias": null
164+
}
165+
]
166+
},
167+
"WithCube": false,
168+
"WithRollup": false,
169+
"WithTotals": false
170+
},
171+
"WithTotal": false,
172+
"Having": null,
173+
"OrderBy": {
174+
"OrderPos": 145,
175+
"ListEnd": 181,
176+
"Items": [
177+
{
178+
"OrderPos": 145,
179+
"Expr": {
180+
"LeftParenPos": 154,
181+
"RightParenPos": 181,
182+
"Items": {
183+
"ListPos": 155,
184+
"ListEnd": 181,
185+
"HasDistinct": false,
186+
"Items": [
187+
{
188+
"Expr": {
189+
"Name": "interval",
190+
"QuoteType": 1,
191+
"NamePos": 155,
192+
"NameEnd": 163
193+
},
194+
"Alias": {
195+
"Name": "i",
196+
"QuoteType": 1,
197+
"NamePos": 167,
198+
"NameEnd": 168
199+
}
200+
},
201+
{
202+
"Expr": {
203+
"Name": "column_name",
204+
"QuoteType": 1,
205+
"NamePos": 170,
206+
"NameEnd": 181
207+
},
208+
"Alias": null
209+
}
210+
]
211+
},
212+
"ColumnArgList": null
213+
},
214+
"Alias": null,
215+
"Direction": "ASC"
216+
}
217+
]
218+
},
219+
"LimitBy": null,
220+
"Limit": null,
221+
"Settings": null,
222+
"Format": null,
223+
"UnionAll": null,
224+
"UnionDistinct": null,
225+
"Except": null
226+
}
227+
]
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
SELECT
2+
toStartOfInterval(timestamp, toIntervalMinute(1)) AS interval,
3+
column_name
4+
FROM table
5+
WHERE true
6+
GROUP BY (interval, column_name)
7+
ORDER BY (interval AS i, column_name) ASC

0 commit comments

Comments
 (0)