refactor(format): subqueries and CTE lists on Doc-IR; fix CTE commas with trailing style

This commit is contained in:
Hein
2026-10-06 14:57:21 +02:00
parent 488801b8b1
commit e9c0d52ae9
5 changed files with 69 additions and 50 deletions
+14 -46
View File
@@ -338,7 +338,6 @@ func dmlSplitAndOr(toks []cst.Tok) [][]cst.Tok {
// formatWithBody formats the body of a WITH clause by splitting CTE definitions
// at depth-0 commas and formatting the subquery inside each AS (...) block.
func formatWithBody(kwText string, body []cst.Tok, st config.Style) string {
nl := st.Newline
cteDefs := dmlSplitCommas(body)
// Filter spurious empty items.
@@ -357,37 +356,11 @@ func formatWithBody(kwText string, body []cst.Tok, st config.Style) string {
return kwText + " " + formatCTEDef(cteDefs[0], st)
default:
// Multiple CTEs: one per line with the configured comma style.
first := st.Indent + " "
cont := st.Indent + ","
contPad := strings.Repeat(" ", len(cont)) // same width as cont, no comma
var b strings.Builder
b.WriteString(kwText)
texts := make([]string, len(cteDefs))
for i, cteDef := range cteDefs {
b.WriteString(nl)
var headPfx, tailPfx string
if i == 0 || st.Commas != config.CommaLeading {
headPfx = first
tailPfx = first
} else {
headPfx = cont
tailPfx = contPad
}
cteText := formatCTEDef(cteDef, st)
cteLines := strings.Split(cteText, nl)
for j, line := range cteLines {
if j > 0 {
b.WriteString(nl)
b.WriteString(tailPfx)
} else {
b.WriteString(headPfx)
}
b.WriteString(line)
}
texts[i] = formatCTEDef(cteDef, st)
}
return b.String()
return dmlCommaList(kwText, texts, st)
}
}
@@ -515,26 +488,21 @@ func dmlWrapSubquery(inner []cst.Tok, st config.Style) string {
if sub == "" {
return "()"
}
lines := strings.Split(sub, nl)
var b strings.Builder
b.WriteString("(")
for i, line := range lines {
if i == 0 && st.SubqueryContent != config.PlacementNewLine {
b.WriteString(line)
continue
// The first line stays on the "(" line unless subquery_content says
// new_line; every later line is indented one level.
var body []Doc
for i, line := range strings.Split(sub, nl) {
if i > 0 || st.SubqueryContent == config.PlacementNewLine {
body = append(body, HardLine())
}
b.WriteString(nl)
if line != "" {
b.WriteString(st.Indent)
}
b.WriteString(line)
body = append(body, Text(line))
}
doc := []Doc{Text("("), Indent(Concat(body...))}
if st.SubqueryClosing == config.PlacementNewLine {
b.WriteString(nl)
doc = append(doc, HardLine())
}
b.WriteString(")")
return b.String()
doc = append(doc, Text(")"))
return Render(Concat(doc...), 0, st.Indent, nl)
}
// litNL stands in for a newline inside a multi-line string literal while DML