From 42517c944f47425bac64cb54a345e0f9e802bf0c Mon Sep 17 00:00:00 2001 From: Leon Zhang Date: Tue, 28 May 2019 15:08:59 +0800 Subject: [PATCH] Fix upgrade mysql driver import RuleMySQLError bug 1. update change log 2. fix ERR parse bug --- CHANGES.md | 14 +++ Makefile | 3 +- advisor/heuristic.go | 11 ++- test/fixture/test_Run_all_test_cases.golden | 98 +++++++++++++++++++++ 4 files changed, 122 insertions(+), 4 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index d4962b7..a6327e8 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,19 @@ # CHANGELOG +## 2019-05 +- Fix issue #208 14c19f4 regression bug +- Add max_execution_time hint for explain query +- Fix #205 create index rewrite error + +## 2019-04 +- Add test case for STA.004 +- RuleSpaceWithQuote add list range check +- Fix #199 -report-type=json add score +- Fix #98 JSON result format +- Fix index col compare case sensitive bug +- Fix ARG.008 cases: col = 1 OR col IS NULL +- Fix tokenize bug with multi type of quote + ## 2019-02 - add go.mod for go1.11 - add new -report-type query-type diff --git a/Makefile b/Makefile index c3a8576..d8c0934 100644 --- a/Makefile +++ b/Makefile @@ -191,7 +191,8 @@ docker: -e MYSQL_DATABASE=sakila \ -p 3306:3306 \ -v `pwd`/test/sql/init.sql.gz:/docker-entrypoint-initdb.d/init.sql.gz \ - $(MYSQL_RELEASE):$(MYSQL_VERSION) + $(MYSQL_RELEASE):$(MYSQL_VERSION) \ + --sql-mode "" @echo "waiting for sakila database initializing " @timeout=180; while [ $${timeout} -gt 0 ] ; do \ diff --git a/advisor/heuristic.go b/advisor/heuristic.go index d8377aa..3bfc81c 100644 --- a/advisor/heuristic.go +++ b/advisor/heuristic.go @@ -3763,9 +3763,14 @@ func RuleMySQLError(item string, err error) Rule { } } - // Received #1146 error from MySQL server: "table xxx doesn't exist" - errReg := regexp.MustCompile(`(?i)Received #([0-9]+) error from MySQL server: ['"](.*)['"]`) errStr := err.Error() + // Error 1071: Specified key was too long; max key length is 3072 bytes + errReg := regexp.MustCompile(`(?i)Error ([0-9]+): (.*)`) + if strings.HasPrefix(errStr, "Received") { + // Received #1146 error from MySQL server: "table xxx doesn't exist" + errReg = regexp.MustCompile(`(?i)Received #([0-9]+) error from MySQL server: ['"](.*)['"]`) + } + msg := errReg.FindStringSubmatch(errStr) var mysqlError MySQLError @@ -3798,7 +3803,7 @@ func RuleMySQLError(item string, err error) Rule { default: return Rule{ Item: item, - Summary: "MySQL execute failed: " + mysqlError.ErrString, + Summary: "MySQL execute failed", Severity: "L8", Content: mysqlError.ErrString, } diff --git a/test/fixture/test_Run_all_test_cases.golden b/test/fixture/test_Run_all_test_cases.golden index 00534de..9d37c63 100644 --- a/test/fixture/test_Run_all_test_cases.golden +++ b/test/fixture/test_Run_all_test_cases.golden @@ -974,6 +974,29 @@ GROUP BY address, district ``` +## Explain信息 + +| id | select\_type | table | partitions | type | possible_keys | key | key\_len | ref | rows | filtered | scalability | Extra | +|---|---|---|---|---|---|---|---|---|---|---|---|---| +| 1 | SIMPLE | *address* | NULL | ALL | NULL | NULL | NULL | NULL | 603 | ☠️ **100.00%** | ☠️ **O(n)** | Using temporary | + + + +### Explain信息解读 + +#### SelectType信息解读 + +* **SIMPLE**: 简单SELECT(不使用UNION或子查询等). + +#### Type信息解读 + +* ☠️ **ALL**: 最坏的情况, 从头到尾全表扫描. + +#### Extra信息解读 + +* ☠️ **Using temporary**: 表示MySQL在对查询结果排序时使用临时表. 常见于排序order by和分组查询group by. + + ## 为sakila库的address表添加索引 * **Item:** IDX.001 @@ -1090,6 +1113,33 @@ ORDER BY language_id ``` +## Explain信息 + +| id | select\_type | table | partitions | type | possible_keys | key | key\_len | ref | rows | filtered | scalability | Extra | +|---|---|---|---|---|---|---|---|---|---|---|---|---| +| 1 | SIMPLE | *film* | NULL | ALL | NULL | NULL | NULL | NULL | 1000 | 10.00% | ☠️ **O(n)** | Using where; Using temporary; Using filesort | + + + +### Explain信息解读 + +#### SelectType信息解读 + +* **SIMPLE**: 简单SELECT(不使用UNION或子查询等). + +#### Type信息解读 + +* ☠️ **ALL**: 最坏的情况, 从头到尾全表扫描. + +#### Extra信息解读 + +* **Using where**: WHERE条件用于筛选出与下一个表匹配的数据然后返回给客户端. 除非故意做的全表扫描, 否则连接类型是ALL或者是index, 且在Extra列的值中没有Using Where, 则该查询可能是有问题的. + +* ☠️ **Using filesort**: MySQL会对结果使用一个外部索引排序,而不是从表里按照索引次序读到相关内容. 可能在内存或者磁盘上进行排序. MySQL中无法利用索引完成的排序操作称为'文件排序'. + +* ☠️ **Using temporary**: 表示MySQL在对查询结果排序时使用临时表. 常见于排序order by和分组查询group by. + + ## 为sakila库的film表添加索引 * **Item:** IDX.001 @@ -3887,6 +3937,31 @@ GROUP BY first_name ``` +## Explain信息 + +| 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 | 14.29% | O(log n) | Using where; Using temporary | + + + +### Explain信息解读 + +#### SelectType信息解读 + +* **SIMPLE**: 简单SELECT(不使用UNION或子查询等). + +#### Type信息解读 + +* **ref**: 连接不能基于关键字选择单个行, 可能查找到多个符合条件的行. 叫做ref是因为索引要跟某个参考值相比较. 这个参考值或者是一个数, 或者是来自一个表里的多表查询的结果值. 例:'SELECT * FROM tbl WHERE idx_col=expr;'. + +#### Extra信息解读 + +* **Using where**: WHERE条件用于筛选出与下一个表匹配的数据然后返回给客户端. 除非故意做的全表扫描, 否则连接类型是ALL或者是index, 且在Extra列的值中没有Using Where, 则该查询可能是有问题的. + +* ☠️ **Using temporary**: 表示MySQL在对查询结果排序时使用临时表. 常见于排序order by和分组查询group by. + + ## 为sakila库的actor表添加索引 * **Item:** IDX.001 @@ -4248,6 +4323,29 @@ GROUP BY DATE( last_update) ``` +## Explain信息 + +| id | select\_type | table | partitions | type | possible_keys | key | key\_len | ref | rows | filtered | scalability | Extra | +|---|---|---|---|---|---|---|---|---|---|---|---|---| +| 1 | SIMPLE | *film* | NULL | ALL | NULL | NULL | NULL | NULL | 1000 | ☠️ **100.00%** | ☠️ **O(n)** | Using temporary | + + + +### Explain信息解读 + +#### SelectType信息解读 + +* **SIMPLE**: 简单SELECT(不使用UNION或子查询等). + +#### Type信息解读 + +* ☠️ **ALL**: 最坏的情况, 从头到尾全表扫描. + +#### Extra信息解读 + +* ☠️ **Using temporary**: 表示MySQL在对查询结果排序时使用临时表. 常见于排序order by和分组查询group by. + + ## 最外层 SELECT 未指定 WHERE 条件 * **Item:** CLA.001 -- GitLab