diff --git a/advisor/heuristic.go b/advisor/heuristic.go index ac2958c2ac01d2224d69e884c9b3f52c489019a8..1d57a0f05b951afd938457ca28b13c8b7bba1fbd 100644 --- a/advisor/heuristic.go +++ b/advisor/heuristic.go @@ -133,16 +133,17 @@ func (q *Query4Audit) RuleEqualLike() Rule { if strings.ToLower(expr.Operator) == "like" { switch sqlval := expr.Right.(type) { case *sqlparser.SQLVal: - // not start with '%', '_' && not end with '%', '_' + // 1. string that not contain '%', '_' + // 2. int, bit, float without wildcard + var hasWildCard bool if sqlval.Type == 0 { - if sqlval.Val[0] != 0x25 && - sqlval.Val[0] != 0x5f && - sqlval.Val[len(sqlval.Val)-1] != 0x5f && - sqlval.Val[len(sqlval.Val)-1] != 0x25 { - rule = HeuristicRules["ARG.002"] - return false, nil + for _, sqlElem := range sqlval.Val { + if sqlElem == 0x25 || sqlElem == 0x5f { + hasWildCard = true + } } - } else { + } + if !hasWildCard { rule = HeuristicRules["ARG.002"] return false, nil } diff --git a/advisor/heuristic_test.go b/advisor/heuristic_test.go index 2c1120a6b26718d745c26a3a04addb09d142d4e0..c9af0c439709f88650baca9d16dc26c0a96b4d99 100644 --- a/advisor/heuristic_test.go +++ b/advisor/heuristic_test.go @@ -132,11 +132,18 @@ func TestRulePrefixLike(t *testing.T) { // ARG.002 func TestRuleEqualLike(t *testing.T) { common.Log.Debug("Entering function: %s", common.GetFunctionName()) - sqls := []string{ - "select col from tbl where id like 'abc'", - "select col from tbl where id like 1", + sqls := [][]string{ + { + "select col from tbl where id like 'abc'", + "select col from tbl where id like 1", + }, + { + "select col from tbl where id like 'abc%'", + "select col from tbl where id like '%abc'", + "select col from tbl where id like 'a%c'", // issue #273 + }, } - for _, sql := range sqls { + for _, sql := range sqls[0] { q, err := NewQuery4Audit(sql) if err == nil { rule := q.RuleEqualLike() @@ -147,6 +154,19 @@ func TestRuleEqualLike(t *testing.T) { t.Error("sqlparser.Parse Error:", err) } } + + for _, sql := range sqls[1] { + q, err := NewQuery4Audit(sql) + if err == nil { + rule := q.RuleEqualLike() + if rule.Item == "ARG.002" { + t.Error("Rule not match:", rule.Item, "Expect : OK") + } + } else { + t.Error("sqlparser.Parse Error:", err) + } + } + common.Log.Debug("Exiting function: %s", common.GetFunctionName()) }