diff --git a/advisor/heuristic.go b/advisor/heuristic.go index 3485c07ebffbd25c352256000348d4a7a9cdfcaf..a1e61527b78e8aca4605f0b2ef56b8b48d6e3d4b 100644 --- a/advisor/heuristic.go +++ b/advisor/heuristic.go @@ -31,6 +31,7 @@ import ( "github.com/percona/go-mysql/query" tidb "github.com/pingcap/parser/ast" "github.com/pingcap/parser/mysql" + "github.com/tidwall/gjson" "vitess.io/vitess/go/vt/sqlparser" ) @@ -1312,37 +1313,16 @@ func (q *Query4Audit) RuleLoadFile() Rule { func (q *Query4Audit) RuleMultiCompare() Rule { var rule = q.RuleOK() if q.TiStmt != nil { - for _, tiStmt := range q.TiStmt { - switch node := tiStmt.(type) { - case *tidb.SelectStmt: - switch where := node.Where.(type) { - case *tidb.BinaryOperationExpr: - switch where.L.(type) { - case *tidb.BinaryOperationExpr: - if where.Op.String() == "eq" { - rule = HeuristicRules["RES.009"] - } - } - } - case *tidb.UpdateStmt: - switch where := node.Where.(type) { - case *tidb.BinaryOperationExpr: - switch where.L.(type) { - case *tidb.BinaryOperationExpr: - if where.Op.String() == "eq" { - rule = HeuristicRules["RES.009"] - } - } - } - case *tidb.DeleteStmt: - switch where := node.Where.(type) { - case *tidb.BinaryOperationExpr: - switch where.L.(type) { - case *tidb.BinaryOperationExpr: - if where.Op.String() == "eq" { - rule = HeuristicRules["RES.009"] - } - } + json := ast.StmtNode2JSON(q.Query, "", "") + whereJSON := common.JSONFind(json, "Where") + for _, where := range whereJSON { + conds := []string{where} + conds = append(conds, common.JSONFind(where, "L")...) + conds = append(conds, common.JSONFind(where, "R")...) + for _, cond := range conds { + if gjson.Get(cond, "Op").Int() == 7 && gjson.Get(cond, "L.Op").Int() == 7 { + rule = HeuristicRules["RES.009"] + return rule } } } diff --git a/advisor/heuristic_test.go b/advisor/heuristic_test.go index e163f237f2d9956998c5351de56fdd29632dcd7c..be3359010ab674c48b0ce50da070158256672e95 100644 --- a/advisor/heuristic_test.go +++ b/advisor/heuristic_test.go @@ -946,6 +946,9 @@ func TestRuleMultiCompare(t *testing.T) { sqls := [][]string{ { "SELECT * FROM tbl WHERE col = col = 'abc'", + "SELECT * FROM tbl WHERE col = 'def' and col = col = 'abc'", + "SELECT * FROM tbl WHERE col = 'def' or col = col = 'abc'", + "SELECT * FROM tbl WHERE col = col = 'abc' and col = 'def'", "UPDATE tbl set col = 1 WHERE col = col = 'abc'", "DELETE FROM tbl WHERE col = col = 'abc'", },