Skip to content

Commit

Permalink
*: unify errors in ddl package
Browse files Browse the repository at this point in the history
  • Loading branch information
zimulala committed Mar 29, 2016
1 parent 4319909 commit d17e990
Show file tree
Hide file tree
Showing 10 changed files with 138 additions and 69 deletions.
5 changes: 2 additions & 3 deletions ddl/bg_worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func (d *ddl) handleBgJobQueue() error {
err := kv.RunInNewTxn(d.store, false, func(txn kv.Transaction) error {
t := meta.NewMeta(txn)
owner, err := d.checkOwner(t, bgJobFlag)
if terror.ErrorEqual(err, ErrNotOwner) {
if terror.ErrorEqual(err, errNotOwner) {
return nil
}
if err != nil {
Expand Down Expand Up @@ -85,8 +85,7 @@ func (d *ddl) runBgJob(t *meta.Meta, job *model.Job) {
err = d.delReorgTable(t, job)
default:
job.State = model.JobCancelled
err = errors.Errorf("invalid background job %v", job)

err = errInvalidBgJob
}

if err != nil {
Expand Down
17 changes: 10 additions & 7 deletions ddl/column.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/ngaut/log"
"github.com/pingcap/tidb/ast"
"github.com/pingcap/tidb/column"
"github.com/pingcap/tidb/infoschema"
"github.com/pingcap/tidb/kv"
"github.com/pingcap/tidb/meta"
"github.com/pingcap/tidb/model"
Expand Down Expand Up @@ -66,7 +67,7 @@ func (d *ddl) addColumn(tblInfo *model.TableInfo, colInfo *model.ColumnInfo, pos
} else if pos.Tp == ast.ColumnPositionAfter {
c := findCol(cols, pos.RelativeColumn.Name.L)
if c == nil {
return nil, 0, errors.Errorf("No such column: %v", pos.RelativeColumn)
return nil, 0, infoschema.ErrColumnNotExists.Gen("no such column: %v", pos.RelativeColumn)
}

// Insert position is after the mentioned column.
Expand Down Expand Up @@ -109,7 +110,7 @@ func (d *ddl) onAddColumn(t *meta.Meta, job *model.Job) error {
if columnInfo.State == model.StatePublic {
// we already have a column with same column name
job.State = model.JobCancelled
return errors.Errorf("ADD COLUMN: column already exist %s", col.Name.L)
return infoschema.ErrColumnExists.Gen("ADD COLUMN: column already exist %s", col.Name.L)
}
} else {
columnInfo, offset, err = d.addColumn(tblInfo, col, pos)
Expand Down Expand Up @@ -191,7 +192,7 @@ func (d *ddl) onAddColumn(t *meta.Meta, job *model.Job) error {
job.State = model.JobDone
return nil
default:
return errors.Errorf("invalid column state %v", columnInfo.State)
return ErrInvalidColumnState.Gen("invalid column state %v", columnInfo.State)
}
}

Expand All @@ -212,12 +213,13 @@ func (d *ddl) onDropColumn(t *meta.Meta, job *model.Job) error {
colInfo := findCol(tblInfo.Columns, colName.L)
if colInfo == nil {
job.State = model.JobCancelled
return errors.Errorf("column %s doesn't exist", colName)
return infoschema.ErrColumnNotExists.Gen("column %s doesn't exist", colName)
}

if len(tblInfo.Columns) == 1 {
job.State = model.JobCancelled
return errors.Errorf("can't drop only column %s in table %s", colName, tblInfo.Name)
return ErrCantRemoveAllFields.Gen("can't drop only column %s in table %s",
colName, tblInfo.Name)
}

// we don't support drop column with index covered now.
Expand All @@ -226,7 +228,8 @@ func (d *ddl) onDropColumn(t *meta.Meta, job *model.Job) error {
for _, col := range indexInfo.Columns {
if col.Name.L == colName.L {
job.State = model.JobCancelled
return errors.Errorf("can't drop column %s with index %s covered now", colName, indexInfo.Name)
return errCantDropColWithIndex.Gen("can't drop column %s with index %s covered now",
colName, indexInfo.Name)
}
}
}
Expand Down Expand Up @@ -304,7 +307,7 @@ func (d *ddl) onDropColumn(t *meta.Meta, job *model.Job) error {
job.State = model.JobDone
return nil
default:
return errors.Errorf("invalid table state %v", tblInfo.State)
return ErrInvalidTableState.Gen("invalid table state %v", tblInfo.State)
}
}

Expand Down
121 changes: 96 additions & 25 deletions ddl/ddl.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import (
"github.com/pingcap/tidb/mysql"
"github.com/pingcap/tidb/sessionctx/variable"
"github.com/pingcap/tidb/table"
"github.com/pingcap/tidb/terror"
"github.com/pingcap/tidb/util/charset"
"github.com/pingcap/tidb/util/types"
"github.com/twinj/uuid"
Expand Down Expand Up @@ -251,7 +252,7 @@ func (d *ddl) CreateSchema(ctx context.Context, schema model.CIStr, charsetInfo
is := d.GetInformationSchema()
_, ok := is.SchemaByName(schema)
if ok {
return errors.Trace(infoschema.DatabaseExists)
return errors.Trace(infoschema.ErrDatabaseExists)
}

schemaID, err := d.genGlobalID()
Expand Down Expand Up @@ -283,7 +284,7 @@ func (d *ddl) DropSchema(ctx context.Context, schema model.CIStr) (err error) {
is := d.GetInformationSchema()
old, ok := is.SchemaByName(schema)
if !ok {
return errors.Trace(infoschema.DatabaseNotExists)
return errors.Trace(infoschema.ErrDatabaseNotExists)
}

job := &model.Job{
Expand Down Expand Up @@ -466,14 +467,14 @@ func columnDefToCol(ctx context.Context, offset int, colDef *ast.ColumnDef) (*co
case ast.ColumnOptionDefaultValue:
value, err := getDefaultValue(ctx, v, colDef.Tp.Tp, colDef.Tp.Decimal)
if err != nil {
return nil, nil, errors.Errorf("invalid default value - %s", errors.Trace(err))
return nil, nil, ErrColumnBadNull.Gen("invalid default value - %s", err)
}
col.DefaultValue = value
hasDefaultValue = true
removeOnUpdateNowFlag(col)
case ast.ColumnOptionOnUpdate:
if !evaluator.IsCurrentTimeExpr(v.Expr) {
return nil, nil, errors.Errorf("invalid ON UPDATE for - %s", col.Name)
return nil, nil, ErrInvalidOnUpdate.Gen("invalid ON UPDATE for - %s", col.Name)
}

col.Flag |= mysql.OnUpdateNowFlag
Expand Down Expand Up @@ -575,7 +576,7 @@ func checkDefaultValue(c *column.Col, hasDefaultValue bool) error {

// Set not null but default null is invalid.
if mysql.HasNotNullFlag(c.Flag) {
return errors.Errorf("invalid default value for %s", c.Name)
return ErrColumnBadNull.Gen("invalid default value for %s", c.Name)
}

return nil
Expand All @@ -586,7 +587,7 @@ func checkDuplicateColumn(colDefs []*ast.ColumnDef) error {
for _, colDef := range colDefs {
nameLower := colDef.Name.Name.O
if colNames[nameLower] {
return errors.Errorf("CREATE TABLE: duplicate column %s", colDef.Name)
return infoschema.ErrColumnExists.Gen("duplicate column %s", colDef.Name)
}
colNames[nameLower] = true
}
Expand All @@ -605,7 +606,7 @@ func checkConstraintNames(constraints []*ast.Constraint) error {
if constr.Name != "" {
nameLower := strings.ToLower(constr.Name)
if constrNames[nameLower] {
return errors.Errorf("CREATE TABLE: duplicate key %s", constr.Name)
return infoschema.ErrIndexExists.Gen("CREATE TABLE: duplicate key %s", constr.Name)
}
constrNames[nameLower] = true
}
Expand Down Expand Up @@ -646,7 +647,7 @@ func (d *ddl) buildTableInfo(tableName model.CIStr, cols []*column.Col, constrai
key := constr.Keys[0]
col := column.FindCol(cols, key.Column.Name.O)
if col == nil {
return nil, errors.Errorf("No such column: %v", key)
return nil, infoschema.ErrColumnNotExists.Gen("no such column: %v", key)
}
switch col.Tp {
case mysql.TypeLong, mysql.TypeLonglong:
Expand All @@ -663,7 +664,7 @@ func (d *ddl) buildTableInfo(tableName model.CIStr, cols []*column.Col, constrai
for _, key := range constr.Keys {
col := column.FindCol(cols, key.Column.Name.O)
if col == nil {
return nil, errors.Errorf("No such column: %v", key)
return nil, infoschema.ErrColumnNotExists.Gen("no such column: %v", key)
}
indexColumns = append(indexColumns, &model.IndexColumn{
Name: key.Column.Name,
Expand Down Expand Up @@ -705,10 +706,10 @@ func (d *ddl) CreateTable(ctx context.Context, ident ast.Ident, colDefs []*ast.C
is := d.GetInformationSchema()
schema, ok := is.SchemaByName(ident.Schema)
if !ok {
return infoschema.DatabaseNotExists.Gen("database %s not exists", ident.Schema)
return infoschema.ErrDatabaseNotExists.Gen("database %s not exists", ident.Schema)
}
if is.TableExists(ident.Schema, ident.Name) {
return errors.Trace(infoschema.TableExists)
return errors.Trace(infoschema.ErrTableExists)
}
if err = checkDuplicateColumn(colDefs); err != nil {
return errors.Trace(err)
Expand Down Expand Up @@ -768,7 +769,7 @@ func (d *ddl) handleTableOptions(options []*ast.TableOption, tbInfo *model.Table
func (d *ddl) AlterTable(ctx context.Context, ident ast.Ident, specs []*ast.AlterTableSpec) (err error) {
// now we only allow one schema changes at the same time.
if len(specs) != 1 {
return errors.New("can't run multi schema changes in one DDL")
return errRunMultiSchemaChanges
}

for _, spec := range specs {
Expand Down Expand Up @@ -805,7 +806,7 @@ func checkColumnConstraint(constraints []*ast.ColumnOption) error {
for _, constraint := range constraints {
switch constraint.Tp {
case ast.ColumnOptionAutoIncrement, ast.ColumnOptionPrimaryKey, ast.ColumnOptionUniq, ast.ColumnOptionUniqKey:
return errors.Errorf("unsupported add column constraint - %v", constraint.Tp)
return errUnsupportedAddColumn.Gen("unsupported add column constraint - %v", constraint.Tp)
}
}

Expand All @@ -823,19 +824,19 @@ func (d *ddl) AddColumn(ctx context.Context, ti ast.Ident, spec *ast.AlterTableS
is := d.infoHandle.Get()
schema, ok := is.SchemaByName(ti.Schema)
if !ok {
return errors.Trace(infoschema.DatabaseNotExists)
return errors.Trace(infoschema.ErrDatabaseNotExists)
}

t, err := is.TableByName(ti.Schema, ti.Name)
if err != nil {
return errors.Trace(infoschema.TableNotExists)
return errors.Trace(infoschema.ErrTableNotExists)
}

// Check whether added column has existed.
colName := spec.Column.Name.Name.O
col := column.FindCol(t.Cols(), colName)
if col != nil {
return errors.Errorf("column %s already exists", colName)
return infoschema.ErrColumnExists.Gen("column %s already exists", colName)
}

// ingore table constraints now, maybe return error later
Expand Down Expand Up @@ -863,18 +864,18 @@ func (d *ddl) DropColumn(ctx context.Context, ti ast.Ident, colName model.CIStr)
is := d.infoHandle.Get()
schema, ok := is.SchemaByName(ti.Schema)
if !ok {
return errors.Trace(infoschema.DatabaseNotExists)
return errors.Trace(infoschema.ErrDatabaseNotExists)
}

t, err := is.TableByName(ti.Schema, ti.Name)
if err != nil {
return errors.Trace(infoschema.TableNotExists)
return errors.Trace(infoschema.ErrTableNotExists)
}

// Check whether dropped column has existed.
col := column.FindCol(t.Cols(), colName.L)
if col == nil {
return errors.Errorf("column %s doesn’t exist", colName.L)
return infoschema.ErrColumnNotExists.Gen("column %s doesn’t exist", colName.L)
}

job := &model.Job{
Expand All @@ -894,12 +895,12 @@ func (d *ddl) DropTable(ctx context.Context, ti ast.Ident) (err error) {
is := d.GetInformationSchema()
schema, ok := is.SchemaByName(ti.Schema)
if !ok {
return infoschema.DatabaseNotExists.Gen("database %s not exists", ti.Schema)
return infoschema.ErrDatabaseNotExists.Gen("database %s not exists", ti.Schema)
}

tb, err := is.TableByName(ti.Schema, ti.Name)
if err != nil {
return errors.Trace(infoschema.TableNotExists)
return errors.Trace(infoschema.ErrTableNotExists)
}

job := &model.Job{
Expand All @@ -917,12 +918,12 @@ func (d *ddl) CreateIndex(ctx context.Context, ti ast.Ident, unique bool, indexN
is := d.infoHandle.Get()
schema, ok := is.SchemaByName(ti.Schema)
if !ok {
return infoschema.DatabaseNotExists.Gen("database %s not exists", ti.Schema)
return infoschema.ErrDatabaseNotExists.Gen("database %s not exists", ti.Schema)
}

t, err := is.TableByName(ti.Schema, ti.Name)
if err != nil {
return errors.Trace(infoschema.TableNotExists)
return errors.Trace(infoschema.ErrTableNotExists)
}
indexID, err := d.genGlobalID()
if err != nil {
Expand All @@ -945,12 +946,12 @@ func (d *ddl) DropIndex(ctx context.Context, ti ast.Ident, indexName model.CIStr
is := d.infoHandle.Get()
schema, ok := is.SchemaByName(ti.Schema)
if !ok {
return errors.Trace(infoschema.DatabaseNotExists)
return errors.Trace(infoschema.ErrDatabaseNotExists)
}

t, err := is.TableByName(ti.Schema, ti.Name)
if err != nil {
return errors.Trace(infoschema.TableNotExists)
return errors.Trace(infoschema.ErrTableNotExists)
}

job := &model.Job{
Expand All @@ -976,3 +977,73 @@ func findCol(cols []*model.ColumnInfo, name string) *model.ColumnInfo {

return nil
}

// DDL error codes.
const (
codeInvalidWorker terror.ErrCode = 1
codeNotOwner = 2
codeInvalidDDLJob = 3
codeInvalidBgJob = 4
codeInvalidJobFlag = 5
codeRunMultiSchemaChanges = 6
codeWaitReorgTimeout = 7
codeInvalidStoreVer = 8

codeInvalidDBState = 100
codeInvalidTableState = 101
codeInvalidColumnState = 102
codeInvalidIndexState = 103

codeCantDropColWithIndex = 201
codeUnsupportedAddColumn = 202

codeBadNull = 1048
codeCantRemoveAllFields = 1090
codeCantDropFieldOrKey = 1091
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,
codeCantRemoveAllFields: mysql.ErrCantRemoveAllFields,
codeCantDropFieldOrKey: mysql.ErrCantDropFieldOrKey,
codeInvalidOnUpdate: mysql.ErrInvalidOnUpdate,
}
terror.ErrClassToMySQLCodes[terror.ClassDDL] = ddlMySQLERrCodes
}
Loading

0 comments on commit d17e990

Please sign in to comment.