Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

table: format table error code and error message #13233

Merged
merged 9 commits into from
Dec 3, 2019
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions executor/statement_context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func (s *testSuite1) TestStatementContext(c *C) {
tk.MustExec(strictModeSQL)
_, err = tk.Exec("insert sc2 values (unhex('4040ffff'))")
c.Assert(err, NotNil)
c.Assert(terror.ErrorEqual(err, table.ErrTruncateWrongValue), IsTrue, Commentf("err %v", err))
c.Assert(terror.ErrorEqual(err, table.ErrTruncatedWrongValueForField), IsTrue, Commentf("err %v", err))

tk.MustExec("set @@tidb_skip_utf8_check = '1'")
_, err = tk.Exec("insert sc2 values (unhex('4040ffff'))")
Expand All @@ -98,10 +98,10 @@ func (s *testSuite1) TestStatementContext(c *C) {
tk.MustExec(strictModeSQL)
_, err = tk.Exec("insert t1 values (unhex('f09f8c80'))")
c.Assert(err, NotNil)
c.Assert(terror.ErrorEqual(err, table.ErrTruncateWrongValue), IsTrue, Commentf("err %v", err))
c.Assert(terror.ErrorEqual(err, table.ErrTruncatedWrongValueForField), IsTrue, Commentf("err %v", err))
_, err = tk.Exec("insert t1 values (unhex('F0A48BAE'))")
c.Assert(err, NotNil)
c.Assert(terror.ErrorEqual(err, table.ErrTruncateWrongValue), IsTrue, Commentf("err %v", err))
c.Assert(terror.ErrorEqual(err, table.ErrTruncatedWrongValueForField), IsTrue, Commentf("err %v", err))
old := config.GetGlobalConfig()
conf := *old
conf.CheckMb4ValueInUTF8 = false
Expand Down
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ require (
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4
github.com/jeremywohl/flatten v0.0.0-20190921043622-d936035e55cf
github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
github.com/montanaflynn/stats v0.0.0-20180911141734-db72e6cae808 // indirect
github.com/ngaut/pools v0.0.0-20180318154953-b7bc8c42aac7
github.com/ngaut/sync2 v0.0.0-20141008032647-7a24ed77b2ef
Expand Down
7 changes: 3 additions & 4 deletions table/column.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ func CastValues(ctx sessionctx.Context, rec []types.Datum, cols []*Column) (err

func handleWrongUtf8Value(ctx sessionctx.Context, col *model.ColumnInfo, casted *types.Datum, str string, i int) (types.Datum, error) {
sc := ctx.GetSessionVars().StmtCtx
err := ErrTruncateWrongValue.FastGen("incorrect utf8 value %x(%s) for column %s", casted.GetBytes(), str, col.Name)
err := ErrTruncatedWrongValueForField.FastGen("incorrect utf8 value %x(%s) for column %s", casted.GetBytes(), str, col.Name)
logutil.BgLogger().Error("incorrect UTF-8 value", zap.Uint64("conn", ctx.GetSessionVars().ConnectionID), zap.Error(err))
// Truncate to valid utf8 string.
truncateVal := types.NewStringDatum(str[:i])
Expand Down Expand Up @@ -324,7 +324,7 @@ func CheckOnce(cols []*Column) error {
name := col.Name
_, ok := m[name.L]
if ok {
return errDuplicateColumn.GenWithStack("column specified twice - %s", name)
return errDuplicateColumn.GenWithStackByArgs(name)
}

m[name.L] = struct{}{}
Expand Down Expand Up @@ -416,8 +416,7 @@ func getColDefaultValue(ctx sessionctx.Context, col *model.ColumnInfo, defaultVa
}
value, err := expression.GetTimeValue(ctx, defaultVal, col.Tp, int8(col.Decimal))
if err != nil {
return types.Datum{}, errGetDefaultFailed.GenWithStack("Field '%s' get default value fail - %s",
col.Name, err)
return types.Datum{}, errGetDefaultFailed.GenWithStackByArgs(col.Name)
}
// If the column's default value is not ZeroDatetimeStr or CurrentTimestamp, convert the default value to the current session time zone.
if needChangeTimeZone {
Expand Down
86 changes: 34 additions & 52 deletions table/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,41 +49,39 @@ const (

var (
// ErrColumnCantNull is used for inserting null to a not null column.
ErrColumnCantNull = terror.ClassTable.New(codeColumnCantNull, mysql.MySQLErrName[mysql.ErrBadNull])
errUnknownColumn = terror.ClassTable.New(codeUnknownColumn, "unknown column")
errDuplicateColumn = terror.ClassTable.New(codeDuplicateColumn, "duplicate column")
ErrColumnCantNull = terror.ClassTable.New(mysql.ErrBadNull, mysql.MySQLErrName[mysql.ErrBadNull])
errUnknownColumn = terror.ClassTable.New(mysql.ErrBadField, mysql.MySQLErrName[mysql.ErrBadField])
errDuplicateColumn = terror.ClassTable.New(mysql.ErrFieldSpecifiedTwice, mysql.MySQLErrName[mysql.ErrFieldSpecifiedTwice])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe need change the caller of errUnknownColumn, errDuplicateColumn due to "%" changed in message?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But share same error code may be confused.


errGetDefaultFailed = terror.ClassTable.New(codeGetDefaultFailed, "get default value fail")
errGetDefaultFailed = terror.ClassTable.New(mysql.ErrFieldGetDefaultFailed, mysql.MySQLErrName[mysql.ErrFieldGetDefaultFailed])

// ErrNoDefaultValue is used when insert a row, the column value is not given, and the column has not null flag
// and it doesn't have a default value.
ErrNoDefaultValue = terror.ClassTable.New(codeNoDefaultValue, mysql.MySQLErrName[mysql.ErrNoDefaultForField])
ErrNoDefaultValue = terror.ClassTable.New(mysql.ErrNoDefaultForField, mysql.MySQLErrName[mysql.ErrNoDefaultForField])
// ErrIndexOutBound returns for index column offset out of bound.
ErrIndexOutBound = terror.ClassTable.New(codeIndexOutBound, "index column offset out of bound")
ErrIndexOutBound = terror.ClassTable.New(mysql.ErrIndexOutBound, mysql.MySQLErrName[mysql.ErrIndexOutBound])
// ErrUnsupportedOp returns for unsupported operation.
ErrUnsupportedOp = terror.ClassTable.New(codeUnsupportedOp, "operation not supported")
ErrUnsupportedOp = terror.ClassTable.New(mysql.ErrUnsupportedOp, mysql.MySQLErrName[mysql.ErrUnsupportedOp])
// ErrRowNotFound returns for row not found.
ErrRowNotFound = terror.ClassTable.New(codeRowNotFound, "can not find the row")
ErrRowNotFound = terror.ClassTable.New(mysql.ErrRowNotFound, mysql.MySQLErrName[mysql.ErrRowNotFound])
// ErrTableStateCantNone returns for table none state.
ErrTableStateCantNone = terror.ClassTable.New(codeTableStateCantNone, "table can not be in none state")
ErrTableStateCantNone = terror.ClassTable.New(mysql.ErrTableStateCantNone, mysql.MySQLErrName[mysql.ErrTableStateCantNone])
// ErrColumnStateCantNone returns for column none state.
ErrColumnStateCantNone = terror.ClassTable.New(codeColumnStateCantNone, "column can not be in none state")
ErrColumnStateCantNone = terror.ClassTable.New(mysql.ErrColumnStateCantNone, mysql.MySQLErrName[mysql.ErrColumnStateCantNone])
// ErrColumnStateNonPublic returns for column non-public state.
ErrColumnStateNonPublic = terror.ClassTable.New(codeColumnStateNonPublic, "can not use non-public column")
ErrColumnStateNonPublic = terror.ClassTable.New(mysql.ErrColumnStateNonPublic, mysql.MySQLErrName[mysql.ErrColumnStateNonPublic])
// ErrIndexStateCantNone returns for index none state.
ErrIndexStateCantNone = terror.ClassTable.New(codeIndexStateCantNone, "index can not be in none state")
ErrIndexStateCantNone = terror.ClassTable.New(mysql.ErrIndexStateCantNone, mysql.MySQLErrName[mysql.ErrIndexStateCantNone])
// ErrInvalidRecordKey returns for invalid record key.
ErrInvalidRecordKey = terror.ClassTable.New(codeInvalidRecordKey, "invalid record key")
// ErrTruncateWrongValue returns for truncate wrong value for field.
ErrTruncateWrongValue = terror.ClassTable.New(codeTruncateWrongValue, "incorrect value")
ErrInvalidRecordKey = terror.ClassTable.New(mysql.ErrInvalidRecordKey, mysql.MySQLErrName[mysql.ErrInvalidRecordKey])
// ErrTruncatedWrongValueForField returns for truncate wrong value for field.
ErrTruncatedWrongValueForField = terror.ClassTable.New(codeTruncateWrongValue, mysql.MySQLErrName[mysql.ErrTruncatedWrongValueForField])
ErrTruncatedWrongValueForField = terror.ClassTable.New(mysql.ErrTruncatedWrongValueForField, mysql.MySQLErrName[mysql.ErrTruncatedWrongValueForField])
// ErrUnknownPartition returns unknown partition error.
ErrUnknownPartition = terror.ClassTable.New(codeUnknownPartition, mysql.MySQLErrName[mysql.ErrUnknownPartition])
ErrUnknownPartition = terror.ClassTable.New(mysql.ErrUnknownPartition, mysql.MySQLErrName[mysql.ErrUnknownPartition])
// ErrNoPartitionForGivenValue returns table has no partition for value.
ErrNoPartitionForGivenValue = terror.ClassTable.New(codeNoPartitionForGivenValue, mysql.MySQLErrName[mysql.ErrNoPartitionForGivenValue])
ErrNoPartitionForGivenValue = terror.ClassTable.New(mysql.ErrNoPartitionForGivenValue, mysql.MySQLErrName[mysql.ErrNoPartitionForGivenValue])
// ErrLockOrActiveTransaction returns when execute unsupported statement in a lock session or an active transaction.
ErrLockOrActiveTransaction = terror.ClassTable.New(codeLockOrActiveTransaction, mysql.MySQLErrName[mysql.ErrLockOrActiveTransaction])
ErrLockOrActiveTransaction = terror.ClassTable.New(mysql.ErrLockOrActiveTransaction, mysql.MySQLErrName[mysql.ErrLockOrActiveTransaction])
)

// RecordIterFunc is used for low-level record iteration.
Expand Down Expand Up @@ -232,31 +230,6 @@ var TableFromMeta func(alloc autoid.Allocator, tblInfo *model.TableInfo) (Table,
// MockTableFromMeta only serves for test.
var MockTableFromMeta func(tableInfo *model.TableInfo) Table

// Table error codes.
const (
codeGetDefaultFailed = 1
codeIndexOutBound = 2
codeUnsupportedOp = 3
codeRowNotFound = 4
codeTableStateCantNone = 5
codeColumnStateCantNone = 6
codeColumnStateNonPublic = 7
codeIndexStateCantNone = 8
codeInvalidRecordKey = 9

codeColumnCantNull = mysql.ErrBadNull
codeUnknownColumn = 1054
codeDuplicateColumn = 1110
codeNoDefaultValue = 1364
codeTruncateWrongValue = 1366
// MySQL error code, "Trigger creation context of table `%-.64s`.`%-.64s` is invalid".
// It may happen when inserting some data outside of all table partitions.

codeUnknownPartition = mysql.ErrUnknownPartition
codeNoPartitionForGivenValue = mysql.ErrNoPartitionForGivenValue
codeLockOrActiveTransaction = mysql.ErrLockOrActiveTransaction
)

// Slice is used for table sorting.
type Slice []Table

Expand All @@ -270,14 +243,23 @@ func (s Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }

func init() {
tableMySQLErrCodes := map[terror.ErrCode]uint16{
codeColumnCantNull: mysql.ErrBadNull,
codeUnknownColumn: mysql.ErrBadField,
codeDuplicateColumn: mysql.ErrFieldSpecifiedTwice,
codeNoDefaultValue: mysql.ErrNoDefaultForField,
codeTruncateWrongValue: mysql.ErrTruncatedWrongValueForField,
codeUnknownPartition: mysql.ErrUnknownPartition,
codeNoPartitionForGivenValue: mysql.ErrNoPartitionForGivenValue,
codeLockOrActiveTransaction: mysql.ErrLockOrActiveTransaction,
mysql.ErrBadNull: mysql.ErrBadNull,
mysql.ErrBadField: mysql.ErrBadField,
mysql.ErrFieldSpecifiedTwice: mysql.ErrFieldSpecifiedTwice,
mysql.ErrNoDefaultForField: mysql.ErrNoDefaultForField,
mysql.ErrTruncatedWrongValueForField: mysql.ErrTruncatedWrongValueForField,
mysql.ErrUnknownPartition: mysql.ErrUnknownPartition,
mysql.ErrNoPartitionForGivenValue: mysql.ErrNoPartitionForGivenValue,
mysql.ErrLockOrActiveTransaction: mysql.ErrLockOrActiveTransaction,
mysql.ErrIndexOutBound: mysql.ErrIndexOutBound,
mysql.ErrColumnStateNonPublic: mysql.ErrColumnStateNonPublic,
mysql.ErrFieldGetDefaultFailed: mysql.ErrFieldGetDefaultFailed,
mysql.ErrUnsupportedOp: mysql.ErrUnsupportedOp,
mysql.ErrRowNotFound: mysql.ErrRowNotFound,
mysql.ErrTableStateCantNone: mysql.ErrTableStateCantNone,
mysql.ErrColumnStateCantNone: mysql.ErrColumnStateCantNone,
mysql.ErrIndexStateCantNone: mysql.ErrIndexStateCantNone,
mysql.ErrInvalidRecordKey: mysql.ErrInvalidRecordKey,
}
terror.ErrClassToMySQLCodes[terror.ClassTable] = tableMySQLErrCodes
}
21 changes: 21 additions & 0 deletions table/table_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ package table

import (
. "github.com/pingcap/check"
"github.com/pingcap/parser/mysql"
)

var _ = Suite(&testTableSuite{})
Expand All @@ -27,3 +28,23 @@ func (t *testTableSuite) TestSlice(c *C) {
c.Assert(length, Equals, 2)
sl.Swap(0, 1)
}

func (t *testTableSuite) TestErrorCode(c *C) {
c.Assert(int(ErrColumnCantNull.ToSQLError().Code), Equals, mysql.ErrBadNull)
c.Assert(int(errUnknownColumn.ToSQLError().Code), Equals, mysql.ErrBadField)
c.Assert(int(errDuplicateColumn.ToSQLError().Code), Equals, mysql.ErrFieldSpecifiedTwice)
c.Assert(int(errGetDefaultFailed.ToSQLError().Code), Equals, mysql.ErrFieldGetDefaultFailed)
c.Assert(int(ErrNoDefaultValue.ToSQLError().Code), Equals, mysql.ErrNoDefaultForField)
c.Assert(int(ErrIndexOutBound.ToSQLError().Code), Equals, mysql.ErrIndexOutBound)
c.Assert(int(ErrUnsupportedOp.ToSQLError().Code), Equals, mysql.ErrUnsupportedOp)
c.Assert(int(ErrRowNotFound.ToSQLError().Code), Equals, mysql.ErrRowNotFound)
c.Assert(int(ErrTableStateCantNone.ToSQLError().Code), Equals, mysql.ErrTableStateCantNone)
c.Assert(int(ErrColumnStateCantNone.ToSQLError().Code), Equals, mysql.ErrColumnStateCantNone)
c.Assert(int(ErrColumnStateNonPublic.ToSQLError().Code), Equals, mysql.ErrColumnStateNonPublic)
c.Assert(int(ErrIndexStateCantNone.ToSQLError().Code), Equals, mysql.ErrIndexStateCantNone)
c.Assert(int(ErrInvalidRecordKey.ToSQLError().Code), Equals, mysql.ErrInvalidRecordKey)
c.Assert(int(ErrTruncatedWrongValueForField.ToSQLError().Code), Equals, mysql.ErrTruncatedWrongValueForField)
c.Assert(int(ErrUnknownPartition.ToSQLError().Code), Equals, mysql.ErrUnknownPartition)
c.Assert(int(ErrNoPartitionForGivenValue.ToSQLError().Code), Equals, mysql.ErrNoPartitionForGivenValue)
c.Assert(int(ErrLockOrActiveTransaction.ToSQLError().Code), Equals, mysql.ErrLockOrActiveTransaction)
}
3 changes: 1 addition & 2 deletions table/tables/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -373,8 +373,7 @@ func (c *index) FetchValues(r []types.Datum, vals []types.Datum) ([]types.Datum,
vals = vals[:needLength]
for i, ic := range c.idxInfo.Columns {
if ic.Offset < 0 || ic.Offset >= len(r) {
return nil, table.ErrIndexOutBound.GenWithStack("Index column %s offset out of bound, offset: %d, row: %v",
ic.Name, ic.Offset, r)
return nil, table.ErrIndexOutBound.GenWithStackByArgs(ic.Name, ic.Offset, r)
}
vals[i] = r[ic.Offset]
}
Expand Down
6 changes: 3 additions & 3 deletions table/tables/tables.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,14 @@ func MockTableFromMeta(tblInfo *model.TableInfo) table.Table {
// TableFromMeta creates a Table instance from model.TableInfo.
func TableFromMeta(alloc autoid.Allocator, tblInfo *model.TableInfo) (table.Table, error) {
if tblInfo.State == model.StateNone {
return nil, table.ErrTableStateCantNone.GenWithStack("table %s can't be in none state", tblInfo.Name)
return nil, table.ErrTableStateCantNone.GenWithStackByArgs(tblInfo.Name)
}

colsLen := len(tblInfo.Columns)
columns := make([]*table.Column, 0, colsLen)
for i, colInfo := range tblInfo.Columns {
if colInfo.State == model.StateNone {
return nil, table.ErrColumnStateCantNone.GenWithStack("column %s can't be in none state", colInfo.Name)
return nil, table.ErrColumnStateCantNone.GenWithStackByArgs(colInfo.Name)
}

// Print some information when the column's offset isn't equal to i.
Expand Down Expand Up @@ -156,7 +156,7 @@ func initTableIndices(t *tableCommon) error {
tblInfo := t.meta
for _, idxInfo := range tblInfo.Indices {
if idxInfo.State == model.StateNone {
return table.ErrIndexStateCantNone.GenWithStack("index %s can't be in none state", idxInfo.Name)
return table.ErrIndexStateCantNone.GenWithStackByArgs(idxInfo.Name)
}

// Use partition ID for index, because tableCommon may be table or partition.
Expand Down