diff --git a/CHANGES.md b/CHANGES.md index a6327e8f16a00c3b17e064dc168b6ca0b3b2cee3..624cfd2fc37a712dad192471104d2b14982dd36f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,14 @@ # CHANGELOG +## 2019-08 +- Fix RuleImplicitConversion(ARG.003) with INT and DECIMAL +- Fix RuleImplicitConversion duplicate suggest when use IN () operator + +## 2019-07 +- Fix #213 CLA.001 NO WHERE CONDITION +- Fix PRIMARY key append to multi column index +- fingerprint verbose mode add id + ## 2019-05 - Fix issue #208 14c19f4 regression bug - Add max_execution_time hint for explain query diff --git a/advisor/heuristic.go b/advisor/heuristic.go index 06345e30ebcd5236f6c0d800461fe761b146456a..518f7020420d2562167075db56f944318c51dfb0 100644 --- a/advisor/heuristic.go +++ b/advisor/heuristic.go @@ -169,7 +169,7 @@ func (idxAdv *IndexAdvisor) RuleImplicitConversion() Rule { return rule } - var content string + var content []string conditions := ast.FindAllCondition(idxAdv.Ast) for _, cond := range conditions { var colList []*common.Column @@ -258,9 +258,9 @@ func (idxAdv *IndexAdvisor) RuleImplicitConversion() Rule { colList[0].Table, colList[0].Name, type1, colList[1].Table, colList[1].Name, type2) if strings.ToLower(type1) != strings.ToLower(type2) { - content += fmt.Sprintf("`%s`.`%s` (%s) VS `%s`.`%s` (%s) datatype not match", + content = append(content, fmt.Sprintf("`%s`.`%s` (%s) VS `%s`.`%s` (%s) datatype not match", colList[0].Table, colList[0].Name, type1, - colList[1].Table, colList[1].Name, type2) + colList[1].Table, colList[1].Name, type2)) continue } @@ -269,9 +269,9 @@ func (idxAdv *IndexAdvisor) RuleImplicitConversion() Rule { colList[0].Table, colList[0].Name, colList[0].Character, colList[1].Table, colList[1].Name, colList[1].Character) if colList[0].Character != colList[1].Character { - content += fmt.Sprintf("`%s`.`%s` (%s) VS `%s`.`%s` (%s) charset not match", + content = append(content, fmt.Sprintf("`%s`.`%s` (%s) VS `%s`.`%s` (%s) charset not match", colList[0].Table, colList[0].Name, colList[0].Character, - colList[1].Table, colList[1].Name, colList[1].Character) + colList[1].Table, colList[1].Name, colList[1].Character)) continue } @@ -280,9 +280,9 @@ func (idxAdv *IndexAdvisor) RuleImplicitConversion() Rule { colList[0].Table, colList[0].Name, colList[0].Collation, colList[1].Table, colList[1].Name, colList[1].Collation) if colList[0].Collation != colList[1].Collation { - content += fmt.Sprintf("`%s`.`%s` (%s) VS `%s`.`%s` (%s) collation not match", + content = append(content, fmt.Sprintf("`%s`.`%s` (%s) VS `%s`.`%s` (%s) collation not match", colList[0].Table, colList[0].Name, colList[0].Collation, - colList[1].Table, colList[1].Name, colList[1].Collation) + colList[1].Table, colList[1].Name, colList[1].Collation)) continue } } @@ -294,7 +294,8 @@ func (idxAdv *IndexAdvisor) RuleImplicitConversion() Rule { "date", "time", "datetime", "timestamp", "year", }, sqlparser.IntVal: { - "tinyint", "smallint", "mediumint", "int", "integer", "bigint", "timestamp", "year", "bit", + "tinyint", "smallint", "mediumint", "int", "integer", "bigint", + "timestamp", "year", "bit", "decimal", }, sqlparser.FloatVal: { "float", "double", "real", "decimal", @@ -333,7 +334,7 @@ func (idxAdv *IndexAdvisor) RuleImplicitConversion() Rule { colList[0].Table, colList[0].Name, colList[0].DataType, typNameMap[val.Type]) common.Log.Debug("Implicit data type conversion: %s", c) - content += c + content = append(content, c) } } @@ -343,9 +344,9 @@ func (idxAdv *IndexAdvisor) RuleImplicitConversion() Rule { // TODO } } - if content != "" { + if len(content) > 0 { rule = HeuristicRules["ARG.003"] - rule.Content = content + rule.Content = strings.Join(common.RemoveDuplicatesItem(content), " ") } return rule } diff --git a/advisor/index_test.go b/advisor/index_test.go index d00e1df469e5edc3fcfb73c0856310393dc762c1..677fff687dadaae3dfca9c73116fc8ceabc3cec7 100644 --- a/advisor/index_test.go +++ b/advisor/index_test.go @@ -83,11 +83,13 @@ func TestRuleImplicitConversion(t *testing.T) { "SELECT * FROM t1, t3 WHERE t1.title = t3.title;", "SELECT * FROM t1 WHERE title in (60, '60');", "SELECT * FROM t1 WHERE title in (60);", + "SELECT * FROM t1 WHERE title in (60, 60);", "SELECT * FROM t4 WHERE col = '1'", }, { // https://github.com/XiaoMi/soar/issues/151 "SELECT * FROM t4 WHERE col = 1", + "SELECT * FROM sakila.film WHERE rental_rate > 1", }, } for _, sql := range sqls[0] { diff --git a/test/fixture/test_Run_all_test_cases.golden b/test/fixture/test_Run_all_test_cases.golden index dda503e0ddd44f2c0b505302676966a3763732ba..8fca2033fce7fec2ed68480eeb81e7d31571ea1f 100644 --- a/test/fixture/test_Run_all_test_cases.golden +++ b/test/fixture/test_Run_all_test_cases.golden @@ -3861,7 +3861,7 @@ GROUP BY | id | select\_type | table | partitions | type | possible_keys | key | key\_len | ref | rows | filtered | scalability | Extra | |---|---|---|---|---|---|---|---|---|---|---|---|---| -| 1 | SIMPLE | *actor* | NULL | ref | idx\_actor\_last\_name | idx\_actor\_last\_name | 137 | const | 2 | 25.00% | O(log n) | Using where; Using temporary | +| 1 | SIMPLE | *actor* | NULL | ref | idx\_actor\_last\_name | idx\_actor\_last\_name | 137 | const | 2 | 33.33% | O(log n) | Using where; Using temporary | @@ -4607,7 +4607,7 @@ create table hello. t (id int unsigned) # Query: 291F95B7DCB74C21 -☆ ☆ ☆ ☆ ☆ 0分 +★ ★ ★ ★ ☆ 95分 ```sql @@ -4619,10 +4619,6 @@ WHERE data >= '' ``` -## MySQL execute failed - -Unknown column 'data' in 'where clause' - ## 不建议使用 SELECT * 类型查询 * **Item:** COL.001 @@ -4643,8 +4639,6 @@ DROP DEFAULT ``` -## OK - # Query: B48292EDB9D0E010 ★ ★ ☆ ☆ ☆ 40分