From cfef1bc52fbffa02571c052d7c504b28cf3cd0af Mon Sep 17 00:00:00 2001 From: Tanner Date: Mon, 2 Sep 2019 17:19:31 +0800 Subject: [PATCH] planner/core: add a range check against display width of BIT column type (#11942) --- go.mod | 2 +- go.sum | 4 ++-- planner/core/integration_test.go | 21 +++++++++++++++++++++ planner/core/preprocess.go | 9 ++++++++- types/errors.go | 5 ++++- 5 files changed, 36 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 6413c20dd1..24ebbadf68 100644 --- a/go.mod +++ b/go.mod @@ -41,7 +41,7 @@ require ( github.com/pingcap/goleveldb v0.0.0-20171020122428-b9ff6c35079e github.com/pingcap/kvproto v0.0.0-20190724165112-ec9df5f208a7 github.com/pingcap/log v0.0.0-20190307075452-bd41d9273596 - github.com/pingcap/parser v0.0.0-20190828080649-a621a0f9b06c + github.com/pingcap/parser v0.0.0-20190902030720-275a827cf4e3 github.com/pingcap/pd v0.0.0-20190712044914-75a1f9f3062b github.com/pingcap/tidb-tools v2.1.3-0.20190321065848-1e8b48f5c168+incompatible github.com/pingcap/tipb v0.0.0-20190806070524-16909e03435e diff --git a/go.sum b/go.sum index 87f81d487e..855f4dd8ad 100644 --- a/go.sum +++ b/go.sum @@ -165,8 +165,8 @@ github.com/pingcap/kvproto v0.0.0-20190724165112-ec9df5f208a7/go.mod h1:QMdbTAXC github.com/pingcap/log v0.0.0-20190214045112-b37da76f67a7/go.mod h1:xsfkWVaFVV5B8e1K9seWfyJWFrIhbtUTAD8NV1Pq3+w= github.com/pingcap/log v0.0.0-20190307075452-bd41d9273596 h1:t2OQTpPJnrPDGlvA+3FwJptMTt6MEPdzK1Wt99oaefQ= github.com/pingcap/log v0.0.0-20190307075452-bd41d9273596/go.mod h1:WpHUKhNZ18v116SvGrmjkA9CBhYmuUTKL+p8JC9ANEw= -github.com/pingcap/parser v0.0.0-20190828080649-a621a0f9b06c h1:VcQ60QkH7Vv98dbedNKDEO7RfUw+6TE59r/lQokNz/k= -github.com/pingcap/parser v0.0.0-20190828080649-a621a0f9b06c/go.mod h1:1FNvfp9+J0wvc4kl8eGNh7Rqrxveg15jJoWo/a0uHwA= +github.com/pingcap/parser v0.0.0-20190902030720-275a827cf4e3 h1:fRok+VIrzkDXHkVe7R1ByoLhsvfth/WHMBJmy/91/cM= +github.com/pingcap/parser v0.0.0-20190902030720-275a827cf4e3/go.mod h1:1FNvfp9+J0wvc4kl8eGNh7Rqrxveg15jJoWo/a0uHwA= github.com/pingcap/pd v0.0.0-20190712044914-75a1f9f3062b h1:oS9PftxQqgcRouKhhdaB52tXhVLEP7Ng3Qqsd6Z18iY= github.com/pingcap/pd v0.0.0-20190712044914-75a1f9f3062b/go.mod h1:3DlDlFT7EF64A1bmb/tulZb6wbPSagm5G4p1AlhaEDs= github.com/pingcap/tidb-tools v2.1.3-0.20190321065848-1e8b48f5c168+incompatible h1:MkWCxgZpJBgY2f4HtwWMMFzSBb3+JPzeJgF3VrXE/bU= diff --git a/planner/core/integration_test.go b/planner/core/integration_test.go index ff7ca01e6d..2eae2b1a2a 100644 --- a/planner/core/integration_test.go +++ b/planner/core/integration_test.go @@ -59,3 +59,24 @@ func (s *testIntegrationSuite) TestShowSubquery(c *C) { "a varchar(10) YES ", )) } + +func (s *testIntegrationSuite) BitColErrorMessage(c *C) { + store, dom, err := newStoreWithBootstrap() + c.Assert(err, IsNil) + tk := testkit.NewTestKit(c, store) + defer func() { + dom.Close() + store.Close() + }() + + tk.MustExec("use test") + tk.MustExec("drop table if exists bit_col_t") + tk.MustExec("create table bit_col_t (a bit(64))") + tk.MustExec("drop table bit_col_t") + tk.MustExec("create table bit_col_t (a bit(1))") + tk.MustExec("drop table bit_col_t") + _, err = tk.Exec("create table bit_col_t (a bit(0))") + c.Assert(err, NotNil) + _, err = tk.Exec("create table bit_col_t (a bit(65))") + c.Assert(err, NotNil) +} diff --git a/planner/core/preprocess.go b/planner/core/preprocess.go index d902ffba1f..533195ce83 100644 --- a/planner/core/preprocess.go +++ b/planner/core/preprocess.go @@ -628,13 +628,20 @@ func checkColumn(colDef *ast.ColumnDef) error { if tp.Flen > mysql.MaxDecimalWidth { return types.ErrTooBigPrecision.GenWithStackByArgs(tp.Flen, colDef.Name.Name.O, mysql.MaxDecimalWidth) } + case mysql.TypeBit: + if tp.Flen <= 0 { + return types.ErrInvalidFieldSize.GenWithStackByArgs(colDef.Name.Name.O) + } + if tp.Flen > mysql.MaxBitDisplayWidth { + return types.ErrTooBigDisplayWidth.GenWithStackByArgs(colDef.Name.Name.O, mysql.MaxBitDisplayWidth) + } default: // TODO: Add more types. } return nil } -// isDefaultValNowSymFunc checks whether defaul value is a NOW() builtin function. +// isDefaultValNowSymFunc checks whether default value is a NOW() builtin function. func isDefaultValNowSymFunc(expr ast.ExprNode) bool { if funcCall, ok := expr.(*ast.FuncCallExpr); ok { // Default value NOW() is transformed to CURRENT_TIMESTAMP() in parser. diff --git a/types/errors.go b/types/errors.go index f58bbf34cf..2881595eb8 100644 --- a/types/errors.go +++ b/types/errors.go @@ -34,7 +34,7 @@ var ( // ErrDivByZero is return when do division by 0. ErrDivByZero = terror.ClassTypes.New(codeDivByZero, "Division by 0") // ErrTooBigDisplayWidth is return when display width out of range for column. - ErrTooBigDisplayWidth = terror.ClassTypes.New(codeTooBigDisplayWidth, "Too Big Display width") + ErrTooBigDisplayWidth = terror.ClassTypes.New(codeTooBigDisplayWidth, mysql.MySQLErrName[mysql.ErrTooBigDisplaywidth]) // ErrTooBigFieldLength is return when column length too big for column. ErrTooBigFieldLength = terror.ClassTypes.New(codeTooBigFieldLength, "Too Big Field length") // ErrTooBigSet is returned when too many strings for column. @@ -49,6 +49,8 @@ var ( ErrBadNumber = terror.ClassTypes.New(codeBadNumber, "Bad Number") // ErrInvalidDefault is returned when meet a invalid default value. ErrInvalidDefault = parser_types.ErrInvalidDefault + // ErrInvalidFieldSize is returned when the precision of a column is out of range. + ErrInvalidFieldSize = terror.ClassTypes.New(codeInvalidFieldSize, mysql.MySQLErrName[mysql.ErrInvalidFieldSize]) // ErrCastAsSignedOverflow is returned when positive out-of-range integer, and convert to it's negative complement. ErrCastAsSignedOverflow = terror.ClassTypes.New(codeUnknown, msgCastAsSignedOverflow) // ErrCastNegIntAsUnsigned is returned when a negative integer be casted to an unsigned int. @@ -93,6 +95,7 @@ const ( codeTruncatedWrongValue = terror.ErrCode(mysql.ErrTruncatedWrongValue) codeUnknown = terror.ErrCode(mysql.ErrUnknown) codeInvalidDefault = terror.ErrCode(mysql.ErrInvalidDefault) + codeInvalidFieldSize = terror.ErrCode(mysql.ErrInvalidFieldSize) codeMBiggerThanD = terror.ErrCode(mysql.ErrMBiggerThanD) codeDataOutOfRange = terror.ErrCode(mysql.ErrWarnDataOutOfRange) codeDuplicatedValueInType = terror.ErrCode(mysql.ErrDuplicatedValueInType)