-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmysql.go
71 lines (54 loc) · 1.92 KB
/
mysql.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package breaql
import (
"log/slog"
"strings"
"github.com/pingcap/tidb/pkg/parser"
"github.com/pingcap/tidb/pkg/parser/ast"
"github.com/samber/lo"
// Importing the following parser driver causes a build error.
//_ "github.com/pingcap/tidb/pkg/types/parser_driver"
_ "github.com/pingcap/tidb/pkg/parser/test_driver"
)
// RunMySQL parses the given (possibly composite) DDL statements and returns the breaking ones.
func RunMySQL(sql string) (BreakingChanges, error) {
p := parser.New()
stmtNodes, _, err := p.Parse(sql, "", "")
if err != nil {
return BreakingChanges{}, &ParseError{original: err, Message: err.Error(), funcName: "parser.Parse"}
}
changes := NewBreakingChanges()
for _, stmtNode := range stmtNodes {
stmtText := strings.TrimSpace(stmtNode.Text())
slog.Debug("processing stmt", slog.String("stmt", stmtText))
switch stmt := stmtNode.(type) {
case *ast.DropDatabaseStmt:
changes.Databases.add(stmt.Name.String(), stmtText)
case *ast.DropTableStmt:
lo.ForEach(stmt.Tables, func(stmt *ast.TableName, _ int) { changes.Tables.add(stmt.Name.String(), stmtText) })
case *ast.TruncateTableStmt:
changes.Tables.add(stmt.Table.Name.String(), stmtText)
case *ast.RenameTableStmt:
lo.ForEach(stmt.TableToTables, func(ttt *ast.TableToTable, _ int) { changes.Tables.add(ttt.OldTable.Name.String(), stmtText) })
case *ast.AlterTableStmt:
for _, spec := range stmt.Specs {
if isBreakingAlterTableSpec(spec) {
changes.Tables.add(stmt.Table.Name.String(), stmtText)
break
}
}
}
}
return changes, nil
}
func isBreakingAlterTableSpec(spec *ast.AlterTableSpec) bool {
switch spec.Tp {
case ast.AlterTableDropColumn, ast.AlterTableDropIndex,
ast.AlterTableDropForeignKey, ast.AlterTableDropPrimaryKey:
return true
case ast.AlterTableModifyColumn:
// Note: False positives are accepted here as we cannot obtain the old column type.
return true
default:
return false
}
}