提交 fcba5e74 编写于 作者: L liipx

COL.007 reward

上级 421a866d
......@@ -3272,6 +3272,57 @@ func (q *Query4Audit) RuleMaxTextColsCount() Rule {
return rule
}
// RuleMaxTextColsCount COL.007 checking for existed table
func (idxAdv *IndexAdvisor) RuleMaxTextColsCount() Rule {
rule := HeuristicRules["OK"]
// 未开启测试环境不进行检查
if common.Config.TestDSN.Disable {
return rule
}
sqlparser.Walk(func(node sqlparser.SQLNode) (kontinue bool, err error) {
switch stmt := node.(type) {
case *sqlparser.DDL:
if stmt.Action != "alter" {
return true, nil
}
tb := stmt.Table
// 此处的检查需要在测试环境中的临时数据库中进行检查
// 需要将测试环境 DSN 的数据库暂时指向临时数据库
// 为了防止影响切换数据库环境会影响接下来的测试,需要在检查完后将原配置还原
dbTmp := idxAdv.vEnv.Database
idxAdv.vEnv.Database = idxAdv.vEnv.DBRef[idxAdv.vEnv.Database]
defer func() {
idxAdv.vEnv.Database = dbTmp
}()
// 添加字段的语句会在初始化环境的时候被执行
// 只需要获取该标的 CREAET 语句,后再对该语句进行检查即可
ddl, err := idxAdv.vEnv.ShowCreateTable(tb.Name.String())
if err != nil {
common.Log.Error("RuleMaxTextColsCount create statement got failed: %s", err.Error())
return false, err
}
q, err := NewQuery4Audit(ddl)
if err != nil {
return false, err
}
r := q.RuleMaxTextColsCount()
if r.Item != "OK" {
rule = r
return false, nil
}
}
return true, nil
}, idxAdv.Ast)
return rule
}
// RuleAllowEngine TBL.002
func (q *Query4Audit) RuleAllowEngine() Rule {
var rule = q.RuleOK()
......
......@@ -23,7 +23,10 @@ import (
"github.com/XiaoMi/soar/common"
"github.com/XiaoMi/soar/env"
"github.com/kr/pretty"
"strings"
"vitess.io/vitess/go/vt/sqlparser"
)
// ALI.001
......@@ -3113,6 +3116,49 @@ func TestRuleMaxTextColsCount(t *testing.T) {
common.Log.Debug("Exiting function: %s", common.GetFunctionName())
}
// COL.007
func TestRuleMaxTextColsCountWithEnv(t *testing.T) {
common.Log.Debug("Entering function: %s", common.GetFunctionName())
dsn := common.Config.OnlineDSN
common.Config.OnlineDSN = common.Config.TestDSN
vEnv, rEnv := env.BuildEnv()
defer vEnv.CleanUp()
initSQLs := []string{
`CREATE TABLE t1 (id int, title text, content blob);`,
"alter table t1 add column other text;",
}
for _, sql := range initSQLs {
vEnv.BuildVirtualEnv(rEnv, sql)
if !strings.HasPrefix(strings.ToLower(sql), "alter") {
continue
}
stmt, syntaxErr := sqlparser.Parse(sql)
if syntaxErr != nil {
common.Log.Critical("Syntax Error: %v, SQL: %s", syntaxErr, sql)
}
q := &Query4Audit{Query: sql, Stmt: stmt}
idxAdvisor, err := NewAdvisor(vEnv, *rEnv, *q)
if err != nil {
t.Error("NewAdvisor Error: ", err, "SQL: ", sql)
}
if idxAdvisor != nil {
rule := idxAdvisor.RuleMaxTextColsCount()
if rule.Item != "COL.007" {
t.Error("Rule not match:", rule, "Expect : COL.007, SQL:", sql)
}
}
}
common.Log.Debug("Exiting function: %s", common.GetFunctionName())
common.Config.OnlineDSN = dsn
}
// TBL.002
func TestRuleAllowEngine(t *testing.T) {
common.Log.Debug("Entering function: %s", common.GetFunctionName())
......
......@@ -111,7 +111,11 @@ func NewAdvisor(env *env.VirtualEnv, rEnv database.Connector, q Query4Audit) (*I
}
}
return nil, nil
return &IndexAdvisor{
vEnv: env,
rEnv: rEnv,
Ast: q.Stmt,
}, nil
case *sqlparser.DBDDL:
// 忽略建库语句
......@@ -1011,11 +1015,12 @@ func (idxAdv *IndexAdvisor) HeuristicCheck(q Query4Audit) map[string]Rule {
}
ruleFuncs := []func(*IndexAdvisor) Rule{
(*IndexAdvisor).RuleMaxTextColsCount, // COL.007
(*IndexAdvisor).RuleImplicitConversion, // ARG.003
(*IndexAdvisor).RuleGroupByConst, // CLA.004
(*IndexAdvisor).RuleOrderByConst, // CLA.005
(*IndexAdvisor).RuleUpdatePrimaryKey, // CLA.016
// (*IndexAdvisor).RuleImpossibleOuterJoin, // TODO: JOI.003, JOI.004
(*IndexAdvisor).RuleGroupByConst, // CLA.004
(*IndexAdvisor).RuleOrderByConst, // CLA.005
(*IndexAdvisor).RuleUpdatePrimaryKey, // CLA.016
}
for _, f := range ruleFuncs {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册