feat(dml): implement DML statement formatting and tests
* Add formatDML function for formatting top-level DML statements * Introduce tests for various DML scenarios including SELECT, INSERT, UPDATE, and DELETE * Enhance printer to handle DML statements correctly
This commit is contained in:
@@ -52,6 +52,12 @@ func (p *printer) writeItem(n cst.Node) {
|
||||
switch v := n.(type) {
|
||||
case *cst.CreateFunction:
|
||||
p.writeCreateFunction(v)
|
||||
case *cst.Raw:
|
||||
if isDMLStart(v.Toks) {
|
||||
p.b.WriteString(formatDML(v.Toks, p.st))
|
||||
} else {
|
||||
p.b.WriteString(verbatimSpan(v.Toks))
|
||||
}
|
||||
default:
|
||||
p.b.WriteString(verbatimSpan(cst.Tokens(n)))
|
||||
}
|
||||
@@ -160,6 +166,13 @@ func (p *printer) trailingComments(lead cst.Trivia) {
|
||||
// tightOps are operators printed without surrounding spaces.
|
||||
var tightOps = map[string]bool{"::": true, ":": true, "->": true, "->>": true}
|
||||
|
||||
// parenKws are keywords that always take a space before '(' because they
|
||||
// introduce a subquery or a bracketed clause, not a function-call argument list.
|
||||
var parenKws = map[string]bool{
|
||||
"as": true, "exists": true, "in": true, "not": true,
|
||||
"between": true, "like": true, "ilike": true, "similar": true,
|
||||
}
|
||||
|
||||
func needSpace(a, b lexer.Token) bool {
|
||||
// No space after.
|
||||
switch a.Kind {
|
||||
@@ -177,6 +190,11 @@ func needSpace(a, b lexer.Token) bool {
|
||||
case lexer.LParen:
|
||||
switch a.Kind {
|
||||
case lexer.Ident, lexer.QuotedIdent, lexer.RParen, lexer.RBracket, lexer.Param:
|
||||
// Keywords like AS/EXISTS/IN introduce subqueries or clause groups,
|
||||
// not function calls — always separate with a space.
|
||||
if a.Kind == lexer.Ident && parenKws[lowerASCII(a.Text)] {
|
||||
return true
|
||||
}
|
||||
return false // function call / type modifier
|
||||
}
|
||||
case lexer.LBracket:
|
||||
|
||||
Reference in New Issue
Block a user