Слияние кода завершено, страница обновится автоматически
// Copyright 2015 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.
package session_test
import (
"fmt"
"strconv"
"strings"
"testing"
_ "github.com/go-sql-driver/mysql"
"github.com/hanchuanchuan/goInception/config"
"github.com/hanchuanchuan/goInception/session"
"github.com/hanchuanchuan/goInception/util/testkit"
. "github.com/pingcap/check"
"golang.org/x/net/context"
)
var _ = Suite(&testSessionIncSuite{})
type SQLError = session.SQLError
// SQLAudit 审核类
type SQLAudit struct {
sql string
errors []*SQLError
}
func TestAudit(t *testing.T) {
TestingT(t)
}
type testSessionIncSuite struct {
testCommon
audits []SQLAudit
}
func (s *testSessionIncSuite) add(sql string, errors ...*SQLError) {
s.audits = append(s.audits, SQLAudit{
sql: sql,
errors: errors,
})
}
func (s *testSessionIncSuite) SetUpSuite(c *C) {
s.initSetUp(c)
inc := &s.defaultInc
inc.EnableFingerprint = true
inc.SqlSafeUpdates = 0
inc.EnableDropTable = true
inc.EnableIdentiferKeyword = true
}
func (s *testSessionIncSuite) TearDownSuite(c *C) {
s.tearDownSuite(c)
}
func (s *testSessionIncSuite) TearDownTest(c *C) {
s.reset()
s.tearDownTest(c)
}
func (s *testSessionIncSuite) testErrorCode(c *C, sql string, errors ...*session.SQLError) {
if s.isAPI {
s.sessionService.LoadOptions(session.SourceOptions{
Host: s.defaultInc.BackupHost,
Port: int(s.defaultInc.BackupPort),
User: s.defaultInc.BackupUser,
Password: s.defaultInc.BackupPassword,
RealRowCount: s.realRowCount,
})
s.testAuditResult(c, sql, errors...)
return
}
if s.tk == nil {
s.tk = testkit.NewTestKitWithInit(c, s.store)
}
// session.CheckAuditSetting(config.GetGlobalConfig())
s.runCheck(sql)
row := s.rows[s.getAffectedRows()-1]
errCode := 0
if len(errors) > 0 {
for _, e := range errors {
level := session.GetErrorLevel(e.Code)
if int(level) > errCode {
errCode = int(level)
}
}
}
if errCode > 0 {
errMsgs := []string{}
for _, e := range errors {
errMsgs = append(errMsgs, e.Error())
}
c.Assert(row[4], Equals, strings.Join(errMsgs, "\n"), Commentf("%v", s.rows))
}
c.Assert(row[2], Equals, strconv.Itoa(errCode), Commentf("%v", row))
}
func (s *testSessionIncSuite) testAuditResult(c *C, sql string, errors ...*session.SQLError) {
result, err := s.sessionService.Audit(context.Background(), s.useDB+sql)
c.Assert(err, IsNil)
// for _, row := range result {
// if row.ErrLevel == 2 {
// fmt.Println(fmt.Sprintf("sql: %v, err: %v", row.Sql, row.ErrorMessage))
// } else {
// fmt.Println(fmt.Sprintf("[%v] sql: %v", session.StatusList[row.StageStatus], row.Sql))
// }
// }
s.records = result
row := result[len(result)-1]
errCode := uint8(0)
if len(errors) > 0 {
for _, e := range errors {
level := session.GetErrorLevel(e.Code)
if level > errCode {
errCode = level
}
}
}
if errCode > 0 {
errMsgs := []string{}
for _, e := range errors {
errMsgs = append(errMsgs, e.Error())
}
c.Assert(row.ErrorMessage, Equals, strings.Join(errMsgs, "\n"), Commentf("%v", result))
}
c.Assert(row.ErrLevel, Equals, errCode, Commentf("%#v", row))
}
func (s *testSessionIncSuite) testManyErrors(c *C, sql string, errors ...*session.SQLError) {
if s.tk == nil {
s.tk = testkit.NewTestKitWithInit(c, s.store)
}
s.runCheck(sql)
errCode := 0
if len(errors) > 0 {
for _, e := range errors {
level := session.GetErrorLevel(e.Code)
if int(level) > errCode {
errCode = int(level)
}
}
}
allErrors := []string{}
for _, row := range s.getResultRows() {
if v, ok := row[4].(string); ok {
v = strings.TrimSpace(v)
if v != "<nil>" && v != "" {
allErrors = append(allErrors, v)
}
}
}
errMsgs := []string{}
for _, e := range errors {
errMsgs = append(errMsgs, e.Error())
}
// c.Assert(len(errMsgs), Equals, len(allErrors), Commentf("%v", allErrors))
c.Assert(len(errMsgs), Equals, len(allErrors), Commentf("%#v", s.rows))
for index, err := range allErrors {
c.Assert(err, Equals, errMsgs[index], Commentf("%v", s.rows))
}
}
func (s *testSessionIncSuite) runAudit(c *C) {
c.Assert(len(s.audits), Not(Equals), 0)
var sqls []string
for _, a := range s.audits {
sqls = append(sqls, a.sql)
}
session.TestCheckAuditSetting(config.GetGlobalConfig())
a := `/*%s;--check=1;--backup=0;--enable-ignore-warnings;real_row_count=%v;*/
inception_magic_start;
%s
%s;
inception_magic_commit;`
res := s.tk.MustQueryInc(fmt.Sprintf(a, s.getAddr(), s.realRowCount, s.useDB,
strings.Join(sqls, ";\n"),
))
s.rows = res.Rows()
rows := s.rows
c.Assert(len(s.audits), Equals, len(rows)-1)
for index, row := range rows {
errors := s.audits[index].errors
errCode := 0
if len(errors) > 0 {
for _, e := range errors {
level := session.GetErrorLevel(e.Code)
if int(level) > errCode {
errCode = int(level)
}
}
}
if errCode > 0 {
errMsgs := []string{}
for _, e := range errors {
errMsgs = append(errMsgs, e.Error())
}
c.Assert(row[4], Equals, strings.Join(errMsgs, "\n"), Commentf("%v", rows))
}
c.Assert(row[2], Equals, strconv.Itoa(errCode), Commentf("%v", row))
}
s.audits = nil
}
func (s *testCommon) assertAudit(c *C,
rows [][]interface{},
allErrors ...[]*SQLError) {
c.Assert(len(rows), Not(Equals), 0)
c.Assert(len(rows), Equals, len(allErrors), Commentf("%v", rows))
for index, row := range rows {
errors := allErrors[index]
errCode := 0
if len(errors) > 0 {
for _, e := range errors {
level := session.GetErrorLevel(e.Code)
if int(level) > errCode {
errCode = int(level)
}
}
}
if errCode > 0 {
errMsgs := []string{}
for _, e := range errors {
errMsgs = append(errMsgs, e.Error())
}
c.Assert(row[4], Equals, strings.Join(errMsgs, "\n"), Commentf("%v", rows))
}
if s.isAPI {
c.Assert(row[2], Equals, int64(errCode), Commentf("%v", row))
} else {
c.Assert(row[2], Equals, strconv.Itoa(errCode), Commentf("%v", row))
}
}
}
func (s *testSessionIncSuite) TestBegin(c *C) {
if testing.Short() {
c.Skip("skipping test; in TRAVIS mode")
}
res := s.tk.MustQueryInc("create table t1(id int);")
s.rows = res.Rows()
c.Assert(len(s.rows), Equals, 1, Commentf("%v", s.rows))
for _, row := range s.rows {
c.Assert(row[2], Equals, "2")
c.Assert(row[4], Equals, "Must start as begin statement.")
}
}
func (s *testSessionIncSuite) TestNoSourceInfo(c *C) {
res := s.tk.MustQueryInc(`inception_magic_start;
create table t1(id int);`)
s.rows = res.Rows()
c.Assert(s.getAffectedRows(), Equals, 1)
for _, row := range s.rows {
c.Assert(row[2], Equals, "2")
c.Assert(row[4], Equals, "Invalid source infomation(inception语法格式错误).")
}
}
func (s *testSessionIncSuite) TestNoSourceInfo2(c *C) {
res := s.tk.MustQueryInc(`/*--check=1;*/
inception_magic_start;create table t1(id int)`)
s.rows = res.Rows()
c.Assert(s.getAffectedRows(), Equals, 1)
for _, row := range s.rows {
c.Assert(row[2], Equals, "2")
c.Assert(row[4], Equals, "Invalid source infomation(主机名为空,端口为0,用户名为空).")
}
}
func (s *testSessionIncSuite) TestWrongDBName(c *C) {
res := s.tk.MustQueryInc(fmt.Sprintf(`/*%s;--check=1;--backup=0;--ignore-warnings=1;*/
inception_magic_start;create table t1(id int);inception_magic_commit;`, s.getAddr()))
s.rows = res.Rows()
c.Assert(s.getAffectedRows(), Equals, 1)
for _, row := range s.rows {
c.Assert(row[2], Equals, "2")
c.Assert(row[4], Equals, "Incorrect database name ''.")
}
}
func (s *testSessionIncSuite) TestEnd(c *C) {
res := s.tk.MustQueryInc(fmt.Sprintf(`/*%s;--check=1;--backup=0;--ignore-warnings=1;*/
inception_magic_start;use test_inc;create table t1(id int);`, s.getAddr()))
s.rows = res.Rows()
c.Assert(s.getAffectedRows(), Equals, 3)
row := s.rows[s.getAffectedRows()-1]
c.Assert(row[2], Equals, "2")
c.Assert(row[4], Equals, "Must end with commit.")
}
func (s *testSessionIncSuite) TestCreateTable(c *C) {
sql := ""
config.GetGlobalConfig().Inc.CheckColumnComment = false
config.GetGlobalConfig().Inc.CheckTableComment = false
// 表存在
sql = "create table t1(id int);create table t1(id int);"
s.testErrorCode(c, sql,
session.NewErr(session.ER_TABLE_EXISTS_ERROR, "t1"))
// 重复列
sql = "create table test_error_code1 (c1 int, c2 int, c2 int)"
s.testErrorCode(c, sql,
session.NewErr(session.ER_DUP_FIELDNAME, "c2"))
// 主键
config.GetGlobalConfig().Inc.CheckPrimaryKey = true
sql = ("create table t1(id int);")
s.testErrorCode(c, sql,
session.NewErr(session.ER_TABLE_MUST_HAVE_PK, "t1"))
config.GetGlobalConfig().Inc.CheckPrimaryKey = false
// 数据类型 警告
sql = "create table t1(id int,c1 bit);"
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DATA_TYPE, "c1"))
sql = "create table t1(id int,c1 enum('red', 'blue', 'black'));"
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DATA_TYPE, "c1"))
sql = "create table t1(id int,c1 set('red', 'blue', 'black'));"
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DATA_TYPE, "c1"))
config.GetGlobalConfig().Inc.EnableTimeStampType = false
sql = "create table t1(id int,c1 timestamp);"
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DATA_TYPE, "c1"))
config.GetGlobalConfig().Inc.EnableTimeStampType = true
sql = "create table t1(id int,c1 timestamp);"
s.testErrorCode(c, sql)
// char列建议
config.GetGlobalConfig().Inc.MaxCharLength = 100
sql = `create table t1(id int,c1 char(200),c2 char(100));`
s.testErrorCode(c, sql,
session.NewErr(session.ER_CHAR_TO_VARCHAR_LEN, "c1"))
config.GetGlobalConfig().Inc.MaxCharLength = 0
sql = `create table t1(id int,c1 char(200));`
s.testErrorCode(c, sql)
// 主键的默认值为函数
sql = "create table t1(c1 datetime(6) not null default current_timestamp(6) primary key);"
s.testErrorCode(c, sql)
// 关键字
config.GetGlobalConfig().Inc.EnableIdentiferKeyword = false
config.GetGlobalConfig().Inc.CheckIdentifier = true
sql = ("create table t1(id int, TABLES varchar(20),`c1$` varchar(20),c1234567890123456789012345678901234567890123456789012345678901234567890 varchar(20));")
s.testErrorCode(c, sql,
session.NewErr(session.ER_IDENT_USE_KEYWORD, "TABLES"),
session.NewErr(session.ER_INVALID_IDENT, "c1$"),
session.NewErr(session.ER_TOO_LONG_IDENT, "c1234567890123456789012345678901234567890123456789012345678901234567890"),
)
// 列注释
config.GetGlobalConfig().Inc.CheckColumnComment = true
sql = "create table t1(c1 varchar(20));"
s.testErrorCode(c, sql,
session.NewErr(session.ER_COLUMN_HAVE_NO_COMMENT, "c1", "t1"))
config.GetGlobalConfig().Inc.CheckColumnComment = false
// 表注释
config.GetGlobalConfig().Inc.CheckTableComment = true
sql = ("create table t1(c1 varchar(20));")
s.testErrorCode(c, sql,
session.NewErr(session.ER_TABLE_MUST_HAVE_COMMENT, "t1"))
config.GetGlobalConfig().Inc.CheckTableComment = false
s.mustCheck(c, "create table t1(c1 varchar(20));")
// 无效默认值
config.GetGlobalConfig().Inc.EnableEnumSetBit = true
sql = "create table t1(id int,c1 int default '');"
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DEFAULT, "c1"))
// sql = "create table t1(id int,c1 bit default '');"
// s.testErrorCode(c, sql,
// session.NewErr(session.ER_INVALID_DEFAULT, "c1"))
sql = "create table t1(id int,c1 bit default '0');"
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DEFAULT, "c1"))
sql = "create table t1(id int,c1 bit default b'0');"
s.testErrorCode(c, sql)
// blob/text字段
config.GetGlobalConfig().Inc.EnableBlobType = false
sql = ("create table t1(id int,c1 blob, c2 text);")
s.testErrorCode(c, sql,
session.NewErr(session.ER_USE_TEXT_OR_BLOB, "c1"),
session.NewErr(session.ER_USE_TEXT_OR_BLOB, "c2"),
)
config.GetGlobalConfig().Inc.EnableBlobType = true
sql = ("create table t1(id int,c1 blob not null);")
s.testErrorCode(c, sql,
session.NewErr(session.ER_TEXT_NOT_NULLABLE_ERROR, "c1", "t1"),
)
// 检查默认值
config.GetGlobalConfig().Inc.CheckColumnDefaultValue = true
sql = "create table t1(c1 varchar(10));"
s.testErrorCode(c, sql,
session.NewErr(session.ER_WITH_DEFAULT_ADD_COLUMN, "c1", "t1"))
config.GetGlobalConfig().Inc.CheckColumnDefaultValue = false
// 支持innodb引擎
config.GetGlobalConfig().Inc.EnableSetEngine = true
config.GetGlobalConfig().Inc.SupportEngine = "innodb"
s.mustCheck(c, "create table t1(c1 varchar(10))engine = innodb;")
sql = ("create table t1(c1 varchar(10))engine = myisam;")
s.testErrorCode(c, sql,
session.NewErr(session.ErrEngineNotSupport, "innodb"))
// 时间戳 timestamp默认值
sql = "create table t1(id int primary key,t1 timestamp default CURRENT_TIMESTAMP,t2 timestamp default CURRENT_TIMESTAMP);"
s.testErrorCode(c, sql,
session.NewErrf("Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause"))
config.GetGlobalConfig().Inc.CheckTimestampDefault = false
sql = "create table t1(id int primary key,c1 timestamp default CURRENT_TIMESTAMP,c2 timestamp ON UPDATE CURRENT_TIMESTAMP);"
if s.explicitDefaultsForTimestamp || !(strings.Contains(s.sqlMode, "TRADITIONAL") ||
(strings.Contains(s.sqlMode, "STRICT_") && strings.Contains(s.sqlMode, "NO_ZERO_DATE"))) {
s.testErrorCode(c, sql)
} else {
s.testErrorCode(c, sql, session.NewErr(session.ER_INVALID_DEFAULT, "c2"))
}
config.GetGlobalConfig().Inc.CheckTimestampDefault = true
sql = "create table t1(id int primary key,c1 timestamp default CURRENT_TIMESTAMP,c2 timestamp ON UPDATE CURRENT_TIMESTAMP);"
if s.explicitDefaultsForTimestamp {
s.testErrorCode(c, sql,
session.NewErr(session.ER_TIMESTAMP_DEFAULT, "c2"))
} else if strings.Contains(s.sqlMode, "TRADITIONAL") ||
(strings.Contains(s.sqlMode, "STRICT_") && strings.Contains(s.sqlMode, "NO_ZERO_DATE")) {
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DEFAULT, "c2"))
} else {
s.testErrorCode(c, sql)
}
config.GetGlobalConfig().Inc.CheckTimestampDefault = false
sql = "create table t1(id int primary key,t1 timestamp default CURRENT_TIMESTAMP,t2 timestamp not null ON UPDATE CURRENT_TIMESTAMP);"
if s.explicitDefaultsForTimestamp || !(strings.Contains(s.sqlMode, "TRADITIONAL") ||
(strings.Contains(s.sqlMode, "STRICT_") && strings.Contains(s.sqlMode, "NO_ZERO_DATE"))) {
s.testErrorCode(c, sql)
} else {
s.testErrorCode(c, sql, session.NewErr(session.ER_INVALID_DEFAULT, "t2"))
}
sql = "create table t1(id int primary key,t1 timestamp default CURRENT_TIMESTAMP,t2 date default CURRENT_TIMESTAMP);"
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DEFAULT, "t2"))
// 时间戳 timestamp数量
config.GetGlobalConfig().Inc.CheckTimestampCount = false
sql = "create table t1(id int primary key,t1 timestamp default CURRENT_TIMESTAMP,t2 timestamp ON UPDATE CURRENT_TIMESTAMP);"
if s.explicitDefaultsForTimestamp || !(strings.Contains(s.sqlMode, "TRADITIONAL") ||
(strings.Contains(s.sqlMode, "STRICT_") && strings.Contains(s.sqlMode, "NO_ZERO_DATE"))) {
s.testErrorCode(c, sql)
} else {
s.testErrorCode(c, sql, session.NewErr(session.ER_INVALID_DEFAULT, "t2"))
}
sql = "create table t1(id int primary key,t1 timestamp default CURRENT_TIMESTAMP,t2 timestamp default CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP);"
s.testErrorCode(c, sql)
config.GetGlobalConfig().Inc.CheckTimestampCount = true
sql = "create table t1(id int primary key,t1 timestamp default CURRENT_TIMESTAMP,t2 timestamp ON UPDATE CURRENT_TIMESTAMP);"
if s.explicitDefaultsForTimestamp || !(strings.Contains(s.sqlMode, "TRADITIONAL") ||
(strings.Contains(s.sqlMode, "STRICT_") && strings.Contains(s.sqlMode, "NO_ZERO_DATE"))) {
s.testErrorCode(c, sql)
} else {
s.testErrorCode(c, sql, session.NewErr(session.ER_INVALID_DEFAULT, "t2"))
}
sql = "create table t1(id int primary key,t1 timestamp default CURRENT_TIMESTAMP,t2 timestamp default CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP);"
s.testErrorCode(c, sql,
session.NewErrf("Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause"))
sql = "create table test_error_code1 (c1 int, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa int)"
s.testErrorCode(c, sql, session.NewErr(session.ER_TOO_LONG_IDENT, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"))
sql = "create table aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(a int)"
s.testErrorCode(c, sql,
session.NewErr(session.ER_TOO_LONG_IDENT, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"))
sql = "create table test_error_code1 (c1 int, c2 int, key aa (c1, c2), key aa (c1))"
s.testErrorCode(c, sql,
session.NewErr(session.ER_DUP_INDEX, "aa", "test_inc", "test_error_code1"),
session.NewErr(session.ER_DUP_KEYNAME, "aa"))
sql = "create table test_error_code1 (c1 int, c2 int, c3 int, key(c_not_exist))"
s.testErrorCode(c, sql,
session.NewErr(session.ER_WRONG_NAME_FOR_INDEX, "NULL", "test_error_code1"),
session.NewErr(session.ER_COLUMN_NOT_EXISTED, "test_error_code1.c_not_exist"))
sql = "create table test_error_code1 (c1 int, c2 int, c3 int, primary key(c_not_exist))"
s.testErrorCode(c, sql,
session.NewErr(session.ER_COLUMN_NOT_EXISTED, "test_error_code1.c_not_exist"))
sql = "create table test_error_code1 (c1 int not null default '')"
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DEFAULT, "c1"))
sql = "CREATE TABLE `t` (`a` double DEFAULT 1.0 DEFAULT 2.0 DEFAULT now());"
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DEFAULT, "a"))
sql = "CREATE TABLE `t` (`a` double DEFAULT now());"
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DEFAULT, "a"))
// 字符集
config.GetGlobalConfig().Inc.EnableSetCharset = false
config.GetGlobalConfig().Inc.SupportCharset = ""
sql = "create table t1(a int) character set utf8;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_TABLE_CHARSET_MUST_NULL, "t1"))
config.GetGlobalConfig().Inc.EnableSetCharset = true
config.GetGlobalConfig().Inc.SupportCharset = "utf8mb4"
sql = "create table t1(a int) character set utf8;"
s.testErrorCode(c, sql,
session.NewErr(session.ErrCharsetNotSupport, "utf8mb4"))
config.GetGlobalConfig().Inc.EnableSetCharset = true
config.GetGlobalConfig().Inc.SupportCharset = "utf8,utf8mb4"
sql = "create table t1(a int) character set utf8;"
s.testErrorCode(c, sql)
config.GetGlobalConfig().Inc.EnableSetCharset = true
config.GetGlobalConfig().Inc.SupportCharset = "utf8,utf8mb4"
sql = "create table t1(a int) character set latin1;"
s.testErrorCode(c, sql,
session.NewErr(session.ErrCharsetNotSupport, "utf8,utf8mb4"))
sql = "create table t1(a int) character set latin123;"
s.testErrorCode(c, sql,
session.NewErr(session.ErrCharsetNotSupport, "utf8,utf8mb4"),
session.NewErrf("Unknown charset %s.", "latin123"))
// 外键
sql = "create table test_error_code (a int not null ,b int not null,c int not null, d int not null, foreign key (b, c) references product(id));"
s.testErrorCode(c, sql,
// session.NewErr(session.ER_WRONG_NAME_FOR_INDEX, "NULL", "test_error_code"),
session.NewErr(session.ER_FOREIGN_KEY, "test_error_code"))
sql = "create table test_error_code (a int not null ,b int not null,c int not null, d int not null, foreign key fk_1(b, c) references product(id));"
s.testErrorCode(c, sql,
session.NewErr(session.ER_FOREIGN_KEY, "test_error_code"))
sql = "create table test_error_code_2;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_MUST_AT_LEAST_ONE_COLUMN))
sql = "create table test_error_code_2 (unique(c1));"
s.testErrorCode(c, sql,
session.NewErr(session.ER_MUST_AT_LEAST_ONE_COLUMN))
sql = "create table test_error_code_2(c1 int, c2 int, c3 int, primary key(c1), primary key(c2));"
s.testErrorCode(c, sql,
session.NewErr(session.ER_MULTIPLE_PRI_KEY))
sql = "create table test_error_code_2(c1 int, c2 int, c3 int, primary key(c1), key cca(c2));"
s.testErrorCode(c, sql)
sql = "create table test_error_code_2(c1 int, c2 int, c3 int, primary key(c1), key(c2));"
s.testErrorCode(c, sql,
session.NewErr(session.ER_WRONG_NAME_FOR_INDEX, "NULL", "test_error_code_2"))
config.GetGlobalConfig().Inc.EnableNullIndexName = true
sql = "create table test_error_code_2(c1 int, c2 int, c3 int, primary key(c1), key(c2));"
s.testErrorCode(c, sql)
config.GetGlobalConfig().Inc.EnableNullIndexName = false
indexMaxLength := 767
if s.innodbLargePrefix {
indexMaxLength = 3072
}
config.GetGlobalConfig().Inc.EnableBlobType = false
config.GetGlobalConfig().Inc.CheckIndexPrefix = false
sql = "create table test_error_code_3(pt text ,primary key (pt));"
s.testErrorCode(c, sql,
session.NewErr(session.ER_USE_TEXT_OR_BLOB, "pt"),
session.NewErr(session.ER_TOO_LONG_KEY, "PRIMARY", indexMaxLength))
config.GetGlobalConfig().Inc.EnableBlobType = true
// 索引长度
sql = "create table test_error_code_3(a text, unique (a(3073)));"
s.testErrorCode(c, sql,
session.NewErr(session.ER_WRONG_NAME_FOR_INDEX, "NULL", "test_error_code_3"),
session.NewErr(session.ER_TOO_LONG_KEY, "", indexMaxLength))
sql = "create table test_error_code_3(c1 int,c2 text, unique uq_1(c1,c2(3069)));"
s.testErrorCode(c, sql,
session.NewErr(session.ER_TOO_LONG_KEY, "uq_1", indexMaxLength))
// ----------------- 索引长度审核 varchar ----------------------
if s.innodbLargePrefix {
sql = "create table test_error_code_3(c1 int primary key,c2 varchar(1024),c3 int, key uq_1(c2,c3)) default charset utf8;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_TOO_LONG_KEY, "uq_1", indexMaxLength))
sql = "create table test_error_code_3(c1 int primary key,c2 varchar(1023),c3 int, key uq_1(c2,c3)) default charset utf8;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_TOO_LONG_KEY, "uq_1", indexMaxLength))
sql = "create table test_error_code_3(c1 int primary key,c2 varchar(1022),c3 int, key uq_1(c2,c3)) default charset utf8;"
s.testErrorCode(c, sql)
} else {
sql = "create table test_error_code_3(c1 int primary key,c2 varchar(256),c3 int, key uq_1(c2,c3)) default charset utf8;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_TOO_LONG_KEY, "uq_1", indexMaxLength))
sql = "create table test_error_code_3(c1 int primary key,c2 varchar(255),c3 int, key uq_1(c2,c3)) default charset utf8;"
s.testErrorCode(c, sql)
sql = "create table test_error_code_3(c1 int primary key,c2 varchar(254),c3 int, key uq_1(c2,c3)) default charset utf8;"
s.testErrorCode(c, sql)
}
// sql = "create table test_error_code_3(c1 int,c2 text, unique uq_1(c1,c2(3068)));"
// if indexMaxLength == 3072 {
// s.testErrorCode(c, sql)
// } else {
// s.testErrorCode(c, sql,
// session.NewErr(session.ER_TOO_LONG_KEY, "", indexMaxLength))
// }
sql = "create table test_error_code_3(pt blob ,primary key (pt));"
s.testErrorCode(c, sql,
session.NewErr(session.ER_BLOB_USED_AS_KEY, "pt"))
sql = "create table test_error_code_3(`id` int, key `primary`(`id`));"
s.testErrorCode(c, sql,
session.NewErr(session.ER_WRONG_NAME_FOR_INDEX, "primary", "test_error_code_3"))
sql = "create table t2(c1.c2 varchar(10));"
s.testErrorCode(c, sql,
session.NewErr(session.ER_WRONG_TABLE_NAME, "c1"))
sql = "create table t2 (c1 int default null primary key , age int);"
s.testErrorCode(c, sql,
session.NewErr(session.ER_PRIMARY_CANT_HAVE_NULL))
sql = "create table t2 (id int null primary key , age int);"
s.testErrorCode(c, sql,
session.NewErr(session.ER_PRIMARY_CANT_HAVE_NULL))
sql = "create table t2 (id int default null, age int, primary key(id));"
s.testErrorCode(c, sql,
session.NewErr(session.ER_PRIMARY_CANT_HAVE_NULL))
sql = "create table t2 (id int null, age int, primary key(id));"
s.testErrorCode(c, sql,
session.NewErr(session.ER_PRIMARY_CANT_HAVE_NULL))
sql = `drop table if exists t1;create table t1(
id int auto_increment comment 'test',
crtTime datetime not null DEFAULT CURRENT_TIMESTAMP comment 'test',
uptTime datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP comment 'test',
primary key(id)) comment 'test';`
s.testErrorCode(c, sql)
// 5.7版本新增计算列
config.GetGlobalConfig().Inc.EnableJsonType = true
if s.DBVersion >= 50700 {
sql = `CREATE TABLE t1(c1 json DEFAULT '{}' COMMENT '日志记录',
type tinyint(10) GENERATED ALWAYS AS (json_extract(operate_info, '$.type')) VIRTUAL COMMENT '操作类型')
ENGINE = InnoDB DEFAULT CHARSET = utf8 COMMENT ='xxx';`
s.testErrorCode(c, sql,
session.NewErr(session.ER_BLOB_CANT_HAVE_DEFAULT, "c1"),
session.NewErr(session.ER_IDENT_USE_KEYWORD, "type"),
)
sql = `CREATE TABLE t1(c1 json DEFAULT NULL COMMENT '日志记录',
type1 tinyint(10) GENERATED ALWAYS AS (json_extract(operate_info, '$.type')) VIRTUAL COMMENT '操作类型')
ENGINE = InnoDB DEFAULT CHARSET = utf8 COMMENT ='xxx';`
s.testErrorCode(c, sql)
sql = `CREATE TABLE t1(c1 json COMMENT '日志记录',
type1 tinyint(10) GENERATED ALWAYS AS (json_extract(operate_info, '$.type')) VIRTUAL COMMENT '操作类型')
ENGINE = InnoDB DEFAULT CHARSET = utf8 COMMENT ='xxx';`
s.testErrorCode(c, sql)
// 计算列移除默认值校验
config.GetGlobalConfig().Inc.CheckColumnDefaultValue = true
sql = `CREATE TABLE t1(c1 json DEFAULT '{}' COMMENT '日志记录',
type1 tinyint(10) GENERATED ALWAYS AS (json_extract(operate_info, '$.type')) VIRTUAL COMMENT '操作类型')
ENGINE = InnoDB DEFAULT CHARSET = utf8 COMMENT ='xxx';`
s.testErrorCode(c, sql,
session.NewErr(session.ER_BLOB_CANT_HAVE_DEFAULT, "c1"))
sql = `CREATE TABLE t1(c1 json DEFAULT NULL COMMENT '日志记录',
type1 tinyint(10) GENERATED ALWAYS AS (json_extract(operate_info, '$.type')) VIRTUAL COMMENT '操作类型')
ENGINE = InnoDB DEFAULT CHARSET = utf8 COMMENT ='xxx';`
s.testErrorCode(c, sql)
sql = `CREATE TABLE t1(c1 json COMMENT '日志记录',
type1 tinyint(10) GENERATED ALWAYS AS (json_extract(operate_info, '$.type')) VIRTUAL COMMENT '操作类型')
ENGINE = InnoDB DEFAULT CHARSET = utf8 COMMENT ='xxx';`
s.testErrorCode(c, sql)
config.GetGlobalConfig().Inc.CheckColumnDefaultValue = false
} else if s.DBVersion >= 50600 {
sql = `CREATE TABLE t1(c1 json DEFAULT '{}' COMMENT '日志记录') ENGINE = InnoDB DEFAULT CHARSET = utf8 COMMENT ='xxx';`
s.testErrorCode(c, sql,
session.NewErr(session.ER_BLOB_CANT_HAVE_DEFAULT, "c1"))
sql = `CREATE TABLE t1(c1 json DEFAULT NULL COMMENT '日志记录') ENGINE = InnoDB DEFAULT CHARSET = utf8 COMMENT ='xxx';`
s.testErrorCode(c, sql)
sql = `CREATE TABLE t1(c1 json COMMENT '日志记录') ENGINE = InnoDB DEFAULT CHARSET = utf8 COMMENT ='xxx';`
s.testErrorCode(c, sql)
}
config.GetGlobalConfig().Inc.EnableNullable = false
sql = `drop table if exists t1;CREATE TABLE t1(c1 int);`
s.testErrorCode(c, sql,
session.NewErr(session.ER_NOT_ALLOWED_NULLABLE, "c1", "t1"))
if s.DBVersion >= 50700 {
sql = `CREATE TABLE t1(c1 tinyint(10) GENERATED ALWAYS AS (json_extract(operate_info, '$.type')) VIRTUAL);`
s.testErrorCode(c, sql)
}
config.GetGlobalConfig().Inc.EnableNullable = true
sql = `drop table if exists t1;CREATE TABLE t1(c1 int);`
s.testErrorCode(c, sql)
// 检查必须的字段
config.GetGlobalConfig().Inc.MustHaveColumns = "c1"
sql = `drop table if exists t1;CREATE TABLE t1(id int);`
s.testErrorCode(c, sql,
session.NewErr(session.ER_MUST_HAVE_COLUMNS, "c1"))
sql = `drop table if exists t1;CREATE TABLE t1(c1 int);`
s.testErrorCode(c, sql)
// 配置参数时添加多余空格,判断对类型解析是否正确
config.GetGlobalConfig().Inc.MustHaveColumns = "c1 int,c2 datetime"
sql = `drop table if exists t1;CREATE TABLE t1(id int);`
s.testErrorCode(c, sql,
session.NewErr(session.ER_MUST_HAVE_COLUMNS, "c1 int,c2 datetime"))
sql = `drop table if exists t1;CREATE TABLE t1(c1 bigint,c2 int);`
s.testErrorCode(c, sql,
session.NewErr(session.ER_MUST_HAVE_COLUMNS, "c1 int,c2 datetime"))
sql = `drop table if exists t1;CREATE TABLE t1(c1 int,c2 datetime);`
s.testErrorCode(c, sql)
sql = `drop table if exists t1;CREATE TABLE t1(c1 int,c2 DATETIME);`
s.testErrorCode(c, sql)
config.GetGlobalConfig().Inc.MustHaveColumns = ""
// 如果表包含以下列,列必须有索引。
config.GetGlobalConfig().Inc.ColumnsMustHaveIndex = "c1 , c2 int "
sql = `drop table if exists t1;CREATE TABLE t1(id int, c1 int, c2 int, index idx_c1 (c1));`
s.testErrorCode(c, sql,
session.NewErr(session.ErrColumnsMustHaveIndex, "c2"))
sql = `drop table if exists t1;CREATE TABLE t1(id int, c1 int, c2 varchar (20), index idx_c1 (c1));`
s.testErrorCode(c, sql,
session.NewErr(session.ErrColumnsMustHaveIndexTypeErr, "c2", "int", "varchar"),
session.NewErr(session.ErrColumnsMustHaveIndex, "c2"))
sql = `drop table if exists t1;create table t1(id int,c2 int unique);`
s.testErrorCode(c, sql)
sql = `drop table if exists t1;create table t1(c1 int primary key,c2 int unique)`
s.testErrorCode(c, sql)
sql = `drop table if exists t1;CREATE TABLE t1(id int, c1 int, c2 int, index idx_1 (c1,c2));`
s.testErrorCode(c, sql,
session.NewErr(session.ErrColumnsMustHaveIndex, "c2"))
sql = `drop table if exists t1;CREATE TABLE t1(id int,c1 int ,c2 int,index idx_c1(c1),index idx_c2(c2));`
s.testErrorCode(c, sql)
sql = `drop table if exists t1;CREATE TABLE t1(id int);ALTER TABLE t1 ADD COLUMN c2 varchar(20);`
s.testErrorCode(c, sql,
session.NewErr(session.ErrColumnsMustHaveIndexTypeErr, "c2", "int", "varchar"),
session.NewErr(session.ErrColumnsMustHaveIndex, "c2"))
sql = `drop table if exists t1;CREATE TABLE t1(id int);ALTER TABLE t1 ADD COLUMN c2 int,add index idx_c2(c2);`
s.testErrorCode(c, sql)
config.GetGlobalConfig().Inc.ColumnsMustHaveIndex = ""
config.GetGlobalConfig().Inc.CheckInsertField = false
config.GetGlobalConfig().IncLevel.ER_WITH_INSERT_FIELD = 0
// 测试表名大小写
sql = `drop table if exists t1;CREATE TABLE t1(c1 int);insert into T1 values(1);`
if s.ignoreCase {
s.testErrorCode(c, sql)
} else {
s.runCheck(sql)
row := s.rows[s.getAffectedRows()-1]
c.Assert(row[2], Equals, "2")
c.Assert(row[4], Equals, "Table 'test_inc.T1' doesn't exist.")
}
// 无效默认值
config.GetGlobalConfig().Inc.CheckAutoIncrementName = true
sql = `create table t1(c1 int auto_increment primary key,c2 int);`
s.testErrorCode(c, sql,
session.NewErr(session.ER_AUTO_INCR_ID_WARNING, "c1"))
// 禁止设置存储引擎
config.GetGlobalConfig().Inc.EnableSetEngine = false
sql = ("drop table if exists t1;create table t1(c1 varchar(10))engine = innodb;")
s.testErrorCode(c, sql,
session.NewErr(session.ER_CANT_SET_ENGINE, "t1"))
// 允许设置存储引擎
config.GetGlobalConfig().Inc.EnableSetEngine = true
config.GetGlobalConfig().Inc.SupportEngine = "innodb"
s.mustCheck(c, "drop table if exists t1;create table t1(c1 varchar(10))engine = innodb;")
// 允许blob,text,json列设置为NOT NULL
config.GetGlobalConfig().Inc.EnableBlobNotNull = false
sql = `create table t1(id int auto_increment primary key,c1 blob not null);`
s.testErrorCode(c, sql,
session.NewErr(session.ER_TEXT_NOT_NULLABLE_ERROR, "c1", "t1"))
sql = `create table t1(id int auto_increment primary key,c1 text not null);`
s.testErrorCode(c, sql,
session.NewErr(session.ER_TEXT_NOT_NULLABLE_ERROR, "c1", "t1"))
if s.DBVersion >= 50600 {
sql = `create table t1(id int auto_increment primary key,c1 json not null);`
s.testErrorCode(c, sql,
session.NewErr(session.ER_TEXT_NOT_NULLABLE_ERROR, "c1", "t1"))
}
config.GetGlobalConfig().Inc.EnableBlobNotNull = true
sql = `create table t1(id int auto_increment primary key,c1 blob not null);`
s.testErrorCode(c, sql)
config.GetGlobalConfig().Inc.CheckIndexPrefix = true
sql = "create table test_error_code_3(a text, unique (a(3073)));"
s.testErrorCode(c, sql,
session.NewErr(session.ER_WRONG_NAME_FOR_INDEX, "NULL", "test_error_code_3"),
session.NewErr(session.ER_INDEX_NAME_UNIQ_PREFIX, "",
config.GetGlobalConfig().Inc.UniqIndexPrefix, "test_error_code_3"),
session.NewErr(session.ER_TOO_LONG_KEY, "", indexMaxLength))
sql = "create table test_error_code_3(a text, key (a(3073)));"
s.testErrorCode(c, sql,
session.NewErr(session.ER_WRONG_NAME_FOR_INDEX, "NULL", "test_error_code_3"),
session.NewErr(session.ER_INDEX_NAME_IDX_PREFIX, "",
"test_error_code_3", config.GetGlobalConfig().Inc.IndexPrefix),
session.NewErr(session.ER_TOO_LONG_KEY, "", indexMaxLength))
config.GetGlobalConfig().Inc.IndexPrefix = "idx_,idx1_"
sql = "create table test_error_code_3(c1 int,c2 int,key idx_1(c1),key idx1_2(c2));"
s.testErrorCode(c, sql)
config.GetGlobalConfig().Inc.IndexPrefix = "idx_,idx1_"
sql = "create table test_error_code_3(c1 int,c2 int,key idx_1(c1),key idx2_2(c2));"
s.testErrorCode(c, sql,
session.NewErr(session.ER_INDEX_NAME_IDX_PREFIX, "idx2_2",
"test_error_code_3", config.GetGlobalConfig().Inc.IndexPrefix),
)
config.GetGlobalConfig().Inc.TablePrefix = "t_"
sql = "create table t1(id int primary key);"
s.testErrorCode(c, sql,
session.NewErr(session.ER_TABLE_PREFIX,
config.GetGlobalConfig().Inc.TablePrefix))
// tidb [v3.1.0 版本开始引入]
sql = "create table t1(a bigint primary key auto_random);"
s.testErrorCode(c, sql,
session.NewErr(session.ER_TABLE_PREFIX,
config.GetGlobalConfig().Inc.TablePrefix))
}
func (s *testSessionIncSuite) TestCreateTableAsSelect(c *C) {
if s.enforeGtidConsistency {
sql = "create table t1(id int primary key);create table t11 as select * from t1;"
s.testErrorCode(c, sql,
session.NewErrf("Statement violates GTID consistency: CREATE TABLE ... SELECT."))
} else {
sql = "create table t1(id int primary key);create table t11 as select * from t1;"
s.testErrorCode(c, sql)
}
}
func (s *testSessionIncSuite) TestDropTable(c *C) {
config.GetGlobalConfig().Inc.EnableDropTable = false
sql := ""
sql = "create table t1(id int);drop table t1;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_CANT_DROP_TABLE, "t1"))
config.GetGlobalConfig().Inc.EnableDropTable = true
sql = "create table t1(id int);drop table t1;"
s.testErrorCode(c, sql)
if s.DBVersion < 80000 {
s.mustRunExec(c, `drop table if exists t1;
create table t1(id int auto_increment primary key,c1 int);
insert into t1(id,c1)values(1,1),(2,2);`)
config.GetGlobalConfig().Inc.MaxDDLAffectRows = 1
sql = "drop table t1;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_CHANGE_TOO_MUCH_ROWS, "Drop", 2, 1))
}
}
func (s *testSessionIncSuite) TestAlterTableAddColumn(c *C) {
config.GetGlobalConfig().Inc.CheckColumnComment = false
config.GetGlobalConfig().Inc.CheckTableComment = false
config.GetGlobalConfig().Inc.EnableDropTable = true
s.mustCheck(c, "drop table if exists t1;create table t1(id int);alter table t1 add column c1 int;")
sql = "drop table if exists t1;create table t1(id int);alter table t1 add column c1 int;alter table t1 add column c1 int;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_COLUMN_EXISTED, "t1.c1"))
s.mustCheck(c, "drop table if exists t1;create table t1(id int);alter table t1 add column c1 int first;alter table t1 add column c2 int after c1;")
// after 不存在的列
sql = "drop table if exists t1;create table t1(id int);alter table t1 add column c2 int after c1;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_COLUMN_NOT_EXISTED, "t1.c1"))
// 数据类型 警告
sql = "drop table if exists t1;create table t1(id int);alter table t1 add column c2 bit;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DATA_TYPE, "c2"))
sql = "drop table if exists t1;create table t1(id int);alter table t1 add column c2 enum('red', 'blue', 'black');"
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DATA_TYPE, "c2"))
sql = "drop table if exists t1;create table t1(id int);alter table t1 add column c2 set('red', 'blue', 'black');"
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DATA_TYPE, "c2"))
// char列建议
config.GetGlobalConfig().Inc.MaxCharLength = 100
sql = `drop table if exists t1;create table t1(id int);
alter table t1 add column c1 char(200);`
s.testErrorCode(c, sql,
session.NewErr(session.ER_CHAR_TO_VARCHAR_LEN, "c1"))
// 字符集
sql = `drop table if exists t1;create table t1(id int);
alter table t1 add column c1 varchar(20) character set utf8;
alter table t1 add column c2 varchar(20) COLLATE utf8_bin;`
s.testManyErrors(c, sql,
session.NewErr(session.ER_CHARSET_ON_COLUMN, "t1", "c1"),
session.NewErr(session.ER_CHARSET_ON_COLUMN, "t1", "c2"))
// 关键字
config.GetGlobalConfig().Inc.EnableIdentiferKeyword = false
config.GetGlobalConfig().Inc.CheckIdentifier = true
sql = ("drop table if exists t1;create table t1(id int);alter table t1 add column TABLES varchar(20);alter table t1 add column `c1$` varchar(20);alter table t1 add column c1234567890123456789012345678901234567890123456789012345678901234567890 varchar(20);")
s.testManyErrors(c, sql,
session.NewErr(session.ER_IDENT_USE_KEYWORD, "TABLES"),
session.NewErr(session.ER_INVALID_IDENT, "c1$"),
session.NewErr(session.ER_TOO_LONG_IDENT, "c1234567890123456789012345678901234567890123456789012345678901234567890"),
)
// 列注释
config.GetGlobalConfig().Inc.CheckColumnComment = true
sql = "drop table if exists t1;create table t1(id int);alter table t1 add column c1 varchar(20);"
s.testErrorCode(c, sql,
session.NewErr(session.ER_COLUMN_HAVE_NO_COMMENT, "c1", "t1"))
config.GetGlobalConfig().Inc.CheckColumnComment = false
// 无效默认值
sql = ("drop table if exists t1;create table t1(id int);alter table t1 add column c1 int default '';")
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DEFAULT, "c1"))
sql = "drop table if exists t1;create table t1(id int);alter table t1 add column c1 int default '';"
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DEFAULT, "c1"))
config.GetGlobalConfig().Inc.EnableEnumSetBit = true
sql = "drop table if exists t1;create table t1(id int);alter table t1 add column c1 bit default '0';"
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DEFAULT, "c1"))
// blob/text字段
config.GetGlobalConfig().Inc.EnableBlobType = false
sql = ("drop table if exists t1;create table t1(id int);alter table t1 add column c1 blob;alter table t1 add column c2 text;")
s.testManyErrors(c, sql,
session.NewErr(session.ER_USE_TEXT_OR_BLOB, "c1"),
session.NewErr(session.ER_USE_TEXT_OR_BLOB, "c2"),
)
config.GetGlobalConfig().Inc.EnableBlobType = true
sql = ("drop table if exists t1;create table t1(id int);alter table t1 add column c1 blob not null;")
s.testErrorCode(c, sql,
session.NewErr(session.ER_TEXT_NOT_NULLABLE_ERROR, "c1", "t1"),
)
// 检查默认值
config.GetGlobalConfig().Inc.CheckColumnDefaultValue = true
sql = "drop table if exists t1;create table t1(id int);alter table t1 add column c1 varchar(10);"
s.testErrorCode(c, sql,
session.NewErr(session.ER_WITH_DEFAULT_ADD_COLUMN, "c1", "t1"))
config.GetGlobalConfig().Inc.CheckColumnDefaultValue = false
sql = "drop table if exists t1;create table t1(id int primary key , age int);"
s.testErrorCode(c, sql)
// // add column
sql = "drop table if exists t1;create table t1 (c1 int primary key);alter table t1 add column c1 int"
s.testErrorCode(c, sql,
session.NewErr(session.ER_COLUMN_EXISTED, "t1.c1"))
sql = "drop table if exists t1;create table t1 (c1 int primary key);alter table t1 add column aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa int"
s.testErrorCode(c, sql,
session.NewErr(session.ER_TOO_LONG_IDENT, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"))
sql = "drop table if exists t1;alter table t1 comment 'test comment'"
s.testErrorCode(c, sql,
session.NewErr(session.ER_TABLE_NOT_EXISTED_ERROR, "test_inc.t1"))
sql = "drop table if exists t1;create table t1 (c1 int primary key);alter table t1 add column `a ` int ;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_IDENT, "a "),
session.NewErr(session.ER_WRONG_COLUMN_NAME, "a "))
sql = "drop table if exists t1;create table t1 (c1 int primary key);alter table t1 add column c2 int on update current_timestamp;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_ON_UPDATE, "c2"))
sql = "drop table if exists t1;create table t1(c2 int on update current_timestamp);"
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_ON_UPDATE, "c2"))
if s.DBVersion >= 50600 {
config.GetGlobalConfig().Inc.EnableJsonType = true
sql = "drop table if exists t1;create table t1 (c1 int primary key);alter table t1 add c2 json;"
s.testErrorCode(c, sql)
config.GetGlobalConfig().Inc.EnableJsonType = false
sql = "drop table if exists t1;create table t1 (c1 int primary key);alter table t1 add c2 json;"
s.testErrorCode(c, sql,
session.NewErr(session.ErrJsonTypeSupport, "c2"))
}
sql = "drop table if exists t1;create table t1 (id int primary key);alter table t1 add column (c1 int,c2 varchar(20));"
s.testErrorCode(c, sql)
// 指定特殊选项
sql = "drop table if exists t1;create table t1 (id int primary key);alter table t1 add column c1 int,ALGORITHM=INPLACE, LOCK=NONE;"
s.testErrorCode(c, sql)
config.GetGlobalConfig().Inc.CheckIdentifier = false
// 特殊字符
sql = "drop table if exists `t3!@#$^&*()`;create table `t3!@#$^&*()`(id int primary key);alter table `t3!@#$^&*()` add column `c3!@#$^&*()2` int comment '123';"
s.testErrorCode(c, sql)
sql = "drop table if exists t1;create table t1(id int primary key);alter table t1 add column c1 int primary key;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_DUP_INDEX, "PRIMARY", "test_inc", "t1"))
sql = "drop table if exists t1;create table t1(id int,key c1(id));alter table t1 add column c1 int unique;"
s.testErrorCode(c, sql)
sql = `drop table if exists t1;
create table t1(id int,key c1(id));
alter table t1 add column c1 int unique;
alter table t1 add index c1(c1);`
s.testErrorCode(c, sql,
session.NewErr(session.ER_DUP_INDEX, "c1", "test_inc", "t1"))
}
func (s *testSessionIncSuite) TestAlterTableAlterColumn(c *C) {
sql = ("create table t1(id int);alter table t1 alter column id set default '';")
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DEFAULT, "id"))
s.mustCheck(c, "create table t1(id int);alter table t1 alter column id set default '1';")
s.mustCheck(c, "create table t1(id int);alter table t1 alter column id drop default ;alter table t1 alter column id set default '1';")
}
func (s *testSessionIncSuite) TestAlterTableModifyColumn(c *C) {
config.GetGlobalConfig().Inc.CheckColumnComment = false
config.GetGlobalConfig().Inc.CheckTableComment = false
s.runCheck("create table t1(id int,c1 int);alter table t1 modify column c1 int first;")
c.Assert(s.getAffectedRows(), GreaterEqual, 2)
for _, row := range s.rows {
c.Assert(row[2], Not(Equals), "2")
}
s.runCheck("create table t1(id int,c1 int);alter table t1 modify column id int after c1;")
c.Assert(s.getAffectedRows(), GreaterEqual, 2)
for _, row := range s.rows {
c.Assert(row[2], Not(Equals), "2")
}
// after 不存在的列
sql = "create table t1(id int);alter table t1 modify column c1 int after id;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_COLUMN_NOT_EXISTED, "t1.c1"))
sql = "create table t1(id int,c1 int);alter table t1 modify column c1 int after id1;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_COLUMN_NOT_EXISTED, "t1.id1"))
// 数据类型 警告
sql = "create table t1(id bit);alter table t1 modify column id bit;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DATA_TYPE, "id"))
sql = "create table t1(id enum('red', 'blue'));alter table t1 modify column id enum('red', 'blue', 'black');"
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DATA_TYPE, "id"))
sql = "create table t1(id set('red'));alter table t1 modify column id set('red', 'blue', 'black');"
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DATA_TYPE, "id"))
// char列建议
config.GetGlobalConfig().Inc.MaxCharLength = 100
sql = `create table t1(id int,c1 char(10));
alter table t1 modify column c1 char(200);`
s.testErrorCode(c, sql,
session.NewErr(session.ER_CHAR_TO_VARCHAR_LEN, "c1"))
// 字符集
sql = `create table t1(id int,c1 varchar(20));
alter table t1 modify column c1 varchar(20) character set utf8;
alter table t1 modify column c1 varchar(20) COLLATE utf8_bin;`
s.testManyErrors(c, sql,
session.NewErr(session.ER_CHARSET_ON_COLUMN, "t1", "c1"),
session.NewErr(session.ER_CHARSET_ON_COLUMN, "t1", "c1"))
// 列注释
config.GetGlobalConfig().Inc.CheckColumnComment = true
sql = ("create table t1(id int,c1 varchar(10));alter table t1 modify column c1 varchar(20);")
s.testErrorCode(c, sql,
session.NewErr(session.ER_COLUMN_HAVE_NO_COMMENT, "c1", "t1"),
)
config.GetGlobalConfig().Inc.CheckColumnComment = false
// 无效默认值
sql = ("create table t1(id int,c1 int);alter table t1 modify column c1 int default '';")
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DEFAULT, "c1"))
// blob/text字段
config.GetGlobalConfig().Inc.EnableBlobType = false
sql = ("create table t1(id int,c1 varchar(10));alter table t1 modify column c1 blob;alter table t1 modify column c1 text;")
s.testManyErrors(c, sql,
session.NewErr(session.ER_USE_TEXT_OR_BLOB, "c1"),
session.NewErr(session.ER_USE_TEXT_OR_BLOB, "c1"),
)
config.GetGlobalConfig().Inc.EnableBlobType = true
sql = ("create table t1(id int,c1 blob);alter table t1 modify column c1 blob not null;")
s.testErrorCode(c, sql,
session.NewErr(session.ER_TEXT_NOT_NULLABLE_ERROR, "c1", "t1"),
)
// 检查默认值
config.GetGlobalConfig().Inc.CheckColumnDefaultValue = true
sql = "create table t1(id int,c1 varchar(5));alter table t1 modify column c1 varchar(10);"
s.testErrorCode(c, sql,
session.NewErr(session.ER_WITH_DEFAULT_ADD_COLUMN, "c1", "t1"))
config.GetGlobalConfig().Inc.CheckColumnDefaultValue = false
// 变更类型
config.GetGlobalConfig().Inc.CheckColumnTypeChange = false
sql = "create table t1(c1 int,c1 int);alter table t1 modify column c1 varchar(10);"
s.testErrorCode(c, sql)
// ----------------- 列类型变更 -----------------
config.GetGlobalConfig().Inc.CheckColumnTypeChange = true
sql = "create table t1(c1 int);alter table t1 modify column c1 varchar(10);"
s.testErrorCode(c, sql,
session.NewErr(session.ER_CHANGE_COLUMN_TYPE, "t1.c1", "int(11)", "varchar(10)"))
config.GetGlobalConfig().Inc.CheckColumnTypeChange = true
sql = "create table t1(c1 smallint);alter table t1 modify column c1 int;"
s.testErrorCode(c, sql)
config.GetGlobalConfig().Inc.CheckColumnTypeChange = true
sql = "create table t1(c1 int);alter table t1 modify column c1 smallint;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_CHANGE_COLUMN_TYPE, "t1.c1", "int(11)", "smallint(6)"))
config.GetGlobalConfig().Inc.CheckColumnTypeChange = true
sql = "create table t1(c1 int);alter table t1 modify column c1 smallint(5);"
s.testErrorCode(c, sql,
session.NewErr(session.ER_CHANGE_COLUMN_TYPE, "t1.c1", "int(11)", "smallint(5)"))
config.GetGlobalConfig().Inc.CheckColumnTypeChange = true
sql = "create table t1(c1 varchar(100));alter table t1 modify column c1 varchar(20);"
s.testErrorCode(c, sql,
session.NewErr(session.ER_CHANGE_COLUMN_TYPE, "t1.c1", "varchar(100)", "varchar(20)"))
config.GetGlobalConfig().Inc.CheckColumnTypeChange = true
sql = "create table t1(c1 float);alter table t1 modify column c1 double;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_CHANGE_COLUMN_TYPE, "t1.c1", "float", "double"))
config.GetGlobalConfig().Inc.CheckColumnTypeChange = true
sql = "create table t1(c1 decimal(10,4));alter table t1 modify column c1 int;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_CHANGE_COLUMN_TYPE, "t1.c1", "decimal(10,4)", "int(11)"))
config.GetGlobalConfig().Inc.CheckColumnTypeChange = true
sql = "create table t1(c1 decimal(10,4));alter table t1 modify column c1 decimal(8,4);"
s.testErrorCode(c, sql,
session.NewErr(session.ER_CHANGE_COLUMN_TYPE, "t1.c1", "decimal(10,4)", "decimal(8,4)"))
config.GetGlobalConfig().Inc.CheckColumnTypeChange = true
sql = "create table t1(c1 decimal(10,4));alter table t1 modify column c1 decimal(12,4);"
s.testErrorCode(c, sql)
// 变更长度时不影响(仅长度变小时警告)
sql = "create table t1(c1 char(100));alter table t1 modify column c1 char(20);"
s.testErrorCode(c, sql,
session.NewErr(session.ER_CHANGE_COLUMN_TYPE, "t1.c1", "char(100)", "char(20)"))
sql = "create table t1(c1 varchar(100));alter table t1 modify column c1 char(10);"
s.testErrorCode(c, sql,
session.NewErr(session.ER_CHANGE_COLUMN_TYPE, "t1.c1", "varchar(100)", "char(10)"))
sql = "create table t1(id int primary key,t1 timestamp default CURRENT_TIMESTAMP,t2 timestamp ON UPDATE CURRENT_TIMESTAMP);"
if s.explicitDefaultsForTimestamp || !(strings.Contains(s.sqlMode, "TRADITIONAL") ||
(strings.Contains(s.sqlMode, "STRICT_") && strings.Contains(s.sqlMode, "NO_ZERO_DATE"))) {
s.testErrorCode(c, sql)
} else {
s.testErrorCode(c, sql, session.NewErr(session.ER_INVALID_DEFAULT, "t2"))
}
// modify column
sql = "create table t1(id int primary key,c1 int);alter table t1 modify testx.t1.c1 int"
s.testErrorCode(c, sql,
session.NewErr(session.ER_WRONG_DB_NAME, "testx"))
sql = "create table t1(id int primary key,c1 int);alter table t1 modify t.c1 int"
s.testErrorCode(c, sql,
session.NewErr(session.ER_WRONG_TABLE_NAME, "t"))
config.GetGlobalConfig().Inc.CheckColumnPositionChange = true
sql = "create table t1(id int primary key,c1 int,c2 int);alter table t1 add column c3 int first"
s.testErrorCode(c, sql,
session.NewErr(session.ErCantChangeColumnPosition, "t1.c3"))
sql = "create table t1(id int primary key,c1 int,c2 int);alter table t1 add column c3 int after c1"
s.testErrorCode(c, sql,
session.NewErr(session.ErCantChangeColumnPosition, "t1.c3"))
sql = "create table t1(id int primary key,c1 int,c2 int);alter table t1 modify column c1 int after c2"
s.testErrorCode(c, sql,
session.NewErr(session.ErCantChangeColumnPosition, "t1.c1"))
sql = "create table t1(id int primary key,c1 int,c2 int);alter table t1 change column c1 c3 int after id"
s.testErrorCode(c, sql,
session.NewErr(session.ErCantChangeColumnPosition, "t1.c3"))
config.GetGlobalConfig().Inc.CheckColumnPositionChange = false
// modify column后,列信息更新
s.mustRunExec(c, "drop table if exists t1;create table t1(id int not null,c1 int);")
sql = "alter table t1 add primary key(id,c1);"
s.testErrorCode(c, sql,
session.NewErr(session.ER_PRIMARY_CANT_HAVE_NULL))
sql = "alter table t1 modify c1 int not null;alter table t1 add primary key(id,c1);"
s.testErrorCode(c, sql)
}
func (s *testSessionIncSuite) TestAlterTableChangeColumn(c *C) {
var sql string
config.GetGlobalConfig().Inc.CheckColumnComment = false
config.GetGlobalConfig().Inc.CheckTableComment = false
s.mustCheck(c, "create table t1(id int,c1 int);alter table t1 modify column c1 int first;")
s.mustCheck(c, "create table t1(id int,c1 int);alter table t1 modify column id int after c1;")
config.GetGlobalConfig().Inc.EnableChangeColumn = false
sql = "create table t1(id int primary key,c1 int,c2 int);alter table t1 change column c1 c3 int after id"
s.testErrorCode(c, sql,
session.NewErr(session.ErCantChangeColumn, "c1"))
config.GetGlobalConfig().Inc.EnableChangeColumn = true
}
func (s *testSessionIncSuite) TestAlterTableDropColumn(c *C) {
sql := ""
sql = "create table t1(id int,c1 int);alter table t1 drop column c2;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_COLUMN_NOT_EXISTED, "t1.c2"))
sql = "create table t1(id int,c1 int);alter table t1 drop column c1;"
s.testErrorCode(c, sql)
// // drop column
sql = "create table t2 (id int null);alter table t2 drop c1"
s.testErrorCode(c, sql,
session.NewErr(session.ER_COLUMN_NOT_EXISTED, "t2.c1"))
sql = "create table t2 (id int null);alter table t2 drop id;"
s.testErrorCode(c, sql,
session.NewErr(session.ErrCantRemoveAllFields))
}
func (s *testSessionIncSuite) TestInsert(c *C) {
config.GetGlobalConfig().Inc.CheckInsertField = false
config.GetGlobalConfig().IncLevel.ER_WITH_INSERT_FIELD = 0
// 表不存在
sql = "insert into t1 values(1,1);"
s.testErrorCode(c, sql,
session.NewErr(session.ER_TABLE_NOT_EXISTED_ERROR, "test_inc.t1"))
// 列数不匹配
sql = "create table t1(id int,c1 int);insert into t1(id) values(1,1);"
s.testErrorCode(c, sql,
session.NewErr(session.ER_WRONG_VALUE_COUNT_ON_ROW, 1))
sql = "create table t1(id int,c1 int);insert into t1(id) values(1),(2,1);"
s.testErrorCode(c, sql,
session.NewErr(session.ER_WRONG_VALUE_COUNT_ON_ROW, 2))
sql = "create table t1(id int,c1 int not null);insert into t1(id,c1) select 1;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_WRONG_VALUE_COUNT_ON_ROW, 1))
// 列重复
sql = "create table t1(id int,c1 int);insert into t1(id,id) values(1,1);"
s.testErrorCode(c, sql,
session.NewErr(session.ER_FIELD_SPECIFIED_TWICE, "id", "t1"))
sql = "create table t1(id int,c1 int);insert into t1(id,id) select 1,1;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_FIELD_SPECIFIED_TWICE, "id", "t1"))
// 字段警告
config.GetGlobalConfig().Inc.CheckInsertField = true
config.GetGlobalConfig().IncLevel.ER_WITH_INSERT_FIELD = 1
sql = "create table t1(id int,c1 int);insert into t1 values(1,1);"
s.testErrorCode(c, sql,
session.NewErr(session.ER_WITH_INSERT_FIELD))
config.GetGlobalConfig().Inc.CheckInsertField = false
config.GetGlobalConfig().IncLevel.ER_WITH_INSERT_FIELD = 0
sql = "create table t1(id int,c1 int);insert into t1(id) values();"
s.testErrorCode(c, sql,
session.NewErr(session.ER_WITH_INSERT_VALUES))
// 列不允许为空
sql = "create table t1(id int,c1 int not null);insert into t1(id,c1) values(1,null);"
s.testErrorCode(c, sql,
session.NewErr(session.ER_BAD_NULL_ERROR, "test_inc.t1.c1", 1))
sql = "create table t1(id int,c1 int not null default 1);insert into t1(id,c1) values(1,null);"
s.testErrorCode(c, sql,
session.NewErr(session.ER_BAD_NULL_ERROR, "test_inc.t1.c1", 1))
// insert select 表不存在
sql = "create table t1(id int,c1 int );insert into t1(id,c1) select 1,null from t2;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_TABLE_NOT_EXISTED_ERROR, "test_inc.t2"))
s.mustRunExec(c, "create table t1(id int,c1 int );")
config.GetGlobalConfig().Inc.CheckDMLWhere = true
sql = "insert into t1(id,c1) select 1,null from t1;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_NO_WHERE_CONDITION))
config.GetGlobalConfig().Inc.CheckDMLWhere = false
// limit
config.GetGlobalConfig().Inc.CheckDMLLimit = true
sql = "insert into t1(id,c1) select 1,null from t1 limit 1;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_WITH_LIMIT_CONDITION))
config.GetGlobalConfig().Inc.CheckDMLLimit = false
// order by rand()
// config.GetGlobalConfig().Inc.CheckDMLOrderBy = true
sql = "insert into t1(id,c1) select 1,null from t1 order by rand();"
s.testErrorCode(c, sql,
session.NewErr(session.ER_ORDERY_BY_RAND))
// config.GetGlobalConfig().Inc.CheckDMLOrderBy = false
// 受影响行数
s.runCheck("insert into t1 values(1,1),(2,2);")
s.testAffectedRows(c, 2)
s.runCheck("insert into t1(id,c1) select 1,null;")
s.testAffectedRows(c, 1)
s.mustRunExec(c, "drop table if exists t1; create table t1(c1 char(100) not null);")
sql = "create table t1(c1 char(100) not null);insert into t1(c1) values(null);"
s.testErrorCode(c, sql,
session.NewErr(session.ER_BAD_NULL_ERROR, "test_inc.t1.c1", 1))
sql = "create table t1(c1 char(100) not null);insert into t1(c1) select t1.c1 from t1 inner join t1 on t1.id=t1.id;"
s.testErrorCode(c, sql,
session.NewErr(session.ErrNonUniqTable, "t1"))
// 由于是否报错依赖于实际的mysql版本,所以暂时忽略
// sql = "create table t1(c1 char(100) not null);insert into t1(c1) select t1.c1 from t1 limit 1 union all select t1.c1 from t1;"
// s.testErrorCode(c, sql,
// session.NewErr(session.ErrWrongUsage, "UNION", "LIMIT"))
// sql = "create table t1(c1 char(100) not null);insert into t1(c1) select t1.c1 from t1 order by 1 union all select t1.c1 from t1;"
// s.testErrorCode(c, sql,
// session.NewErr(session.ErrWrongUsage, "UNION", "ORDER BY"))
// insert 行数
config.GetGlobalConfig().Inc.MaxInsertRows = 1
sql = `drop table if exists t1;create table t1(id int);
insert into t1 values(1);`
s.testErrorCode(c, sql)
s.testAffectedRows(c, 1)
sql = `drop table if exists t1;create table t1(id int);
insert into t1 values(1),(2);`
s.testErrorCode(c, sql,
session.NewErr(session.ER_INSERT_TOO_MUCH_ROWS, 2, 1))
config.GetGlobalConfig().Inc.MaxInsertRows = 3
sql = `drop table if exists t1;create table t1(id int);
insert into t1 values(1),(2),(3);`
s.testErrorCode(c, sql)
s.testAffectedRows(c, 3)
s.mustRunExec(c, "drop table if exists t1;create table t1(id int);")
sql = `drop table if exists t2;create table t2 like t1;
insert into t2 select id from t1;`
s.testErrorCode(c, sql)
if s.realRowCount {
s.testAffectedRows(c, 0)
} else {
s.testAffectedRows(c, 1)
}
config.GetGlobalConfig().Inc.EnableSelectStar = true
s.mustRunExec(c, "drop table if exists tt1;create table tt1(id int,c1 int);insert into tt1 values(1,1);")
sql = `insert into tt1 select a.* from tt1 a inner join tt1 b on a.id=b.id;`
s.testErrorCode(c, sql)
sql = `insert into tt1 select a.* from tt1 a inner join tt1 b on a.id=b.id;`
s.testErrorCode(c, sql)
sql = `insert into tt1 select A.* from (select * from tt1) a inner join tt1 b on a.id=b.id;`
s.testErrorCode(c, sql)
sql = `insert into tt1 select A.* from (select c2.* from tt1 c1 inner join tt1 c2 on c1.id=c2.id) a inner join test_inc.tt1 b on a.id=b.id;`
s.testErrorCode(c, sql)
sql = `insert into test_inc.tt1 select A.* from (select * from tt1 c1 union all select * from tt1 c2) a inner join test_inc.tt1 b on a.id=b.id;`
s.testErrorCode(c, sql)
sql = `insert into test_inc.tt1 select test_inc.B.* from tt1 a inner join test_inc.tt1 b on a.id=b.id;`
s.testErrorCode(c, sql)
sql = `insert into test_inc.tt1 select * from test_inc.tt1 ;`
s.testErrorCode(c, sql)
sql = `insert into test_inc.tt1(id)values(c1);`
s.testErrorCode(c, sql)
sql = `insert into test_inc.tt1(id)values(now);`
s.testErrorCode(c, sql,
session.NewErr(session.ER_COLUMN_NOT_EXISTED, "now"))
sql = `insert into t1(id) values(nullif(a,'123'));`
s.testErrorCode(c, sql,
session.NewErr(session.ER_COLUMN_NOT_EXISTED, "a"))
sql = `insert into t1(id) values(now);`
s.testErrorCode(c, sql,
session.NewErr(session.ER_COLUMN_NOT_EXISTED, "now"))
sql = `insert into t1(id) values(now());`
s.testErrorCode(c, sql)
sql = `insert into t1(id) values(max(1));`
s.testErrorCode(c, sql)
sql = `insert into t1(id) values(max(a));`
s.testErrorCode(c, sql,
session.NewErr(session.ER_COLUMN_NOT_EXISTED, "a"))
sql = `insert into t1(id) values(abs(-1));`
s.testErrorCode(c, sql)
sql = `insert into t1(id) values(cast(a as signed));`
s.testErrorCode(c, sql,
session.NewErr(session.ER_COLUMN_NOT_EXISTED, "a"))
sql = `drop table if exists tt1;create table tt1(id int,c1 int);insert into tt1(id) select max(id) from tt1 where id in (select id1 from tt1);`
s.testErrorCode(c, sql,
session.NewErr(session.ER_COLUMN_NOT_EXISTED, "id1"))
sql = `drop table if exists tt1;create table tt1(id int,c1 int);
drop table if exists t1;create table t1(id int primary key,c1 int);
insert into tt1(id)
select s1.id from t1 as s1 inner join t1 as s2 on s1.c1 = s2.c1 where s1.id > s2.id;`
s.testErrorCode(c, sql)
config.GetGlobalConfig().Inc.EnableSelectStar = false
sql = `drop table if exists tt1;create table tt1(id int,c1 int);insert into tt1 select * from tt1;`
s.testErrorCode(c, sql,
session.NewErr(session.ER_SELECT_ONLY_STAR))
// datetime format 验证
sql = `drop table if exists t1;
create table t1(id int auto_increment primary key,c1 date,c2 time,c3 datetime,c4 timestamp);`
s.mustRunExec(c, sql)
sql = `insert into t1(c1) values('2020-1-32');`
s.testErrorCode(c, sql,
session.NewErr(session.ErrIncorrectDateTimeValue, "2020-1-32", "test_inc.t1.c1"))
sql = `insert into t1(c2) values('10:70');`
s.testErrorCode(c, sql,
session.NewErr(session.ErrIncorrectDateTimeValue, "10:70", "test_inc.t1.c2"))
sql = `insert into t1(c3) values('2020-1-32');`
s.testErrorCode(c, sql,
session.NewErr(session.ErrIncorrectDateTimeValue, "2020-1-32", "test_inc.t1.c3"))
sql = `insert into t1(c4) values('2020-1-32');`
s.testErrorCode(c, sql,
session.NewErr(session.ErrIncorrectDateTimeValue, "2020-1-32", "test_inc.t1.c4"))
}
func (s *testSessionIncSuite) TestSelect(c *C) {
config.GetGlobalConfig().Inc.EnableSelectStar = false
s.mustRunExec(c, "drop table if exists t1;create table t1(id int,c1 integer);")
sql = `select * from t1;`
s.testErrorCode(c, sql,
session.NewErr(session.ER_SELECT_ONLY_STAR))
sql = `select id,c1 from t1 union all select * from t1;`
s.testErrorCode(c, sql,
session.NewErr(session.ER_SELECT_ONLY_STAR))
// 列隐式转换审核
config.GetGlobalConfig().Inc.CheckImplicitTypeConversion = true
sql = `select id,c1 from t1 where c1 ="1";`
s.testErrorCode(c, sql,
session.NewErr(session.ErrImplicitTypeConversion, "t1", "c1", "int"))
sql = `select id from t1 order by id;`
s.testErrorCode(c, sql)
}
func (s *testSessionIncSuite) TestPartition(c *C) {
config.GetGlobalConfig().Inc.EnablePartitionTable = false
s.mustRunExec(c, "drop table if exists test_partition;")
sql = `create table test_partition(
id int unsigned not null auto_increment comment 'id',
a varchar(10) comment 'a',
buss_day varchar(8) comment 'day',
primary key (id,buss_day)
) comment '分区表'
partition by list columns (buss_day)
(
partition p1 values in('20200101'),
partition p2 values in('20200102'),
partition p3 values in('20200103')
)`
s.testErrorCode(c, sql,
session.NewErr(session.ER_PARTITION_NOT_ALLOWED))
sql = `create table test_partition(
id int unsigned not null auto_increment comment 'id',
a varchar(10) comment 'a',
buss_day varchar(8) comment 'day',
primary key (id,buss_day)
) comment '分区表'
partition by list columns (buss_day)
(
partition p1 values in('20200101'),
partition p2 values in('20200102'),
partition p3 values in('20200103')
);
alter table test_partition add partition (
partition p4 values in('20200104'),
partition p5 values in('20200105'),
partition p6 values in('20200106')
);`
s.testErrorCode(c, sql,
session.NewErr(session.ER_PARTITION_NOT_ALLOWED))
// ----------- enable partition -----------
config.GetGlobalConfig().Inc.EnablePartitionTable = true
sql = `create table test_partition(
id int unsigned not null auto_increment comment 'id',
a varchar(10) comment 'a',
buss_day varchar(8) comment 'day',
primary key (id,buss_day)
) comment '分区表'
partition by list columns (buss_day)
(
partition p1 values in('20200101'),
partition p2 values in('20200102'),
partition p3 values in('20200103')
)`
s.testErrorCode(c, sql)
s.mustRunExec(c, sql)
sql = `alter table test_partition add partition (
partition p4 values in('20200104'),
partition p5 values in('20200105'),
partition p6 values in('20200106')
);`
s.testErrorCode(c, sql)
s.mustRunExec(c, sql)
sql = `alter table test_partition drop partition p5,p6;`
s.testErrorCode(c, sql)
s.mustRunExec(c, sql)
sql = `alter table test_partition drop partition p5,p6;`
s.testErrorCode(c, sql,
session.NewErr(session.ErrPartitionNotExisted, "p5"),
session.NewErr(session.ErrPartitionNotExisted, "p6"))
sql = `CREATE TABLE my_range_datetime(
id INT,
hiredate DATETIME
)
PARTITION BY RANGE (TO_DAYS(hiredate) ) (
PARTITION p1 VALUES LESS THAN ( TO_DAYS('20171202') ),
PARTITION p2 VALUES LESS THAN ( TO_DAYS('20171203') ),
PARTITION p3 VALUES LESS THAN ( TO_DAYS('20171204') ),
PARTITION p4 VALUES LESS THAN ( TO_DAYS('20171205') ),
PARTITION p5 VALUES LESS THAN ( TO_DAYS('20171206') ),
PARTITION p6 VALUES LESS THAN ( TO_DAYS('20171207') ),
PARTITION p7 VALUES LESS THAN ( TO_DAYS('20171208') ),
PARTITION p8 VALUES LESS THAN ( TO_DAYS('20171209') ),
PARTITION p9 VALUES LESS THAN ( TO_DAYS('20171210') ),
PARTITION p10 VALUES LESS THAN ( TO_DAYS('20171211') ),
PARTITION p11 VALUES LESS THAN (MAXVALUE)
);`
s.mustRunExec(c, sql)
sql = `create table t_list(a int(11),b int(11))
partition by list (b)(
partition p0 values in (1,3,5,7,9),
partition p1 values in (2,4,6,8,0));`
s.mustRunExec(c, sql)
sql = `CREATE TABLE my_member (
id INT NOT NULL,
fname VARCHAR(30),
lname VARCHAR(30),
created DATE NOT NULL DEFAULT '1970-01-01',
separated DATE NOT NULL DEFAULT '9999-12-31',
job_code INT,
store_id INT
)
PARTITION BY HASH(id)
PARTITIONS 4;`
s.mustRunExec(c, sql)
sql = `CREATE TABLE my_members (
id INT NOT NULL,
fname VARCHAR(30),
lname VARCHAR(30),
hired DATE NOT NULL DEFAULT '1970-01-01',
separated DATE NOT NULL DEFAULT '9999-12-31',
job_code INT,
store_id INT
)
PARTITION BY LINEAR HASH( id )
PARTITIONS 4;`
s.mustRunExec(c, sql)
sql = `CREATE TABLE k1 (
id INT NOT NULL PRIMARY KEY,
name VARCHAR(20)
)
PARTITION BY KEY()
PARTITIONS 2;`
s.mustRunExec(c, sql)
sql = `CREATE TABLE tm1 (
s1 CHAR(32)
)
PARTITION BY KEY(s1)
PARTITIONS 10;`
s.mustRunExec(c, sql)
sql = `CREATE TABLE customer_login_log (
customer_id int(10) unsigned NOT NULL COMMENT '登录用户ID',
login_time DATETIME NOT NULL COMMENT '用户登录时间',
login_ip int(10) unsigned NOT NULL COMMENT '登录IP',
login_type tinyint(4) NOT NULL COMMENT '登录类型:0未成功 1成功'
) ENGINE=InnoDB
PARTITION BY RANGE (YEAR(login_time))(
PARTITION p0 VALUES LESS THAN (2017),
PARTITION p1 VALUES LESS THAN (2018),
PARTITION p2 VALUES LESS THAN (2019)
);
CREATE TABLE arch_customer_login_log (
customer_id INT unsigned NOT NULL COMMENT '登录用户ID',
login_time DATETIME NOT NULL COMMENT '用户登录时间',
login_ip INT unsigned NOT NULL COMMENT '登录IP',
login_type TINYINT NOT NULL COMMENT '登录类型:0未成功 1成功'
) ENGINE=InnoDB ;`
s.mustRunExec(c, sql)
sql = `ALTER TABLE customer_login_log
exchange PARTITION p1 WITH TABLE arch_customer_login_log;`
s.mustRunExec(c, sql)
}
func (s *testSessionIncSuite) TestSubSelect(c *C) {
config.GetGlobalConfig().Inc.EnableSelectStar = true
s.mustRunExec(c, `drop table if exists t1,t2;
CREATE TABLE t1(id INT,NAME VARCHAR(30));
CREATE TABLE t2(id INT ,salesid INT ,title VARCHAR(100));`)
sql = `SELECT a.id,a.title,(SELECT b.name FROM t1 b WHERE b.id = a.salesid) AS salesname
FROM t2 a;`
s.testErrorCode(c, sql)
}
func (s *testSessionIncSuite) TestUpdate(c *C) {
saved := config.GetGlobalConfig().Inc
defer func() {
config.GetGlobalConfig().Inc = saved
s.realRowCount = true
}()
config.GetGlobalConfig().Inc.CheckInsertField = false
config.GetGlobalConfig().IncLevel.ER_WITH_INSERT_FIELD = 0
config.GetGlobalConfig().Inc.EnableSetEngine = true
// 表不存在
sql = "update t1 set c1 = 1;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_TABLE_NOT_EXISTED_ERROR, "test_inc.t1"))
sql = "create table t1(id int);update t1 set id = 1;"
s.testErrorCode(c, sql)
sql = "create table t1(id int);update t1 as tmp set t1.id = 1;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_COLUMN_NOT_EXISTED, "t1.id"))
sql = "create table t1(id int);update t1 set c1 = 1;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_COLUMN_NOT_EXISTED, "c1"))
sql = "create table t1(id int,c1 int);update t1 set c1 = 1,c2 = 1;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_COLUMN_NOT_EXISTED, "t1.c2"))
sql = `create table t1(id int primary key,c1 int);
update t1 s1 inner join t1 s2 on s1.id=s2.id set s1.c1=s2.c1 where s1.c1=1;`
s.testErrorCode(c, sql)
sql = `create table t1(id int primary key,c1 int);
create table t2(id int primary key,c1 int,c2 int);
update t1 inner join t2 on t1.id=t2.id2 set t1.c1=t2.c1 where c11=1;`
s.testErrorCode(c, sql,
session.NewErr(session.ER_COLUMN_NOT_EXISTED, "t2.id2"),
session.NewErr(session.ER_COLUMN_NOT_EXISTED, "c11"))
sql = `create table t1(id int primary key,c1 int);
create table t2(id int primary key,c1 int,c2 int);
update t1,t2 t3 set t1.c1=t2.c3 where t1.id=t3.id;`
s.testErrorCode(c, sql,
session.NewErr(session.ER_COLUMN_NOT_EXISTED, "t2.c3"))
sql = `create table t1(id int primary key,c1 int);
create table t2(id int primary key,c1 int,c2 int);
update t1,t2 t3 set t1.c1=t2.c3 where t1.id=t3.id;`
s.testErrorCode(c, sql,
session.NewErr(session.ER_COLUMN_NOT_EXISTED, "t2.c3"))
// where
config.GetGlobalConfig().Inc.CheckDMLWhere = true
sql = "create table t1(id int,c1 int);update t1 set c1 = 1;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_NO_WHERE_CONDITION))
sql = `create table t1(id int,c1 int);
create table t2(id int,c1 int);`
s.mustRunExec(c, sql)
sql = `update t1 join t2 set t1.c1 = 1;`
s.testErrorCode(c, sql,
session.NewErr(session.ErrJoinNoOnCondition),
session.NewErr(session.ER_NO_WHERE_CONDITION))
sql = `update t1,t2 set t1.c1 = 1;`
s.testErrorCode(c, sql,
session.NewErr(session.ErrJoinNoOnCondition),
session.NewErr(session.ER_NO_WHERE_CONDITION))
sql = `update t1 NATURAL join t2 set t1.c1 = 1 ;`
s.testErrorCode(c, sql,
session.NewErr(session.ER_NO_WHERE_CONDITION))
sql = `create table t1(id int,c1 int);
create table t2(id int,c1 int);
update t1 join t2 using(id) set t1.c1 = 1 ;`
s.testErrorCode(c, sql,
session.NewErr(session.ER_NO_WHERE_CONDITION))
sql = `update t1,t2 set t1.c1 = 1 where t1.id=1;`
s.testErrorCode(c, sql)
config.GetGlobalConfig().Inc.CheckDMLWhere = false
// limit
config.GetGlobalConfig().Inc.CheckDMLLimit = true
sql = "create table t1(id int,c1 int);update t1 set c1 = 1 limit 1;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_WITH_LIMIT_CONDITION))
config.GetGlobalConfig().Inc.CheckDMLLimit = false
// order by rand()
config.GetGlobalConfig().Inc.CheckDMLOrderBy = true
sql = "create table t1(id int,c1 int);update t1 set c1 = 1 order by rand();"
s.testErrorCode(c, sql,
session.NewErr(session.ER_WITH_ORDERBY_CONDITION))
config.GetGlobalConfig().Inc.CheckDMLOrderBy = false
// 受影响行数
s.realRowCount = false
s.mustCheck(c, "drop table if exists t1,t2;create table t1(id int,c1 int);update t1 set c1 = 1;")
s.testAffectedRows(c, 0)
// 受影响行数: explain计算规则
s.mustRunExec(c, `drop table if exists t1,t2;
create table t1(id int primary key,c1 int);
create table t2(id int primary key,c1 int);
insert into t1(id,c1)values(1,1);
insert into t2(id,c1)values(1,1),(2,2),(3,3);`)
config.GetGlobalConfig().Inc.ExplainRule = "first"
sql = `update t1 inner join t2 on 1=1 set t1.c1=t2.c1 where 1=1;`
s.mustCheck(c, sql)
s.testAffectedRows(c, 1)
config.GetGlobalConfig().Inc.ExplainRule = "max"
s.mustCheck(c, sql)
s.testAffectedRows(c, 3)
s.mustRunExec(c, `drop table if exists t1,t2`)
sql = `drop table if exists table1;drop table if exists table2;
create table table1(id int primary key,c1 int);
create table table2(id int primary key,c1 int,c2 int);
update table1 t1,table2 t2 set t1.c1=t2.c1 where t1.id=t2.id;`
s.testErrorCode(c, sql)
sql = `drop table if exists table1;drop table if exists table2;
create table table1(id1 int primary key,c1 int);
create table table2(id2 int primary key,c2 int,c22 int);
update table1 t1,table2 t2 set t1.c1=t2.c2 where t1.id1=t2.id2;`
s.testErrorCode(c, sql)
sql = `drop table if exists table1;drop table if exists table2;
create table table1(id1 int primary key,c1 int);
create table table2(id2 int primary key,c2 int,c22 int);
update table1 a1,table2 a2 set a1.c1=a2.c2 where a1.id1=a2.id2 and a1.c1=a2.c2 and a1.id1 in (1,2,3);`
s.testErrorCode(c, sql)
sql = `drop table if exists table1;drop table if exists table2;
create table table1(id1 int primary key,c1 int);
create table test.table2(id2 int primary key,c2 int,c22 int);
update table1 a1,test.table2 a2 set a1.c1=a2.c2 where a1.id1=a2.id2 and a1.c1=a2.c2 and a1.id1 in (1,2,3);`
s.testErrorCode(c, sql)
s.mustRunExec(c, "drop table if exists t1;create table t1(id int,c1 int);insert into t1(id) values(1);")
sql = `update t1 set c1=1 where id =1;`
s.testErrorCode(c, sql)
s.testAffectedRows(c, 1)
sql = `drop table if exists tt1,t1;
create table tt1(id int primary key,table_schema varchar(20),table_name varchar(64),version int);
create table t1 like tt1;
UPDATE tt1
INNER JOIN
(SELECT table_schema,
max(VERSION) AS VERSION,
table_name
FROM t1
GROUP BY table_schema)t2 ON tt1.table_schema=t2.table_schema
SET tt1.VERSION=t2.VERSION
WHERE tt1.id=1;`
if strings.Contains(s.sqlMode, "ONLY_FULL_GROUP_BY") {
s.testErrorCode(c, sql,
session.NewErr(session.ErrFieldNotInGroupBy, 3, "SELECT list", "table_name"))
} else {
s.testErrorCode(c, sql)
}
sql = `drop table if exists tt1,t1;
create table tt1(id int primary key,table_schema varchar(20),table_name varchar(64),version int);
create table t1 like tt1;
UPDATE tt1
INNER JOIN
(SELECT table_schema,
max(VERSION) AS VERSION
FROM t1
GROUP BY table_schema)t2 ON tt1.table_schema=t2.table_schema
SET tt1.VERSION=t2.VERSION
WHERE tt1.id=1;`
s.testErrorCode(c, sql)
sql = `drop table if exists tt1,t1;
create table tt1(id int primary key,table_schema varchar(20),table_name varchar(64),version int);
create table t1 like tt1;
UPDATE tt1
INNER JOIN
(SELECT table_schema,
max(VERSION) AS VERSION
FROM t1)t2 ON tt1.table_schema=t2.table_schema
SET tt1.VERSION=t2.VERSION
WHERE tt1.id=1;`
if strings.Contains(s.sqlMode, "ONLY_FULL_GROUP_BY") {
s.testErrorCode(c, sql,
session.NewErr(session.ErrMixOfGroupFuncAndFields, 1, "table_schema"))
} else {
s.testErrorCode(c, sql)
}
sql = `drop table if exists t1;create table t1(id int primary key,c1 int,c2 int);
update t1 set c1=1 and c2 = 1 where id=1;`
s.testErrorCode(c, sql,
session.NewErr(session.ErrWrongAndExpr))
sql = `drop table if exists t1;create table t1(id int primary key,c1 int,c2 int);
update t1 set c1=1,c2 = 1 where id=1;`
s.testErrorCode(c, sql)
// 列隐式转换审核
s.mustRunExec(c, `drop table if exists t1;`)
config.GetGlobalConfig().Inc.CheckImplicitTypeConversion = true
sql = `create table t1(id int primary key,c1 char(100));
update t1 s1 inner join t1 s2 on s1.id=s2.id set s1.c1=s2.c1 where s1.c1=1;`
s.testErrorCode(c, sql,
session.NewErr(session.ErrImplicitTypeConversion, "s1", "c1", "char"))
sql = `create table t1(id int primary key,c1 varchar(100));
update t1 s1 inner join t1 s2 on s1.id=s2.id set s1.c1=s2.c1 where s1.c1=1;`
s.testErrorCode(c, sql,
session.NewErr(session.ErrImplicitTypeConversion, "s1", "c1", "varchar"))
sql = `create table t1(id int primary key,c1 json);
update t1 s1 inner join t1 s2 on s1.id=s2.id set s1.c1=s2.c1 where s1.c1=1;`
s.testErrorCode(c, sql,
session.NewErr(session.ErrImplicitTypeConversion, "s1", "c1", "json"))
sql = `create table t1(id int primary key,c1 int);
update t1 s1 inner join t1 s2 on s1.id=s2.id set s1.c1=s2.c1 where s1.c1="1";`
s.testErrorCode(c, sql,
session.NewErr(session.ErrImplicitTypeConversion, "s1", "c1", "int"))
sql = `create table t1(id int primary key,c1 int);
update t1 s1 inner join t1 s2 on s1.id=s2.id set s1.c1=s2.c1 where s1.c1="1";`
s.testErrorCode(c, sql,
session.NewErr(session.ErrImplicitTypeConversion, "s1", "c1", "int"))
sql = `drop table if exists table1;drop table if exists table2;
create table table1(id1 int primary key,c1 int);
create table table2(id2 int primary key,c1 int,c2 int,c22 int);
update table1 t1,table2 t2 set c1=t2.c2 where t1.id1=t2.id2;`
s.testErrorCode(c, sql,
session.NewErr(session.ER_NON_UNIQ_ERROR, "c1"))
sql = `drop table if exists table1;drop table if exists table2;
create table table1(id1 int primary key,c1 int);
create table table2(id2 int primary key,c1 int,c2 int,c22 int);
update table1 t1,table2 t2 set t1.c1=t2.c2 where t1.id1=t2.id2 and c1=2;`
s.testErrorCode(c, sql,
session.NewErr(session.ER_NON_UNIQ_ERROR, "c1"))
sql = `drop table if exists table1;drop table if exists table2;
create table table1(id1 int primary key,c1 int,c2 int);
create table table2(id2 int primary key,c1 int,c2 int,c22 int);
update table1 t1,table2 t2 set t1.c1=c2 where t1.id1=t2.id2 and c1=2;`
s.testErrorCode(c, sql,
session.NewErr(session.ER_NON_UNIQ_ERROR, "c2"),
session.NewErr(session.ER_NON_UNIQ_ERROR, "c1"))
// -------------------- 多表update -------------------
sql = `drop table if exists table1;drop table if exists table2;
create table table1(id1 int primary key,c1 int,c2 int);
create table table2(id2 int primary key,c1 int,c2 int,c22 int);
update table1 t1,table2 t2 set t1.c1=c2,t2.c22=2 where t1.id1=t2.id2 and c1=2;`
s.testErrorCode(c, sql,
session.NewErr(session.ER_NON_UNIQ_ERROR, "c2"),
session.NewErr(session.ER_NON_UNIQ_ERROR, "c1"))
sql = `drop table if exists table1;drop table if exists table2;
create table table1(id1 int primary key,c1 int,c2 int);
create table table2(id2 int primary key,c1 int,c2 int,c22 int);
update table1 t1,table2 t2 set t1.c1=c2,t2.c222=2 where t1.id1=t2.id2 and c1=2;`
s.testErrorCode(c, sql,
session.NewErr(session.ER_NON_UNIQ_ERROR, "c2"),
session.NewErr(session.ER_COLUMN_NOT_EXISTED, "t2.c222"),
session.NewErr(session.ER_NON_UNIQ_ERROR, "c1"))
sql = `drop table if exists table1;drop table if exists table2;
create table table1(id1 int primary key,c1 int,c2 int);
create table table2(id2 int primary key,c1 int,c2 int,c22 int);
update table1 t1,table2 t2 set t1.c1=c2,c222=2 where t1.id1=t2.id2 and c1=2;`
s.testErrorCode(c, sql,
session.NewErr(session.ER_NON_UNIQ_ERROR, "c2"),
session.NewErr(session.ER_COLUMN_NOT_EXISTED, "c222"),
session.NewErr(session.ER_NON_UNIQ_ERROR, "c1"))
sql = `drop table if exists table1;drop table if exists table2;
create table table1(id1 int primary key,c1 int,c2 int);
create table table2(id2 int primary key,c1 int,c2 int,c22 int);
update table1 t1,table2 t2 set c1=2 where t1.id1=t2.id2 and t2.c1=2;`
s.testErrorCode(c, sql,
session.NewErr(session.ER_NON_UNIQ_ERROR, "c1"))
sql = `drop table if exists table1,table2;
create table table1(id1 int primary key,c1 int,c2 int);
update table1 t1 join (select 1 as id2) t2 set c1=2 where t1.id1=t2.id2;`
s.testErrorCode(c, sql)
sql = `drop table if exists table1,table2;
create table table1(id1 int primary key,c1 int,c2 int);
update table1 t1 join (select 1 as id2 union all select 2) t2 set c1=2 where t1.id1=t2.id2;`
s.testErrorCode(c, sql)
}
func (s *testSessionIncSuite) TestDelete(c *C) {
config.GetGlobalConfig().Inc.CheckInsertField = false
config.GetGlobalConfig().IncLevel.ER_WITH_INSERT_FIELD = 0
// 表不存在
sql = "delete from t1 where c1 = 1;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_TABLE_NOT_EXISTED_ERROR, "test_inc.t1"))
// where
config.GetGlobalConfig().Inc.CheckDMLWhere = true
sql = "create table t1(id int,c1 int);delete from t1;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_NO_WHERE_CONDITION))
config.GetGlobalConfig().Inc.CheckDMLWhere = false
// limit
config.GetGlobalConfig().Inc.CheckDMLLimit = true
sql = "create table t1(id int,c1 int);delete from t1 where id = 1 limit 1;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_WITH_LIMIT_CONDITION))
config.GetGlobalConfig().Inc.CheckDMLLimit = false
// order by rand()
config.GetGlobalConfig().Inc.CheckDMLOrderBy = true
sql = "create table t1(id int,c1 int);delete from t1 where id = 1 order by rand();"
s.testErrorCode(c, sql,
session.NewErr(session.ER_WITH_ORDERBY_CONDITION))
config.GetGlobalConfig().Inc.CheckDMLOrderBy = false
// 表不存在
sql = `create table t1(id int primary key,c1 int);
create table t2(id int primary key,c1 int,c2 int);
delete from t3 where id1 =1;`
s.testErrorCode(c, sql,
session.NewErr(session.ER_TABLE_NOT_EXISTED_ERROR, "test_inc.t3"))
sql = `create table t1(id int primary key,c1 int);
create table t2(id int primary key,c1 int,c2 int);
delete from t1 where id1 =1;`
s.testErrorCode(c, sql,
session.NewErr(session.ER_COLUMN_NOT_EXISTED, "id1"))
sql = `create table t1(id int primary key,c1 int);
create table t2(id int primary key,c1 int,c2 int);
delete t2 from t1 inner join t2 on t1.id=t2.id2 where c11=1;`
s.testErrorCode(c, sql,
session.NewErr(session.ER_COLUMN_NOT_EXISTED, "t2.id2"))
// 受影响行数
s.mustCheck(c, "create table t1(id int,c1 int);delete from t1 where id = 1;")
s.testAffectedRows(c, 0)
s.mustRunExec(c, "drop table if exists t1;create table t1(id int,c1 int);insert into t1(id) values(1);")
sql = `delete from t1 where id =1;`
s.testErrorCode(c, sql)
s.testAffectedRows(c, 1)
sql = `drop table if exists t1;create table t1(id int primary key,c1 int);
delete tmp from t1 as tmp where tmp.id=1;`
s.testErrorCode(c, sql)
sql = `drop table if exists t1;create table t1(id int primary key,c1 int);
delete t1 from t1 as tmp where tmp.id=1;`
s.testErrorCode(c, sql,
session.NewErr(session.ER_TABLE_NOT_EXISTED_ERROR, "test_inc.t1"))
sql = `drop table if exists t1;create table t1(id int primary key,c1 int);
delete s1 from t1 as s1 inner join t1 as s2 on s1.c1 = s2.c1 where s1.id > s2.id;`
s.testErrorCode(c, sql)
s.mustRunExec(c, "drop table if exists t1;create table t1(id int primary key,c1 int);")
sql = `create table t2(id int primary key,c1 int);
delete t1 from t1 inner join t2 where t2.c1 = 1;`
s.testErrorCode(c, sql)
// 列隐式转换审核
config.GetGlobalConfig().Inc.CheckImplicitTypeConversion = true
sql = `drop table if exists t1;
create table t1(id int primary key,c1 char(100));
delete from t1 where c1 =1;`
s.testErrorCode(c, sql,
session.NewErr(session.ErrImplicitTypeConversion, "t1", "c1", "char"))
s.mustRunExec(c, `drop table if exists t1;CREATE TABLE t1 (
id bigint(20) AUTO_INCREMENT primary key,
goods_id bigint(20) unsigned NOT NULL DEFAULT '0' ,
sku_id bigint(20) unsigned NOT NULL DEFAULT '0' ,
bar_code varchar(30) NOT NULL DEFAULT ''
);`)
sql = "delete from t1 where id in (select id from (select any_value(id) as id,count(*) as num from t1 group by `goods_id`, `sku_id`, `bar_code` having num > 1) as t)"
s.testErrorCode(c, sql)
}
func (s *testSessionIncSuite) TestCreateDataBase(c *C) {
config.GetGlobalConfig().Inc.EnableDropDatabase = false
// 不存在
sql = "drop database if exists test1111111111111111111;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_CANT_DROP_DATABASE, "test1111111111111111111"))
sql = "drop database test1111111111111111111;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_CANT_DROP_DATABASE, "test1111111111111111111"))
config.GetGlobalConfig().Inc.EnableDropDatabase = true
sql = "drop database if exists test1111111111111111111;create database test1111111111111111111;"
s.testErrorCode(c, sql)
// 存在
sql = "create database test1111111111111111111;create database test1111111111111111111;"
s.testErrorCode(c, sql,
session.NewErrf("数据库'test1111111111111111111'已存在."))
// if not exists 创建
sql = "create database if not exists test1111111111111111111;create database if not exists test1111111111111111111;"
s.testErrorCode(c, sql)
// create database
sql := "create database aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
s.testErrorCode(c, sql,
session.NewErr(session.ER_TOO_LONG_IDENT, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"))
sql = "create database mysql"
s.testErrorCode(c, sql,
session.NewErrf("数据库'%s'已存在.", "mysql"))
// 字符集
config.GetGlobalConfig().Inc.EnableSetCharset = false
config.GetGlobalConfig().Inc.SupportCharset = ""
sql = "drop database test1;create database test1 character set utf8;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_CANT_SET_CHARSET, "utf8"))
config.GetGlobalConfig().Inc.SupportCharset = "utf8mb4"
sql = "drop database test1;create database test1 character set utf8;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_CANT_SET_CHARSET, "utf8"))
config.GetGlobalConfig().Inc.EnableSetCharset = true
config.GetGlobalConfig().Inc.SupportCharset = "utf8,utf8mb4"
sql = "drop database test1;create database test1 character set utf8;"
s.testErrorCode(c, sql)
config.GetGlobalConfig().Inc.EnableSetCharset = true
config.GetGlobalConfig().Inc.SupportCharset = "utf8,utf8mb4"
sql = "drop database test1;create database test1 character set latin1;"
s.testErrorCode(c, sql,
session.NewErr(session.ErrCharsetNotSupport, "utf8,utf8mb4"))
sql = `drop database test1;create database test1;
use test1;
create table t1(id int primary key);
insert into t1 values(1);
insert into t1 select count(1)+1 from t1;
alter table t1 add column c1 int;
update t1 set c1=1 where id=1;
delete from t1 where id =1;`
s.testErrorCode(c, sql)
}
func (s *testSessionIncSuite) TestTimestampColumn(c *C) {
sql := ""
sql = `drop table if exists timeTable;create table timeTable(c1 timestamp default '');`
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DEFAULT, "c1"))
sql = `drop table if exists timeTable;create table timeTable(c1 timestamp default '0');`
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DEFAULT, "c1"))
sql = `drop table if exists timeTable;create table timeTable(c1 timestamp default '2100-1-1 1:1:1');`
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DEFAULT, "c1"))
sql = `drop table if exists timeTable;create table timeTable(c1 timestamp default '1900-1-1 1:1:1');`
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DEFAULT, "c1"))
sql = `drop table if exists timeTable;create table timeTable(c1 datetime default '');`
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DEFAULT, "c1"))
sql = `drop table if exists timeTable;create table timeTable(c1 datetime default '0');`
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DEFAULT, "c1"))
sql = `drop table if exists timeTable;create table timeTable(c1 datetime default '2100-1-1 1:1:1');`
s.testErrorCode(c, sql)
sql = `drop table if exists timeTable;create table timeTable(c1 datetime default '1900-1-1 1:1:1');`
s.testErrorCode(c, sql)
sql = `drop table if exists timeTable;create table timeTable(c1 date default '');`
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DEFAULT, "c1"))
sql = `drop table if exists timeTable;create table timeTable(c1 date default '0');`
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DEFAULT, "c1"))
sql = `drop table if exists timeTable;create table timeTable(c1 date default '2100-1-1 1:1:1');`
s.testErrorCode(c, sql)
sql = `drop table if exists timeTable;create table timeTable(c1 date default '1900-1-1 1:1:1');`
s.testErrorCode(c, sql)
sql = `drop table if exists timeTable;create table timeTable(c1 timestamp(6) default '1900-1-1 1:1:1');`
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DEFAULT, "c1"))
sql = `drop table if exists timeTable;create table timeTable(c1 timestamp(7) default '2000-1-1 1:1:1');`
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DEFAULT, "c1"))
sql = `drop table if exists timeTable;create table timeTable(c1 timestamp(0) default '2000-1-1 1:1:1');`
s.testErrorCode(c, sql)
sql = `drop table if exists timeTable;create table timeTable(c1 timestamp(3) default '2000-1-1 1:1:1');`
s.testErrorCode(c, sql)
sql = `drop table if exists timeTable;create table timeTable(c1 timestamp(6) default '2000-1-1 1:1:1');`
s.testErrorCode(c, sql)
// 零值审核
if strings.Contains(s.sqlMode, "TRADITIONAL") ||
(strings.Contains(s.sqlMode, "STRICT_") && strings.Contains(s.sqlMode, "NO_ZERO_DATE")) {
sql = `drop table if exists timeTable;create table timeTable(c1 timestamp default '0000-0-0');`
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DEFAULT, "c1"))
sql = `drop table if exists timeTable;create table timeTable(c1 timestamp default '0000-0-0 00:00:00');`
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DEFAULT, "c1"))
sql = `drop table if exists timeTable;create table timeTable(c1 datetime default '0000-0-0');`
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DEFAULT, "c1"))
sql = `drop table if exists timeTable;create table timeTable(c1 datetime default '0000-0-0 00:00:00');`
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DEFAULT, "c1"))
sql = `drop table if exists timeTable;create table timeTable(c1 date default '0000-0-0');`
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DEFAULT, "c1"))
sql = `drop table if exists timeTable;create table timeTable(c1 date default '0000-0-0 00:00:00');`
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DEFAULT, "c1"))
} else {
sql = `drop table if exists timeTable;create table timeTable(c1 timestamp default '0000-0-0');`
s.testErrorCode(c, sql)
sql = `drop table if exists timeTable;create table timeTable(c1 timestamp default '0000-0-0 00:00:00');`
s.testErrorCode(c, sql)
sql = `drop table if exists timeTable;create table timeTable(c1 datetime default '0000-0-0');`
s.testErrorCode(c, sql)
sql = `drop table if exists timeTable;create table timeTable(c1 datetime default '0000-0-0 00:00:00');`
s.testErrorCode(c, sql)
sql = `drop table if exists timeTable;create table timeTable(c1 date default '0000-0-0');`
s.testErrorCode(c, sql)
sql = `drop table if exists timeTable;create table timeTable(c1 date default '0000-0-0 00:00:00');`
s.testErrorCode(c, sql)
}
// 月,日零值审核
if strings.Contains(s.sqlMode, "TRADITIONAL") ||
(strings.Contains(s.sqlMode, "STRICT_") && strings.Contains(s.sqlMode, "NO_ZERO_IN_DATE")) {
sql = `drop table if exists timeTable;create table timeTable(c1 timestamp default '2000-1-0 1:1:1');`
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DEFAULT, "c1"))
sql = `drop table if exists timeTable;create table timeTable(c1 datetime default '2000-1-0 1:1:1');`
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DEFAULT, "c1"))
sql = `drop table if exists timeTable;create table timeTable(c1 date default '2000-1-0 1:1:1');`
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DEFAULT, "c1"))
} else {
sql = `drop table if exists timeTable;create table timeTable(c1 timestamp default '2000-1-0 1:1:1');`
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DEFAULT, "c1"))
sql = `drop table if exists timeTable;create table timeTable(c1 datetime default '2000-1-0 1:1:1');`
s.testErrorCode(c, sql)
sql = `drop table if exists timeTable;create table timeTable(c1 date default '2000-1-0 1:1:1');`
s.testErrorCode(c, sql)
}
}
func (s *testSessionIncSuite) TestRenameTable(c *C) {
// 不存在
sql = "drop table if exists t1;create table t1(id int primary key);alter table t1 rename t2;"
s.testErrorCode(c, sql)
sql = "drop table if exists t1;create table t1(id int primary key);rename table t1 to t2;"
s.testErrorCode(c, sql)
// 存在
sql = "drop table if exists t1;create table t1(id int primary key);rename table t1 to t1;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_TABLE_EXISTS_ERROR, "t1"))
}
func (s *testSessionIncSuite) TestCreateView(c *C) {
s.mustRunExec(c, "drop table if exists t1;drop view if exists v_1;")
sql = "create table t1(id int primary key);create view v_1 as select * from t1;"
s.testErrorCode(c, sql,
session.NewErr(session.ErrViewSupport, "v_1"))
config.GetGlobalConfig().Inc.EnableUseView = true
sql = "create table t1(id int primary key);create view v_1 as select * from t1;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_SELECT_ONLY_STAR))
sql = "create table t1(id int primary key);create view v_1 as select id from t1;"
s.testErrorCode(c, sql)
sql = "create table t1(id int primary key,c1 int);create view v_1(id,id) as select id,c1 from t1;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_FIELD_SPECIFIED_TWICE, "id", "v_1"))
sql = "create table t1(id int primary key,c1 int);create view v_1(id,c1,c2) as select id,c1 from t1;"
s.testErrorCode(c, sql,
session.NewErr(session.ErrViewColumnCount))
sql = "create table t1(id int primary key,c1 int);create view v_1(id,c1,c2) as select * from t1;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_SELECT_ONLY_STAR),
session.NewErr(session.ErrViewColumnCount))
sql = "create table t1(id int primary key,c1 int);create view v_1 as select id,c1 from t1;"
s.testErrorCode(c, sql)
}
func (s *testSessionIncSuite) TestAlterTableAddIndex(c *C) {
config.GetGlobalConfig().Inc.CheckColumnComment = false
config.GetGlobalConfig().Inc.CheckTableComment = false
// add index
sql = "create table t1(id int);alter table t1 add index idx (c1)"
s.testErrorCode(c, sql,
session.NewErr(session.ER_COLUMN_NOT_EXISTED, "t1.c1"))
sql = "create table t1(id int,c1 int);alter table t1 add index idx (c1);"
s.testErrorCode(c, sql)
sql = "create table t1(id int,c1 int);alter table t1 add index idx (c1);alter table t1 add index idx (c1);"
s.testErrorCode(c, sql,
session.NewErr(session.ER_DUP_INDEX, "idx", "test_inc", "t1"))
if s.DBVersion >= 50701 {
sql = "create table t1(id int,c1 int);alter table t1 add index idx (c1);alter table t1 rename index idx to idx2;"
s.testErrorCode(c, sql)
sql = `create table t1(id int,c1 int);
alter table t1 add index idx (c1),add index idx2 (c1);
alter table t1 rename index idx to idx2;`
s.testErrorCode(c, sql,
session.NewErr(session.ER_DUP_KEYNAME, "idx2"))
sql = `create table t1(id int,c1 int);
alter table t1 add index idx (c1),add index idx2 (c1);
alter table t1 rename index idx3 to idx2;`
s.testErrorCode(c, sql,
session.NewErr(session.ER_CANT_DROP_FIELD_OR_KEY, "t1.idx3"))
}
sql = "create table t1(id int,c1 int,key idx (c1));alter table t1 add index idx (c1);"
s.testErrorCode(c, sql,
session.NewErr(session.ER_DUP_INDEX, "idx", "test_inc", "t1"))
sql = "create table t1(id int primary key);alter table t1 drop primary key;"
s.testErrorCode(c, sql)
sql = "CREATE TABLE geom (g GEOMETRY NOT NULL, SPATIAL INDEX ix_1(g));"
s.testErrorCode(c, sql)
sql = "CREATE TABLE geom (g GEOMETRY NULL, SPATIAL INDEX ix_1(g));"
s.testErrorCode(c, sql,
&session.SQLError{Code: 0,
Message: "All parts of a SPATIAL index must be NOT NULL."})
sql = "CREATE TABLE geom (id int,g GEOMETRY NOT NULL, SPATIAL INDEX ix_1(id,g));"
s.testErrorCode(c, sql,
session.NewErr(session.ER_TOO_MANY_KEY_PARTS, "ix_1", "geom", 1))
sql = "CREATE TABLE geom (id int,g GEOMETRY NOT NULL);alter table geom add SPATIAL INDEX ix_1(id,g);"
s.testErrorCode(c, sql,
session.NewErr(session.ER_TOO_MANY_KEY_PARTS, "ix_1", "geom", 1))
sql = `create table t1(id int,c1 int);
alter table t1 add index idx (c1) visible;`
s.testErrorCode(c, sql,
session.NewErr(session.ErrUseIndexVisibility))
sql = `create table t1(id int,c1 int);
alter table t1 add index idx2 (c1) invisible;`
s.testErrorCode(c, sql,
session.NewErr(session.ErrUseIndexVisibility))
}
func (s *testSessionIncSuite) TestAlterTableDropIndex(c *C) {
config.GetGlobalConfig().Inc.CheckColumnComment = false
config.GetGlobalConfig().Inc.CheckTableComment = false
// drop index
sql = "create table t1(id int);alter table t1 drop index idx"
s.testErrorCode(c, sql,
session.NewErr(session.ER_CANT_DROP_FIELD_OR_KEY, "t1.idx"))
sql = "create table t1(c1 int);alter table t1 add index idx (c1);alter table t1 drop index idx;"
s.testErrorCode(c, sql)
}
func (s *testSessionIncSuite) TestAlterTable(c *C) {
config.GetGlobalConfig().Inc.CheckColumnComment = false
config.GetGlobalConfig().Inc.CheckTableComment = false
config.GetGlobalConfig().Inc.EnableDropTable = true
// 删除后添加列
sql = "drop table if exists t1;create table t1(id int,c1 int);alter table t1 drop column c1;alter table t1 add column c1 varchar(20);"
s.testErrorCode(c, sql)
sql = "drop table if exists t1;create table t1(id int,c1 int);alter table t1 drop column c1,add column c1 varchar(20);"
s.testErrorCode(c, sql)
// 删除后添加索引
sql = "drop table if exists t1;create table t1(id int,c1 int,key ix(c1));alter table t1 drop index ix;alter table t1 add index ix(c1);"
s.testErrorCode(c, sql)
sql = "drop table if exists t1;create table t1(id int,c1 int,key ix(c1));alter table t1 drop index ix,add index ix(c1);"
s.testErrorCode(c, sql)
s.mustRunExec(c, "drop table if exists t1;create table t1(id int auto_increment primary key,c1 int);")
sql = "alter table t1 auto_increment 20 comment '123';"
s.testErrorCode(c, sql)
if s.DBVersion < 80000 {
config.GetGlobalConfig().Inc.MaxDDLAffectRows = 1
s.mustRunExec(c, "insert into t1(id,c1)values(1,1),(2,2);")
sql = "alter table t1 add column c2 int;"
s.testErrorCode(c, sql,
session.NewErr(session.ER_CHANGE_TOO_MUCH_ROWS, "Alter", 2, 1))
}
sql = `drop table if exists t1;
create table t1(id int primary key);
alter table t1 add column c1 geometry;
alter table t1 add column c2 point;
alter table t1 add column c3 linestring;
alter table t1 add column c4 polygon;
alter table t1 drop column c1;
alter table t1 drop column c2;
alter table t1 drop column c3;
alter table t1 drop column c4; `
s.testErrorCode(c, sql)
// 列字符集&排序规则
config.GetGlobalConfig().Inc.EnableColumnCharset = false
sql = `drop table if exists t1;
create table t1(id int primary key);
alter table t1 add column c4 varchar(22) charset utf8;`
s.testErrorCode(c, sql,
session.NewErr(session.ER_CHARSET_ON_COLUMN, "t1", "c4"))
sql = `drop table if exists t1;
create table t1(id int primary key);
alter table t1 add column c4 varchar(22) collate utf8_bin;`
s.testErrorCode(c, sql,
session.NewErr(session.ER_CHARSET_ON_COLUMN, "t1", "c4"))
sql = `drop table if exists t1;
create table t1(id int primary key);
alter table t1 add column c4 varchar(22) charset utf8 collate utf8_bin;`
s.testErrorCode(c, sql,
session.NewErr(session.ER_CHARSET_ON_COLUMN, "t1", "c4"),
session.NewErr(session.ER_CHARSET_ON_COLUMN, "t1", "c4"))
config.GetGlobalConfig().Inc.EnableColumnCharset = true
config.GetGlobalConfig().Inc.SupportCharset = "utf8mb4"
sql = `drop table if exists t1;
create table t1(id int primary key);
alter table t1 add column c4 varchar(22) charset utf8 collate utf8_bin;`
s.testErrorCode(c, sql,
session.NewErr(session.ErrCharsetNotSupport, "utf8mb4"))
config.GetGlobalConfig().Inc.SupportCharset = "utf8"
config.GetGlobalConfig().Inc.SupportCollation = "utf8_bin"
sql = `drop table if exists t1;
create table t1(id int primary key);
alter table t1 add column c4 varchar(22) charset utf8 collate utf8mb4_bin;`
s.testErrorCode(c, sql,
session.NewErr(session.ErrCollationNotSupport, "utf8_bin"))
}
func (s *testSessionIncSuite) TestCreateTablePrimaryKey(c *C) {
sql := ""
config.GetGlobalConfig().Inc.CheckColumnComment = false
config.GetGlobalConfig().Inc.CheckTableComment = false
// EnablePKColumnsOnlyInt
config.GetGlobalConfig().Inc.EnablePKColumnsOnlyInt = true
sql = "create table t1(id tinyint, primary key(id));"
s.testErrorCode(c, sql,
session.NewErr(session.ER_PK_COLS_NOT_INT, "id", "test_inc", "t1"))
sql = "create table t1(id mediumint, primary key(id));"
s.testErrorCode(c, sql)
sql = "create table t1(id int, primary key(id));"
s.testErrorCode(c, sql)
sql = "create table t1(id bigint, primary key(id));"
s.testErrorCode(c, sql)
sql = "create table t1(id varchar(10), primary key(id));"
s.testErrorCode(c, sql,
session.NewErr(session.ER_PK_COLS_NOT_INT, "id", "test_inc", "t1"))
sql = "create table t1(id tinyint primary key);"
s.testErrorCode(c, sql,
session.NewErr(session.ER_PK_COLS_NOT_INT, "id", "test_inc", "t1"))
sql = "create table t1(id mediumint primary key);"
s.testErrorCode(c, sql)
sql = "create table t1(id int primary key);"
s.testErrorCode(c, sql)
sql = "create table t1(id bigint primary key);"
s.testErrorCode(c, sql)
sql = "create table t1(id varchar(10) primary key);"
s.testErrorCode(c, sql,
session.NewErr(session.ER_PK_COLS_NOT_INT, "id", "test_inc", "t1"))
}
func (s *testSessionIncSuite) TestTableCharsetCollation(c *C) {
sql := ""
config.GetGlobalConfig().Inc.CheckColumnComment = false
config.GetGlobalConfig().Inc.CheckTableComment = false
// 表存在
sql = ("create table t1(id int);create table t1(id int);")
s.testErrorCode(c, sql,
session.NewErr(session.ER_TABLE_EXISTS_ERROR, "t1"))
// 字符集
sql = `create table t1(id int,c1 varchar(20) character set utf8,
c2 varchar(20) COLLATE utf8_bin);`
s.testErrorCode(c, sql,
session.NewErr(session.ER_CHARSET_ON_COLUMN, "t1", "c1"),
session.NewErr(session.ER_CHARSET_ON_COLUMN, "t1", "c2"))
config.GetGlobalConfig().Inc.EnableSetCharset = false
sql = `create table t1(id int,c1 varchar(20)) character set utf8;`
s.testErrorCode(c, sql,
session.NewErr(session.ER_TABLE_CHARSET_MUST_NULL, "t1"))
config.GetGlobalConfig().Inc.EnableSetCollation = false
sql = `create table t1(id int,c1 varchar(20)) COLLATE utf8_bin;`
s.testErrorCode(c, sql,
session.NewErr(session.ErrTableCollationNotSupport, "t1"))
sql = `create table t1(id int,c1 varchar(20)) character set utf8 COLLATE utf8_bin;`
s.testErrorCode(c, sql,
session.NewErr(session.ER_TABLE_CHARSET_MUST_NULL, "t1"),
session.NewErr(session.ErrTableCollationNotSupport, "t1"))
config.GetGlobalConfig().Inc.EnableSetCharset = true
config.GetGlobalConfig().Inc.EnableSetCollation = true
config.GetGlobalConfig().Inc.SupportCharset = ""
config.GetGlobalConfig().Inc.SupportCollation = ""
sql = `create table t1(id int,c1 varchar(20)) character set utf8 COLLATE utf8_bin;`
s.testErrorCode(c, sql)
config.GetGlobalConfig().Inc.SupportCharset = "utf8"
sql = `create table t1(id int,c1 varchar(20)) character set utf8mb4 COLLATE utf8_bin;`
s.testErrorCode(c, sql,
session.NewErr(session.ErrCharsetNotSupport, "utf8"),
session.NewErrf("字符集和排序规则不匹配!"))
config.GetGlobalConfig().Inc.SupportCollation = "utf8_bin"
sql = `create table t1(id int,c1 varchar(20)) character set utf8mb4 COLLATE utf8mb4_bin;`
s.testErrorCode(c, sql,
session.NewErr(session.ErrCharsetNotSupport, "utf8"),
session.NewErr(session.ErrCollationNotSupport, "utf8_bin"))
}
func (s *testSessionIncSuite) TestForeignKey(c *C) {
sql := ""
config.GetGlobalConfig().Inc.EnableForeignKey = false
s.mustRunExec(c, "drop table if exists t2; create table t2(id int primary key,c1 int,index ix_1(c1));drop table if exists t1; ")
sql = `create table t1(id int primary key,pid int,constraint FK_1 foreign key (pid) references t2(id));`
s.testErrorCode(c, sql,
session.NewErr(session.ER_FOREIGN_KEY, "t1"))
config.GetGlobalConfig().Inc.EnableForeignKey = true
sql = `create table t1(id int primary key,pid int,constraint FK_1 foreign key (pid) references t2(id));`
s.testErrorCode(c, sql)
sql = `create table t1(id int primary key,pid int,constraint FK_1 foreign key (pid) references t2(id1));`
s.testErrorCode(c, sql,
session.NewErr(session.ER_COLUMN_NOT_EXISTED, "t2.id1"))
sql = `create table t1(id int primary key,pid int,constraint FK_1 foreign key (pid1) references t2(id));`
s.testErrorCode(c, sql,
session.NewErr(session.ER_COLUMN_NOT_EXISTED, "t1.pid1"))
sql = `create table t1(id int primary key,c1 int,c2 int,
constraint foreign key (c1,c2) references t2(id));`
s.testErrorCode(c, sql,
session.NewErr(session.ErrWrongFkDefWithMatch, ""))
sql = `create table t1(id int primary key,c1 int,c2 int,
constraint fk_1 foreign key (c1) references t2(id));`
s.testErrorCode(c, sql)
s.mustRunExec(c, sql)
sql = `alter table t1 drop foreign key fk_1;`
s.testErrorCode(c, sql)
}
func (s *testSessionIncSuite) TestZeroDate(c *C) {
sql := ""
config.GetGlobalConfig().Inc.EnableZeroDate = false
sql = `create table t4 (id int unsigned not null auto_increment primary key
comment 'primary key', a datetime not null default 0 comment 'a') comment 'test';`
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DEFAULT, "a"))
config.GetGlobalConfig().Inc.EnableZeroDate = true
}
func (s *testSessionIncSuite) TestTimestampType(c *C) {
sql := ""
config.GetGlobalConfig().Inc.EnableTimeStampType = false
// sql = `create table t4 (id int unsigned not null auto_increment primary key comment 'primary key', a timestamp not null default 0 comment 'a') comment 'test';`
sql = `create table t4 (id int unsigned not null auto_increment primary key comment 'primary key', a timestamp not null comment 'a') comment 'test';`
s.testErrorCode(c, sql,
session.NewErr(session.ER_INVALID_DATA_TYPE, "a"))
config.GetGlobalConfig().Inc.EnableTimeStampType = true
}
func (s *testSessionIncSuite) TestAlterNoOption(c *C) {
sql := `drop table if exists t1;create table t1(id int,c1 int,key ix(c1));alter table t1;`
s.testErrorCode(c, sql,
session.NewErr(session.ER_NOT_SUPPORTED_YET))
}
func (s *testSessionIncSuite) TestFloatDouble(c *C) {
config.GetGlobalConfig().Inc.CheckFloatDouble = true
sql := `drop table if exists t1;create table t1(id int,c1 float,key ix(c1));`
s.testErrorCode(c, sql,
session.NewErr(session.ErrFloatDoubleToDecimal, "c1"))
sql = `drop table if exists t1;create table t1(id int, c2 double,key ix(c2));`
s.testErrorCode(c, sql,
session.NewErr(session.ErrFloatDoubleToDecimal, "c2"))
config.GetGlobalConfig().Inc.CheckFloatDouble = false
}
func (s *testSessionIncSuite) TestIdentifierUpper(c *C) {
config.GetGlobalConfig().Inc.CheckIdentifierUpper = true
sql := `drop table if exists hello;create table HELLO(ID int,C1 float, C2 double,key IDX_C1(C1),UNIQUE INDEX uniq_A(C2));`
s.testErrorCode(c, sql,
session.NewErr(session.ErrIdentifierUpper, "uniq_A"),
)
config.GetGlobalConfig().Inc.CheckIdentifierUpper = false
}
func (s *testSessionIncSuite) TestMaxKeys(c *C) {
//er_too_many_keys
config.GetGlobalConfig().Inc.MaxKeys = 2
sql = "drop table if exists t1; create table t1(id int primary key,name varchar(10),age varchar(10));alter table t1 add index idx_test(id),add index idx_test2(name);"
s.testErrorCode(c, sql,
session.NewErr(session.ER_TOO_MANY_KEYS, "t1", 2))
config.GetGlobalConfig().Inc.MaxKeys = 3
sql = "drop table if exists t1; create table t1(id int primary key,name varchar(10),age varchar(10));alter table t1 add index idx_test(id),add index idx_test2(name);"
s.testErrorCode(c, sql)
//er_too_many_key_parts
config.GetGlobalConfig().Inc.MaxKeyParts = 2
sql = "drop table if exists t1; create table t1(id int primary key,name varchar(10),age varchar(10));alter table t1 add index idx_test(id,name,age);"
s.testErrorCode(c, sql,
session.NewErr(session.ER_TOO_MANY_KEY_PARTS, "idx_test", "t1", 2))
config.GetGlobalConfig().Inc.MaxKeyParts = 3
sql = "drop table if exists t1; create table t1(id int primary key,name varchar(10),age varchar(10));alter table t1 add index idx_test(id,name,age);"
s.testErrorCode(c, sql)
//er_pk_too_many_parts
config.GetGlobalConfig().Inc.MaxPrimaryKeyParts = 2
sql = "drop table if exists t1; create table t1(id int,name varchar(10),age varchar(10),primary key(id,name,age));"
s.testErrorCode(c, sql,
session.NewErr(session.ER_PK_TOO_MANY_PARTS, "test_inc", "t1", 2))
config.GetGlobalConfig().Inc.MaxPrimaryKeyParts = 3
sql = "drop table if exists t1; create table t1(id int,name varchar(10),age varchar(10),primary key(id,name));"
s.testErrorCode(c, sql)
}
func (s *testSessionIncSuite) TestSetStmt(c *C) {
sql = `set names abc;
set names '';
set names utf8;
set names utf8mb4;
set autocommit = 1;
`
s.runCheck(sql)
s.assertAudit(c, s.getResultRows(),
[]*SQLError{
session.NewErr(session.ErrCharsetNotSupport, "utf8,utf8mb4"),
},
[]*SQLError{
session.NewErr(session.ErrCharsetNotSupport, "utf8,utf8mb4"),
},
nil,
nil,
[]*SQLError{
session.NewErr(session.ER_NOT_SUPPORTED_YET),
})
// s.add(`set names abc`, session.NewErr(session.ErrCharsetNotSupport, "utf8,utf8mb4"))
// s.add(`set names ''`, session.NewErr(session.ErrCharsetNotSupport, "utf8,utf8mb4"))
// s.add(`set names utf8`)
// s.add(`set names utf8mb4`)
// s.add(`set autocommit = 1`, session.NewErr(session.ER_NOT_SUPPORTED_YET))
// s.runAudit(c)
}
func (s *testSessionIncSuite) TestMergeAlterTable(c *C) {
//er_alter_table_once
config.GetGlobalConfig().Inc.MergeAlterTable = true
sql = `drop table if exists t1;
create table t1(id int primary key,name varchar(10));
alter table t1 add age varchar(10);
alter table t1 add sex varchar(10);`
s.testErrorCode(c, sql,
session.NewErr(session.ER_ALTER_TABLE_ONCE, "t1"))
//er_alter_table_once
config.GetGlobalConfig().Inc.MergeAlterTable = true
sql = "drop table if exists t1; create table t1(id int primary key,name varchar(10));alter table t1 modify name varchar(10);alter table t1 modify name varchar(10);"
s.testErrorCode(c, sql,
session.NewErr(session.ER_ALTER_TABLE_ONCE, "t1"),
)
//er_alter_table_once
config.GetGlobalConfig().Inc.MergeAlterTable = true
sql = "drop table if exists t1; create table t1(id int primary key,name varchar(10));alter table t1 change name name varchar(10);alter table t1 change name name varchar(10);"
s.testErrorCode(c, sql,
session.NewErr(session.ER_ALTER_TABLE_ONCE, "t1"))
}
func (s *testSessionIncSuite) TestNewRewrite(c *C) {
var (
newSql string
rw *session.Rewrite
)
sqls := []struct {
sql string
selectSql string
countSql string
}{
{
"insert into t2 select * from t1 where id >0;",
"select * from t1 where id > 0",
"select count(*) from t1 where id > 0",
},
{
"insert into t2 select * from t1 where id >0 limit 10;",
"select * from t1 where id > 0 limit 10",
"SELECT COUNT(1) FROM (select * from t1 where id > 0 limit 10)t",
},
{
"insert into t2 select * from t1 where id >0 order by c1 desc limit 10;",
"select * from t1 where id > 0 order by c1 desc limit 10",
"SELECT COUNT(1) FROM (select * from t1 where id > 0 limit 10)t",
},
{
"insert into t2 select distinct id from t1 where id >0 order by c1 desc limit 10;",
"select distinct id from t1 where id > 0 order by c1 desc limit 10",
"SELECT COUNT(1) FROM (select distinct id from t1 where id > 0 order by c1 desc limit 10)t",
},
{
"insert into t2 select c1,count(1) as cnt from t1 where id >0 group by c1 limit 10;",
"select c1, count(1) as cnt from t1 where id > 0 group by c1 limit 10",
"SELECT COUNT(1) FROM (select c1, count(1) as cnt from t1 where id > 0 group by c1 limit 10)t",
},
{
"delete from t1 where id >0;",
"select * from t1 where id > 0",
"select count(*) from t1 where id > 0",
},
{
"delete from t1 where id >0 limit 10;",
"select * from t1 where id > 0 limit 10",
"SELECT COUNT(1) FROM (select * from t1 where id > 0 limit 10)t",
},
{
"delete from t1 where id >0 order by c1 desc limit 10;",
"select * from t1 where id > 0 order by c1 desc limit 10",
"SELECT COUNT(1) FROM (select * from t1 where id > 0 limit 10)t",
},
{
"update t1 set c1=1 where id >0;",
"select * from t1 where id > 0",
"select count(*) from t1 where id > 0",
},
{
"update t1 set c1=1 where id >0 limit 10;",
"select * from t1 where id > 0 limit 10",
"SELECT COUNT(1) FROM (select * from t1 where id > 0 limit 10)t",
},
{
"update t1 set c1=1 where id >0 order by c1 desc limit 10;",
"select * from t1 where id > 0 order by c1 desc limit 10",
"SELECT COUNT(1) FROM (select * from t1 where id > 0 limit 10)t",
},
{
"update t1 inner join t2 on t1.id=t2.id2 set t1.c1=t2.c1 where c11=1;",
"select * from t1 join t2 on t1.id = t2.id2 where c11 = 1",
"select count(*) from t1 join t2 on t1.id = t2.id2 where c11 = 1",
},
{
"update t1,t2 set t1.c1=t2.c1 where t1.id=t2.id2 and c11=1;",
"select * from t1, t2 where t1.id = t2.id2 and c11 = 1",
"select count(*) from t1, t2 where t1.id = t2.id2 and c11 = 1",
},
{
"update t1,t2 set t1.c1=t2.c1 where t1.id=t2.id2 and c11=1 limit 10;",
"select * from t1, t2 where t1.id = t2.id2 and c11 = 1 limit 10",
"SELECT COUNT(1) FROM (select * from t1, t2 where t1.id = t2.id2 and c11 = 1 limit 10)t",
},
}
for _, row := range sqls {
rw, _ = session.NewRewrite(row.sql)
rw.RewriteDML2Select()
c.Assert(rw.SQL, Equals, row.selectSql)
newSql = rw.TestSelect2Count()
c.Assert(newSql, Equals, row.countSql)
}
}
func (s *testSessionIncSuite) TestGetAlterTablePostPart(c *C) {
sqls := []struct {
sql string
outPT string
outGhost string
}{
{
"alter table tb_archery add unique index uniq_test_ghost_3 (test_ghost_3);",
"ADD UNIQUE \\`uniq_test_ghost_3\\`(\\`test_ghost_3\\`)",
"ADD UNIQUE `uniq_test_ghost_3`(`test_ghost_3`)",
},
{
"alter table tb_archery add COLUMN c1 varchar(100) default null comment '!@#$%^&*(){}:<>?,./' after id123;",
"ADD COLUMN \\`c1\\` VARCHAR(100) DEFAULT NULL COMMENT '!@#\\$%^&*(){}:<>?,./' AFTER \\`id123\\`",
"ADD COLUMN `c1` VARCHAR(100) DEFAULT NULL COMMENT '!@#$%^&*(){}:<>?,./' AFTER `id123`",
},
{
"alter table tb_archery add primary key(id);",
"ADD PRIMARY KEY(\\`id\\`)",
"ADD PRIMARY KEY(`id`)",
},
{
"alter table tb_archery add unique key uniq_1(c1);",
"ADD UNIQUE \\`uniq_1\\`(\\`c1\\`)",
"ADD UNIQUE `uniq_1`(`c1`)",
},
{
"alter table tb_archery alter column c1 drop default;",
"ALTER COLUMN \\`c1\\` DROP DEFAULT",
"ALTER COLUMN `c1` DROP DEFAULT",
},
{
"alter table tb_archery default character set utf8 collate utf8_bin;",
"CONVERT TO CHARACTER SET UTF8 COLLATE UTF8_BIN",
"CONVERT TO CHARACTER SET UTF8 COLLATE UTF8_BIN",
},
{
"alter table tb_archery collate = utf8_bin;",
"DEFAULT COLLATE = UTF8_BIN",
"DEFAULT COLLATE = UTF8_BIN",
},
{
"alter table t1 modify c1 varchar(100) character set utf8 collate utf8_bin;",
"MODIFY COLUMN \\`c1\\` VARCHAR(100) CHARACTER SET UTF8 COLLATE utf8_bin",
"MODIFY COLUMN `c1` VARCHAR(100) CHARACTER SET UTF8 COLLATE utf8_bin",
},
{
"alter table t1 modify column c1 varchar(100) collate utf8_bin;",
"MODIFY COLUMN \\`c1\\` VARCHAR(100) COLLATE utf8_bin",
"MODIFY COLUMN `c1` VARCHAR(100) COLLATE utf8_bin",
},
}
for _, row := range sqls {
out := s.session.GetAlterTablePostPart(row.sql, true)
c.Assert(out, Equals, row.outPT, Commentf("%v", row.sql))
out = s.session.GetAlterTablePostPart(row.sql, false)
c.Assert(out, Equals, row.outGhost, Commentf("%v", row.sql))
}
}
// TestDisplayWidth 测试列指定长度参数
func (s *testSessionIncSuite) TestDisplayWidth(c *C) {
sql := ""
config.GetGlobalConfig().Inc.CheckColumnComment = false
config.GetGlobalConfig().Inc.CheckTableComment = false
config.GetGlobalConfig().Inc.EnableEnumSetBit = true
s.mustRunExec(c, "drop table if exists t1;")
// 数据类型 警告
sql = `create table t1(c1 bit(100),
c2 tinyint(1000),
c3 smallint(1000),
c4 mediumint(1000),
c5 int(1000),
c6 bigint(1000) );`
s.testErrorCode(c, sql,
session.NewErrf("Too big display width for column '%s' (max = 64).", "c1"),
session.NewErrf("Too big display width for column '%s' (max = 255).", "c2"),
session.NewErrf("Too big display width for column '%s' (max = 255).", "c3"),
session.NewErrf("Too big display width for column '%s' (max = 255).", "c4"),
session.NewErrf("Too big display width for column '%s' (max = 255).", "c5"),
session.NewErrf("Too big display width for column '%s' (max = 255).", "c6"),
)
// 数据类型 警告
sql = `create table t1(id int);
alter table t1 add column c1 tinyint(1000);
`
s.testErrorCode(c, sql,
session.NewErrf("Too big display width for column '%s' (max = 255).", "c1"))
}
// TestSetVariables 设置会话级变量进行审核
func (s *testSessionIncSuite) TestSetSessionVariables(c *C) {
sql := ""
s.mustRunExec(c, "drop table if exists t1;")
config.GetGlobalConfig().Inc.CheckTableComment = true
sql = `create table t1(id int primary key);`
s.testErrorCode(c, sql,
session.NewErr(session.ER_TABLE_MUST_HAVE_COMMENT, "t1"))
sql = `inception set check_table_comment = 0;
create table t1(id int primary key);`
s.testErrorCode(c, sql)
sql = `inception set check_table_comment = "123";
create table t1(id int primary key);`
s.testManyErrors(c, sql,
session.NewErrf("[variable:1231]Variable 'check_table_comment' can't be set to the value of '123'."),
session.NewErr(session.ER_TABLE_MUST_HAVE_COMMENT, "t1"))
sql = `inception set level er_table_must_have_comment = 2;`
s.testManyErrors(c, sql,
session.NewErrf("暂不支持会话级的自定义审核级别."))
sql = `inception set global check_table_comment = 1;`
s.testManyErrors(c, sql,
session.NewErrf("全局变量仅支持单独设置."))
sql = `inception set lang = 'zh_cn';
create table t1(id int primary key);
inception set lang = 'en_us';
create table t2(id int primary key);`
s.testManyErrors(c, sql,
session.NewErrf("表 't1' 需要设置注释."),
session.NewErrf("Set comments for table 't2'."))
config.GetGlobalConfig().Inc.CheckTableComment = false
sql = `inception set osc_chunk_time = 1.1;;
create table t1(id int primary key);`
s.testErrorCode(c, sql)
}
// TestSetVariables 设置会话级变量进行审核
func (s *testSessionIncSuite) TestBlobAndText(c *C) {
sql := ""
s.mustRunExec(c, "drop table if exists t1,t2;")
config.GetGlobalConfig().Inc.EnableBlobType = false
sql = `create table t1(id int primary key,
c1 tinyblob ,
c2 blob,
c3 mediumblob,
c4 longblob);`
s.testErrorCode(c, sql,
session.NewErr(session.ER_USE_TEXT_OR_BLOB, "c1"),
session.NewErr(session.ER_USE_TEXT_OR_BLOB, "c2"),
session.NewErr(session.ER_USE_TEXT_OR_BLOB, "c3"),
session.NewErr(session.ER_USE_TEXT_OR_BLOB, "c4"))
sql = `create table t2(id int primary key,
c1 tinytext ,
c2 text,
c3 mediumtext,
c4 longtext);`
s.testErrorCode(c, sql,
session.NewErr(session.ER_USE_TEXT_OR_BLOB, "c1"),
session.NewErr(session.ER_USE_TEXT_OR_BLOB, "c2"),
session.NewErr(session.ER_USE_TEXT_OR_BLOB, "c3"),
session.NewErr(session.ER_USE_TEXT_OR_BLOB, "c4"))
}
func (s *testSessionIncSuite) TestWhereCondition(c *C) {
sql := ""
s.mustRunExec(c, "drop table if exists t1,t2;create table t1(id int);")
sql = "update t1 set id = 1 where 123;"
config.GetGlobalConfig().IncLevel.ErrUseValueExpr = 0
s.testErrorCode(c, sql)
config.GetGlobalConfig().IncLevel.ErrUseValueExpr = 1
s.testErrorCode(c, sql,
session.NewErr(session.ErrUseValueExpr))
sql = "update t1 set id = 1 where null;"
s.testErrorCode(c, sql,
session.NewErr(session.ErrUseValueExpr))
sql = `
update t1 set id = 1 where 1+2;
update t1 set id = 1 where 1-2;
update t1 set id = 1 where 1*2;
delete from t1 where 1/2;
delete from t1 where 1&2;
delete from t1 where 1|2;
delete from t1 where 1^2;
delete from t1 where 1 div 2;
`
s.testManyErrors(c, sql,
session.NewErr(session.ErrUseValueExpr),
session.NewErr(session.ErrUseValueExpr),
session.NewErr(session.ErrUseValueExpr),
session.NewErr(session.ErrUseValueExpr),
session.NewErr(session.ErrUseValueExpr),
session.NewErr(session.ErrUseValueExpr),
session.NewErr(session.ErrUseValueExpr),
session.NewErr(session.ErrUseValueExpr),
)
sql = `
update t1 set id = 1 where 1+2=3;
update t1 set id = 1 where id is null;
update t1 set id = 1 where id is not null;
update t1 set id = 1 where 1=1;
update t1 set id = 1 where id in (1,2);
update t1 set id = 1 where id is true;
`
s.testManyErrors(c, sql)
}
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )