From d9d7627a4d65a887651a2cf922fbe0cec8fd6e1d Mon Sep 17 00:00:00 2001 From: Leon Zhang Date: Fri, 14 Dec 2018 11:41:40 +0800 Subject: [PATCH] fix #163 column.Tp may be nil when checking --- advisor/heuristic.go | 69 +++++++++++++++++++++++++++++++++++++++ advisor/heuristic_test.go | 2 ++ vendor/vendor.json | 68 +++++++++++++++++++------------------- 3 files changed, 105 insertions(+), 34 deletions(-) diff --git a/advisor/heuristic.go b/advisor/heuristic.go index 8945f03..0b82982 100644 --- a/advisor/heuristic.go +++ b/advisor/heuristic.go @@ -1629,6 +1629,9 @@ func (q *Query4Audit) RuleImpreciseDataType() Rule { case *tidb.CreateTableStmt: // Create table statement for _, col := range node.Cols { + if col.Tp == nil { + continue + } switch col.Tp.Tp { case mysql.TypeFloat, mysql.TypeDouble, mysql.TypeDecimal, mysql.TypeNewDecimal: rule = HeuristicRules["COL.009"] @@ -1641,6 +1644,9 @@ func (q *Query4Audit) RuleImpreciseDataType() Rule { switch spec.Tp { case tidb.AlterTableAddColumns, tidb.AlterTableChangeColumn, tidb.AlterTableModifyColumn: for _, col := range spec.NewColumns { + if col.Tp == nil { + continue + } switch col.Tp.Tp { case mysql.TypeFloat, mysql.TypeDouble, mysql.TypeDecimal, mysql.TypeNewDecimal: @@ -1686,6 +1692,9 @@ func (q *Query4Audit) RuleValuesInDefinition() Rule { switch node := tiStmt.(type) { case *tidb.CreateTableStmt: for _, col := range node.Cols { + if col.Tp == nil { + continue + } switch col.Tp.Tp { case mysql.TypeSet, mysql.TypeEnum, mysql.TypeBit: rule = HeuristicRules["COL.010"] @@ -1696,6 +1705,9 @@ func (q *Query4Audit) RuleValuesInDefinition() Rule { switch spec.Tp { case tidb.AlterTableAddColumns, tidb.AlterTableChangeColumn, tidb.AlterTableModifyColumn: for _, col := range spec.NewColumns { + if col.Tp == nil { + continue + } switch col.Tp.Tp { case mysql.TypeSet, mysql.TypeEnum, mysql.TypeBit: rule = HeuristicRules["COL.010"] @@ -2238,6 +2250,9 @@ func (q *Query4Audit) RuleReadablePasswords() Rule { switch node := tiStmt.(type) { case *tidb.CreateTableStmt: for _, col := range node.Cols { + if col.Tp == nil { + continue + } switch col.Tp.Tp { case mysql.TypeString, mysql.TypeVarchar, mysql.TypeVarString, mysql.TypeBlob, mysql.TypeTinyBlob, mysql.TypeMediumBlob: @@ -2253,6 +2268,9 @@ func (q *Query4Audit) RuleReadablePasswords() Rule { switch spec.Tp { case tidb.AlterTableModifyColumn, tidb.AlterTableChangeColumn, tidb.AlterTableAddColumns: for _, col := range spec.NewColumns { + if col.Tp == nil { + continue + } switch col.Tp.Tp { case mysql.TypeString, mysql.TypeVarchar, mysql.TypeVarString, mysql.TypeBlob, mysql.TypeTinyBlob, mysql.TypeMediumBlob: @@ -2426,6 +2444,9 @@ func (q *Query4Audit) RuleVarcharVSChar() Rule { switch node := tiStmt.(type) { case *tidb.CreateTableStmt: for _, col := range node.Cols { + if col.Tp == nil { + continue + } switch col.Tp.Tp { // 在 TiDB 的 AST 中,char 和 binary 的 type 都是 mysql.TypeString // 只是 binary 数据类型的 character 和 collate 是 binary @@ -2439,6 +2460,9 @@ func (q *Query4Audit) RuleVarcharVSChar() Rule { switch spec.Tp { case tidb.AlterTableAddColumns, tidb.AlterTableChangeColumn, tidb.AlterTableModifyColumn: for _, col := range spec.NewColumns { + if col.Tp == nil { + continue + } switch col.Tp.Tp { case mysql.TypeString: rule = HeuristicRules["COL.008"] @@ -2553,6 +2577,9 @@ func (q *Query4Audit) RuleBLOBNotNull() Rule { switch node := tiStmt.(type) { case *tidb.CreateTableStmt: for _, col := range node.Cols { + if col.Tp == nil { + continue + } switch col.Tp.Tp { case mysql.TypeBlob, mysql.TypeTinyBlob, mysql.TypeMediumBlob, mysql.TypeLongBlob: for _, opt := range col.Options { @@ -2573,6 +2600,9 @@ func (q *Query4Audit) RuleBLOBNotNull() Rule { switch spec.Tp { case tidb.AlterTableAddColumns, tidb.AlterTableModifyColumn, tidb.AlterTableChangeColumn: for _, col := range spec.NewColumns { + if col.Tp == nil { + continue + } switch col.Tp.Tp { case mysql.TypeBlob, mysql.TypeTinyBlob, mysql.TypeMediumBlob, mysql.TypeLongBlob: for _, opt := range col.Options { @@ -2808,6 +2838,9 @@ func (q *Query4Audit) RuleTimestampDefault() Rule { switch node := tiStmt.(type) { case *tidb.CreateTableStmt: for _, col := range node.Cols { + if col.Tp == nil { + continue + } if col.Tp.Tp == mysql.TypeTimestamp { hasDefault := false for _, option := range col.Options { @@ -2829,6 +2862,9 @@ func (q *Query4Audit) RuleTimestampDefault() Rule { tidb.AlterTableChangeColumn, tidb.AlterTableAlterColumn: for _, col := range spec.NewColumns { + if col.Tp == nil { + continue + } if col.Tp.Tp == mysql.TypeTimestamp { hasDefault := false for _, option := range col.Options { @@ -2879,6 +2915,9 @@ func (q *Query4Audit) RuleColumnWithCharset() Rule { switch node := tiStmt.(type) { case *tidb.CreateTableStmt: for _, col := range node.Cols { + if col.Tp == nil { + continue + } if col.Tp.Charset != "" || col.Tp.Collate != "" { rule = HeuristicRules["COL.014"] break @@ -2890,6 +2929,9 @@ func (q *Query4Audit) RuleColumnWithCharset() Rule { case tidb.AlterTableAlterColumn, tidb.AlterTableChangeColumn, tidb.AlterTableModifyColumn, tidb.AlterTableAddColumns: for _, col := range spec.NewColumns { + if col.Tp == nil { + continue + } if col.Tp.Charset != "" || col.Tp.Collate != "" { rule = HeuristicRules["COL.014"] break @@ -3091,6 +3133,9 @@ func (q *Query4Audit) RuleBlobDefaultValue() Rule { switch node := tiStmt.(type) { case *tidb.CreateTableStmt: for _, col := range node.Cols { + if col.Tp == nil { + continue + } switch col.Tp.Tp { case mysql.TypeBlob, mysql.TypeMediumBlob, mysql.TypeTinyBlob, mysql.TypeLongBlob: for _, opt := range col.Options { @@ -3107,6 +3152,9 @@ func (q *Query4Audit) RuleBlobDefaultValue() Rule { case tidb.AlterTableModifyColumn, tidb.AlterTableAlterColumn, tidb.AlterTableChangeColumn, tidb.AlterTableAddColumns: for _, col := range spec.NewColumns { + if col.Tp == nil { + continue + } switch col.Tp.Tp { case mysql.TypeBlob, mysql.TypeMediumBlob, mysql.TypeTinyBlob, mysql.TypeLongBlob: for _, opt := range col.Options { @@ -3134,6 +3182,9 @@ func (q *Query4Audit) RuleIntPrecision() Rule { switch node := tiStmt.(type) { case *tidb.CreateTableStmt: for _, col := range node.Cols { + if col.Tp == nil { + continue + } switch col.Tp.Tp { case mysql.TypeLong: if (col.Tp.Flen < 10 || col.Tp.Flen > 11) && col.Tp.Flen > 0 { @@ -3154,6 +3205,9 @@ func (q *Query4Audit) RuleIntPrecision() Rule { case tidb.AlterTableAddColumns, tidb.AlterTableChangeColumn, tidb.AlterTableAlterColumn, tidb.AlterTableModifyColumn: for _, col := range spec.NewColumns { + if col.Tp == nil { + continue + } switch col.Tp.Tp { case mysql.TypeLong: if (col.Tp.Flen < 10 || col.Tp.Flen > 11) && col.Tp.Flen > 0 { @@ -3185,6 +3239,9 @@ func (q *Query4Audit) RuleVarcharLength() Rule { switch node := tiStmt.(type) { case *tidb.CreateTableStmt: for _, col := range node.Cols { + if col.Tp == nil { + continue + } switch col.Tp.Tp { case mysql.TypeVarchar, mysql.TypeVarString: if col.Tp.Flen > common.Config.MaxVarcharLength { @@ -3199,6 +3256,9 @@ func (q *Query4Audit) RuleVarcharLength() Rule { case tidb.AlterTableAddColumns, tidb.AlterTableChangeColumn, tidb.AlterTableAlterColumn, tidb.AlterTableModifyColumn: for _, col := range spec.NewColumns { + if col.Tp == nil { + continue + } switch col.Tp.Tp { case mysql.TypeVarchar, mysql.TypeVarString: if col.Tp.Flen > common.Config.MaxVarcharLength { @@ -3292,6 +3352,9 @@ func (q *Query4Audit) RuleMaxTextColsCount() Rule { switch node := tiStmt.(type) { case *tidb.CreateTableStmt: for _, col := range node.Cols { + if col.Tp == nil { + continue + } switch col.Tp.Tp { case mysql.TypeBlob, mysql.TypeLongBlob, mysql.TypeMediumBlob, mysql.TypeTinyBlob: textColsCount++ @@ -3452,6 +3515,9 @@ func (q *Query4Audit) RuleAutoIncUnsigned() Rule { switch node := tiStmt.(type) { case *tidb.CreateTableStmt: for _, col := range node.Cols { + if col.Tp == nil { + continue + } for _, opt := range col.Options { if opt.Tp == tidb.ColumnOptionAutoIncrement { if !mysql.HasUnsignedFlag(col.Tp.Flag) { @@ -3471,6 +3537,9 @@ func (q *Query4Audit) RuleAutoIncUnsigned() Rule { case tidb.AlterTableChangeColumn, tidb.AlterTableAlterColumn, tidb.AlterTableModifyColumn, tidb.AlterTableAddColumns: for _, col := range spec.NewColumns { + if col.Tp == nil { + continue + } for _, opt := range col.Options { if opt.Tp == tidb.ColumnOptionAutoIncrement { if !mysql.HasUnsignedFlag(col.Tp.Flag) { diff --git a/advisor/heuristic_test.go b/advisor/heuristic_test.go index a729e01..b288728 100644 --- a/advisor/heuristic_test.go +++ b/advisor/heuristic_test.go @@ -2792,6 +2792,8 @@ func TestRuleColumnWithCharset(t *testing.T) { // 反面的例子 { "CREATE TABLE `tb` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `c` char(120) NOT NULL DEFAULT '', PRIMARY KEY (`id`))", + // https://github.com/XiaoMi/soar/issues/163 + "alter table tb alter column id drop default", }, } for _, sql := range sqls[0] { diff --git a/vendor/vendor.json b/vendor/vendor.json index 58b3e48..d8fbea1 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -167,44 +167,44 @@ { "checksumSHA1": "fWqL/7jTYOiqDNmiUcQi3u45Hw0=", "path": "github.com/pingcap/tidb/sessionctx/stmtctx", - "revision": "9f51a626e6587118db4306882a5578e7ffe3d2a6", - "revisionTime": "2018-12-13T05:17:24Z" + "revision": "4ccd7456fcdc5e62e68f49a0a542cbcf88e38343", + "revisionTime": "2018-12-13T09:52:39Z" }, { "checksumSHA1": "0CCq+3fAyaXs9XU+xWaRvbbtSOQ=", "path": "github.com/pingcap/tidb/types", - "revision": "9f51a626e6587118db4306882a5578e7ffe3d2a6", - "revisionTime": "2018-12-13T05:17:24Z" + "revision": "4ccd7456fcdc5e62e68f49a0a542cbcf88e38343", + "revisionTime": "2018-12-13T09:52:39Z" }, { "checksumSHA1": "DWVD7+ygtT66IQ+cqXmMJ5OVqUk=", "path": "github.com/pingcap/tidb/types/json", - "revision": "9f51a626e6587118db4306882a5578e7ffe3d2a6", - "revisionTime": "2018-12-13T05:17:24Z" + "revision": "4ccd7456fcdc5e62e68f49a0a542cbcf88e38343", + "revisionTime": "2018-12-13T09:52:39Z" }, { "checksumSHA1": "Zp5ME8OXNTmHnYTwJJUZlydN4/U=", "path": "github.com/pingcap/tidb/types/parser_driver", - "revision": "9f51a626e6587118db4306882a5578e7ffe3d2a6", - "revisionTime": "2018-12-13T05:17:24Z" + "revision": "4ccd7456fcdc5e62e68f49a0a542cbcf88e38343", + "revisionTime": "2018-12-13T09:52:39Z" }, { "checksumSHA1": "s709bhSrG2Ec35406mGtrySid4s=", "path": "github.com/pingcap/tidb/util/execdetails", - "revision": "9f51a626e6587118db4306882a5578e7ffe3d2a6", - "revisionTime": "2018-12-13T05:17:24Z" + "revision": "4ccd7456fcdc5e62e68f49a0a542cbcf88e38343", + "revisionTime": "2018-12-13T09:52:39Z" }, { "checksumSHA1": "nUC7zVoAMNR2a+z2iGqHoN2AkFE=", "path": "github.com/pingcap/tidb/util/hack", - "revision": "9f51a626e6587118db4306882a5578e7ffe3d2a6", - "revisionTime": "2018-12-13T05:17:24Z" + "revision": "4ccd7456fcdc5e62e68f49a0a542cbcf88e38343", + "revisionTime": "2018-12-13T09:52:39Z" }, { "checksumSHA1": "xSyepiuqsoaaeDch7cXeumvVHKM=", "path": "github.com/pingcap/tidb/util/memory", - "revision": "9f51a626e6587118db4306882a5578e7ffe3d2a6", - "revisionTime": "2018-12-13T05:17:24Z" + "revision": "4ccd7456fcdc5e62e68f49a0a542cbcf88e38343", + "revisionTime": "2018-12-13T09:52:39Z" }, { "checksumSHA1": "SmYeIK/fIYXNu8IKxD6HOVQVTuU=", @@ -401,62 +401,62 @@ { "checksumSHA1": "aKn1oKcY74N8TRLm3Ayt7Q4bbI4=", "path": "vitess.io/vitess/go/bytes2", - "revision": "84a3524002899f761096c454e02924774c61d6ee", - "revisionTime": "2018-12-12T17:00:54Z" + "revision": "eb5a5e0e435db30856600b794d8cff235fdf24b7", + "revisionTime": "2018-12-13T22:28:01Z" }, { "checksumSHA1": "JVCEN4UGRmg3TofIBdzZMZ3G0Ww=", "path": "vitess.io/vitess/go/hack", - "revision": "84a3524002899f761096c454e02924774c61d6ee", - "revisionTime": "2018-12-12T17:00:54Z" + "revision": "eb5a5e0e435db30856600b794d8cff235fdf24b7", + "revisionTime": "2018-12-13T22:28:01Z" }, { "checksumSHA1": "e1WJ7vCnVrlQQQlc6n/FewCDMso=", "path": "vitess.io/vitess/go/sqltypes", - "revision": "84a3524002899f761096c454e02924774c61d6ee", - "revisionTime": "2018-12-12T17:00:54Z" + "revision": "eb5a5e0e435db30856600b794d8cff235fdf24b7", + "revisionTime": "2018-12-13T22:28:01Z" }, { "checksumSHA1": "ntFIQYkBS51G6y+FEkjFW40+HOU=", "path": "vitess.io/vitess/go/vt/log", - "revision": "84a3524002899f761096c454e02924774c61d6ee", - "revisionTime": "2018-12-12T17:00:54Z" + "revision": "eb5a5e0e435db30856600b794d8cff235fdf24b7", + "revisionTime": "2018-12-13T22:28:01Z" }, { "checksumSHA1": "tPQFPwbMdjuX0qjNl4Zl8zc37JQ=", "path": "vitess.io/vitess/go/vt/proto/query", - "revision": "84a3524002899f761096c454e02924774c61d6ee", - "revisionTime": "2018-12-12T17:00:54Z" + "revision": "eb5a5e0e435db30856600b794d8cff235fdf24b7", + "revisionTime": "2018-12-13T22:28:01Z" }, { "checksumSHA1": "o0tR/c7lgr0pLkxk7CdvjiNDAKU=", "path": "vitess.io/vitess/go/vt/proto/topodata", - "revision": "84a3524002899f761096c454e02924774c61d6ee", - "revisionTime": "2018-12-12T17:00:54Z" + "revision": "eb5a5e0e435db30856600b794d8cff235fdf24b7", + "revisionTime": "2018-12-13T22:28:01Z" }, { "checksumSHA1": "77UojBqi0yyeQvR70j7C3kcKclQ=", "path": "vitess.io/vitess/go/vt/proto/vtgate", - "revision": "84a3524002899f761096c454e02924774c61d6ee", - "revisionTime": "2018-12-12T17:00:54Z" + "revision": "eb5a5e0e435db30856600b794d8cff235fdf24b7", + "revisionTime": "2018-12-13T22:28:01Z" }, { "checksumSHA1": "QpWGhoVDwM+8+sgYLI/YU+95iGU=", "path": "vitess.io/vitess/go/vt/proto/vtrpc", - "revision": "84a3524002899f761096c454e02924774c61d6ee", - "revisionTime": "2018-12-12T17:00:54Z" + "revision": "eb5a5e0e435db30856600b794d8cff235fdf24b7", + "revisionTime": "2018-12-13T22:28:01Z" }, { "checksumSHA1": "lENrUY/YyxwYFHYN+21TBH92P3U=", "path": "vitess.io/vitess/go/vt/sqlparser", - "revision": "84a3524002899f761096c454e02924774c61d6ee", - "revisionTime": "2018-12-12T17:00:54Z" + "revision": "eb5a5e0e435db30856600b794d8cff235fdf24b7", + "revisionTime": "2018-12-13T22:28:01Z" }, { "checksumSHA1": "oF4XzuOzwvj1iduX/lYqNSyY/HM=", "path": "vitess.io/vitess/go/vt/vterrors", - "revision": "84a3524002899f761096c454e02924774c61d6ee", - "revisionTime": "2018-12-12T17:00:54Z" + "revision": "eb5a5e0e435db30856600b794d8cff235fdf24b7", + "revisionTime": "2018-12-13T22:28:01Z" } ], "rootPath": "github.com/XiaoMi/soar" -- GitLab