ddl: set default value to zero value when add a not null column. (#1443)

This commit is contained in:
Ewan Chou
2016-07-14 10:57:34 +08:00
committed by GitHub
parent 0e585ab047
commit fda013b080
4 changed files with 32 additions and 7 deletions

View File

@ -21,6 +21,7 @@ import (
"github.com/pingcap/tidb/kv"
"github.com/pingcap/tidb/meta"
"github.com/pingcap/tidb/model"
"github.com/pingcap/tidb/mysql"
"github.com/pingcap/tidb/table"
"github.com/pingcap/tidb/tablecodec"
"github.com/pingcap/tidb/terror"
@ -165,7 +166,7 @@ func (d *ddl) onAddColumn(t *meta.Meta, job *model.Job) error {
if err != nil {
return errors.Trace(err)
}
if columnInfo.DefaultValue != nil {
if columnInfo.DefaultValue != nil || mysql.HasNotNullFlag(columnInfo.Flag) {
err = d.runReorgJob(func() error {
return d.backfillColumn(tbl, columnInfo, reorgInfo)
})
@ -321,9 +322,17 @@ func (d *ddl) backfillColumn(t table.Table, columnInfo *model.ColumnInfo, reorgI
}
func (d *ddl) backfillColumnData(t table.Table, columnInfo *model.ColumnInfo, handles []int64, reorgInfo *reorgInfo) error {
defaultVal, _, err := table.GetColDefaultValue(nil, columnInfo)
if err != nil {
return errors.Trace(err)
var (
defaultVal types.Datum
err error
)
if columnInfo.DefaultValue != nil {
defaultVal, _, err = table.GetColDefaultValue(nil, columnInfo)
if err != nil {
return errors.Trace(err)
}
} else if mysql.HasNotNullFlag(columnInfo.Flag) {
defaultVal = table.GetZeroValue(columnInfo)
}
colMap := make(map[int64]*types.FieldType)
for _, col := range t.Meta().Columns {

View File

@ -141,3 +141,18 @@ func (s *testSuite) TestAlterTable(c *C) {
tk.MustExec("create table if not exists alter_test (c1 int)")
tk.MustExec("alter table alter_test add column c2 int")
}
func (s *testSuite) TestAddNotNullColumnNoDefault(c *C) {
defer testleak.AfterTest(c)()
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("create table nn (c1 int)")
tk.MustExec("insert nn values (1), (2)")
tk.MustExec("alter table nn add column c2 int not null")
tk.MustQuery("select * from nn").Check(testkit.Rows("1 0", "2 0"))
_, err := tk.Exec("insert nn (c1) values (3)")
c.Check(err, NotNil)
tk.MustExec("set sql_mode=''")
tk.MustExec("insert nn (c1) values (3)")
tk.MustQuery("select * from nn").Check(testkit.Rows("1 0", "2 0", "3 0"))
}

View File

@ -237,7 +237,7 @@ func GetColDefaultValue(ctx context.Context, col *model.ColumnInfo) (types.Datum
sessVars := variable.GetSessionVars(ctx)
if !sessVars.StrictSQLMode {
// TODO: add warning.
return getZeroValue(col), true, nil
return GetZeroValue(col), true, nil
}
}
return types.Datum{}, false, errors.Trace(err)
@ -269,7 +269,8 @@ func GetColDefaultValue(ctx context.Context, col *model.ColumnInfo) (types.Datum
return value, true, nil
}
func getZeroValue(col *model.ColumnInfo) types.Datum {
// GetZeroValue gets zero value for given column type.
func GetZeroValue(col *model.ColumnInfo) types.Datum {
var d types.Datum
switch col.Tp {
case mysql.TypeTiny, mysql.TypeInt24, mysql.TypeShort, mysql.TypeLong, mysql.TypeLonglong, mysql.TypeYear:

View File

@ -175,7 +175,7 @@ func (s *testColumnSuite) TestGetZeroValue(c *C) {
}
for _, ca := range cases {
colInfo := &model.ColumnInfo{FieldType: *ca.ft}
zv := getZeroValue(colInfo)
zv := GetZeroValue(colInfo)
c.Assert(zv.Kind(), Equals, ca.value.Kind())
cmp, err := zv.CompareDatum(ca.value)
c.Assert(err, IsNil)