提交 1b2c6850 编写于 作者: L LonelyChick

COL.014 modify the judgment about the character set;COL.012/COL.015 add the...

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