未验证 提交 5c36e33c 编写于 作者: L LonelyChick 提交者: GitHub

Merge pull request #262 from LonelyChick/dev

COL.014 modify the judgment about the character set;COL.012/COL.015 a…
......@@ -832,7 +832,7 @@ func (q *Query4Audit) RuleAddDefaultValue() Rule {
}
switch c.Tp.Tp {
case mysql.TypeBlob, mysql.TypeTinyBlob, mysql.TypeMediumBlob, mysql.TypeLongBlob:
case mysql.TypeBlob, mysql.TypeTinyBlob, mysql.TypeMediumBlob, mysql.TypeLongBlob, mysql.TypeJSON:
colDefault = true
}
......@@ -855,7 +855,7 @@ func (q *Query4Audit) RuleAddDefaultValue() Rule {
}
switch c.Tp.Tp {
case mysql.TypeBlob, mysql.TypeTinyBlob, mysql.TypeMediumBlob, mysql.TypeLongBlob:
case mysql.TypeBlob, mysql.TypeTinyBlob, mysql.TypeMediumBlob, mysql.TypeLongBlob, mysql.TypeJSON:
colDefault = true
}
......@@ -2677,8 +2677,14 @@ func (q *Query4Audit) RuleAlterCharset() Rule {
for _, option := range spec.Options {
if option.Tp == tidb.TableOptionCharset ||
option.Tp == tidb.TableOptionCollate {
rule = HeuristicRules["ALT.001"]
break
//增加CONVERT TO的判断
convertReg, _ := regexp.Compile("convert to")
if convertReg.Match([]byte(strings.ToLower(q.Query))) {
break
} else {
rule = HeuristicRules["ALT.001"]
break
}
}
}
}
......@@ -2755,7 +2761,7 @@ func (q *Query4Audit) RuleBLOBNotNull() Rule {
continue
}
switch col.Tp.Tp {
case mysql.TypeBlob, mysql.TypeTinyBlob, mysql.TypeMediumBlob, mysql.TypeLongBlob:
case mysql.TypeBlob, mysql.TypeTinyBlob, mysql.TypeMediumBlob, mysql.TypeLongBlob, mysql.TypeJSON:
for _, opt := range col.Options {
if opt.Tp == tidb.ColumnOptionNotNull {
rule = HeuristicRules["COL.012"]
......@@ -2778,7 +2784,7 @@ func (q *Query4Audit) RuleBLOBNotNull() Rule {
continue
}
switch col.Tp.Tp {
case mysql.TypeBlob, mysql.TypeTinyBlob, mysql.TypeMediumBlob, mysql.TypeLongBlob:
case mysql.TypeBlob, mysql.TypeTinyBlob, mysql.TypeMediumBlob, mysql.TypeLongBlob, mysql.TypeJSON:
for _, opt := range col.Options {
if opt.Tp == tidb.ColumnOptionNotNull {
rule = HeuristicRules["COL.012"]
......@@ -3105,7 +3111,8 @@ func (q *Query4Audit) RuleColumnWithCharset() Rule {
for _, tk := range tks {
if tk.Type == ast.TokenTypeWord {
switch strings.TrimSpace(strings.ToLower(tk.Val)) {
case "national", "nvarchar", "nchar", "nvarchar(", "nchar(", "character":
//character移到后面检查
case "national", "nvarchar", "nchar", "nvarchar(", "nchar(":
rule = HeuristicRules["COL.014"]
return rule
}
......@@ -3121,6 +3128,16 @@ func (q *Query4Audit) RuleColumnWithCharset() Rule {
continue
}
if col.Tp.Charset != "" || col.Tp.Collate != "" {
if col.Tp.Charset == "binary" || col.Tp.Collate == "binary" {
continue
} else {
rule = HeuristicRules["COL.014"]
break
}
}
//在这里检查character
characterReg, _ := regexp.Compile("character set")
if characterReg.Match([]byte(strings.ToLower(q.Query))) {
rule = HeuristicRules["COL.014"]
break
}
......@@ -3135,6 +3152,15 @@ func (q *Query4Audit) RuleColumnWithCharset() Rule {
continue
}
if col.Tp.Charset != "" || col.Tp.Collate != "" {
if col.Tp.Charset == "binary" || col.Tp.Collate == "binary" {
continue
} else {
rule = HeuristicRules["COL.014"]
break
}
}
characterReg, _ := regexp.Compile("character set")
if characterReg.Match([]byte(strings.ToLower(q.Query))) {
rule = HeuristicRules["COL.014"]
break
}
......@@ -3339,7 +3365,7 @@ func (q *Query4Audit) RuleBlobDefaultValue() Rule {
continue
}
switch col.Tp.Tp {
case mysql.TypeBlob, mysql.TypeMediumBlob, mysql.TypeTinyBlob, mysql.TypeLongBlob:
case mysql.TypeBlob, mysql.TypeMediumBlob, mysql.TypeTinyBlob, mysql.TypeLongBlob, mysql.TypeJSON:
for _, opt := range col.Options {
if opt.Tp == tidb.ColumnOptionDefaultValue && opt.Expr.GetType().Tp != mysql.TypeNull {
rule = HeuristicRules["COL.015"]
......@@ -3358,7 +3384,7 @@ func (q *Query4Audit) RuleBlobDefaultValue() Rule {
continue
}
switch col.Tp.Tp {
case mysql.TypeBlob, mysql.TypeMediumBlob, mysql.TypeTinyBlob, mysql.TypeLongBlob:
case mysql.TypeBlob, mysql.TypeMediumBlob, mysql.TypeTinyBlob, mysql.TypeLongBlob, mysql.TypeJSON:
for _, opt := range col.Options {
if opt.Tp == tidb.ColumnOptionDefaultValue && opt.Expr.GetType().Tp != mysql.TypeNull {
rule = HeuristicRules["COL.015"]
......
......@@ -3258,17 +3258,24 @@ func TestRuleBlobDefaultValue(t *testing.T) {
sqls := [][]string{
{
"CREATE TABLE `tb` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `c` blob NOT NULL DEFAULT '', PRIMARY KEY (`id`));",
"CREATE TABLE `tb` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT, `c` json NOT NULL DEFAULT '', PRIMARY KEY (`id`));",
"alter table `tb` add column `c` blob NOT NULL DEFAULT '';",
"alter table `tb` add column `c` json NOT NULL DEFAULT '';",
},
{
"CREATE TABLE `tb` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `c` blob NOT NULL, PRIMARY KEY (`id`));",
"CREATE TABLE `tb` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `c` json NOT NULL, PRIMARY KEY (`id`));",
"CREATE TABLE `tb` (`col` text NOT NULL);",
"alter table `tb` add column `c` blob NOT NULL;",
"alter table `tb` add column `c` json NOT NULL;",
"ALTER TABLE tb ADD COLUMN a BLOB DEFAULT NULL",
"ALTER TABLE tb ADD COLUMN a JSON DEFAULT NULL",
"CREATE TABLE tb ( a BLOB DEFAULT NULL)",
"CREATE TABLE tb ( a JSON DEFAULT NULL)",
"alter TABLE `tbl` add column `c` longblob;",
"alter TABLE `tbl` add column `c` text;",
"alter TABLE `tbl` add column `c` blob;",
"alter TABLE `tbl` add column `c` json;",
},
}
......
......@@ -523,8 +523,8 @@ func init() {
"COL.012": {
Item: "COL.012",
Severity: "L5",
Summary: "BLOB 和 TEXT 类型的字段不建议设置为 NOT NULL",
Content: `BLOB 和 TEXT 类型的字段无法指定非 NULL 的默认值,如果添加了 NOT NULL 限制,写入数据时又未对该字段指定值可能导致写入失败。`,
Summary: "TEXT、BLOB 和 JSON 类型的字段不建议设置为 NOT NULL",
Content: `TEXT、BLOB 和 JSON 类型的字段无法指定非 NULL 的默认值,如果添加了 NOT NULL 限制,写入数据时又未对该字段指定值可能导致写入失败。`,
Case: "CREATE TABLE `tb`(`c` longblob NOT NULL);",
Func: (*Query4Audit).RuleBLOBNotNull,
},
......@@ -548,8 +548,8 @@ func init() {
"COL.015": {
Item: "COL.015",
Severity: "L4",
Summary: "TEXT 和 BLOB 类型的字段不可指定非 NULL 的默认值",
Content: `MySQL 数据库中 TEXT 和 BLOB 类型的字段不可指定非 NULL 的默认值。TEXT最大长度为2^16-1个字符,MEDIUMTEXT最大长度为2^32-1个字符,LONGTEXT最大长度为2^64-1个字符。`,
Summary: "TEXT、BLOB 和 JSON 类型的字段不可指定非 NULL 的默认值",
Content: `MySQL 数据库中 TEXT、BLOB 和 JSON 类型的字段不可指定非 NULL 的默认值。TEXT最大长度为2^16-1个字符,MEDIUMTEXT最大长度为2^32-1个字符,LONGTEXT最大长度为2^64-1个字符。`,
Case: "CREATE TABLE `tbl` (`c` blob DEFAULT NULL);",
Func: (*Query4Audit).RuleBlobDefaultValue,
},
......
......@@ -476,7 +476,7 @@ select c1,c2,c3 from tbl where c4 is null or c4 <> 1
* **Item**:COL.012
* **Severity**:L5
* **Content**:BLOB 和 TEXT 类型的字段无法指定非 NULL 的默认值,如果添加了 NOT NULL 限制,写入数据时又未对该字段指定值可能导致写入失败。
* **Content**:TEXT、BLOB 和 JSON 类型的字段无法指定非 NULL 的默认值,如果添加了 NOT NULL 限制,写入数据时又未对该字段指定值可能导致写入失败。
* **Case**:
```sql
......@@ -506,7 +506,7 @@ CREATE TABLE `tb2` ( `id` int(11) DEFAULT NULL, `col` char(10) CHARACTER SET utf
* **Item**:COL.015
* **Severity**:L4
* **Content**:MySQL 数据库中 TEXT 和 BLOB 类型的字段不可指定非 NULL 的默认值。TEXT最大长度为2^16-1个字符,MEDIUMTEXT最大长度为2^32-1个字符,LONGTEXT最大长度为2^64-1个字符。
* **Content**:MySQL 数据库中 TEXT、BLOB 和 JSON 类型的字段不可指定非 NULL 的默认值。TEXT最大长度为2^16-1个字符,MEDIUMTEXT最大长度为2^32-1个字符,LONGTEXT最大长度为2^64-1个字符。
* **Case**:
```sql
......
......@@ -70,6 +70,15 @@ type tableStatusRow struct {
Comment []byte // 注释
}
// 记录去除逗号类型是外健还是分区表
type deleteComaType int8
const (
_ deleteComaType = iota
CS
PART
)
// newTableStat 构造 table Stat 对象
func newTableStat(tableName string) *TableStatInfo {
return &TableStatInfo{
......@@ -478,21 +487,37 @@ func (db *Connector) ShowCreateTable(tableName string) (string, error) {
if len(lines) > 2 {
var noConstraint []string
relationReg, _ := regexp.Compile("CONSTRAINT")
partitionReg, _ := regexp.Compile("PARTITIONS")
var DeleteComaT deleteComaType
for _, line := range lines[1 : len(lines)-1] {
if relationReg.Match([]byte(line)) {
DeleteComaT = CS
continue
} else if partitionReg.Match([]byte(line)) {
DeleteComaT = PART
}
line = strings.TrimSuffix(line, ",")
noConstraint = append(noConstraint, line)
}
// 去除外键语句会使DDL中多一个','导致语法错误,要把多余的逗号去除
ddl = fmt.Sprint(
lines[0], "\n",
strings.Join(noConstraint, ",\n"), "\n",
lines[len(lines)-1],
)
// len(lines) > 2的判断方式有问题,如果是分区表也会判断成为外键语句,导致建表语句的逗号错乱
if DeleteComaT == CS {
ddl = fmt.Sprint(
lines[0], "\n",
strings.Join(noConstraint, ",\n"), "\n",
lines[len(lines)-1],
)
} else if DeleteComaT == PART {
ddl = fmt.Sprint(
lines[0], "\n",
strings.Join(noConstraint, ",\n"), "\n",
lines[len(lines)-3],
)
}
}
return ddl, err
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册