Skip to content

Commit aa2f543

Browse files
authored
Enable 168 format roundtrip tests by adding missing Format support (#60)
1 parent 4452b96 commit aa2f543

170 files changed

Lines changed: 338 additions & 168 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.

internal/format/expressions.go

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,17 @@ func formatTableIdentifier(sb *strings.Builder, t *ast.TableIdentifier) {
159159
// formatFunctionCall formats a function call.
160160
func formatFunctionCall(sb *strings.Builder, fn *ast.FunctionCall) {
161161
sb.WriteString(fn.Name)
162+
// Handle parametric functions like quantile(0.9)(x)
163+
if len(fn.Parameters) > 0 {
164+
sb.WriteString("(")
165+
for i, p := range fn.Parameters {
166+
if i > 0 {
167+
sb.WriteString(", ")
168+
}
169+
Expression(sb, p)
170+
}
171+
sb.WriteString(")")
172+
}
162173
sb.WriteString("(")
163174
if fn.Distinct {
164175
sb.WriteString("DISTINCT ")
@@ -170,8 +181,98 @@ func formatFunctionCall(sb *strings.Builder, fn *ast.FunctionCall) {
170181
Expression(sb, arg)
171182
}
172183
sb.WriteString(")")
184+
// Handle SETTINGS for table functions
185+
if len(fn.Settings) > 0 {
186+
sb.WriteString(" SETTINGS ")
187+
for i, s := range fn.Settings {
188+
if i > 0 {
189+
sb.WriteString(", ")
190+
}
191+
sb.WriteString(s.Name)
192+
sb.WriteString(" = ")
193+
Expression(sb, s.Value)
194+
}
195+
}
196+
// Handle window functions (OVER clause)
197+
if fn.Over != nil {
198+
sb.WriteString(" OVER ")
199+
formatWindowSpec(sb, fn.Over)
200+
}
201+
// Handle alias
202+
if fn.Alias != "" {
203+
sb.WriteString(" AS ")
204+
sb.WriteString(fn.Alias)
205+
}
173206
}
174207

208+
// formatWindowSpec formats a window specification.
209+
func formatWindowSpec(sb *strings.Builder, w *ast.WindowSpec) {
210+
if w.Name != "" {
211+
sb.WriteString(w.Name)
212+
return
213+
}
214+
sb.WriteString("(")
215+
if len(w.PartitionBy) > 0 {
216+
sb.WriteString("PARTITION BY ")
217+
for i, expr := range w.PartitionBy {
218+
if i > 0 {
219+
sb.WriteString(", ")
220+
}
221+
Expression(sb, expr)
222+
}
223+
}
224+
if len(w.OrderBy) > 0 {
225+
if len(w.PartitionBy) > 0 {
226+
sb.WriteString(" ")
227+
}
228+
sb.WriteString("ORDER BY ")
229+
for i, elem := range w.OrderBy {
230+
if i > 0 {
231+
sb.WriteString(", ")
232+
}
233+
formatOrderByElement(sb, elem)
234+
}
235+
}
236+
if w.Frame != nil {
237+
sb.WriteString(" ")
238+
formatWindowFrame(sb, w.Frame)
239+
}
240+
sb.WriteString(")")
241+
}
242+
243+
// formatWindowFrame formats a window frame.
244+
func formatWindowFrame(sb *strings.Builder, f *ast.WindowFrame) {
245+
sb.WriteString(string(f.Type))
246+
sb.WriteString(" ")
247+
if f.EndBound != nil {
248+
sb.WriteString("BETWEEN ")
249+
formatFrameBound(sb, f.StartBound)
250+
sb.WriteString(" AND ")
251+
formatFrameBound(sb, f.EndBound)
252+
} else {
253+
formatFrameBound(sb, f.StartBound)
254+
}
255+
}
256+
257+
// formatFrameBound formats a frame bound.
258+
func formatFrameBound(sb *strings.Builder, b *ast.FrameBound) {
259+
switch b.Type {
260+
case ast.BoundCurrentRow:
261+
sb.WriteString("CURRENT ROW")
262+
case ast.BoundUnboundedPre:
263+
sb.WriteString("UNBOUNDED PRECEDING")
264+
case ast.BoundUnboundedFol:
265+
sb.WriteString("UNBOUNDED FOLLOWING")
266+
case ast.BoundPreceding:
267+
Expression(sb, b.Offset)
268+
sb.WriteString(" PRECEDING")
269+
case ast.BoundFollowing:
270+
Expression(sb, b.Offset)
271+
sb.WriteString(" FOLLOWING")
272+
}
273+
}
274+
275+
175276
// formatBinaryExpr formats a binary expression.
176277
func formatBinaryExpr(sb *strings.Builder, expr *ast.BinaryExpr) {
177278
Expression(sb, expr.Left)
@@ -194,6 +295,28 @@ func formatAsterisk(sb *strings.Builder, a *ast.Asterisk) {
194295
sb.WriteString(".")
195296
}
196297
sb.WriteString("*")
298+
if len(a.Except) > 0 {
299+
sb.WriteString(" EXCEPT (")
300+
for i, col := range a.Except {
301+
if i > 0 {
302+
sb.WriteString(", ")
303+
}
304+
sb.WriteString(col)
305+
}
306+
sb.WriteString(")")
307+
}
308+
if len(a.Replace) > 0 {
309+
sb.WriteString(" REPLACE (")
310+
for i, r := range a.Replace {
311+
if i > 0 {
312+
sb.WriteString(", ")
313+
}
314+
Expression(sb, r.Expr)
315+
sb.WriteString(" AS ")
316+
sb.WriteString(r.Name)
317+
}
318+
sb.WriteString(")")
319+
}
197320
}
198321

199322
// formatAliasedExpr formats an aliased expression.

internal/format/statements.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,13 @@ func formatSelectQuery(sb *strings.Builder, q *ast.SelectQuery) {
4848
sb.WriteString("DISTINCT ")
4949
}
5050

51+
// Format TOP clause
52+
if q.Top != nil {
53+
sb.WriteString("TOP ")
54+
Expression(sb, q.Top)
55+
sb.WriteString(" ")
56+
}
57+
5158
// Format columns
5259
for i, col := range q.Columns {
5360
if i > 0 {
@@ -105,6 +112,25 @@ func formatSelectQuery(sb *strings.Builder, q *ast.SelectQuery) {
105112
Expression(sb, q.Having)
106113
}
107114

115+
// Format QUALIFY clause
116+
if q.Qualify != nil {
117+
sb.WriteString(" QUALIFY ")
118+
Expression(sb, q.Qualify)
119+
}
120+
121+
// Format WINDOW clause
122+
if len(q.Window) > 0 {
123+
sb.WriteString(" WINDOW ")
124+
for i, w := range q.Window {
125+
if i > 0 {
126+
sb.WriteString(", ")
127+
}
128+
sb.WriteString(w.Name)
129+
sb.WriteString(" AS ")
130+
formatWindowSpec(sb, w.Spec)
131+
}
132+
}
133+
108134
// Format ORDER BY clause
109135
if len(q.OrderBy) > 0 {
110136
sb.WriteString(" ORDER BY ")
@@ -126,6 +152,17 @@ func formatSelectQuery(sb *strings.Builder, q *ast.SelectQuery) {
126152
Expression(sb, q.Offset)
127153
}
128154

155+
// Format LIMIT BY clause
156+
if len(q.LimitBy) > 0 {
157+
sb.WriteString(" BY ")
158+
for i, expr := range q.LimitBy {
159+
if i > 0 {
160+
sb.WriteString(", ")
161+
}
162+
Expression(sb, expr)
163+
}
164+
}
165+
129166
// Format SETTINGS clause
130167
if len(q.Settings) > 0 {
131168
sb.WriteString(" SETTINGS ")
@@ -139,6 +176,16 @@ func formatSelectQuery(sb *strings.Builder, q *ast.SelectQuery) {
139176
}
140177
}
141178

179+
// Format INTO OUTFILE clause
180+
if q.IntoOutfile != nil {
181+
sb.WriteString(" INTO OUTFILE '")
182+
sb.WriteString(q.IntoOutfile.Filename)
183+
sb.WriteString("'")
184+
if q.IntoOutfile.Truncate {
185+
sb.WriteString(" TRUNCATE")
186+
}
187+
}
188+
142189
// Format FORMAT clause
143190
if q.Format != nil {
144191
sb.WriteString(" FORMAT ")
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"todo_format":true}
1+
{}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"todo_format":true}
1+
{}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"todo_format":true}
1+
{}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"todo_format":true}
1+
{}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"todo_format":true}
1+
{}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"todo_format":true}
1+
{}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"todo_format":true}
1+
{}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"todo_format":true}
1+
{}

0 commit comments

Comments
 (0)