Skip to content

Commit 4099994

Browse files
authored
Add support of parsing query placeholder ? (#95)
1 parent 3ecb2c7 commit 4099994

File tree

9 files changed

+313
-0
lines changed

9 files changed

+313
-0
lines changed

parser/ast.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3481,6 +3481,30 @@ func (s *StringLiteral) Accept(visitor ASTVisitor) error {
34813481
return visitor.VisitStringLiteral(s)
34823482
}
34833483

3484+
type PlaceHolder struct {
3485+
PlaceholderPos Pos
3486+
PlaceHolderEnd Pos
3487+
Type string
3488+
}
3489+
3490+
func (p *PlaceHolder) Pos() Pos {
3491+
return p.PlaceholderPos
3492+
}
3493+
3494+
func (p *PlaceHolder) End() Pos {
3495+
return p.PlaceHolderEnd
3496+
}
3497+
3498+
func (p *PlaceHolder) String(int) string {
3499+
return p.Type
3500+
}
3501+
3502+
func (p *PlaceHolder) Accept(visitor ASTVisitor) error {
3503+
visitor.enter(p)
3504+
defer visitor.leave(p)
3505+
return visitor.VisitPlaceHolderExpr(p)
3506+
}
3507+
34843508
type RatioExpr struct {
34853509
Numerator *NumberLiteral
34863510
// numberLiteral (SLASH numberLiteral)?

parser/ast_visitor.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ type ASTVisitor interface {
143143
VisitSystemDropExpr(expr *SystemDropExpr) error
144144
VisitTruncateTable(expr *TruncateTable) error
145145
VisitSampleRatioExpr(expr *SampleClause) error
146+
VisitPlaceHolderExpr(expr *PlaceHolder) error
146147
VisitDeleteFromExpr(expr *DeleteClause) error
147148
VisitColumnNamesExpr(expr *ColumnNamesExpr) error
148149
VisitValuesExpr(expr *AssignmentValues) error
@@ -1158,6 +1159,13 @@ func (v *DefaultASTVisitor) VisitSampleRatioExpr(expr *SampleClause) error {
11581159
return nil
11591160
}
11601161

1162+
func (v *DefaultASTVisitor) VisitPlaceHolderExpr(expr *PlaceHolder) error {
1163+
if v.Visit != nil {
1164+
return v.Visit(expr)
1165+
}
1166+
return nil
1167+
}
1168+
11611169
func (v *DefaultASTVisitor) VisitDeleteFromExpr(expr *DeleteClause) error {
11621170
if v.Visit != nil {
11631171
return v.Visit(expr)

parser/parser_column.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,14 @@ func (p *Parser) parseColumnExpr(pos Pos) (Expr, error) { //nolint:funlen
380380
return p.parseQueryParam(p.Pos())
381381
}
382382
return p.parseMapLiteral(p.Pos())
383+
case p.matchTokenKind(opTypeQuery):
384+
// Placeholder `?`
385+
_ = p.lexer.consumeToken()
386+
return &PlaceHolder{
387+
PlaceholderPos: pos,
388+
PlaceHolderEnd: pos,
389+
Type: opTypeQuery,
390+
}, nil
383391
default:
384392
return nil, fmt.Errorf("unexpected token kind: %s", p.lastTokenKind())
385393
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
-- Origin SQL:
2+
INSERT INTO t0(user_id, message, timestamp, metric) VALUES
3+
(?, ?, ?, ?),
4+
(?, ?, ?, ?),
5+
(?, ?, ?, ?),
6+
(?, ?, ?, ?)
7+
8+
-- Format SQL:
9+
INSERT INTO TABLE t0
10+
(user_id, message, timestamp, metric)
11+
VALUES
12+
(?, ?, ?, ?),
13+
(?, ?, ?, ?),
14+
(?, ?, ?, ?),
15+
(?, ?, ?, ?);
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
INSERT INTO t0(user_id, message, timestamp, metric) VALUES
2+
(?, ?, ?, ?),
3+
(?, ?, ?, ?),
4+
(?, ?, ?, ?),
5+
(?, ?, ?, ?)
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
[
2+
{
3+
"InsertPos": 0,
4+
"Format": null,
5+
"Table": {
6+
"Database": null,
7+
"Table": {
8+
"Name": "t0",
9+
"QuoteType": 1,
10+
"NamePos": 12,
11+
"NameEnd": 14
12+
}
13+
},
14+
"ColumnNames": {
15+
"LeftParenPos": 14,
16+
"RightParenPos": 50,
17+
"ColumnNames": [
18+
{
19+
"Ident": {
20+
"Name": "user_id",
21+
"QuoteType": 1,
22+
"NamePos": 15,
23+
"NameEnd": 22
24+
},
25+
"DotIdent": null
26+
},
27+
{
28+
"Ident": {
29+
"Name": "message",
30+
"QuoteType": 1,
31+
"NamePos": 24,
32+
"NameEnd": 31
33+
},
34+
"DotIdent": null
35+
},
36+
{
37+
"Ident": {
38+
"Name": "timestamp",
39+
"QuoteType": 1,
40+
"NamePos": 33,
41+
"NameEnd": 42
42+
},
43+
"DotIdent": null
44+
},
45+
{
46+
"Ident": {
47+
"Name": "metric",
48+
"QuoteType": 1,
49+
"NamePos": 44,
50+
"NameEnd": 50
51+
},
52+
"DotIdent": null
53+
}
54+
]
55+
},
56+
"Values": [
57+
{
58+
"LeftParenPos": 63,
59+
"RightParenPos": 74,
60+
"Values": [
61+
{
62+
"PlaceholderPos": 64,
63+
"PlaceHolderEnd": 64,
64+
"Type": "?"
65+
},
66+
{
67+
"PlaceholderPos": 67,
68+
"PlaceHolderEnd": 67,
69+
"Type": "?"
70+
},
71+
{
72+
"PlaceholderPos": 70,
73+
"PlaceHolderEnd": 70,
74+
"Type": "?"
75+
},
76+
{
77+
"PlaceholderPos": 73,
78+
"PlaceHolderEnd": 73,
79+
"Type": "?"
80+
}
81+
]
82+
},
83+
{
84+
"LeftParenPos": 81,
85+
"RightParenPos": 92,
86+
"Values": [
87+
{
88+
"PlaceholderPos": 82,
89+
"PlaceHolderEnd": 82,
90+
"Type": "?"
91+
},
92+
{
93+
"PlaceholderPos": 85,
94+
"PlaceHolderEnd": 85,
95+
"Type": "?"
96+
},
97+
{
98+
"PlaceholderPos": 88,
99+
"PlaceHolderEnd": 88,
100+
"Type": "?"
101+
},
102+
{
103+
"PlaceholderPos": 91,
104+
"PlaceHolderEnd": 91,
105+
"Type": "?"
106+
}
107+
]
108+
},
109+
{
110+
"LeftParenPos": 99,
111+
"RightParenPos": 110,
112+
"Values": [
113+
{
114+
"PlaceholderPos": 100,
115+
"PlaceHolderEnd": 100,
116+
"Type": "?"
117+
},
118+
{
119+
"PlaceholderPos": 103,
120+
"PlaceHolderEnd": 103,
121+
"Type": "?"
122+
},
123+
{
124+
"PlaceholderPos": 106,
125+
"PlaceHolderEnd": 106,
126+
"Type": "?"
127+
},
128+
{
129+
"PlaceholderPos": 109,
130+
"PlaceHolderEnd": 109,
131+
"Type": "?"
132+
}
133+
]
134+
},
135+
{
136+
"LeftParenPos": 117,
137+
"RightParenPos": 128,
138+
"Values": [
139+
{
140+
"PlaceholderPos": 118,
141+
"PlaceHolderEnd": 118,
142+
"Type": "?"
143+
},
144+
{
145+
"PlaceholderPos": 121,
146+
"PlaceHolderEnd": 121,
147+
"Type": "?"
148+
},
149+
{
150+
"PlaceholderPos": 124,
151+
"PlaceHolderEnd": 124,
152+
"Type": "?"
153+
},
154+
{
155+
"PlaceholderPos": 127,
156+
"PlaceHolderEnd": 127,
157+
"Type": "?"
158+
}
159+
]
160+
}
161+
],
162+
"SelectExpr": null
163+
}
164+
]
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
-- Origin SQL:
2+
SELECT * FROM t0 WHERE id = ?;
3+
4+
-- Format SQL:
5+
6+
SELECT
7+
*
8+
FROM
9+
t0
10+
WHERE
11+
id = ?;
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
[
2+
{
3+
"SelectPos": 0,
4+
"StatementEnd": 28,
5+
"With": null,
6+
"Top": null,
7+
"SelectColumns": {
8+
"ListPos": 7,
9+
"ListEnd": 7,
10+
"HasDistinct": false,
11+
"Items": [
12+
{
13+
"Name": "*",
14+
"QuoteType": 0,
15+
"NamePos": 7,
16+
"NameEnd": 7
17+
}
18+
]
19+
},
20+
"From": {
21+
"FromPos": 9,
22+
"Expr": {
23+
"Table": {
24+
"TablePos": 14,
25+
"TableEnd": 16,
26+
"Alias": null,
27+
"Expr": {
28+
"Database": null,
29+
"Table": {
30+
"Name": "t0",
31+
"QuoteType": 1,
32+
"NamePos": 14,
33+
"NameEnd": 16
34+
}
35+
},
36+
"HasFinal": false
37+
},
38+
"StatementEnd": 16,
39+
"SampleRatio": null,
40+
"HasFinal": false
41+
}
42+
},
43+
"ArrayJoin": null,
44+
"Window": null,
45+
"Prewhere": null,
46+
"Where": {
47+
"WherePos": 17,
48+
"Expr": {
49+
"LeftExpr": {
50+
"Name": "id",
51+
"QuoteType": 1,
52+
"NamePos": 23,
53+
"NameEnd": 25
54+
},
55+
"Operation": "=",
56+
"RightExpr": {
57+
"PlaceholderPos": 28,
58+
"PlaceHolderEnd": 28,
59+
"Type": "?"
60+
},
61+
"HasGlobal": false,
62+
"HasNot": false
63+
}
64+
},
65+
"GroupBy": null,
66+
"WithTotal": false,
67+
"Having": null,
68+
"OrderBy": null,
69+
"LimitBy": null,
70+
"Limit": null,
71+
"Settings": null,
72+
"Format": null,
73+
"UnionAll": null,
74+
"UnionDistinct": null,
75+
"Except": null
76+
}
77+
]
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
SELECT * FROM t0 WHERE id = ?;

0 commit comments

Comments
 (0)