Merge pull request #781 from pingcap/shenli/mysql-error

*: schema errors
This commit is contained in:
Shen Li
2015-12-23 15:01:24 +08:00
9 changed files with 69 additions and 45 deletions

View File

@ -24,9 +24,9 @@ import (
"github.com/juju/errors"
"github.com/ngaut/log"
"github.com/pingcap/tidb/infoschema"
"github.com/pingcap/tidb/mysql"
"github.com/pingcap/tidb/sessionctx/variable"
"github.com/pingcap/tidb/terror"
)
const (
@ -122,7 +122,7 @@ const (
func checkBootstrapped(s Session) (bool, error) {
// Check if system db exists.
_, err := s.Execute(fmt.Sprintf("USE %s;", mysql.SystemDB))
if err != nil && terror.DatabaseNotExists.NotEqual(err) {
if err != nil && infoschema.DatabaseNotExists.NotEqual(err) {
log.Fatal(err)
}
// Check bootstrapped variable value in TiDB table.
@ -138,7 +138,7 @@ func checkBootstrappedVar(s Session) (bool, error) {
mysql.SystemDB, mysql.TiDBTable, bootstrappedVar)
rs, err := s.Execute(sql)
if err != nil {
if terror.TableNotExists.Equal(err) {
if infoschema.TableNotExists.Equal(err) {
return false, nil
}
return false, errors.Trace(err)

View File

@ -35,7 +35,6 @@ import (
"github.com/pingcap/tidb/parser/coldef"
"github.com/pingcap/tidb/sessionctx/variable"
"github.com/pingcap/tidb/table"
"github.com/pingcap/tidb/terror"
"github.com/pingcap/tidb/util/charset"
"github.com/twinj/uuid"
)
@ -473,7 +472,7 @@ func (d *ddl) CreateTable(ctx context.Context, ident table.Ident, colDefs []*col
is := d.GetInformationSchema()
schema, ok := is.SchemaByName(ident.Schema)
if !ok {
return terror.DatabaseNotExists.Gen("database %s not exists", ident.Schema)
return infoschema.DatabaseNotExists.Gen("database %s not exists", ident.Schema)
}
if is.TableExists(ident.Schema, ident.Name) {
return errors.Trace(ErrExists)
@ -567,7 +566,7 @@ func (d *ddl) AddColumn(ctx context.Context, ti table.Ident, spec *AlterSpecific
is := d.infoHandle.Get()
schema, ok := is.SchemaByName(ti.Schema)
if !ok {
return errors.Trace(terror.DatabaseNotExists)
return errors.Trace(infoschema.DatabaseNotExists)
}
t, err := is.TableByName(ti.Schema, ti.Name)
@ -607,7 +606,7 @@ func (d *ddl) DropColumn(ctx context.Context, ti table.Ident, colName model.CISt
is := d.infoHandle.Get()
schema, ok := is.SchemaByName(ti.Schema)
if !ok {
return errors.Trace(terror.DatabaseNotExists)
return errors.Trace(infoschema.DatabaseNotExists)
}
t, err := is.TableByName(ti.Schema, ti.Name)
@ -638,7 +637,7 @@ func (d *ddl) DropTable(ctx context.Context, ti table.Ident) (err error) {
is := d.GetInformationSchema()
schema, ok := is.SchemaByName(ti.Schema)
if !ok {
return terror.DatabaseNotExists.Gen("database %s not exists", ti.Schema)
return infoschema.DatabaseNotExists.Gen("database %s not exists", ti.Schema)
}
tb, err := is.TableByName(ti.Schema, ti.Name)
@ -661,7 +660,7 @@ func (d *ddl) CreateIndex(ctx context.Context, ti table.Ident, unique bool, inde
is := d.infoHandle.Get()
schema, ok := is.SchemaByName(ti.Schema)
if !ok {
return terror.DatabaseNotExists.Gen("database %s not exists", ti.Schema)
return infoschema.DatabaseNotExists.Gen("database %s not exists", ti.Schema)
}
t, err := is.TableByName(ti.Schema, ti.Name)
@ -689,7 +688,7 @@ func (d *ddl) DropIndex(ctx context.Context, ti table.Ident, indexName model.CIS
is := d.infoHandle.Get()
schema, ok := is.SchemaByName(ti.Schema)
if !ok {
return errors.Trace(terror.DatabaseNotExists)
return errors.Trace(infoschema.DatabaseNotExists)
}
t, err := is.TableByName(ti.Schema, ti.Name)

View File

@ -22,6 +22,7 @@ import (
"github.com/pingcap/tidb/context"
"github.com/pingcap/tidb/ddl"
"github.com/pingcap/tidb/executor"
"github.com/pingcap/tidb/infoschema"
"github.com/pingcap/tidb/kv"
"github.com/pingcap/tidb/model"
"github.com/pingcap/tidb/mysql"
@ -74,7 +75,7 @@ func (ts *testSuite) TestDDL(c *C) {
tbStmt := statement(ctx, "create table t (a int primary key not null, b varchar(255), key idx_b (b), c int, d int unique)").(*stmts.CreateTableStmt)
err = sessionctx.GetDomain(ctx).DDL().CreateTable(ctx, table.Ident{Schema: noExist, Name: tbIdent.Name}, tbStmt.Cols, tbStmt.Constraints)
c.Assert(terror.DatabaseNotExists.Equal(err), IsTrue)
c.Assert(infoschema.DatabaseNotExists.Equal(err), IsTrue)
err = sessionctx.GetDomain(ctx).DDL().CreateTable(ctx, tbIdent, tbStmt.Cols, tbStmt.Constraints)
c.Assert(err, IsNil)

View File

@ -15,6 +15,7 @@ package ddl
import (
"github.com/juju/errors"
"github.com/pingcap/tidb/infoschema"
"github.com/pingcap/tidb/meta"
"github.com/pingcap/tidb/meta/autoid"
"github.com/pingcap/tidb/model"
@ -36,7 +37,7 @@ func (d *ddl) onCreateTable(t *meta.Meta, job *model.Job) error {
tables, err := t.ListTables(schemaID)
if terror.ErrorEqual(err, meta.ErrDBNotExists) {
job.State = model.JobCancelled
return errors.Trace(terror.DatabaseNotExists)
return errors.Trace(infoschema.DatabaseNotExists)
} else if err != nil {
return errors.Trace(err)
}
@ -82,7 +83,7 @@ func (d *ddl) onDropTable(t *meta.Meta, job *model.Job) error {
tblInfo, err := t.GetTable(schemaID, tableID)
if terror.ErrorEqual(err, meta.ErrDBNotExists) {
job.State = model.JobCancelled
return errors.Trace(terror.DatabaseNotExists)
return errors.Trace(infoschema.DatabaseNotExists)
} else if err != nil {
return errors.Trace(err)
}

View File

@ -20,6 +20,7 @@ import (
"github.com/pingcap/tidb/kv"
"github.com/pingcap/tidb/meta/autoid"
"github.com/pingcap/tidb/model"
"github.com/pingcap/tidb/mysql"
"github.com/pingcap/tidb/table"
"github.com/pingcap/tidb/terror"
// import table implementation to init table.TableFromMeta
@ -106,7 +107,7 @@ func (is *infoSchema) SchemaExists(schema model.CIStr) bool {
func (is *infoSchema) TableByName(schema, table model.CIStr) (t table.Table, err error) {
id, ok := is.tableNameToID[tableName{schema: schema.L, table: table.L}]
if !ok {
return nil, terror.TableNotExists.Gen("table %s.%s does not exist", schema, table)
return nil, TableNotExists.Gen("table %s.%s does not exist", schema, table)
}
t = is.tables[id]
return
@ -250,3 +251,28 @@ func (h *Handle) Get() InfoSchema {
schema, _ := v.(InfoSchema)
return schema
}
// Schema error codes.
const (
CodeDatabaseNotExists terror.ErrCode = 1049
CodeTableNotExists = 1146
CodeColumnNotExists = 1054
)
var (
// DatabaseNotExists returns for database not exists.
DatabaseNotExists = terror.ClassSchema.New(CodeDatabaseNotExists, "database not exists")
// TableNotExists returns for table not exists.
TableNotExists = terror.ClassSchema.New(CodeTableNotExists, "table not exists")
// ColumnNotExists returns for column not exists.
ColumnNotExists = terror.ClassSchema.New(CodeColumnNotExists, "field not exists")
)
func init() {
schemaMySQLErrCodes := map[terror.ErrCode]uint16{
CodeDatabaseNotExists: mysql.ErrBadDb,
CodeTableNotExists: mysql.ErrNoSuchTable,
CodeColumnNotExists: mysql.ErrBadField,
}
terror.ErrClassToMySQLCodes[terror.ClassSchema] = schemaMySQLErrCodes
}

View File

@ -23,6 +23,7 @@ import (
"github.com/juju/errors"
"github.com/pingcap/tidb/context"
"github.com/pingcap/tidb/ddl"
"github.com/pingcap/tidb/infoschema"
"github.com/pingcap/tidb/model"
"github.com/pingcap/tidb/mysql"
"github.com/pingcap/tidb/privilege"
@ -138,7 +139,7 @@ func (s *DropTableStmt) Exec(ctx context.Context) (rset.Recordset, error) {
}
err = sessionctx.GetDomain(ctx).DDL().DropTable(ctx, fullti)
if terror.ErrorEqual(err, ddl.ErrNotExists) || terror.DatabaseNotExists.Equal(err) {
if terror.ErrorEqual(err, ddl.ErrNotExists) || infoschema.DatabaseNotExists.Equal(err) {
notExistTables = append(notExistTables, ti.String())
} else if err != nil {
return nil, errors.Trace(err)
@ -182,7 +183,7 @@ func (s *DropIndexStmt) SetText(text string) {
// Exec implements the stmt.Statement Exec interface.
func (s *DropIndexStmt) Exec(ctx context.Context) (rset.Recordset, error) {
err := sessionctx.GetDomain(ctx).DDL().DropIndex(ctx, s.TableIdent.Full(ctx), model.NewCIStr(s.IndexName))
if (terror.ErrorEqual(err, ddl.ErrNotExists) || terror.DatabaseNotExists.Equal(err)) && s.IfExists {
if (terror.ErrorEqual(err, ddl.ErrNotExists) || infoschema.DatabaseNotExists.Equal(err)) && s.IfExists {
err = nil
}

View File

@ -19,13 +19,13 @@ package stmts
import (
"github.com/pingcap/tidb/context"
"github.com/pingcap/tidb/infoschema"
"github.com/pingcap/tidb/model"
"github.com/pingcap/tidb/rset"
"github.com/pingcap/tidb/sessionctx"
"github.com/pingcap/tidb/sessionctx/db"
"github.com/pingcap/tidb/sessionctx/variable"
"github.com/pingcap/tidb/stmt"
"github.com/pingcap/tidb/terror"
"github.com/pingcap/tidb/util/format"
)
@ -64,7 +64,7 @@ func (s *UseStmt) Exec(ctx context.Context) (_ rset.Recordset, err error) {
dbname := model.NewCIStr(s.DBName)
dbinfo, exists := sessionctx.GetDomain(ctx).InfoSchema().SchemaByName(dbname)
if !exists {
return nil, terror.DatabaseNotExists.Gen("database %s not exists", dbname)
return nil, infoschema.DatabaseNotExists.Gen("database %s not exists", dbname)
}
db.BindCurrentSchema(ctx, dbname.O)
s.updateSysVars(ctx, dbinfo)

View File

@ -25,9 +25,6 @@ import (
// Common base error instances.
var (
DatabaseNotExists = ClassSchema.New(CodeDatabaseNotExists, "database not exists")
TableNotExists = ClassSchema.New(CodeTableNotExists, "table not exists")
CommitNotInTransaction = ClassExecutor.New(CodeCommitNotInTransaction, "commit not in transaction")
RollbackNotInTransaction = ClassExecutor.New(CodeRollbackNotInTransaction, "rollback not in transaction")
ExecResultIsEmpty = ClassExecutor.New(CodeExecResultIsEmpty, "exec result is empty")
@ -44,24 +41,18 @@ var (
// Same error code can be used in different error classes.
type ErrCode int
// Schema error codes.
const (
CodeDatabaseNotExists ErrCode = iota + 1
CodeTableNotExists
)
// Executor error codes.
const (
CodeCommitNotInTransaction ErrCode = iota + 1
CodeRollbackNotInTransaction
CodeExecResultIsEmpty
CodeCommitNotInTransaction ErrCode = 1
CodeRollbackNotInTransaction = 2
CodeExecResultIsEmpty = 3
)
// KV error codes.
const (
CodeIncompatibleDBFormat ErrCode = iota + 1
CodeNoDataForHandle
CodeKeyExists
CodeIncompatibleDBFormat ErrCode = 1
CodeNoDataForHandle = 2
CodeKeyExists = 3
)
// Variable error codes.
@ -204,7 +195,7 @@ func (e *Error) ToSQLError() *mysql.SQLError {
var defaultMySQLErrorCode uint16
func (e *Error) getMySQLErrorCode() uint16 {
codeMap, ok := errClassToMySQLCodes[e.class]
codeMap, ok := ErrClassToMySQLCodes[e.class]
if !ok {
log.Warnf("Unknown error class: %v", e.class)
return defaultMySQLErrorCode
@ -220,7 +211,6 @@ func (e *Error) getMySQLErrorCode() uint16 {
var (
// ErrCode to mysql error code map.
parserMySQLErrCodes = map[ErrCode]uint16{}
schemaMySQLErrCodes = map[ErrCode]uint16{}
optimizerMySQLErrCodes = map[ErrCode]uint16{}
executorMySQLErrCodes = map[ErrCode]uint16{}
kvMySQLErrCodes = map[ErrCode]uint16{
@ -229,19 +219,18 @@ var (
serverMySQLErrCodes = map[ErrCode]uint16{}
expressionMySQLErrCodes = map[ErrCode]uint16{}
// ErrClass to code-map map.
errClassToMySQLCodes map[ErrClass](map[ErrCode]uint16)
// ErrClassToMySQLCodes is the map of ErrClass to code-map.
ErrClassToMySQLCodes map[ErrClass](map[ErrCode]uint16)
)
func init() {
errClassToMySQLCodes = make(map[ErrClass](map[ErrCode]uint16))
errClassToMySQLCodes[ClassParser] = parserMySQLErrCodes
errClassToMySQLCodes[ClassSchema] = schemaMySQLErrCodes
errClassToMySQLCodes[ClassOptimizer] = optimizerMySQLErrCodes
errClassToMySQLCodes[ClassExecutor] = executorMySQLErrCodes
errClassToMySQLCodes[ClassKV] = kvMySQLErrCodes
errClassToMySQLCodes[ClassServer] = serverMySQLErrCodes
errClassToMySQLCodes[ClassExpression] = expressionMySQLErrCodes
ErrClassToMySQLCodes = make(map[ErrClass](map[ErrCode]uint16))
ErrClassToMySQLCodes[ClassParser] = parserMySQLErrCodes
ErrClassToMySQLCodes[ClassOptimizer] = optimizerMySQLErrCodes
ErrClassToMySQLCodes[ClassExecutor] = executorMySQLErrCodes
ErrClassToMySQLCodes[ClassKV] = kvMySQLErrCodes
ErrClassToMySQLCodes[ClassServer] = serverMySQLErrCodes
ErrClassToMySQLCodes[ClassExpression] = expressionMySQLErrCodes
defaultMySQLErrorCode = mysql.ErrUnknown
}

View File

@ -231,6 +231,13 @@ func runTestErrorCode(c *C) {
c.Assert(err, IsNil)
err = txn1.Commit()
checkErrorCode(c, err, tmysql.ErrDupEntry)
txn2, err := dbt.db.Begin()
c.Assert(err, IsNil)
_, err = txn2.Exec("use db_not_exists;")
checkErrorCode(c, err, tmysql.ErrBadDb)
_, err = txn2.Exec("select * from tbl_not_exists;")
checkErrorCode(c, err, tmysql.ErrNoSuchTable)
})
}