提交 dc6d2b3c 编写于 作者: martianzhang's avatar martianzhang

support #114 add heuristic rule KWR.004

上级 147ee2d0
......@@ -22,6 +22,7 @@ import (
"regexp"
"strconv"
"strings"
"unicode/utf8"
"github.com/XiaoMi/soar/ast"
"github.com/XiaoMi/soar/common"
......@@ -1393,6 +1394,22 @@ func (q *Query4Audit) RulePluralWord() Rule {
return rule
}
// RuleMultiBytesWord KWR.004
func (q *Query4Audit) RuleMultiBytesWord() Rule {
// TODO: 目前使用 utf8 字符集检查,其他字符集输入可能会有问题
var rule = q.RuleOK()
for _, tk := range ast.Tokenize(q.Query) {
switch tk.Type {
case ast.TokenTypeBacktickQuote, ast.TokenTypeWord:
if utf8.RuneCountInString(tk.Val) != len(tk.Val) {
rule = HeuristicRules["KWR.004"]
}
default:
}
}
return rule
}
// RuleInsertSelect LCK.001
func (q *Query4Audit) RuleInsertSelect() Rule {
var rule = q.RuleOK()
......@@ -3177,7 +3194,7 @@ func (q *Query4Audit) RuleStandardName() Rule {
rule = HeuristicRules["STA.004"]
}
case ast.TokenTypeWord:
// TOKEN_TYPE_WORD中处理连续下划线的情况,其他情况容易误伤
// TOKEN_TYPE_WORD 中处理连续下划线的情况,其他情况容易误伤
if strings.Contains(tk.Val, "__") {
rule = HeuristicRules["STA.004"]
}
......
......@@ -1035,6 +1035,44 @@ func TestRulePluralWord(t *testing.T) {
common.Log.Debug("Exiting function: %s", common.GetFunctionName())
}
// KWR.004
func TestRuleMultiBytesWord(t *testing.T) {
common.Log.Debug("Entering function: %s", common.GetFunctionName())
sqls := [][]string{
{
"select col as 列 from tb",
"select col as `列` from tb",
},
{
"select col as c from tb",
"select '列'",
},
}
for _, sql := range sqls[0] {
q, err := NewQuery4Audit(sql)
if err == nil {
rule := q.RuleMultiBytesWord()
if rule.Item != "KWR.004" {
t.Error("Rule not match:", rule.Item, "Expect : KWR.004")
}
} else {
t.Error("sqlparser.Parse Error:", err)
}
}
for _, sql := range sqls[1] {
q, err := NewQuery4Audit(sql)
if err == nil {
rule := q.RuleMultiBytesWord()
if rule.Item != "OK" {
t.Error("Rule not match:", rule.Item, "Expect : OK")
}
} else {
t.Error("sqlparser.Parse Error:", err)
}
}
common.Log.Debug("Exiting function: %s", common.GetFunctionName())
}
// LCK.001
func TestRuleInsertSelect(t *testing.T) {
common.Log.Debug("Entering function: %s", common.GetFunctionName())
......
......@@ -797,6 +797,14 @@ func init() {
Case: "CREATE TABLE tbl ( `books` int )",
Func: (*Query4Audit).RulePluralWord,
},
"KWR.004": {
Item: "KWR.004",
Severity: "L1",
Summary: "不建议使用使用多字节编码字符(中文)命名",
Content: `为库、表、列、别名命名时建议使用英文,数字,下划线等字符,不建议使用中文或其他多字节编码字符。`,
Case: "select col as 列 from tb",
Func: (*Query4Audit).RuleMultiBytesWord,
},
"LCK.001": {
Item: "LCK.001",
Severity: "L3",
......
......@@ -812,6 +812,16 @@ CREATE TABLE tbl ( `select` int )
```sql
CREATE TABLE tbl ( `books` int )
```
## 不建议使用使用多字节编码字符(中文)命名
* **Item**:KWR.004
* **Severity**:L1
* **Content**:为库、表、列、别名命名时建议使用英文,数字,下划线等字符,不建议使用中文或其他多字节编码字符。
* **Case**:
```sql
select col as 列 from tb
```
## INSERT INTO xx SELECT 加锁粒度较大请谨慎
* **Item**:LCK.001
......
......@@ -75,6 +75,7 @@ advisor.Rule{Item:"KEY.009", Severity:"L0", Summary:"添加唯一索引前请注
advisor.Rule{Item:"KWR.001", Severity:"L2", Summary:"SQL_CALC_FOUND_ROWS 效率低下", Content:"因为 SQL_CALC_FOUND_ROWS 不能很好地扩展,所以可能导致性能问题; 建议业务使用其他策略来替代 SQL_CALC_FOUND_ROWS 提供的计数功能,比如:分页结果展示等。", Case:"select SQL_CALC_FOUND_ROWS col from tbl where id>1000", Position:0, Func:func(*advisor.Query4Audit) advisor.Rule {...}}
advisor.Rule{Item:"KWR.002", Severity:"L2", Summary:"不建议使用 MySQL 关键字做列名或表名", Content:"当使用关键字做为列名或表名时程序需要对列名和表名进行转义,如果疏忽被将导致请求无法执行。", Case:"CREATE TABLE tbl ( `select` int )", Position:0, Func:func(*advisor.Query4Audit) advisor.Rule {...}}
advisor.Rule{Item:"KWR.003", Severity:"L1", Summary:"不建议使用复数做列名或表名", Content:"表名应该仅仅表示表里面的实体内容,不应该表示实体数量,对应于 DO 类名也是单数形式,符合表达习惯。", Case:"CREATE TABLE tbl ( `books` int )", Position:0, Func:func(*advisor.Query4Audit) advisor.Rule {...}}
advisor.Rule{Item:"KWR.004", Severity:"L1", Summary:"不建议使用使用多字节编码字符(中文)命名", Content:"为库、表、列、别名命名时建议使用英文,数字,下划线等字符,不建议使用中文或其他多字节编码字符。", Case:"select col as 列 from tb", Position:0, Func:func(*advisor.Query4Audit) advisor.Rule {...}}
advisor.Rule{Item:"LCK.001", Severity:"L3", Summary:"INSERT INTO xx SELECT 加锁粒度较大请谨慎", Content:"INSERT INTO xx SELECT 加锁粒度较大请谨慎", Case:"INSERT INTO tbl SELECT * FROM tbl2;", Position:0, Func:func(*advisor.Query4Audit) advisor.Rule {...}}
advisor.Rule{Item:"LCK.002", Severity:"L3", Summary:"请慎用 INSERT ON DUPLICATE KEY UPDATE", Content:"当主键为自增键时使用 INSERT ON DUPLICATE KEY UPDATE 可能会导致主键出现大量不连续快速增长,导致主键快速溢出无法继续写入。极端情况下还有可能导致主从数据不一致。", Case:"INSERT INTO t1(a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=c+1;", Position:0, Func:func(*advisor.Query4Audit) advisor.Rule {...}}
advisor.Rule{Item:"LIT.001", Severity:"L2", Summary:"用字符类型存储IP地址", Content:"字符串字面上看起来像IP地址,但不是 INET_ATON() 的参数,表示数据被存储为字符而不是整数。将IP地址存储为整数更为有效。", Case:"insert into tbl (IP,name) values('10.20.306.122','test')", Position:0, Func:func(*advisor.Query4Audit) advisor.Rule {...}}
......
......@@ -812,6 +812,16 @@ CREATE TABLE tbl ( `select` int )
```sql
CREATE TABLE tbl ( `books` int )
```
## 不建议使用使用多字节编码字符(中文)命名
* **Item**:KWR.004
* **Severity**:L1
* **Content**:为库、表、列、别名命名时建议使用英文,数字,下划线等字符,不建议使用中文或其他多字节编码字符。
* **Case**:
```sql
select col as from tb
```
## INSERT INTO xx SELECT 加锁粒度较大请谨慎
* **Item**:LCK.001
......
......@@ -1034,68 +1034,68 @@
{
"checksumSHA1": "q7Bd5YJHsxvzEpiOBaYn+wEpqyU=",
"path": "vitess.io/vitess",
"revision": "b0d2eee6a26cd87bbc748e2bd07fefaa44ef59be",
"revisionTime": "2018-11-19T18:27:10Z"
"revision": "32dd398dd5459e5cf15904db35aba7460519b612",
"revisionTime": "2018-11-22T02:19:16Z"
},
{
"checksumSHA1": "aKn1oKcY74N8TRLm3Ayt7Q4bbI4=",
"path": "vitess.io/vitess/go/bytes2",
"revision": "b0d2eee6a26cd87bbc748e2bd07fefaa44ef59be",
"revisionTime": "2018-11-19T18:27:10Z"
"revision": "32dd398dd5459e5cf15904db35aba7460519b612",
"revisionTime": "2018-11-22T02:19:16Z"
},
{
"checksumSHA1": "JVCEN4UGRmg3TofIBdzZMZ3G0Ww=",
"path": "vitess.io/vitess/go/hack",
"revision": "b0d2eee6a26cd87bbc748e2bd07fefaa44ef59be",
"revisionTime": "2018-11-19T18:27:10Z"
"revision": "32dd398dd5459e5cf15904db35aba7460519b612",
"revisionTime": "2018-11-22T02:19:16Z"
},
{
"checksumSHA1": "e1WJ7vCnVrlQQQlc6n/FewCDMso=",
"path": "vitess.io/vitess/go/sqltypes",
"revision": "b0d2eee6a26cd87bbc748e2bd07fefaa44ef59be",
"revisionTime": "2018-11-19T18:27:10Z"
"revision": "32dd398dd5459e5cf15904db35aba7460519b612",
"revisionTime": "2018-11-22T02:19:16Z"
},
{
"checksumSHA1": "ntFIQYkBS51G6y+FEkjFW40+HOU=",
"path": "vitess.io/vitess/go/vt/log",
"revision": "b0d2eee6a26cd87bbc748e2bd07fefaa44ef59be",
"revisionTime": "2018-11-19T18:27:10Z"
"revision": "32dd398dd5459e5cf15904db35aba7460519b612",
"revisionTime": "2018-11-22T02:19:16Z"
},
{
"checksumSHA1": "XozR8bmeSR5KTe/nlUJkpJY2HKI=",
"path": "vitess.io/vitess/go/vt/proto/query",
"revision": "b0d2eee6a26cd87bbc748e2bd07fefaa44ef59be",
"revisionTime": "2018-11-19T18:27:10Z"
"revision": "32dd398dd5459e5cf15904db35aba7460519b612",
"revisionTime": "2018-11-22T02:19:16Z"
},
{
"checksumSHA1": "OnWsUHLDKcO3spwH0jD55SvKD24=",
"path": "vitess.io/vitess/go/vt/proto/topodata",
"revision": "b0d2eee6a26cd87bbc748e2bd07fefaa44ef59be",
"revisionTime": "2018-11-19T18:27:10Z"
"revision": "32dd398dd5459e5cf15904db35aba7460519b612",
"revisionTime": "2018-11-22T02:19:16Z"
},
{
"checksumSHA1": "sBAuZ/itMR8U8qbK4yLHxkP6Cpc=",
"path": "vitess.io/vitess/go/vt/proto/vtgate",
"revision": "b0d2eee6a26cd87bbc748e2bd07fefaa44ef59be",
"revisionTime": "2018-11-19T18:27:10Z"
"revision": "32dd398dd5459e5cf15904db35aba7460519b612",
"revisionTime": "2018-11-22T02:19:16Z"
},
{
"checksumSHA1": "pLWM+SPGZs3k+IhjktE/cGUlpM0=",
"path": "vitess.io/vitess/go/vt/proto/vtrpc",
"revision": "b0d2eee6a26cd87bbc748e2bd07fefaa44ef59be",
"revisionTime": "2018-11-19T18:27:10Z"
"revision": "32dd398dd5459e5cf15904db35aba7460519b612",
"revisionTime": "2018-11-22T02:19:16Z"
},
{
"checksumSHA1": "2ZBC/pPjs13cocUf8PoMSvAO5u4=",
"path": "vitess.io/vitess/go/vt/sqlparser",
"revision": "b0d2eee6a26cd87bbc748e2bd07fefaa44ef59be",
"revisionTime": "2018-11-19T18:27:10Z"
"revision": "32dd398dd5459e5cf15904db35aba7460519b612",
"revisionTime": "2018-11-22T02:19:16Z"
},
{
"checksumSHA1": "oF4XzuOzwvj1iduX/lYqNSyY/HM=",
"path": "vitess.io/vitess/go/vt/vterrors",
"revision": "b0d2eee6a26cd87bbc748e2bd07fefaa44ef59be",
"revisionTime": "2018-11-19T18:27:10Z"
"revision": "32dd398dd5459e5cf15904db35aba7460519b612",
"revisionTime": "2018-11-22T02:19:16Z"
}
],
"rootPath": "github.com/XiaoMi/soar"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册