Merge pull request #1033 from pingcap/zimuxia/change-terror

*: Unfiy error format
This commit is contained in:
zimulala
2016-03-31 20:00:14 +08:00
31 changed files with 341 additions and 213 deletions

View File

@ -80,7 +80,7 @@ func testCreateColumn(c *C, ctx context.Context, d *ddl, dbInfo *model.DBInfo, t
Args: []interface{}{col, pos, 0},
}
err = d.startDDLJob(ctx, job)
err = d.doDDLJob(ctx, job)
c.Assert(err, IsNil)
return job
}
@ -93,7 +93,7 @@ func testDropColumn(c *C, ctx context.Context, d *ddl, dbInfo *model.DBInfo, tbl
Args: []interface{}{model.NewCIStr(colName)},
}
err := d.startDDLJob(ctx, job)
err := d.doDDLJob(ctx, job)
if isError {
c.Assert(err, NotNil)
return nil

View File

@ -43,6 +43,41 @@ import (
"github.com/twinj/uuid"
)
var (
// errWorkerClosed means we have already closed the DDL worker.
errInvalidWorker = terror.ClassDDL.New(codeInvalidWorker, "invalid worker")
// errNotOwner means we are not owner and can't handle DDL jobs.
errNotOwner = terror.ClassDDL.New(codeNotOwner, "not Owner")
errInvalidDDLJob = terror.ClassDDL.New(codeInvalidDDLJob, "invalid ddl job")
errInvalidBgJob = terror.ClassDDL.New(codeInvalidBgJob, "invalid background job")
errInvalidJobFlag = terror.ClassDDL.New(codeInvalidJobFlag, "invalid job flag")
errRunMultiSchemaChanges = terror.ClassDDL.New(codeRunMultiSchemaChanges, "can't run multi schema change")
errWaitReorgTimeout = terror.ClassDDL.New(codeWaitReorgTimeout, "wait for reorganization timeout")
errInvalidStoreVer = terror.ClassDDL.New(codeInvalidStoreVer, "invalid storage current version")
// we don't support drop column with index covered now.
errCantDropColWithIndex = terror.ClassDDL.New(codeCantDropColWithIndex, "can't drop column with index")
errUnsupportedAddColumn = terror.ClassDDL.New(codeUnsupportedAddColumn, "unsupported add column")
// ErrInvalidDBState returns for invalid database state.
ErrInvalidDBState = terror.ClassDDL.New(codeInvalidDBState, "invalid database state")
// ErrInvalidTableState returns for invalid Table state.
ErrInvalidTableState = terror.ClassDDL.New(codeInvalidTableState, "invalid table state")
// ErrInvalidColumnState returns for invalid column state.
ErrInvalidColumnState = terror.ClassDDL.New(codeInvalidColumnState, "invalid column state")
// ErrInvalidIndexState returns for invalid index state.
ErrInvalidIndexState = terror.ClassDDL.New(codeInvalidIndexState, "invalid index state")
// ErrColumnBadNull returns for a bad null value.
ErrColumnBadNull = terror.ClassDDL.New(codeBadNull, "column cann't be null")
// ErrCantRemoveAllFields returns for deleting all columns.
ErrCantRemoveAllFields = terror.ClassDDL.New(codeCantRemoveAllFields, "can't delete all columns with ALTER TABLE")
// ErrCantDropFieldOrKey returns for dropping a non-existent field or key.
ErrCantDropFieldOrKey = terror.ClassDDL.New(codeCantDropFieldOrKey, "can't drop field; check that column/key exists")
// ErrInvalidOnUpdate returns for invalid ON UPDATE clause.
ErrInvalidOnUpdate = terror.ClassDDL.New(codeInvalidOnUpdate, "invalid ON UPDATE clause for the column")
)
// DDL is responsible for updating schema in data store and maintaining in-memory InfoSchema cache.
type DDL interface {
CreateSchema(ctx context.Context, name model.CIStr, charsetInfo *ast.CharsetOpt) error
@ -275,7 +310,7 @@ func (d *ddl) CreateSchema(ctx context.Context, schema model.CIStr, charsetInfo
Args: []interface{}{dbInfo},
}
err = d.startDDLJob(ctx, job)
err = d.doDDLJob(ctx, job)
err = d.hook.OnChanged(err)
return errors.Trace(err)
}
@ -292,7 +327,7 @@ func (d *ddl) DropSchema(ctx context.Context, schema model.CIStr) (err error) {
Type: model.ActionDropSchema,
}
err = d.startDDLJob(ctx, job)
err = d.doDDLJob(ctx, job)
err = d.hook.OnChanged(err)
return errors.Trace(err)
}
@ -737,7 +772,7 @@ func (d *ddl) CreateTable(ctx context.Context, ident ast.Ident, colDefs []*ast.C
Args: []interface{}{tbInfo},
}
err = d.startDDLJob(ctx, job)
err = d.doDDLJob(ctx, job)
if err == nil {
err = d.handleTableOptions(options, tbInfo, schema.ID)
}
@ -854,7 +889,7 @@ func (d *ddl) AddColumn(ctx context.Context, ti ast.Ident, spec *ast.AlterTableS
Args: []interface{}{&col.ColumnInfo, spec.Position, 0},
}
err = d.startDDLJob(ctx, job)
err = d.doDDLJob(ctx, job)
err = d.hook.OnChanged(err)
return errors.Trace(err)
}
@ -885,7 +920,7 @@ func (d *ddl) DropColumn(ctx context.Context, ti ast.Ident, colName model.CIStr)
Args: []interface{}{colName},
}
err = d.startDDLJob(ctx, job)
err = d.doDDLJob(ctx, job)
err = d.hook.OnChanged(err)
return errors.Trace(err)
}
@ -909,7 +944,7 @@ func (d *ddl) DropTable(ctx context.Context, ti ast.Ident) (err error) {
Type: model.ActionDropTable,
}
err = d.startDDLJob(ctx, job)
err = d.doDDLJob(ctx, job)
err = d.hook.OnChanged(err)
return errors.Trace(err)
}
@ -937,7 +972,7 @@ func (d *ddl) CreateIndex(ctx context.Context, ti ast.Ident, unique bool, indexN
Args: []interface{}{unique, indexName, indexID, idxColNames},
}
err = d.startDDLJob(ctx, job)
err = d.doDDLJob(ctx, job)
err = d.hook.OnChanged(err)
return errors.Trace(err)
}
@ -961,7 +996,7 @@ func (d *ddl) DropIndex(ctx context.Context, ti ast.Ident, indexName model.CIStr
Args: []interface{}{indexName},
}
err = d.startDDLJob(ctx, job)
err = d.doDDLJob(ctx, job)
err = d.hook.OnChanged(err)
return errors.Trace(err)
}
@ -1003,41 +1038,6 @@ const (
codeInvalidOnUpdate = 1294
)
var (
// errWorkerClosed means we have already closed the DDL worker.
errInvalidWorker = terror.ClassDDL.New(codeInvalidWorker, "invalid worker")
// errNotOwner means we are not owner and can't handle DDL jobs.
errNotOwner = terror.ClassDDL.New(codeNotOwner, "not Owner")
errInvalidDDLJob = terror.ClassDDL.New(codeInvalidDDLJob, "invalid ddl job")
errInvalidBgJob = terror.ClassDDL.New(codeInvalidBgJob, "invalid background job")
errInvalidJobFlag = terror.ClassDDL.New(codeInvalidJobFlag, "invalid job flag")
errRunMultiSchemaChanges = terror.ClassDDL.New(codeRunMultiSchemaChanges, "can't run multi schema change")
errWaitReorgTimeout = terror.ClassDDL.New(codeWaitReorgTimeout, "wait for reorganization timeout")
errInvalidStoreVer = terror.ClassDDL.New(codeInvalidStoreVer, "invalid storage current version")
// we don't support drop column with index covered now.
errCantDropColWithIndex = terror.ClassDDL.New(codeCantDropColWithIndex, "can't drop column with index")
errUnsupportedAddColumn = terror.ClassDDL.New(codeUnsupportedAddColumn, "unsupported add column")
// ErrInvalidDBState returns for invalid database state.
ErrInvalidDBState = terror.ClassDDL.New(codeInvalidDBState, "invalid database state")
// ErrInvalidTableState returns for invalid Table state.
ErrInvalidTableState = terror.ClassDDL.New(codeInvalidTableState, "invalid table state")
// ErrInvalidColumnState returns for invalid column state.
ErrInvalidColumnState = terror.ClassDDL.New(codeInvalidColumnState, "invalid column state")
// ErrInvalidIndexState returns for invalid index state.
ErrInvalidIndexState = terror.ClassDDL.New(codeInvalidIndexState, "invalid index state")
// ErrColumnBadNull returns for a bad null value.
ErrColumnBadNull = terror.ClassDDL.New(codeBadNull, "column cann't be null")
// ErrCantRemoveAllFields returns for deleting all columns.
ErrCantRemoveAllFields = terror.ClassDDL.New(codeCantRemoveAllFields, "can't delete all columns with ALTER TABLE")
// ErrCantDropFieldOrKey returns for dropping a non-existent field or key.
ErrCantDropFieldOrKey = terror.ClassDDL.New(codeCantDropFieldOrKey, "can't drop field; check that column/key exists")
// ErrInvalidOnUpdate returns for invalid ON UPDATE clause.
ErrInvalidOnUpdate = terror.ClassDDL.New(codeInvalidOnUpdate, "invalid ON UPDATE clause for the column")
)
func init() {
ddlMySQLERrCodes := map[terror.ErrCode]uint16{
codeBadNull: mysql.ErrBadNull,

View File

@ -25,7 +25,7 @@ import (
"github.com/pingcap/tidb/terror"
)
func (d *ddl) startDDLJob(ctx context.Context, job *model.Job) error {
func (d *ddl) doDDLJob(ctx context.Context, job *model.Job) error {
// for every DDL, we must commit current transaction.
if err := ctx.FinishTxn(false); err != nil {
return errors.Trace(err)

View File

@ -125,7 +125,7 @@ func (s *testDDLSuite) TestSchemaError(c *C) {
ctx := testNewContext(c, d)
err := d.startDDLJob(ctx, job)
err := d.doDDLJob(ctx, job)
c.Assert(err, NotNil)
testCheckJobCancelled(c, d, job)
}
@ -148,7 +148,7 @@ func (s *testDDLSuite) TestTableError(c *C) {
ctx := testNewContext(c, d)
err := d.startDDLJob(ctx, job)
err := d.doDDLJob(ctx, job)
c.Assert(err, NotNil)
testCheckJobCancelled(c, d, job)
@ -157,7 +157,7 @@ func (s *testDDLSuite) TestTableError(c *C) {
tblInfo := testTableInfo(c, d, "t", 3)
job.Args = []interface{}{tblInfo}
err = d.startDDLJob(ctx, job)
err = d.doDDLJob(ctx, job)
c.Assert(err, NotNil)
testCheckJobCancelled(c, d, job)
@ -167,7 +167,7 @@ func (s *testDDLSuite) TestTableError(c *C) {
Type: model.ActionDropTable,
}
err = d.startDDLJob(ctx, job)
err = d.doDDLJob(ctx, job)
c.Assert(err, NotNil)
testCheckJobCancelled(c, d, job)
@ -180,7 +180,7 @@ func (s *testDDLSuite) TestTableError(c *C) {
Type: model.ActionDropTable,
}
err = d.startDDLJob(ctx, job)
err = d.doDDLJob(ctx, job)
c.Assert(err, NotNil)
testCheckJobCancelled(c, d, job)
@ -217,7 +217,7 @@ func (s *testDDLSuite) TestIndexError(c *C) {
Type: model.ActionAddIndex,
}
err := d.startDDLJob(ctx, job)
err := d.doDDLJob(ctx, job)
c.Assert(err, NotNil)
testCheckJobCancelled(c, d, job)
@ -227,7 +227,7 @@ func (s *testDDLSuite) TestIndexError(c *C) {
Type: model.ActionDropIndex,
}
err = d.startDDLJob(ctx, job)
err = d.doDDLJob(ctx, job)
c.Assert(err, NotNil)
testCheckJobCancelled(c, d, job)
@ -243,7 +243,7 @@ func (s *testDDLSuite) TestIndexError(c *C) {
Type: model.ActionAddIndex,
Args: []interface{}{1},
}
err = d.startDDLJob(ctx, job)
err = d.doDDLJob(ctx, job)
c.Assert(err, NotNil)
testCheckJobCancelled(c, d, job)
@ -253,7 +253,7 @@ func (s *testDDLSuite) TestIndexError(c *C) {
Type: model.ActionAddIndex,
Args: []interface{}{false, model.NewCIStr("t"), []*ast.IndexColName{{Column: &ast.ColumnName{Name: model.NewCIStr("c")}, Length: 256}}},
}
err = d.startDDLJob(ctx, job)
err = d.doDDLJob(ctx, job)
c.Assert(err, NotNil)
testCheckJobCancelled(c, d, job)
@ -263,7 +263,7 @@ func (s *testDDLSuite) TestIndexError(c *C) {
Type: model.ActionAddIndex,
Args: []interface{}{false, model.NewCIStr("c1_index"), []*ast.IndexColName{{Column: &ast.ColumnName{Name: model.NewCIStr("c")}, Length: 256}}},
}
err = d.startDDLJob(ctx, job)
err = d.doDDLJob(ctx, job)
c.Assert(err, NotNil)
testCheckJobCancelled(c, d, job)
@ -275,7 +275,7 @@ func (s *testDDLSuite) TestIndexError(c *C) {
Type: model.ActionAddIndex,
Args: []interface{}{false, model.NewCIStr("c1_index"), []*ast.IndexColName{{Column: &ast.ColumnName{Name: model.NewCIStr("c1")}, Length: 256}}},
}
err = d.startDDLJob(ctx, job)
err = d.doDDLJob(ctx, job)
c.Assert(err, NotNil)
testCheckJobCancelled(c, d, job)
@ -285,7 +285,7 @@ func (s *testDDLSuite) TestIndexError(c *C) {
Type: model.ActionDropIndex,
Args: []interface{}{1},
}
err = d.startDDLJob(ctx, job)
err = d.doDDLJob(ctx, job)
c.Assert(err, NotNil)
testCheckJobCancelled(c, d, job)
@ -297,7 +297,7 @@ func (s *testDDLSuite) TestIndexError(c *C) {
Type: model.ActionDropIndex,
Args: []interface{}{model.NewCIStr("c1_index")},
}
err = d.startDDLJob(ctx, job)
err = d.doDDLJob(ctx, job)
c.Assert(err, NotNil)
testCheckJobCancelled(c, d, job)
}
@ -319,7 +319,7 @@ func (s *testDDLSuite) TestColumnError(c *C) {
Type: model.ActionAddColumn,
}
err := d.startDDLJob(ctx, job)
err := d.doDDLJob(ctx, job)
c.Assert(err, NotNil)
testCheckJobCancelled(c, d, job)
@ -329,7 +329,7 @@ func (s *testDDLSuite) TestColumnError(c *C) {
Type: model.ActionDropColumn,
}
err = d.startDDLJob(ctx, job)
err = d.doDDLJob(ctx, job)
c.Assert(err, NotNil)
testCheckJobCancelled(c, d, job)
@ -358,7 +358,7 @@ func (s *testDDLSuite) TestColumnError(c *C) {
Args: []interface{}{col, pos, 0},
}
err = d.startDDLJob(ctx, job)
err = d.doDDLJob(ctx, job)
c.Assert(err, NotNil)
testCheckJobCancelled(c, d, job)
@ -369,7 +369,7 @@ func (s *testDDLSuite) TestColumnError(c *C) {
Args: []interface{}{1},
}
err = d.startDDLJob(ctx, job)
err = d.doDDLJob(ctx, job)
c.Assert(err, NotNil)
testCheckJobCancelled(c, d, job)
}

View File

@ -69,7 +69,7 @@ func testCreateIndex(c *C, ctx context.Context, d *ddl, dbInfo *model.DBInfo, tb
Args: []interface{}{unique, model.NewCIStr(indexName), id, []*ast.IndexColName{{Column: &ast.ColumnName{Name: model.NewCIStr(colName)}, Length: 256}}},
}
err = d.startDDLJob(ctx, job)
err = d.doDDLJob(ctx, job)
c.Assert(err, IsNil)
return job
}
@ -82,7 +82,7 @@ func testDropIndex(c *C, ctx context.Context, d *ddl, dbInfo *model.DBInfo, tblI
Args: []interface{}{model.NewCIStr(indexName)},
}
err := d.startDDLJob(ctx, job)
err := d.doDDLJob(ctx, job)
c.Assert(err, IsNil)
return job
}

View File

@ -48,7 +48,7 @@ func testCreateSchema(c *C, ctx context.Context, d *ddl, dbInfo *model.DBInfo) *
Args: []interface{}{dbInfo},
}
err := d.startDDLJob(ctx, job)
err := d.doDDLJob(ctx, job)
c.Assert(err, IsNil)
return job
}
@ -59,7 +59,7 @@ func testDropSchema(c *C, ctx context.Context, d *ddl, dbInfo *model.DBInfo) *mo
Type: model.ActionDropSchema,
}
err := d.startDDLJob(ctx, job)
err := d.doDDLJob(ctx, job)
c.Assert(err, IsNil)
return job
}
@ -156,7 +156,7 @@ func (s *testSchemaSuite) TestSchema(c *C) {
Type: model.ActionDropSchema,
}
err := d1.startDDLJob(ctx, job)
err := d1.doDDLJob(ctx, job)
c.Assert(terror.ErrorEqual(err, infoschema.ErrDatabaseNotExists), IsTrue)
}
@ -195,7 +195,7 @@ func (s *testSchemaSuite) TestSchemaWaitJob(c *C) {
Args: []interface{}{dbInfo},
}
err = d2.startDDLJob(ctx, job)
err = d2.doDDLJob(ctx, job)
c.Assert(err, NotNil)
testCheckJobCancelled(c, d2, job)
@ -207,7 +207,7 @@ func testRunInterruptedJob(c *C, d *ddl, job *model.Job) {
ctx := mock.NewContext()
done := make(chan error, 1)
go func() {
done <- d.startDDLJob(ctx, job)
done <- d.doDDLJob(ctx, job)
}()
ticker := time.NewTicker(d.lease * 1)

View File

@ -60,7 +60,7 @@ func (s *testStatSuite) TestStat(c *C) {
ctx := mock.NewContext()
done := make(chan error, 1)
go func() {
done <- d.startDDLJob(ctx, job)
done <- d.doDDLJob(ctx, job)
}()
ticker := time.NewTicker(d.lease * 1)

View File

@ -77,7 +77,7 @@ func testCreateTable(c *C, ctx context.Context, d *ddl, dbInfo *model.DBInfo, tb
Args: []interface{}{tblInfo},
}
err := d.startDDLJob(ctx, job)
err := d.doDDLJob(ctx, job)
c.Assert(err, IsNil)
return job
}
@ -89,7 +89,7 @@ func testDropTable(c *C, ctx context.Context, d *ddl, dbInfo *model.DBInfo, tblI
Type: model.ActionDropTable,
}
err := d.startDDLJob(ctx, job)
err := d.doDDLJob(ctx, job)
c.Assert(err, IsNil)
return job
}
@ -168,7 +168,7 @@ func (s *testTableSuite) TestTable(c *C) {
Args: []interface{}{newTblInfo},
}
err := d.startDDLJob(ctx, job)
err := d.doDDLJob(ctx, job)
c.Assert(err, NotNil)
testCheckJobCancelled(c, d, job)

View File

@ -184,7 +184,7 @@ func (do *Domain) reload() error {
case err := <-done:
return errors.Trace(err)
case <-time.After(timeout):
return errors.New("reload schema timeout")
return errLoadSchemaTimeOut
}
}
@ -268,3 +268,12 @@ func NewDomain(store kv.Storage, lease time.Duration) (d *Domain, err error) {
return d, nil
}
// Domain error codes.
const (
codeLoadSchemaTimeOut terror.ErrCode = 1
)
var (
errLoadSchemaTimeOut = terror.ClassDomain.New(codeLoadSchemaTimeOut, "reload schema timeout")
)

View File

@ -31,6 +31,28 @@ import (
"github.com/pingcap/tidb/util/types"
)
var (
// ErrDatabaseDropExists returns for dropping a non-existent database.
ErrDatabaseDropExists = terror.ClassSchema.New(codeDBDropExists, "database doesn't exist")
// ErrDatabaseNotExists returns for database not exists.
ErrDatabaseNotExists = terror.ClassSchema.New(codeDatabaseNotExists, "database not exists")
// ErrTableNotExists returns for table not exists.
ErrTableNotExists = terror.ClassSchema.New(codeTableNotExists, "table not exists")
// ErrColumnNotExists returns for column not exists.
ErrColumnNotExists = terror.ClassSchema.New(codeColumnNotExists, "field not exists")
// ErrDatabaseExists returns for database already exists.
ErrDatabaseExists = terror.ClassSchema.New(codeDatabaseExists, "database already exists")
// ErrTableExists returns for table already exists.
ErrTableExists = terror.ClassSchema.New(codeTableExists, "table already exists")
// ErrTableDropExists returns for dropping a non-existent table.
ErrTableDropExists = terror.ClassSchema.New(codeBadTable, "unknown table")
// ErrColumnExists returns for column already exists.
ErrColumnExists = terror.ClassSchema.New(codeColumnExists, "Duplicate column")
// ErrIndexExists returns for index already exists.
ErrIndexExists = terror.ClassSchema.New(codeIndexExists, "Duplicate Index")
)
// InfoSchema is the interface used to retrieve the schema information.
// It works as a in memory cache and doesn't handle any schema change.
// InfoSchema is read-only, and the returned value is a copy.
@ -457,7 +479,7 @@ func (h *Handle) Get() InfoSchema {
// Schema error codes.
const (
codeDbDropExists terror.ErrCode = 1008
codeDBDropExists terror.ErrCode = 1008
codeDatabaseNotExists = 1049
codeTableNotExists = 1146
codeColumnNotExists = 1054
@ -469,35 +491,13 @@ const (
codeIndexExists = 1831
)
var (
// ErrDatabaseDropExists returns for dropping a non-existent database.
ErrDatabaseDropExists = terror.ClassSchema.New(codeDbDropExists, "database doesn't exist")
// ErrDatabaseNotExists returns for database not exists.
ErrDatabaseNotExists = terror.ClassSchema.New(codeDatabaseNotExists, "database not exists")
// ErrTableNotExists returns for table not exists.
ErrTableNotExists = terror.ClassSchema.New(codeTableNotExists, "table not exists")
// ErrColumnNotExists returns for column not exists.
ErrColumnNotExists = terror.ClassSchema.New(codeColumnNotExists, "field not exists")
// ErrDatabaseExists returns for database already exists.
ErrDatabaseExists = terror.ClassSchema.New(codeDatabaseExists, "database already exists")
// ErrTableExists returns for table already exists.
ErrTableExists = terror.ClassSchema.New(codeTableExists, "table already exists")
// ErrTableDropExists returns for dropping a non-existent table.
ErrTableDropExists = terror.ClassSchema.New(codeBadTable, "unknown table")
// ErrColumnExists returns for column already exists.
ErrColumnExists = terror.ClassSchema.New(codeColumnExists, "Duplicate column")
// ErrIndexExists returns for index already exists.
ErrIndexExists = terror.ClassSchema.New(codeIndexExists, "Duplicate Index")
)
func init() {
schemaMySQLErrCodes := map[terror.ErrCode]uint16{
codeDbDropExists: mysql.ErrDbDropExists,
codeDatabaseNotExists: mysql.ErrBadDb,
codeDBDropExists: mysql.ErrDBDropExists,
codeDatabaseNotExists: mysql.ErrBadDB,
codeTableNotExists: mysql.ErrNoSuchTable,
codeColumnNotExists: mysql.ErrBadField,
codeDatabaseExists: mysql.ErrDbCreateExists,
codeDatabaseExists: mysql.ErrDBCreateExists,
codeTableExists: mysql.ErrTableExists,
codeBadTable: mysql.ErrBadTable,
codeColumnExists: mysql.ErrDupFieldName,

View File

@ -196,7 +196,7 @@ func checkIndexAndRecord(txn kv.Transaction, t table.Table, idx *column.IndexedC
vals2, err := rowWithCols(txn, t, h, cols)
if terror.ErrorEqual(err, kv.ErrNotExist) {
record := &RecordData{Handle: h, Values: vals1}
err = errors.Errorf("index:%v != record:%v", record, nil)
err = errDateNotEqual.Gen("index:%v != record:%v", record, nil)
}
if err != nil {
return errors.Trace(err)
@ -204,7 +204,7 @@ func checkIndexAndRecord(txn kv.Transaction, t table.Table, idx *column.IndexedC
if !reflect.DeepEqual(vals1, vals2) {
record1 := &RecordData{Handle: h, Values: vals1}
record2 := &RecordData{Handle: h, Values: vals2}
return errors.Errorf("index:%v != record:%v", record1, record2)
return errDateNotEqual.Gen("index:%v != record:%v", record1, record2)
}
}
@ -224,14 +224,14 @@ func checkRecordAndIndex(txn kv.Transaction, t table.Table, idx *column.IndexedC
if terror.ErrorEqual(err, kv.ErrKeyExists) {
record1 := &RecordData{Handle: h1, Values: vals1}
record2 := &RecordData{Handle: h2, Values: vals1}
return false, errors.Errorf("index:%v != record:%v", record2, record1)
return false, errDateNotEqual.Gen("index:%v != record:%v", record2, record1)
}
if err != nil {
return false, errors.Trace(err)
}
if !isExist {
record := &RecordData{Handle: h1, Values: vals1}
return false, errors.Errorf("index:%v != record:%v", nil, record)
return false, errDateNotEqual.Gen("index:%v != record:%v", nil, record)
}
return true, nil
@ -310,7 +310,7 @@ func CompareTableRecord(txn kv.Transaction, t table.Table, data []*RecordData, e
m := make(map[int64][]types.Datum, len(data))
for _, r := range data {
if _, ok := m[r.Handle]; ok {
return errors.Errorf("handle:%d is repeated in data", r.Handle)
return errRepeatHandle.Gen("handle:%d is repeated in data", r.Handle)
}
m[r.Handle] = r.Values
}
@ -320,7 +320,7 @@ func CompareTableRecord(txn kv.Transaction, t table.Table, data []*RecordData, e
vals2, ok := m[h]
if !ok {
record := &RecordData{Handle: h, Values: vals}
return false, errors.Errorf("data:%v != record:%v", nil, record)
return false, errDateNotEqual.Gen("data:%v != record:%v", nil, record)
}
if !exact {
delete(m, h)
@ -330,7 +330,7 @@ func CompareTableRecord(txn kv.Transaction, t table.Table, data []*RecordData, e
if !reflect.DeepEqual(vals, vals2) {
record1 := &RecordData{Handle: h, Values: vals2}
record2 := &RecordData{Handle: h, Values: vals}
return false, errors.Errorf("data:%v != record:%v", record1, record2)
return false, errDateNotEqual.Gen("data:%v != record:%v", record1, record2)
}
delete(m, h)
@ -344,7 +344,7 @@ func CompareTableRecord(txn kv.Transaction, t table.Table, data []*RecordData, e
for h, vals := range m {
record := &RecordData{Handle: h, Values: vals}
return errors.Errorf("data:%v != record:%v", record, nil)
return errDateNotEqual.Gen("data:%v != record:%v", record, nil)
}
return nil
@ -386,7 +386,7 @@ func rowWithCols(txn kv.Retriever, t table.Table, h int64, cols []*column.Col) (
v := make([]types.Datum, len(cols))
for i, col := range cols {
if col.State != model.StatePublic {
return nil, errors.Errorf("Cannot use none public column - %v", cols)
return nil, errInvalidColumnState.Gen("Cannot use none public column - %v", cols)
}
if col.IsPKHandleColumn(t.Meta()) {
v[i].SetInt64(h)
@ -450,3 +450,16 @@ func iterRecords(retriever kv.Retriever, t table.Table, startKey kv.Key, cols []
return nil
}
// inspectkv error codes.
const (
codeDataNotEqual terror.ErrCode = 1
codeRepeatHandle = 2
codeInvalidColumnState = 3
)
var (
errDateNotEqual = terror.ClassInspectkv.New(codeDataNotEqual, "data isn't equal")
errRepeatHandle = terror.ClassInspectkv.New(codeRepeatHandle, "handle is repeated")
errInvalidColumnState = terror.ClassInspectkv.New(codeInvalidColumnState, "invalid column state")
)

View File

@ -238,7 +238,7 @@ func (s *testSuite) TestScan(c *C) {
}
func newDiffRetError(prefix string, ra, rb *RecordData) string {
return fmt.Sprintf("%s:%v != record:%v", prefix, ra, rb)
return fmt.Sprintf("[inspectkv:1]%s:%v != record:%v", prefix, ra, rb)
}
func (s *testSuite) testTableData(c *C, tb table.Table, rs []*RecordData) {
@ -288,7 +288,7 @@ func (s *testSuite) testTableData(c *C, tb table.Table, rs []*RecordData) {
errRs := append(rs, &RecordData{Handle: int64(1), Values: types.MakeDatums(int64(3))})
err = CompareTableRecord(txn, tb, errRs, false)
c.Assert(err.Error(), DeepEquals, "handle:1 is repeated in data")
c.Assert(err.Error(), DeepEquals, "[inspectkv:2]handle:1 is repeated in data")
}
func (s *testSuite) testIndex(c *C, tb table.Table, idx *column.IndexedCol) {

View File

@ -14,7 +14,6 @@
package kv
import (
"errors"
"strings"
"github.com/pingcap/go-themis"
@ -24,41 +23,49 @@ import (
// KV error codes.
const (
CodeIncompatibleDBFormat terror.ErrCode = 1
CodeNoDataForHandle terror.ErrCode = 2
CodeKeyExists terror.ErrCode = 3
codeClosed terror.ErrCode = 1
codeNotExist = 2
codeCondithinNotMatch = 3
codeLockConfilict = 4
codeLazyConditionPairsNotMatch = 5
codeRetryable = 6
codeCantSetNilValue = 7
codeInvalidTxn = 8
codeNotCommitted = 9
codeKeyExists = 1062
)
var (
// ErrClosed is used when close an already closed txn.
ErrClosed = errors.New("Error: Transaction already closed")
ErrClosed = terror.ClassKV.New(codeClosed, "Error: Transaction already closed")
// ErrNotExist is used when try to get an entry with an unexist key from KV store.
ErrNotExist = errors.New("Error: key not exist")
ErrNotExist = terror.ClassKV.New(codeNotExist, "Error: key not exist")
// ErrConditionNotMatch is used when condition is not met.
ErrConditionNotMatch = errors.New("Error: Condition not match")
ErrConditionNotMatch = terror.ClassKV.New(codeCondithinNotMatch, "Error: Condition not match")
// ErrLockConflict is used when try to lock an already locked key.
ErrLockConflict = errors.New("Error: Lock conflict")
ErrLockConflict = terror.ClassKV.New(codeLockConfilict, "Error: Lock conflict")
// ErrLazyConditionPairsNotMatch is used when value in store differs from expect pairs.
ErrLazyConditionPairsNotMatch = errors.New("Error: Lazy condition pairs not match")
ErrLazyConditionPairsNotMatch = terror.ClassKV.New(codeLazyConditionPairsNotMatch, "Error: Lazy condition pairs not match")
// ErrRetryable is used when KV store occurs RPC error or some other
// errors which SQL layer can safely retry.
ErrRetryable = errors.New("Error: KV error safe to retry")
ErrRetryable = terror.ClassKV.New(codeRetryable, "Error: KV error safe to retry")
// ErrCannotSetNilValue is the error when sets an empty value.
ErrCannotSetNilValue = errors.New("can not set nil value")
ErrCannotSetNilValue = terror.ClassKV.New(codeCantSetNilValue, "can not set nil value")
// ErrInvalidTxn is the error when commits or rollbacks in an invalid transaction.
ErrInvalidTxn = errors.New("invalid transaction")
ErrInvalidTxn = terror.ClassKV.New(codeInvalidTxn, "invalid transaction")
// ErrNotCommitted is the error returned by CommitVersion when this
// transaction is not committed.
ErrNotCommitted = errors.New("this transaction has not committed")
ErrNotCommitted = terror.ClassKV.New(codeNotCommitted, "this transaction has not committed")
// ErrKeyExists returns when key is already exist.
ErrKeyExists = terror.ClassKV.New(CodeKeyExists, "key already exist")
ErrKeyExists = terror.ClassKV.New(codeKeyExists, "key already exist")
)
func init() {
kvMySQLErrCodes := map[terror.ErrCode]uint16{
CodeKeyExists: mysql.ErrDupEntry,
codeKeyExists: mysql.ErrDupEntry,
}
terror.ErrClassToMySQLCodes[terror.ClassKV] = kvMySQLErrCodes
}

View File

@ -20,12 +20,15 @@ import (
"github.com/ngaut/log"
"github.com/pingcap/tidb/kv"
"github.com/pingcap/tidb/meta"
"github.com/pingcap/tidb/terror"
)
const (
step = 1000
)
var errInvalidTableID = terror.ClassAutoid.New(codeInvalidTableID, "invalid TableID")
// Allocator is an auto increment id generator.
// Just keep id unique actually.
type Allocator interface {
@ -49,7 +52,7 @@ type allocator struct {
// Rebase implements autoid.Allocator Rebase interface.
func (alloc *allocator) Rebase(tableID, newBase int64, allocIDs bool) error {
if tableID == 0 {
return errors.New("Invalid tableID")
return errInvalidTableID.Gen("Invalid tableID")
}
alloc.mu.Lock()
@ -93,7 +96,7 @@ func (alloc *allocator) Rebase(tableID, newBase int64, allocIDs bool) error {
// Alloc implements autoid.Allocator Alloc interface.
func (alloc *allocator) Alloc(tableID int64) (int64, error) {
if tableID == 0 {
return 0, errors.New("Invalid tableID")
return 0, errInvalidTableID.Gen("Invalid tableID")
}
alloc.mu.Lock()
defer alloc.mu.Unlock()
@ -149,7 +152,7 @@ func (alloc *memoryAllocator) Rebase(tableID, newBase int64, allocIDs bool) erro
// Alloc implements autoid.Allocator Alloc interface.
func (alloc *memoryAllocator) Alloc(tableID int64) (int64, error) {
if tableID == 0 {
return 0, errors.New("Invalid tableID")
return 0, errInvalidTableID.Gen("Invalid tableID")
}
alloc.mu.Lock()
defer alloc.mu.Unlock()
@ -178,3 +181,6 @@ func NewMemoryAllocator(dbID int64) Allocator {
dbID: dbID,
}
}
//autoid error codes.
const codeInvalidTableID terror.ErrCode = 1

View File

@ -25,7 +25,9 @@ import (
"github.com/juju/errors"
"github.com/pingcap/tidb/kv"
"github.com/pingcap/tidb/model"
"github.com/pingcap/tidb/mysql"
"github.com/pingcap/tidb/structure"
"github.com/pingcap/tidb/terror"
)
var (
@ -58,14 +60,17 @@ var (
)
var (
errInvalidTableKey = terror.ClassMeta.New(codeInvalidTableKey, "invalid table meta key")
errInvalidDBKey = terror.ClassMeta.New(codeInvalidDBKey, "invalid db key")
// ErrDBExists is the error for db exists.
ErrDBExists = errors.New("database already exists")
ErrDBExists = terror.ClassMeta.New(codeDatabaseExists, "database already exists")
// ErrDBNotExists is the error for db not exists.
ErrDBNotExists = errors.New("database doesn't exist")
ErrDBNotExists = terror.ClassMeta.New(codeDatabaseNotExists, "database doesn't exist")
// ErrTableExists is the error for table exists.
ErrTableExists = errors.New("table already exists")
ErrTableExists = terror.ClassMeta.New(codeTableExists, "table already exists")
// ErrTableNotExists is the error for table not exists.
ErrTableNotExists = errors.New("table doesn't exist")
ErrTableNotExists = terror.ClassMeta.New(codeTableNotExists, "table doesn't exist")
)
// Meta is for handling meta information in a transaction.
@ -648,3 +653,24 @@ func (m *Meta) GetBgJobOwner() (*model.Owner, error) {
func (m *Meta) SetBgJobOwner(o *model.Owner) error {
return m.setJobOwner(mBgJobOwnerKey, o)
}
// meta error codes.
const (
codeInvalidTableKey terror.ErrCode = 1
codeInvalidDBKey = 2
codeDatabaseExists = 1007
codeDatabaseNotExists = 1049
codeTableExists = 1050
codeTableNotExists = 1146
)
func init() {
metaMySQLErrCodes := map[terror.ErrCode]uint16{
codeDatabaseExists: mysql.ErrDBCreateExists,
codeDatabaseNotExists: mysql.ErrBadDB,
codeTableNotExists: mysql.ErrNoSuchTable,
codeTableExists: mysql.ErrTableExists,
}
terror.ErrClassToMySQLCodes[terror.ClassMeta] = metaMySQLErrCodes
}

View File

@ -23,11 +23,11 @@ const (
ErrYes = 1003
ErrCantCreateFile = 1004
ErrCantCreateTable = 1005
ErrCantCreateDb = 1006
ErrDbCreateExists = 1007
ErrDbDropExists = 1008
ErrDbDropDelete = 1009
ErrDbDropRmdir = 1010
ErrCantCreateDB = 1006
ErrDBCreateExists = 1007
ErrDBDropExists = 1008
ErrDBDropDelete = 1009
ErrDBDropRmdir = 1010
ErrCantDeleteFile = 1011
ErrCantFindSystemRec = 1012
ErrCantGetStat = 1013
@ -61,12 +61,12 @@ const (
ErrOutOfResources = 1041
ErrBadHost = 1042
ErrHandshake = 1043
ErrDbaccessDenied = 1044
ErrDBaccessDenied = 1044
ErrAccessDenied = 1045
ErrNoDb = 1046
ErrNoDB = 1046
ErrUnknownCom = 1047
ErrBadNull = 1048
ErrBadDb = 1049
ErrBadDB = 1049
ErrTableExists = 1050
ErrBadTable = 1051
ErrNonUniq = 1052
@ -119,7 +119,7 @@ const (
ErrTableNotLockedForWrite = 1099
ErrTableNotLocked = 1100
ErrBlobCantHaveDefault = 1101
ErrWrongDbName = 1102
ErrWrongDBName = 1102
ErrWrongTableName = 1103
ErrTooBigSelect = 1104
ErrUnknown = 1105
@ -225,8 +225,8 @@ const (
ErrLockWaitTimeout = 1205
ErrLockTableFull = 1206
ErrReadOnlyTransaction = 1207
ErrDropDbWithReadLock = 1208
ErrCreateDbWithReadLock = 1209
ErrDropDBWithReadLock = 1208
ErrCreateDBWithReadLock = 1209
ErrWrongArguments = 1210
ErrNoPermissionToCreateUser = 1211
ErrUnionTablesInDifferentDir = 1212
@ -261,7 +261,7 @@ const (
ErrOperandColumns = 1241
ErrSubqueryNo1Row = 1242
ErrUnknownStmtHandler = 1243
ErrCorruptHelpDb = 1244
ErrCorruptHelpDB = 1244
ErrCyclicReference = 1245
ErrAutoConvert = 1246
ErrIllegalReference = 1247
@ -594,7 +594,7 @@ const (
ErrRbrNotAvailable = 1574
ErrBase64Decode = 1575
ErrEventRecursionForbidden = 1576
ErrEventsDb = 1577
ErrEventsDB = 1577
ErrOnlyIntegersAllowed = 1578
ErrUnsuportedLogEngine = 1579
ErrBadLogStatement = 1580
@ -771,7 +771,7 @@ const (
ErrWarningNotCompleteRollbackWithCreatedTempTable = 1751
ErrWarningNotCompleteRollbackWithDroppedTempTable = 1752
ErrMtsFeatureIsNotSupported = 1753
ErrMtsUpdatedDbsGreaterMax = 1754
ErrMtsUpdatedDBsGreaterMax = 1754
ErrMtsCantParallel = 1755
ErrMtsInconsistentData = 1756
ErrFulltextNotSupportedWithPartitioning = 1757

View File

@ -21,11 +21,11 @@ var MySQLErrName = map[uint16]string{
ErrYes: "YES",
ErrCantCreateFile: "Can't create file '%-.200s' (errno: %d - %s)",
ErrCantCreateTable: "Can't create table '%-.200s' (errno: %d)",
ErrCantCreateDb: "Can't create database '%-.192s' (errno: %d)",
ErrDbCreateExists: "Can't create database '%-.192s'; database exists",
ErrDbDropExists: "Can't drop database '%-.192s'; database doesn't exist",
ErrDbDropDelete: "Error dropping database (can't delete '%-.192s', errno: %d)",
ErrDbDropRmdir: "Error dropping database (can't rmdir '%-.192s', errno: %d)",
ErrCantCreateDB: "Can't create database '%-.192s' (errno: %d)",
ErrDBCreateExists: "Can't create database '%-.192s'; database exists",
ErrDBDropExists: "Can't drop database '%-.192s'; database doesn't exist",
ErrDBDropDelete: "Error dropping database (can't delete '%-.192s', errno: %d)",
ErrDBDropRmdir: "Error dropping database (can't rmdir '%-.192s', errno: %d)",
ErrCantDeleteFile: "Error on delete of '%-.192s' (errno: %d - %s)",
ErrCantFindSystemRec: "Can't read record in system table",
ErrCantGetStat: "Can't get status of '%-.200s' (errno: %d - %s)",
@ -59,12 +59,12 @@ var MySQLErrName = map[uint16]string{
ErrOutOfResources: "Out of memory; check if mysqld or some other process uses all available memory; if not, you may have to use 'ulimit' to allow mysqld to use more memory or you can add more swap space",
ErrBadHost: "Can't get hostname for your address",
ErrHandshake: "Bad handshake",
ErrDbaccessDenied: "Access denied for user '%-.48s'@'%-.64s' to database '%-.192s'",
ErrDBaccessDenied: "Access denied for user '%-.48s'@'%-.64s' to database '%-.192s'",
ErrAccessDenied: "Access denied for user '%-.48s'@'%-.64s' (using password: %s)",
ErrNoDb: "No database selected",
ErrNoDB: "No database selected",
ErrUnknownCom: "Unknown command",
ErrBadNull: "Column '%-.192s' cannot be null",
ErrBadDb: "Unknown database '%-.192s'",
ErrBadDB: "Unknown database '%-.192s'",
ErrTableExists: "Table '%-.192s' already exists",
ErrBadTable: "Unknown table '%-.100s'",
ErrNonUniq: "Column '%-.192s' in %-.192s is ambiguous",
@ -117,7 +117,7 @@ var MySQLErrName = map[uint16]string{
ErrTableNotLockedForWrite: "Table '%-.192s' was locked with a READ lock and can't be updated",
ErrTableNotLocked: "Table '%-.192s' was not locked with LOCK TABLES",
ErrBlobCantHaveDefault: "BLOB/TEXT column '%-.192s' can't have a default value",
ErrWrongDbName: "Incorrect database name '%-.100s'",
ErrWrongDBName: "Incorrect database name '%-.100s'",
ErrWrongTableName: "Incorrect table name '%-.100s'",
ErrTooBigSelect: "The SELECT would examine more than MAXJOINSIZE rows; check your WHERE and use SET SQLBIGSELECTS=1 or SET MAXJOINSIZE=# if the SELECT is okay",
ErrUnknown: "Unknown error",
@ -223,8 +223,8 @@ var MySQLErrName = map[uint16]string{
ErrLockWaitTimeout: "Lock wait timeout exceeded; try restarting transaction",
ErrLockTableFull: "The total number of locks exceeds the lock table size",
ErrReadOnlyTransaction: "Update locks cannot be acquired during a READ UNCOMMITTED transaction",
ErrDropDbWithReadLock: "DROP DATABASE not allowed while thread is holding global read lock",
ErrCreateDbWithReadLock: "CREATE DATABASE not allowed while thread is holding global read lock",
ErrDropDBWithReadLock: "DROP DATABASE not allowed while thread is holding global read lock",
ErrCreateDBWithReadLock: "CREATE DATABASE not allowed while thread is holding global read lock",
ErrWrongArguments: "Incorrect arguments to %s",
ErrNoPermissionToCreateUser: "'%-.48s'@'%-.64s' is not allowed to create new users",
ErrUnionTablesInDifferentDir: "Incorrect table definition; all MERGE tables must be in the same database",
@ -259,7 +259,7 @@ var MySQLErrName = map[uint16]string{
ErrOperandColumns: "Operand should contain %d column(s)",
ErrSubqueryNo1Row: "Subquery returns more than 1 row",
ErrUnknownStmtHandler: "Unknown prepared statement handler (%.*s) given to %s",
ErrCorruptHelpDb: "Help database is corrupt or does not exist",
ErrCorruptHelpDB: "Help database is corrupt or does not exist",
ErrCyclicReference: "Cyclic reference on subqueries",
ErrAutoConvert: "Converting column '%s' from %s to %s",
ErrIllegalReference: "Reference '%-.64s' not supported (%s)",
@ -592,7 +592,7 @@ var MySQLErrName = map[uint16]string{
ErrRbrNotAvailable: "The server was not built with row-based replication",
ErrBase64Decode: "Decoding of base64 string failed",
ErrEventRecursionForbidden: "Recursion of EVENT DDL statements is forbidden when body is present",
ErrEventsDb: "Cannot proceed because system tables used by Event Scheduler were found damaged at server start",
ErrEventsDB: "Cannot proceed because system tables used by Event Scheduler were found damaged at server start",
ErrOnlyIntegersAllowed: "Only integers allowed as number here",
ErrUnsuportedLogEngine: "This storage engine cannot be used for log tables\"",
ErrBadLogStatement: "You cannot '%s' a log table if logging is enabled",
@ -769,7 +769,7 @@ var MySQLErrName = map[uint16]string{
ErrWarningNotCompleteRollbackWithCreatedTempTable: "The creation of some temporary tables could not be rolled back.",
ErrWarningNotCompleteRollbackWithDroppedTempTable: "Some temporary tables were dropped, but these operations could not be rolled back.",
ErrMtsFeatureIsNotSupported: "%s is not supported in multi-threaded slave mode. %s",
ErrMtsUpdatedDbsGreaterMax: "The number of modified databases exceeds the maximum %d; the database names will not be included in the replication event metadata.",
ErrMtsUpdatedDBsGreaterMax: "The number of modified databases exceeds the maximum %d; the database names will not be included in the replication event metadata.",
ErrMtsCantParallel: "Cannot execute the current event group in the parallel mode. Encountered event %s, relay-log name %s, position %s which prevents execution of this event group in parallel mode. Reason: %s.",
ErrMtsInconsistentData: "%s",
ErrFulltextNotSupportedWithPartitioning: "FULLTEXT index is not supported for partitioned tables.",

View File

@ -23,13 +23,13 @@ type testSQLErrorSuite struct {
}
func (s *testSQLErrorSuite) TestSQLError(c *C) {
e := NewErrf(ErrNoDb, "no db error")
e := NewErrf(ErrNoDB, "no db error")
c.Assert(len(e.Error()), Greater, 0)
e = NewErrf(0, "customized error")
c.Assert(len(e.Error()), Greater, 0)
e = NewErr(ErrNoDb)
e = NewErr(ErrNoDB)
c.Assert(len(e.Error()), Greater, 0)
e = NewErr(0, "customized error")

View File

@ -27,12 +27,12 @@ var MySQLState = map[uint16]string{
ErrConCount: "08004",
ErrBadHost: "08S01",
ErrHandshake: "08S01",
ErrDbaccessDenied: "42000",
ErrDBaccessDenied: "42000",
ErrAccessDenied: "28000",
ErrNoDb: "3D000",
ErrNoDB: "3D000",
ErrUnknownCom: "08S01",
ErrBadNull: "23000",
ErrBadDb: "42000",
ErrBadDB: "42000",
ErrTableExists: "42S01",
ErrBadTable: "42S02",
ErrNonUniq: "23000",
@ -67,7 +67,7 @@ var MySQLState = map[uint16]string{
ErrCantRemoveAllFields: "42000",
ErrCantDropFieldOrKey: "42000",
ErrBlobCantHaveDefault: "42000",
ErrWrongDbName: "42000",
ErrWrongDBName: "42000",
ErrWrongTableName: "42000",
ErrTooBigSelect: "42000",
ErrUnknownProcedure: "42000",

View File

@ -331,7 +331,7 @@ func buildEnumColumnInfo(offset int, name string, elems []string, flag uint, def
func (ps *perfSchema) initRecords(tbName string, records [][]types.Datum) error {
tbl, ok := ps.mTables[tbName]
if !ok {
return errors.Errorf("Unknown PerformanceSchema table: %s", tbName)
return errInvalidPerfSchemaTable.Gen("Unknown PerformanceSchema table: %s", tbName)
}
for _, rec := range records {
_, err := tbl.AddRecord(nil, rec)

View File

@ -70,7 +70,7 @@ func (ps *perfSchema) addInstrument(name string) (uint64, error) {
func (ps *perfSchema) getTimerName(flag int) (enumTimerName, error) {
if flag < 0 || flag >= len(setupTimersRecords) {
return timerNameNone, errors.Errorf("Unknown timerName flag %d", flag)
return timerNameNone, errInvalidTimerFlag.Gen("Unknown timerName flag %d", flag)
}
timerName := fmt.Sprintf("%s", setupTimersRecords[flag][1].GetString())
switch timerName {

View File

@ -17,6 +17,12 @@ import (
"github.com/pingcap/tidb/kv"
"github.com/pingcap/tidb/model"
"github.com/pingcap/tidb/table"
"github.com/pingcap/tidb/terror"
)
var (
errInvalidPerfSchemaTable = terror.ClassPerfSchema.New(codeInvalidPerfSchemaTable, "invalid perfschema table")
errInvalidTimerFlag = terror.ClassPerfSchema.New(codeInvalidTimerFlag, "invalid timer flag")
)
// StatementInstrument defines the methods for statement instrumentation points
@ -72,3 +78,9 @@ func init() {
schema := &perfSchema{}
PerfHandle = schema
}
// perfschema error codes.
const (
codeInvalidPerfSchemaTable terror.ErrCode = 1
codeInvalidTimerFlag = 2
)

View File

@ -24,10 +24,22 @@ import (
"github.com/pingcap/tidb/mysql"
"github.com/pingcap/tidb/privilege"
"github.com/pingcap/tidb/sessionctx/variable"
"github.com/pingcap/tidb/terror"
"github.com/pingcap/tidb/util/sqlexec"
"github.com/pingcap/tidb/util/types"
)
// privilege error codes.
const (
codeInvalidPrivilegeType terror.ErrCode = 1
codeInvalidUserNameFormat = 2
)
var (
errInvalidPrivilegeType = terror.ClassPrivilege.New(codeInvalidPrivilegeType, "unknown privilege type")
errInvalidUserNameFormat = terror.ClassPrivilege.New(codeInvalidUserNameFormat, "wrong username format")
)
var _ privilege.Checker = (*UserPrivileges)(nil)
type privileges struct {
@ -209,7 +221,7 @@ func (p *UserPrivileges) Check(ctx context.Context, db *model.DBInfo, tbl *model
func (p *UserPrivileges) loadPrivileges(ctx context.Context) error {
strs := strings.Split(p.User, "@")
if len(strs) != 2 {
return errors.Errorf("Wrong username format: %s", p.User)
return errInvalidUserNameFormat.Gen("Wrong username format: %s", p.User)
}
username, host := strs[0], strs[1]
p.privs = &userPrivileges{
@ -262,7 +274,7 @@ func (p *UserPrivileges) loadGlobalPrivileges(ctx context.Context) error {
for i := userTablePrivColumnStartIndex; i < len(fs); i++ {
d := row.Data[i]
if d.Kind() != types.KindMysqlEnum {
return errors.Errorf("Privilege should be mysql.Enum: %v(%T)", d, d)
return errInvalidPrivilegeType.Gen("Privilege should be mysql.Enum: %v(%T)", d, d)
}
ed := d.GetMysqlEnum()
if ed.String() != "Y" {
@ -271,7 +283,7 @@ func (p *UserPrivileges) loadGlobalPrivileges(ctx context.Context) error {
f := fs[i]
p, ok := mysql.Col2PrivType[f.ColumnAsName.O]
if !ok {
return errors.New("Unknown Privilege Type!")
return errInvalidPrivilegeType.Gen("Unknown Privilege Type!")
}
ps.add(p)
}
@ -307,7 +319,7 @@ func (p *UserPrivileges) loadDBScopePrivileges(ctx context.Context) error {
for i := dbTablePrivColumnStartIndex; i < len(fs); i++ {
d := row.Data[i]
if d.Kind() != types.KindMysqlEnum {
return errors.Errorf("Privilege should be mysql.Enum: %v(%T)", d, d)
return errInvalidPrivilegeType.Gen("Privilege should be mysql.Enum: %v(%T)", d, d)
}
ed := d.GetMysqlEnum()
if ed.String() != "Y" {
@ -316,7 +328,7 @@ func (p *UserPrivileges) loadDBScopePrivileges(ctx context.Context) error {
f := fs[i]
p, ok := mysql.Col2PrivType[f.ColumnAsName.O]
if !ok {
return errors.New("Unknown Privilege Type!")
return errInvalidPrivilegeType.Gen("Unknown Privilege Type!")
}
ps[dbStr].add(p)
}
@ -357,7 +369,7 @@ func (p *UserPrivileges) loadTableScopePrivileges(ctx context.Context) error {
for _, d := range pvs {
p, ok := mysql.SetStr2Priv[d]
if !ok {
return errors.New("Unknown Privilege Type!")
return errInvalidPrivilegeType.Gen("Unknown Privilege Type!")
}
ps[dbStr][tblStr].add(p)
}

View File

@ -1286,12 +1286,12 @@ func (s *testSessionSuite) TestIssue461(c *C) {
c.Assert(err, NotNil)
// Check error type and error message
c.Assert(terror.ErrorEqual(err, kv.ErrKeyExists), IsTrue)
c.Assert(err.Error(), Equals, "[kv:3]Duplicate entry '1' for key 'PRIMARY'")
c.Assert(err.Error(), Equals, "[kv:1062]Duplicate entry '1' for key 'PRIMARY'")
_, err = se2.Execute("commit")
c.Assert(err, NotNil)
c.Assert(terror.ErrorEqual(err, kv.ErrKeyExists), IsTrue)
c.Assert(err.Error(), Equals, "[kv:3]Duplicate entry '2' for key 'val'")
c.Assert(err.Error(), Equals, "[kv:1062]Duplicate entry '2' for key 'val'")
se := newSession(c, store, s.dbName)
mustExecSQL(c, se, "drop table test;")

View File

@ -14,10 +14,14 @@
package variable
import (
"github.com/juju/errors"
"github.com/pingcap/tidb/context"
"github.com/pingcap/tidb/terror"
)
const codeCantGetValidID terror.ErrCode = 1
var errCantGetValidID = terror.ClassVariable.New(codeCantGetValidID, "cannot get valid auto-increment id in retry")
// RetryInfo saves retry infomation.
type RetryInfo struct {
Retrying bool
@ -46,7 +50,7 @@ func (r *RetryInfo) ResetOffset() {
// GetCurrAutoIncrementID gets current AutoIncrementID.
func (r *RetryInfo) GetCurrAutoIncrementID() (int64, error) {
if r.currRetryOff >= len(r.autoIncrementIDs) {
return 0, errors.New("cannot get valid auto-increment id in retry")
return 0, errCantGetValidID
}
id := r.autoIncrementIDs[r.currRetryOff]
r.currRetryOff++

View File

@ -265,7 +265,7 @@ func (t *TxStructure) loadHashMeta(metaKey []byte) (hashMeta, error) {
}
if len(v) != 8 {
return meta, errors.New("invalid list meta data")
return meta, errInvalidListMetaData
}
meta.FieldCount = int64(binary.BigEndian.Uint64(v[0:8]))

View File

@ -160,7 +160,7 @@ func (t *TxStructure) LSet(key []byte, index int64, value []byte) error {
if index >= meta.LIndex && index < meta.RIndex {
return t.txn.Set(t.encodeListDataKey(key, index), value)
}
return errors.Errorf("invalid index %d", index)
return errInvalidListIndex.Gen("invalid list index %d", index)
}
// LClear removes the list of the key.
@ -195,7 +195,7 @@ func (t *TxStructure) loadListMeta(metaKey []byte) (listMeta, error) {
}
if len(v) != 16 {
return meta, errors.Errorf("invalid list meta data")
return meta, errInvalidListMetaData
}
meta.LIndex = int64(binary.BigEndian.Uint64(v[0:8]))

View File

@ -13,7 +13,25 @@
package structure
import "github.com/pingcap/tidb/kv"
import (
"github.com/pingcap/tidb/kv"
"github.com/pingcap/tidb/terror"
)
// structure error codes.
const (
codeInvalidHashKeyFlag terror.ErrCode = 1
codeInvalidHashKeyPrefix = 2
codeInvalidListIndex = 3
codeInvalidListMetaData = 4
)
var (
errInvalidHashKeyFlag = terror.ClassStructure.New(codeInvalidHashKeyFlag, "invalid encoded hash key flag")
errInvalidHashKeyPrefix = terror.ClassStructure.New(codeInvalidHashKeyPrefix, "invalid encoded hash key prefix")
errInvalidListIndex = terror.ClassStructure.New(codeInvalidListMetaData, "invalid list index")
errInvalidListMetaData = terror.ClassStructure.New(codeInvalidListMetaData, "invalid list meta data")
)
// NewStructure creates a TxStructure in transaction txn and with key prefix.
func NewStructure(txn kv.Transaction, prefix []byte) *TxStructure {

View File

@ -86,7 +86,7 @@ func (t *TxStructure) decodeHashDataKey(ek kv.Key) ([]byte, []byte, error) {
if err != nil {
return nil, nil, errors.Trace(err)
} else if TypeFlag(tp) != HashData {
return nil, nil, errors.Errorf("invalid encoded hash data key flag %c", byte(tp))
return nil, nil, errInvalidHashKeyFlag.Gen("invalid encoded hash data key flag %c", byte(tp))
}
_, field, err = codec.DecodeBytes(ek)

View File

@ -53,41 +53,62 @@ type ErrClass int
// Error classes.
const (
ClassParser ErrClass = iota + 1
ClassSchema
ClassAutoid ErrClass = iota + 1
ClassDDL
ClassDomain
ClassEvaluator
ClassExecutor
ClassExpression
ClassInspectkv
ClassKV
ClassMeta
ClassOptimizer
ClassOptimizerPlan
ClassExecutor
ClassEvaluator
ClassKV
ClassParser
ClassPerfSchema
ClassPrivilege
ClassSchema
ClassServer
ClassStructure
ClassVariable
ClassExpression
ClassDDL
// Add more as needed.
)
// String implements fmt.Stringer interface.
func (ec ErrClass) String() string {
switch ec {
case ClassParser:
return "parser"
case ClassSchema:
return "schema"
case ClassOptimizer:
return "optimizer"
case ClassExecutor:
return "executor"
case ClassKV:
return "kv"
case ClassServer:
return "server"
case ClassVariable:
return "variable"
case ClassExpression:
return "expression"
case ClassAutoid:
return "autoid"
case ClassDDL:
return "ddl"
case ClassDomain:
return "domain"
case ClassExecutor:
return "executor"
case ClassExpression:
return "expression"
case ClassInspectkv:
return "inspectkv"
case ClassMeta:
return "meta"
case ClassKV:
return "kv"
case ClassOptimizer:
return "optimizer"
case ClassParser:
return "parser"
case ClassPerfSchema:
return "perfschema"
case ClassPrivilege:
return "privilege"
case ClassSchema:
return "schema"
case ClassServer:
return "server"
case ClassStructure:
return "structure"
case ClassVariable:
return "variable"
}
return strconv.Itoa(int(ec))
}
@ -208,10 +229,10 @@ var (
func init() {
ErrClassToMySQLCodes = make(map[ErrClass](map[ErrCode]uint16))
ErrClassToMySQLCodes[ClassParser] = parserMySQLErrCodes
ErrClassToMySQLCodes[ClassExecutor] = executorMySQLErrCodes
ErrClassToMySQLCodes[ClassServer] = serverMySQLErrCodes
ErrClassToMySQLCodes[ClassExpression] = expressionMySQLErrCodes
ErrClassToMySQLCodes[ClassParser] = parserMySQLErrCodes
ErrClassToMySQLCodes[ClassServer] = serverMySQLErrCodes
defaultMySQLErrorCode = mysql.ErrUnknown
}

View File

@ -236,17 +236,17 @@ func runTestErrorCode(c *C) {
txn2, err := dbt.db.Begin()
c.Assert(err, IsNil)
_, err = txn2.Exec("use db_not_exists;")
checkErrorCode(c, err, tmysql.ErrBadDb)
checkErrorCode(c, err, tmysql.ErrBadDB)
_, err = txn2.Exec("select * from tbl_not_exists;")
checkErrorCode(c, err, tmysql.ErrNoSuchTable)
_, err = txn2.Exec("create database test;")
checkErrorCode(c, err, tmysql.ErrDbCreateExists)
checkErrorCode(c, err, tmysql.ErrDBCreateExists)
_, err = txn2.Exec("create table test (c int);")
checkErrorCode(c, err, tmysql.ErrTableExists)
_, err = txn2.Exec("drop table unknown_table;")
checkErrorCode(c, err, tmysql.ErrBadTable)
_, err = txn2.Exec("drop database unknown_db;")
checkErrorCode(c, err, tmysql.ErrDbDropExists)
checkErrorCode(c, err, tmysql.ErrDBDropExists)
// Optimizer errors
_, err = txn2.Exec("select *, * from test;")