Skip to content

Commit

Permalink
- make generated column ref in insert set available (#11042)
Browse files Browse the repository at this point in the history
- change generated column calculation later in fillValue, resolve related compatible problems
  • Loading branch information
cfzjywxk authored Jul 4, 2019
1 parent 247a07f commit 862a2be
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 18 deletions.
39 changes: 24 additions & 15 deletions executor/insert_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -432,30 +432,39 @@ func (e *InsertValues) fillColValue(datum types.Datum, idx int, column *table.Co
// For NOT NULL column, it will return error or use zero value based on sql_mode.
func (e *InsertValues) fillRow(row []types.Datum, hasValue []bool) ([]types.Datum, error) {
gIdx := 0
gCols := make([]*table.Column, 0)
for i, c := range e.Table.Cols() {
var err error
// Get the default value for all no value columns, the auto increment column is different from the others.
row[i], err = e.fillColValue(row[i], i, c, hasValue[i])
if err != nil {
return nil, err
}

// Evaluate the generated columns.
// Evaluate the generated columns later after real columns set
if c.IsGenerated() {
var val types.Datum
val, err = e.GenExprs[gIdx].Eval(chunk.MutRowFromDatums(row).ToRow())
gIdx++
if e.filterErr(err) != nil {
gCols = append(gCols, c)
} else {
// Get the default value for all no value columns, the auto increment column is different from the others.
row[i], err = e.fillColValue(row[i], i, c, hasValue[i])
if err != nil {
return nil, err
}
row[i], err = table.CastValue(e.ctx, val, c.ToInfo())
if err != nil {
// Handle the bad null error.
if row[i], err = c.HandleBadNull(row[i], e.ctx.GetSessionVars().StmtCtx); err != nil {
return nil, err
}
}

}
for _, gCol := range gCols {
var err error
var val types.Datum
colIdx := gCol.ColumnInfo.Offset
val, err = e.GenExprs[gIdx].Eval(chunk.MutRowFromDatums(row).ToRow())
gIdx++
if e.filterErr(err) != nil {
return nil, err
}
row[colIdx], err = table.CastValue(e.ctx, val, gCol.ToInfo())
if err != nil {
return nil, err
}
// Handle the bad null error.
if row[i], err = c.HandleBadNull(row[i], e.ctx.GetSessionVars().StmtCtx); err != nil {
if row[colIdx], err = gCol.HandleBadNull(row[colIdx], e.ctx.GetSessionVars().StmtCtx); err != nil {
return nil, err
}
}
Expand Down
43 changes: 43 additions & 0 deletions executor/write_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2452,3 +2452,46 @@ func (s *testSuite4) TestIssue11059(c *C) {
_, err := tk.Exec("update t set pk = 2 where uk = 7")
c.Assert(err, NotNil)
}

func (s *testSuite4) TestSetWithRefGenCol(c *C) {
tk := testkit.NewTestKitWithInit(c, s.store)
tk.MustExec("use test")
tk.MustExec(`create table t (i int, j int as (i+1) not null);`)
tk.MustExec(`insert into t set i = j + 1;`)
tk.MustQuery("select * from t").Check(testkit.Rows("1 2"))
tk.MustExec(`insert into t set i = j + 100;`)
tk.MustQuery("select * from t").Check(testkit.Rows("1 2", "100 101"))

tk.MustExec(`create table te (i int)`)
tk.MustExec(`insert into te set i = i + 10;`)
tk.MustQuery("select * from te").Check(testkit.Rows("<nil>"))
tk.MustExec(`insert into te set i = i;`)
tk.MustQuery("select * from te").Check(testkit.Rows("<nil>", "<nil>"))

tk.MustExec(`create table tn (i int not null)`)
tk.MustExec(`insert into tn set i = i;`)
tk.MustQuery("select * from tn").Check(testkit.Rows("0"))
tk.MustExec(`insert into tn set i = i + 10;`)
tk.MustQuery("select * from tn").Check(testkit.Rows("0", "10"))

//
tk.MustExec(`create table t1 (j int(11) GENERATED ALWAYS AS (i + 1) stored, i int(11) DEFAULT '10');`)
tk.MustExec(`insert into t1 values()`)
tk.MustQuery("select * from t1").Check(testkit.Rows("11 10"))
tk.MustExec(`insert into t1 values()`)
tk.MustQuery("select * from t1").Check(testkit.Rows("11 10", "11 10"))

tk.MustExec(`create table t2 (j int(11) GENERATED ALWAYS AS (i + 1) stored not null, i int(11) DEFAULT '5');`)
tk.MustExec(`insert into t2 set i = j + 9`)
tk.MustQuery("select * from t2").Check(testkit.Rows("10 9"))
_, err := tk.Exec(`insert into t2 set j = i + 1`)
c.Assert(err, NotNil)
tk.MustExec(`insert into t2 set i = j + 100`)
tk.MustQuery("select * from t2").Check(testkit.Rows("10 9", "101 100"))

tk.MustExec(`create table t3(j int(11) GENERATED ALWAYS AS (i + 1) stored, i int(11) DEFAULT '5');`)
tk.MustExec(`insert into t3 set i = j + 100`)
tk.MustQuery("select * from t3").Check(testkit.Rows("<nil> <nil>"))
_, err = tk.Exec(`insert into t3 set j = i + 1`)
c.Assert(err, NotNil)
}
3 changes: 0 additions & 3 deletions table/column.go
Original file line number Diff line number Diff line change
Expand Up @@ -432,9 +432,6 @@ func getColDefaultValueFromNil(ctx sessionctx.Context, col *model.ColumnInfo) (t
// Auto increment column doesn't has default value and we should not return error.
return GetZeroValue(col), nil
}
if col.IsGenerated() {
return types.Datum{}, nil
}
vars := ctx.GetSessionVars()
sc := vars.StmtCtx
if sc.BadNullAsWarning {
Expand Down

0 comments on commit 862a2be

Please sign in to comment.