snapshot of https://github.com/sqlc-dev/sqlc.git (main, 2026-09-16; blobs > 131072B omitted)
Some checks failed
kotlin / test (push) Has been skipped
python / test (push) Has been skipped
typescript / test (push) Has been skipped
go / build darwin/amd64 (push) Has been cancelled
go / build linux/amd64 (push) Has been cancelled
go / build windows/amd64 (push) Has been cancelled
go / build darwin/arm64 (push) Has been cancelled
go / build linux/arm64 (push) Has been cancelled
go / build windows/arm64 (push) Has been cancelled
go / test (push) Has been cancelled
go / vuln_check (push) Has been cancelled
Some checks failed
kotlin / test (push) Has been skipped
python / test (push) Has been skipped
typescript / test (push) Has been skipped
go / build darwin/amd64 (push) Has been cancelled
go / build linux/amd64 (push) Has been cancelled
go / build windows/amd64 (push) Has been cancelled
go / build darwin/arm64 (push) Has been cancelled
go / build linux/arm64 (push) Has been cancelled
go / build windows/arm64 (push) Has been cancelled
go / test (push) Has been cancelled
go / vuln_check (push) Has been cancelled
This commit is contained in:
55
internal/engine/dolphin/fingerprint.go
Normal file
55
internal/engine/dolphin/fingerprint.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package dolphin
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
pcast "github.com/sqlc-dev/marino/ast"
|
||||
"github.com/sqlc-dev/marino/format"
|
||||
"github.com/sqlc-dev/marino/parser"
|
||||
)
|
||||
|
||||
// deparen unwraps parenthesized expressions so a redundant pair of
|
||||
// parentheses added or dropped by formatting does not change the
|
||||
// fingerprint. Everything else about the tree survives untouched.
|
||||
type deparen struct{}
|
||||
|
||||
func (v deparen) Enter(n pcast.Node) (pcast.Node, bool) { return n, false }
|
||||
func (v deparen) Leave(n pcast.Node) (pcast.Node, bool) {
|
||||
if p, ok := n.(*pcast.ParenthesesExpr); ok {
|
||||
return p.Expr, true
|
||||
}
|
||||
return n, true
|
||||
}
|
||||
|
||||
// Fingerprint reduces a statement to a canonical form that survives changes
|
||||
// in whitespace, keyword case, quoting style and redundant parentheses —
|
||||
// and nothing else. Identifier case is preserved: MySQL table names are
|
||||
// case-sensitive on most servers, so a formatting pass that changes one is
|
||||
// a semantic change and must not fingerprint equal. fmt uses this as its
|
||||
// proof that a formatted statement still means what the author wrote; a
|
||||
// statement whose fingerprint it cannot match is left exactly as written.
|
||||
func (p *Parser) Fingerprint(sql string) (string, error) {
|
||||
// A fresh parser: p.pingcap carries per-parse comment state that
|
||||
// ParseFile is still using.
|
||||
stmts, _, err := parser.New().Parse(sql, "", "")
|
||||
if err != nil {
|
||||
return "", normalizeErr(err)
|
||||
}
|
||||
flags := format.RestoreStringSingleQuotes |
|
||||
format.RestoreKeyWordUppercase |
|
||||
format.RestoreNameBackQuotes
|
||||
parts := make([]string, 0, len(stmts))
|
||||
for _, s := range stmts {
|
||||
n, ok := s.Accept(deparen{})
|
||||
if !ok {
|
||||
return "", fmt.Errorf("fingerprint: rewrite failed")
|
||||
}
|
||||
var sb strings.Builder
|
||||
if err := n.Restore(format.NewRestoreCtx(flags, &sb)); err != nil {
|
||||
return "", fmt.Errorf("fingerprint: %w", err)
|
||||
}
|
||||
parts = append(parts, sb.String())
|
||||
}
|
||||
return strings.Join(parts, "; "), nil
|
||||
}
|
||||
Reference in New Issue
Block a user