Skip to content

Commit 95a195f

Browse files
committed
Add the beautify format SQL gold files
1 parent 925428d commit 95a195f

190 files changed

Lines changed: 3254 additions & 25 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

parser/format.go

Lines changed: 87 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ func (f *Formatter) WriteExpr(expr Expr) {
7171
expr.FormatSQL(f)
7272
}
7373

74+
7475
func (f *Formatter) NewLine() {
7576
if f.mode != FormatModeBeautify {
7677
return
@@ -107,7 +108,46 @@ func Format(expr Expr) string {
107108
return formatter.String()
108109
}
109110

111+
func (p *BinaryOperation) isLogicalOp() bool {
112+
switch p.Operation {
113+
case TokenKind(KeywordAnd), TokenKind(KeywordOr):
114+
return true
115+
default:
116+
return p.HasGlobal || p.HasNot
117+
}
118+
}
119+
120+
func isLogicalBinaryOp(expr Expr) bool {
121+
if bin, ok := expr.(*BinaryOperation); ok {
122+
return bin.isLogicalOp()
123+
}
124+
return false
125+
}
126+
127+
func (p *BinaryOperation) writeLogicalOperand(formatter *Formatter, expr Expr) {
128+
if isLogicalBinaryOp(expr) {
129+
formatter.WriteExpr(expr)
130+
} else {
131+
formatter.Indent()
132+
formatter.WriteExpr(expr)
133+
formatter.Dedent()
134+
}
135+
}
136+
110137
func (p *BinaryOperation) FormatSQL(formatter *Formatter) {
138+
if p.isLogicalOp() && formatter.mode == FormatModeBeautify {
139+
p.writeLogicalOperand(formatter, p.LeftExpr)
140+
formatter.NewLine()
141+
if p.HasNot {
142+
formatter.WriteString("NOT ")
143+
} else if p.HasGlobal {
144+
formatter.WriteString("GLOBAL ")
145+
}
146+
formatter.WriteString(string(p.Operation))
147+
formatter.NewLine()
148+
p.writeLogicalOperand(formatter, p.RightExpr)
149+
return
150+
}
111151
formatter.WriteExpr(p.LeftExpr)
112152
if p.Operation != TokenKindDash {
113153
formatter.WriteByte(whitespace)
@@ -478,8 +518,10 @@ func (a *AuthenticationClause) FormatSQL(formatter *Formatter) {
478518
func (f *BetweenClause) FormatSQL(formatter *Formatter) {
479519
if f.Expr != nil {
480520
formatter.WriteExpr(f.Expr)
521+
formatter.WriteString(" BETWEEN ")
522+
} else {
523+
formatter.WriteString("BETWEEN ")
481524
}
482-
formatter.WriteString(" BETWEEN ")
483525
formatter.WriteExpr(f.Between)
484526
formatter.WriteString(" AND ")
485527
formatter.WriteExpr(f.And)
@@ -502,21 +544,24 @@ func (c *CTEStmt) FormatSQL(formatter *Formatter) {
502544
}
503545

504546
func (c *CaseExpr) FormatSQL(formatter *Formatter) {
505-
formatter.WriteString("CASE ")
547+
formatter.WriteString("CASE")
506548
if c.Expr != nil {
549+
formatter.WriteByte(whitespace)
507550
formatter.WriteExpr(c.Expr)
508551
}
509-
for i, when := range c.Whens {
510-
if i > 0 {
511-
formatter.WriteByte(whitespace)
512-
}
552+
formatter.Indent()
553+
for _, when := range c.Whens {
554+
formatter.Break()
513555
formatter.WriteExpr(when)
514556
}
515557
if c.Else != nil {
516-
formatter.WriteString(" ELSE ")
558+
formatter.Break()
559+
formatter.WriteString("ELSE ")
517560
formatter.WriteExpr(c.Else)
518561
}
519-
formatter.WriteString(" END")
562+
formatter.Dedent()
563+
formatter.Break()
564+
formatter.WriteString("END")
520565
}
521566

522567
func (c *CastExpr) FormatSQL(formatter *Formatter) {
@@ -1458,12 +1503,35 @@ func (g *GranteesClause) FormatSQL(formatter *Formatter) {
14581503
}
14591504

14601505
func (g *GroupByClause) FormatSQL(formatter *Formatter) {
1461-
formatter.WriteString("GROUP BY ")
1506+
formatter.WriteString("GROUP BY")
14621507
if g.AggregateType != "" {
1508+
formatter.WriteByte(whitespace)
14631509
formatter.WriteString(g.AggregateType)
14641510
}
14651511
if g.Expr != nil {
1466-
formatter.WriteExpr(g.Expr)
1512+
if g.AggregateType == "" && formatter.mode == FormatModeBeautify {
1513+
if columnList, ok := g.Expr.(*ColumnExprList); ok && len(columnList.Items) > 0 {
1514+
formatter.Indent()
1515+
for i, item := range columnList.Items {
1516+
if i == 0 {
1517+
formatter.Break()
1518+
} else {
1519+
formatter.WriteByte(',')
1520+
formatter.Break()
1521+
}
1522+
formatter.WriteExpr(item)
1523+
}
1524+
formatter.Dedent()
1525+
} else {
1526+
formatter.WriteByte(whitespace)
1527+
formatter.WriteExpr(g.Expr)
1528+
}
1529+
} else if g.AggregateType == "" {
1530+
formatter.WriteByte(whitespace)
1531+
formatter.WriteExpr(g.Expr)
1532+
} else {
1533+
formatter.WriteExpr(g.Expr)
1534+
}
14671535
}
14681536
if g.WithCube {
14691537
formatter.WriteString(" WITH CUBE")
@@ -2591,16 +2659,17 @@ func (w *WhenClause) FormatSQL(formatter *Formatter) {
25912659
}
25922660
}
25932661

2594-
func isLogicalOperation(operation TokenKind) bool {
2595-
return strings.EqualFold(string(operation), KeywordAnd) || strings.EqualFold(string(operation), KeywordOr)
2596-
}
2597-
25982662
func (w *WhereClause) FormatSQL(formatter *Formatter) {
25992663
formatter.WriteString("WHERE")
2600-
formatter.Indent()
2601-
formatter.Break()
2602-
formatter.WriteExpr(w.Expr)
2603-
formatter.Dedent()
2664+
if isLogicalBinaryOp(w.Expr) {
2665+
formatter.Break()
2666+
formatter.WriteExpr(w.Expr)
2667+
} else {
2668+
formatter.Indent()
2669+
formatter.Break()
2670+
formatter.WriteExpr(w.Expr)
2671+
formatter.Dedent()
2672+
}
26042673
}
26052674

26062675
func (w *WindowDefinition) FormatSQL(formatter *Formatter) {

parser/parser_test.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,48 @@ func TestParser_Format(t *testing.T) {
114114
}
115115
}
116116

117+
func TestParser_FormatBeautify(t *testing.T) {
118+
for _, dir := range []string{"./testdata/dml", "./testdata/ddl", "./testdata/query", "./testdata/basic"} {
119+
outputDir := dir + "/format/beautify"
120+
121+
entries, err := os.ReadDir(dir)
122+
if err != nil {
123+
require.NoError(t, err)
124+
}
125+
for _, entry := range entries {
126+
if !strings.HasSuffix(entry.Name(), ".sql") {
127+
continue
128+
}
129+
t.Run(entry.Name(), func(t *testing.T) {
130+
fileBytes, err := os.ReadFile(filepath.Join(dir, entry.Name()))
131+
require.NoError(t, err)
132+
parser := Parser{
133+
lexer: NewLexer(string(fileBytes)),
134+
}
135+
stmts, err := parser.ParseStmts()
136+
require.NoError(t, err)
137+
var builder strings.Builder
138+
builder.WriteString("-- Origin SQL:\n")
139+
builder.Write(fileBytes)
140+
builder.WriteString("\n\n-- Beautify SQL:\n")
141+
for _, stmt := range stmts {
142+
formatter := NewFormatter()
143+
formatter.WithBeautify()
144+
formatter.WriteExpr(stmt)
145+
builder.WriteString(formatter.String())
146+
builder.WriteByte(';')
147+
builder.WriteByte('\n')
148+
}
149+
g := goldie.New(t,
150+
goldie.WithNameSuffix(""),
151+
goldie.WithDiffEngine(goldie.ColoredDiff),
152+
goldie.WithFixtureDir(outputDir))
153+
g.Assert(t, entry.Name(), []byte(builder.String()))
154+
})
155+
}
156+
}
157+
}
158+
117159
// validFormatSQL Verify that the format sql can be re-parsed with consistent results
118160
func validFormatSQL(t *testing.T, sql string) {
119161
parser := NewParser(sql)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
-- Origin SQL:
2+
SELECT quantile(0.9)(x), quantiles(0.5, 0.9)(x);
3+
4+
5+
-- Beautify SQL:
6+
SELECT
7+
quantile(0.9)(x),
8+
quantiles(0.5, 0.9)(x);
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
-- Origin SQL:
2+
SET allow_suspicious_low_cardinality_types = true;
3+
4+
SET max_block_size = 65536;
5+
6+
SET output_format_json_quote_64bit_integers = 'true';
7+
8+
SET max_threads = 8, max_memory_usage = 10000000000, enable_optimize_predicate_expression = false;
9+
10+
SET allow_experimental_analyzer = true;
11+
12+
13+
-- Beautify SQL:
14+
SET allow_suspicious_low_cardinality_types=true;
15+
SET max_block_size=65536;
16+
SET output_format_json_quote_64bit_integers='true';
17+
SET max_threads=8, max_memory_usage=10000000000, enable_optimize_predicate_expression=false;
18+
SET allow_experimental_analyzer=true;
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
-- Origin SQL:
2+
SETTINGS allow_suspicious_low_cardinality_types = true;
3+
4+
SETTINGS max_block_size = 65536;
5+
6+
SETTINGS output_format_json_quote_64bit_integers = 'true';
7+
8+
SETTINGS max_threads = 8, max_memory_usage = 10000000000, enable_optimize_predicate_expression = false;
9+
10+
SETTINGS allow_experimental_analyzer = true;
11+
12+
13+
-- Beautify SQL:
14+
SET allow_suspicious_low_cardinality_types=true;
15+
SET max_block_size=65536;
16+
SET output_format_json_quote_64bit_integers='true';
17+
SET max_threads=8, max_memory_usage=10000000000, enable_optimize_predicate_expression=false;
18+
SET allow_experimental_analyzer=true;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-- Origin SQL:
2+
USE test;
3+
4+
-- Beautify SQL:
5+
USE test;
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
-- Origin SQL:
2+
-- Tags: no-parallel
3+
4+
ALTER ROLE r1_01293;
5+
ALTER ROLE r1_01293 ON CLUSTER cluster_1 RENAME TO r2_01293;
6+
ALTER ROLE r1_01293 RENAME TO r2_01293, r3_01293 RENAME TO r4_01293;
7+
ALTER ROLE r1_01293 SETTINGS NONE;
8+
ALTER ROLE r2_01293 SETTINGS PROFILE 'default';
9+
ALTER ROLE r3_01293 SETTINGS max_memory_usage=5000000;
10+
ALTER ROLE r4_01293 SETTINGS max_memory_usage MIN=5000000;
11+
ALTER ROLE r5_01293 SETTINGS max_memory_usage MAX=5000000;
12+
ALTER ROLE r6_01293 SETTINGS max_memory_usage CONST;
13+
ALTER ROLE r7_01293 SETTINGS max_memory_usage WRITABLE;
14+
ALTER ROLE r8_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 CONST;
15+
ALTER ROLE r9_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000 WRITABLE;
16+
ALTER ROLE r1_01293, r2_01293;
17+
ALTER ROLE r1_01293 SETTINGS readonly=1;
18+
ALTER ROLE r2_01293 SETTINGS PROFILE 'default';
19+
ALTER ROLE r3_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 WRITABLE;
20+
ALTER ROLE r4_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000, readonly=1;
21+
ALTER ROLE r5_01293 SETTINGS NONE;
22+
ALTER ROLE r1_01293@'%';
23+
ALTER ROLE r2_01293@'%.myhost.com';
24+
25+
-- Beautify SQL:
26+
ALTER ROLE r1_01293;
27+
ALTER ROLE r1_01293 ON CLUSTER cluster_1 RENAME TO r2_01293;
28+
ALTER ROLE r1_01293 RENAME TO r2_01293, r3_01293 RENAME TO r4_01293;
29+
ALTER ROLE r1_01293 SETTINGS NONE;
30+
ALTER ROLE r2_01293 SETTINGS PROFILE 'default';
31+
ALTER ROLE r3_01293 SETTINGS max_memory_usage=5000000;
32+
ALTER ROLE r4_01293 SETTINGS max_memory_usage MIN=5000000;
33+
ALTER ROLE r5_01293 SETTINGS max_memory_usage MAX=5000000;
34+
ALTER ROLE r6_01293 SETTINGS max_memory_usage CONST;
35+
ALTER ROLE r7_01293 SETTINGS max_memory_usage WRITABLE;
36+
ALTER ROLE r8_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 CONST;
37+
ALTER ROLE r9_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000 WRITABLE;
38+
ALTER ROLE r1_01293, r2_01293;
39+
ALTER ROLE r1_01293 SETTINGS readonly=1;
40+
ALTER ROLE r2_01293 SETTINGS PROFILE 'default';
41+
ALTER ROLE r3_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 WRITABLE;
42+
ALTER ROLE r4_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000, readonly=1;
43+
ALTER ROLE r5_01293 SETTINGS NONE;
44+
ALTER ROLE r1_01293@'%';
45+
ALTER ROLE r2_01293@'%.myhost.com';
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
-- Origin SQL:
2+
ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD COLUMN f1 String AFTER f0 SETTINGS alter_sync = 2;
3+
4+
5+
-- Beautify SQL:
6+
ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD COLUMN f1 String AFTER f0 SETTINGS alter_sync=2;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
-- Origin SQL:
2+
ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX my_index(f0) TYPE minmax GRANULARITY 1024;
3+
ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX api_id_idx api_id TYPE set(100) GRANULARITY 2;
4+
ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX arr_idx arr TYPE bloom_filter(0.01) GRANULARITY 3;
5+
ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX content_idx content TYPE tokenbf_v1(30720, 2, 0) GRANULARITY 1;
6+
ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX output_idx output TYPE ngrambf_v1(3, 10000, 2, 1) GRANULARITY 2;
7+
8+
9+
-- Beautify SQL:
10+
ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX my_index(f0) TYPE minmax GRANULARITY 1024;
11+
ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX api_id_idx api_id TYPE set(100) GRANULARITY 2;
12+
ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX arr_idx arr TYPE bloom_filter(0.01) GRANULARITY 3;
13+
ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX content_idx content TYPE tokenbf_v1(30720, 2, 0) GRANULARITY 1;
14+
ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX output_idx output TYPE ngrambf_v1(3, 10000, 2, 1) GRANULARITY 2;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
-- Origin SQL:
2+
ALTER TABLE visits_order
3+
ADD PROJECTION IF NOT EXISTS user_name_projection
4+
(SELECT * GROUP BY user_name ORDER BY user_name) AFTER a.user_id;
5+
6+
7+
-- Beautify SQL:
8+
ALTER TABLE visits_order ADD PROJECTION IF NOT EXISTS user_name_projection (SELECT * GROUP BY
9+
user_name ORDER BY user_name) AFTER a.user_id;

0 commit comments

Comments
 (0)