Merge pull request #781 from pingcap/shenli/mysql-error
*: schema errors
This commit is contained in:
@ -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)
|
||||
|
||||
13
ddl/ddl.go
13
ddl/ddl.go
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
@ -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)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user