Skip to content

Commit 5c4ca69

Browse files
authored
Fix wrongly format the ON CLUSTER and LIMIT OFFSET clause (#76)
1 parent 16c376a commit 5c4ca69

File tree

10 files changed

+54
-27
lines changed

10 files changed

+54
-27
lines changed

parser/ast.go

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1761,7 +1761,7 @@ func (r *RoleName) String(level int) string {
17611761
builder.WriteString(r.Scope.String(level))
17621762
}
17631763
if r.OnCluster != nil {
1764-
builder.WriteString(" ON ")
1764+
builder.WriteByte(' ')
17651765
builder.WriteString(r.OnCluster.String(level))
17661766
}
17671767
return builder.String()
@@ -1851,7 +1851,9 @@ func (r *RoleSetting) String(level int) string {
18511851
builder.WriteString(settingPair.String(level))
18521852
}
18531853
if r.Modifier != nil {
1854-
builder.WriteString(" ")
1854+
if len(r.SettingPairs) > 0 {
1855+
builder.WriteString(" ")
1856+
}
18551857
builder.WriteString(r.Modifier.String(level))
18561858
}
18571859
return builder.String()
@@ -4490,12 +4492,8 @@ func (g *GroupByClause) String(level int) string {
44904492
builder.WriteString("GROUP BY ")
44914493
if g.AggregateType != "" {
44924494
builder.WriteString(g.AggregateType)
4493-
builder.WriteByte('(')
44944495
}
44954496
builder.WriteString(g.Expr.String(level))
4496-
if g.AggregateType != "" {
4497-
builder.WriteByte(')')
4498-
}
44994497
if g.WithCube {
45004498
builder.WriteString(" WITH CUBE")
45014499
}
@@ -4606,10 +4604,7 @@ func (l *LimitByClause) End() Pos {
46064604

46074605
func (l *LimitByClause) String(level int) string {
46084606
var builder strings.Builder
4609-
builder.WriteString("LIMIT ")
4610-
builder.WriteString(l.Limit.String(level))
46114607
if l.Limit != nil {
4612-
builder.WriteString(" OFFSET ")
46134608
builder.WriteString(l.Limit.String(level))
46144609
}
46154610
if l.ByExpr != nil {

parser/parser_table.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1095,10 +1095,11 @@ func (p *Parser) parseColumnNamesExpr(pos Pos) (*ColumnNamesExpr, error) {
10951095
if err != nil {
10961096
return nil, err
10971097
}
1098+
1099+
columnNames = append(columnNames, *name)
10981100
if p.tryConsumeTokenKind(",") == nil {
10991101
break
11001102
}
1101-
columnNames = append(columnNames, *name)
11021103
}
11031104
rightParenPos := p.Pos()
11041105
if _, err := p.consumeTokenKind(")"); err != nil {

parser/parser_test.go

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,15 @@ func TestParser_Format(t *testing.T) {
9595
builder.WriteString("-- Origin SQL:\n")
9696
builder.Write(fileBytes)
9797
builder.WriteString("\n\n-- Format SQL:\n")
98+
var formatSQLBuilder strings.Builder
9899
for _, stmt := range stmts {
99-
builder.WriteString(stmt.String(0))
100-
builder.WriteByte(';')
101-
builder.WriteByte('\n')
100+
formatSQLBuilder.WriteString(stmt.String(0))
101+
formatSQLBuilder.WriteByte(';')
102+
formatSQLBuilder.WriteByte('\n')
102103
}
104+
formatSQL := formatSQLBuilder.String()
105+
builder.WriteString(formatSQL)
106+
validFormatSQL(t, formatSQL)
103107
g := goldie.New(t,
104108
goldie.WithNameSuffix(""),
105109
goldie.WithDiffEngine(goldie.ColoredDiff),
@@ -109,3 +113,17 @@ func TestParser_Format(t *testing.T) {
109113
}
110114
}
111115
}
116+
117+
// validFormatSQL Verify that the format sql can be re-parsed with consistent results
118+
func validFormatSQL(t *testing.T, sql string) {
119+
parser := NewParser(sql)
120+
stmts, err := parser.ParseStmts()
121+
require.NoError(t, err)
122+
var builder strings.Builder
123+
for _, stmt := range stmts {
124+
builder.WriteString(stmt.String(0))
125+
builder.WriteByte(';')
126+
builder.WriteByte('\n')
127+
}
128+
require.Equal(t, sql, builder.String())
129+
}

parser/testdata/ddl/format/alter_role.sql

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ ALTER ROLE r2_01293@'%.myhost.com';
2424

2525
-- Format SQL:
2626
ALTER ROLE r1_01293;
27-
ALTER ROLE r1_01293 ON ON CLUSTER cluster_1 RENAME TO r2_01293;
27+
ALTER ROLE r1_01293 ON CLUSTER cluster_1 RENAME TO r2_01293;
2828
ALTER ROLE r1_01293 RENAME TO r2_01293, r3_01293 RENAME TO r4_01293;
29-
ALTER ROLE r1_01293 SETTINGS NONE;
29+
ALTER ROLE r1_01293 SETTINGS NONE;
3030
ALTER ROLE r2_01293 SETTINGS PROFILE 'default';
3131
ALTER ROLE r3_01293 SETTINGS max_memory_usage 5000000;
3232
ALTER ROLE r4_01293 SETTINGS max_memory_usage MIN 5000000;
@@ -40,6 +40,6 @@ ALTER ROLE r1_01293 SETTINGS readonly 1;
4040
ALTER ROLE r2_01293 SETTINGS PROFILE 'default';
4141
ALTER ROLE r3_01293 SETTINGS max_memory_usage 5000000 MIN 4000000 MAX 6000000 WRITABLE;
4242
ALTER ROLE r4_01293 SETTINGS PROFILE 'default', max_memory_usage 5000000, readonly 1;
43-
ALTER ROLE r5_01293 SETTINGS NONE;
43+
ALTER ROLE r5_01293 SETTINGS NONE;
4444
ALTER ROLE r1_01293@'%';
4545
ALTER ROLE r2_01293@'%.myhost.com';

parser/testdata/ddl/format/create_role.sql

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ CREATE ROLE r2_01293@'%.myhost.com';
2626

2727
-- Format SQL:
2828
CREATE ROLE r1_01293;
29-
CREATE ROLE r1_01293 ON ON CLUSTER cluster_1;
29+
CREATE ROLE r1_01293 ON CLUSTER cluster_1;
3030
CREATE ROLE r1_01293, r2_01293;
31-
CREATE ROLE r1_01293 ON ON CLUSTER cluster_1, r2_01293;
32-
CREATE ROLE r1_01293 ON ON CLUSTER cluster_1, r2_01293 ON ON CLUSTER cluster_2;
33-
CREATE ROLE r1_01293 SETTINGS NONE;
31+
CREATE ROLE r1_01293 ON CLUSTER cluster_1, r2_01293;
32+
CREATE ROLE r1_01293 ON CLUSTER cluster_1, r2_01293 ON CLUSTER cluster_2;
33+
CREATE ROLE r1_01293 SETTINGS NONE;
3434
CREATE ROLE r2_01293 SETTINGS PROFILE 'default';
3535
CREATE ROLE r3_01293 SETTINGS max_memory_usage 5000000;
3636
CREATE ROLE r4_01293 SETTINGS max_memory_usage MIN 5000000;
@@ -44,6 +44,6 @@ CREATE ROLE r1_01293 SETTINGS readonly 1;
4444
CREATE ROLE r2_01293 SETTINGS PROFILE 'default';
4545
CREATE ROLE r3_01293 SETTINGS max_memory_usage 5000000 MIN 4000000 MAX 6000000 WRITABLE;
4646
CREATE ROLE r4_01293 SETTINGS PROFILE 'default', max_memory_usage 5000000, readonly 1;
47-
CREATE ROLE r5_01293 SETTINGS NONE;
47+
CREATE ROLE r5_01293 SETTINGS NONE;
4848
CREATE ROLE r1_01293@'%';
4949
CREATE ROLE r2_01293@'%.myhost.com';

parser/testdata/dml/format/insert_values.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ INSERT INTO helloworld.my_first_table (user_id, message, timestamp, metric) VALU
77

88
-- Format SQL:
99
INSERT INTO TABLE helloworld.my_first_table
10-
(user_id, message, timestamp)
10+
(user_id, message, timestamp, metric)
1111
VALUES
1212
(101, 'Hello, ClickHouse!', now(), -1.0),
1313
(102, 'Insert a lot of rows per batch', yesterday(), 1.41421),

parser/testdata/dml/output/insert_values.sql.golden.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,15 @@
4646
"NameEnd": 66
4747
},
4848
"DotIdent": null
49+
},
50+
{
51+
"Ident": {
52+
"Name": "metric",
53+
"QuoteType": 1,
54+
"NamePos": 68,
55+
"NameEnd": 74
56+
},
57+
"DotIdent": null
4958
}
5059
]
5160
},

parser/testdata/query/format/select_simple.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,4 @@ FROM
2424
WHERE
2525
(f0 IN ('foo', 'bar', 'test')) AND (f1 = 'testing') AND (f2 NOT LIKE 'testing2') AND f3 NOT IN ('a', 'b', 'c')
2626
GROUP BY f0, f1
27-
LIMIT LIMIT 10 OFFSET 100 OFFSET LIMIT 10 OFFSET 100 BY f0;
27+
LIMIT 10 OFFSET 100 BY f0;

parser/testdata/query/format/select_simple_with_group_by_with_cube_totals.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ SELECT
88
COUNT(b)
99
FROM
1010
group_by_all
11-
GROUP BY CUBE((a)) WITH CUBE WITH TOTALS
11+
GROUP BY CUBE(a) WITH CUBE WITH TOTALS
1212
ORDER BY a;

parser/visitor_test.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,18 @@ func TestVisitor_Identical(t *testing.T) {
3535
builder.WriteString("-- Origin SQL:\n")
3636
builder.Write(fileBytes)
3737
builder.WriteString("\n\n-- Format SQL:\n")
38+
var formatSQLBuilder strings.Builder
3839
for _, stmt := range stmts {
3940
err := stmt.Accept(&visitor)
4041
require.NoError(t, err)
4142

42-
builder.WriteString(stmt.String(0))
43-
builder.WriteByte(';')
44-
builder.WriteByte('\n')
43+
formatSQLBuilder.WriteString(stmt.String(0))
44+
formatSQLBuilder.WriteByte(';')
45+
formatSQLBuilder.WriteByte('\n')
4546
}
47+
formatSQL := formatSQLBuilder.String()
48+
builder.WriteString(formatSQL)
49+
validFormatSQL(t, formatSQL)
4650
g := goldie.New(t,
4751
goldie.WithNameSuffix(""),
4852
goldie.WithDiffEngine(goldie.ColoredDiff),

0 commit comments

Comments
 (0)