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

fix RuleDateNotQuote spell error

上级 f720930c
......@@ -960,8 +960,8 @@ func (q *Query4Audit) RuleIPString() Rule {
return rule
}
// RuleDataNotQuote LIT.002
func (q *Query4Audit) RuleDataNotQuote() Rule {
// RuleDateNotQuote LIT.002
func (q *Query4Audit) RuleDateNotQuote() Rule {
var rule = q.RuleOK()
// by pass insert except, insert select
......@@ -984,6 +984,10 @@ func (q *Query4Audit) RuleDataNotQuote() Rule {
re = regexp.MustCompile(`^['"\w-].*`)
if re.FindString(sql) == "" {
rule = HeuristicRules["LIT.002"]
if position := re.FindIndex([]byte(q.Query)); len(position) > 0 {
rule.Position = position[0]
}
return rule
}
}
......@@ -993,13 +997,13 @@ func (q *Query4Audit) RuleDataNotQuote() Rule {
for _, sql := range sqls {
re = regexp.MustCompile(`^['"\w-].*`)
if re.FindString(sql) == "" {
if position := re.FindIndex([]byte(q.Query)); len(position) > 0 {
rule.Position = position[0]
}
rule = HeuristicRules["LIT.002"]
}
}
if position := re.FindIndex([]byte(q.Query)); len(position) > 0 {
rule.Position = position[0]
}
return rule
}
......
......@@ -665,13 +665,14 @@ func TestRuleIPString(t *testing.T) {
}
// LIT.002
func TestRuleDataNotQuote(t *testing.T) {
func TestRuleDateNotQuote(t *testing.T) {
common.Log.Debug("Entering function: %s", common.GetFunctionName())
sqls := [][]string{
{
"select col1,col2 from tbl where time < 2018-01-10",
"select col1,col2 from tbl where time < 18-01-10",
"INSERT INTO tb1 SELECT * FROM tb2 WHERE time < 2020-01-10",
`select * from tb where col < ' 2022-01-10'`,
},
{
"select col1,col2 from tbl where time < '2018-01-10'",
......@@ -684,7 +685,7 @@ func TestRuleDataNotQuote(t *testing.T) {
for _, sql := range sqls[0] {
q, err := NewQuery4Audit(sql)
if err == nil {
rule := q.RuleDataNotQuote()
rule := q.RuleDateNotQuote()
if rule.Item != "LIT.002" {
t.Error("Rule not match:", rule.Item, "Expect : LIT.002")
}
......@@ -696,7 +697,7 @@ func TestRuleDataNotQuote(t *testing.T) {
for _, sql := range sqls[1] {
q, err := NewQuery4Audit(sql)
if err == nil {
rule := q.RuleDataNotQuote()
rule := q.RuleDateNotQuote()
if rule.Item != "OK" {
t.Error("Rule not match:", rule.Item, "Expect : OK")
}
......
......@@ -918,9 +918,9 @@ func InitHeuristicRules() {
Item: "LIT.002",
Severity: "L4",
Summary: "日期/时间未使用引号括起",
Content: `诸如“WHERE col <2010-02-12”之类的查询是有效的SQL,但可能是一个错误,因为它将被解释为“WHERE col <1996”; 日期/时间文字应该加引号。`,
Content: `诸如“WHERE col <2010-02-12”之类的查询是有效的SQL,但可能是一个错误,因为它将被解释为“WHERE col <1996”; 日期/时间文字应该加引号,且引号前后不应有空格。`,
Case: "select col1,col2 from tbl where time < 2018-01-10",
Func: (*Query4Audit).RuleDataNotQuote,
Func: (*Query4Audit).RuleDateNotQuote,
},
"LIT.003": {
Item: "LIT.003",
......
......@@ -956,7 +956,7 @@ insert into tbl (IP,name) values('10.20.306.122','test')
* **Item**:LIT.002
* **Severity**:L4
* **Content**:诸如“WHERE col <2010-02-12”之类的查询是有效的SQL,但可能是一个错误,因为它将被解释为“WHERE col <1996”; 日期/时间文字应该加引号。
* **Content**:诸如“WHERE col <2010-02-12”之类的查询是有效的SQL,但可能是一个错误,因为它将被解释为“WHERE col <1996”; 日期/时间文字应该加引号,且引号前后不应有空格
* **Case**:
```sql
......
......@@ -89,7 +89,7 @@ advisor.Rule{Item:"KWR.005", Severity:"L1", Summary:"SQL 中包含 unicode 特
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 {...}}
advisor.Rule{Item:"LIT.002", Severity:"L4", Summary:"日期/时间未使用引号括起", Content:"诸如“WHERE col <2010-02-12”之类的查询是有效的SQL,但可能是一个错误,因为它将被解释为“WHERE col <1996”; 日期/时间文字应该加引号。", Case:"select col1,col2 from tbl where time < 2018-01-10", Position:0, Func:func(*advisor.Query4Audit) advisor.Rule {...}}
advisor.Rule{Item:"LIT.002", Severity:"L4", Summary:"日期/时间未使用引号括起", Content:"诸如“WHERE col <2010-02-12”之类的查询是有效的SQL,但可能是一个错误,因为它将被解释为“WHERE col <1996”; 日期/时间文字应该加引号,且引号前后不应有空格。", Case:"select col1,col2 from tbl where time < 2018-01-10", Position:0, Func:func(*advisor.Query4Audit) advisor.Rule {...}}
advisor.Rule{Item:"LIT.003", Severity:"L3", Summary:"一列中存储一系列相关数据的集合", Content:"将 ID 存储为一个列表,作为 VARCHAR/TEXT 列,这样能导致性能和数据完整性问题。查询这样的列需要使用模式匹配的表达式。使用逗号分隔的列表来做多表联结查询定位一行数据是极不优雅和耗时的。这将使验证 ID 更加困难。考虑一下,列表最多支持存放多少数据呢?将 ID 存储在一张单独的表中,代替使用多值属性,从而每个单独的属性值都可以占据一行。这样交叉表实现了两张表之间的多对多关系。这将更好地简化查询,也更有效地验证ID。", Case:"select c1,c2,c3,c4 from tab1 where col_id REGEXP '[[:<:]]12[[:>:]]'", Position:0, Func:func(*advisor.Query4Audit) advisor.Rule {...}}
advisor.Rule{Item:"LIT.004", Severity:"L1", Summary:"请使用分号或已设定的 DELIMITER 结尾", Content:"USE database, SHOW DATABASES 等命令也需要使用使用分号或已设定的 DELIMITER 结尾。", Case:"USE db", Position:0, Func:func(*advisor.Query4Audit) advisor.Rule {...}}
advisor.Rule{Item:"OK", Severity:"L0", Summary:"OK", Content:"OK", Case:"OK", Position:0, Func:func(*advisor.Query4Audit) advisor.Rule {...}}
......
......@@ -956,7 +956,7 @@ insert into tbl (IP,name) values('10.20.306.122','test')
* **Item**:LIT.002
* **Severity**:L4
* **Content**:诸如“WHERE col <2010-02-12”之类的查询是有效的SQL,但可能是一个错误,因为它将被解释为“WHERE col <1996”; 日期/时间文字应该加引号。
* **Content**:诸如“WHERE col <2010-02-12”之类的查询是有效的SQL,但可能是一个错误,因为它将被解释为“WHERE col <1996”; 日期/时间文字应该加引号,且引号前后不应有空格
* **Case**:
```sql
......
......@@ -4416,7 +4416,7 @@ GROUP BY
* **Content:** 为列description添加索引,散粒度为: n%;
* **Case:** ALTER TABLE \`sakila\`.\`film\` add index \`idx\_description\` (\`description\`(255)) ;
* **Case:** ALTER TABLE \`sakila\`.\`film\` add index \`idx\_description\` (\`description\`(191)) ;
......@@ -4530,7 +4530,7 @@ ORDER BY
| id | select\_type | table | partitions | type | possible_keys | key | key\_len | ref | rows | filtered | scalability | Extra |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | SIMPLE | *NULL* | NULL | NULL | NULL | NULL | NULL | NULL | 0 | n% | NULL | Impossible WHERE |
| 1 | SIMPLE | *t* | NULL | ALL | NULL | NULL | NULL | NULL | 600 | n% | ☠️ **O(n)** | Using where; Using filesort |
......@@ -4540,9 +4540,15 @@ ORDER BY
* **SIMPLE**: 简单SELECT(不使用UNION或子查询等).
#### Type信息解读
* ☠️ **ALL**: 最坏的情况, 从头到尾全表扫描.
#### Extra信息解读
* **Impossible WHERE**: WHERE条件过滤没有效果, 最终是全表扫描.
* **Using where**: WHERE条件用于筛选出与下一个表匹配的数据然后返回给客户端. 除非故意做的全表扫描, 否则连接类型是ALL或者是index, 且在Extra列的值中没有Using Where, 则该查询可能是有问题的.
* ☠️ **Using filesort**: MySQL会对结果使用一个外部索引排序,而不是从表里按照索引次序读到相关内容. 可能在内存或者磁盘上进行排序. MySQL中无法利用索引完成的排序操作称为'文件排序'.
## 为sakila库的city表添加索引
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册