github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/pingcap/tidb/executor/executor_write.go (about)

     1  // Copyright 2016 PingCAP, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package executor
    15  
    16  import (
    17  	"fmt"
    18  	"strings"
    19  
    20  	"github.com/insionng/yougam/libraries/juju/errors"
    21  	"github.com/insionng/yougam/libraries/pingcap/tidb/ast"
    22  	"github.com/insionng/yougam/libraries/pingcap/tidb/column"
    23  	"github.com/insionng/yougam/libraries/pingcap/tidb/context"
    24  	"github.com/insionng/yougam/libraries/pingcap/tidb/evaluator"
    25  	"github.com/insionng/yougam/libraries/pingcap/tidb/kv"
    26  	"github.com/insionng/yougam/libraries/pingcap/tidb/mysql"
    27  	"github.com/insionng/yougam/libraries/pingcap/tidb/sessionctx"
    28  	"github.com/insionng/yougam/libraries/pingcap/tidb/sessionctx/variable"
    29  	"github.com/insionng/yougam/libraries/pingcap/tidb/table"
    30  	"github.com/insionng/yougam/libraries/pingcap/tidb/terror"
    31  	"github.com/insionng/yougam/libraries/pingcap/tidb/util/types"
    32  )
    33  
    34  var (
    35  	_ Executor = &UpdateExec{}
    36  	_ Executor = &DeleteExec{}
    37  	_ Executor = &InsertExec{}
    38  )
    39  
    40  // UpdateExec represents an update executor.
    41  type UpdateExec struct {
    42  	SelectExec  Executor
    43  	OrderedList []*ast.Assignment
    44  
    45  	// Map for unique (Table, handle) pair.
    46  	updatedRowKeys map[table.Table]map[int64]struct{}
    47  	ctx            context.Context
    48  
    49  	rows        []*Row          // The rows fetched from TableExec.
    50  	newRowsData [][]types.Datum // The new values to be set.
    51  	fetched     bool
    52  	cursor      int
    53  }
    54  
    55  // Next implements Executor Next interface.
    56  func (e *UpdateExec) Next() (*Row, error) {
    57  	if !e.fetched {
    58  		err := e.fetchRows()
    59  		if err != nil {
    60  			return nil, errors.Trace(err)
    61  		}
    62  		e.fetched = true
    63  	}
    64  
    65  	columns, err := getUpdateColumns(e.OrderedList)
    66  	if err != nil {
    67  		return nil, errors.Trace(err)
    68  	}
    69  	if e.cursor >= len(e.rows) {
    70  		return nil, nil
    71  	}
    72  	if e.updatedRowKeys == nil {
    73  		e.updatedRowKeys = make(map[table.Table]map[int64]struct{})
    74  	}
    75  	row := e.rows[e.cursor]
    76  	newData := e.newRowsData[e.cursor]
    77  	for _, entry := range row.RowKeys {
    78  		tbl := entry.Tbl
    79  		if e.updatedRowKeys[tbl] == nil {
    80  			e.updatedRowKeys[tbl] = make(map[int64]struct{})
    81  		}
    82  		offset := e.getTableOffset(tbl)
    83  		handle := entry.Handle
    84  		oldData := row.Data[offset : offset+len(tbl.Cols())]
    85  		newTableData := newData[offset : offset+len(tbl.Cols())]
    86  
    87  		_, ok := e.updatedRowKeys[tbl][handle]
    88  		if ok {
    89  			// Each matching row is updated once, even if it matches the conditions multiple times.
    90  			continue
    91  		}
    92  		// Update row
    93  		err1 := updateRecord(e.ctx, handle, oldData, newTableData, columns, tbl, offset, false)
    94  		if err1 != nil {
    95  			return nil, errors.Trace(err1)
    96  		}
    97  		e.updatedRowKeys[tbl][handle] = struct{}{}
    98  	}
    99  	e.cursor++
   100  	return &Row{}, nil
   101  }
   102  
   103  func getUpdateColumns(assignList []*ast.Assignment) (map[int]*ast.Assignment, error) {
   104  	m := make(map[int]*ast.Assignment, len(assignList))
   105  	for i, v := range assignList {
   106  		m[i] = v
   107  	}
   108  	return m, nil
   109  }
   110  
   111  func (e *UpdateExec) fetchRows() error {
   112  	for {
   113  		row, err := e.SelectExec.Next()
   114  		if err != nil {
   115  			return errors.Trace(err)
   116  		}
   117  		if row == nil {
   118  			return nil
   119  		}
   120  		data := make([]types.Datum, len(e.SelectExec.Fields()))
   121  		newData := make([]types.Datum, len(e.SelectExec.Fields()))
   122  		for i, f := range e.SelectExec.Fields() {
   123  			data[i] = types.NewDatum(f.Expr.GetValue())
   124  			newData[i] = data[i]
   125  			if e.OrderedList[i] != nil {
   126  				val, err := evaluator.Eval(e.ctx, e.OrderedList[i].Expr)
   127  				if err != nil {
   128  					return errors.Trace(err)
   129  				}
   130  				newData[i] = val
   131  			}
   132  		}
   133  		row.Data = data
   134  		e.rows = append(e.rows, row)
   135  		e.newRowsData = append(e.newRowsData, newData)
   136  	}
   137  }
   138  
   139  func (e *UpdateExec) getTableOffset(t table.Table) int {
   140  	fields := e.SelectExec.Fields()
   141  	i := 0
   142  	for i < len(fields) {
   143  		field := fields[i]
   144  		if field.Table.Name.L == t.Meta().Name.L {
   145  			return i
   146  		}
   147  		i += len(field.Table.Columns)
   148  	}
   149  	return 0
   150  }
   151  
   152  func updateRecord(ctx context.Context, h int64, oldData, newData []types.Datum, updateColumns map[int]*ast.Assignment, t table.Table, offset int, onDuplicateUpdate bool) error {
   153  	if err := t.LockRow(ctx, h, false); err != nil {
   154  		return errors.Trace(err)
   155  	}
   156  
   157  	cols := t.Cols()
   158  	touched := make(map[int]bool, len(cols))
   159  
   160  	assignExists := false
   161  	var newHandle types.Datum
   162  	for i, asgn := range updateColumns {
   163  		if asgn == nil {
   164  			continue
   165  		}
   166  		if i < offset || i >= offset+len(cols) {
   167  			// The assign expression is for another table, not this.
   168  			continue
   169  		}
   170  
   171  		colIndex := i - offset
   172  		col := cols[colIndex]
   173  		if col.IsPKHandleColumn(t.Meta()) {
   174  			newHandle = newData[i]
   175  		}
   176  		if mysql.HasAutoIncrementFlag(col.Flag) {
   177  			if newData[i].Kind() == types.KindNull {
   178  				return errors.Errorf("Column '%v' cannot be null", col.Name.O)
   179  			}
   180  			val, err := newData[i].ToInt64()
   181  			if err != nil {
   182  				return errors.Trace(err)
   183  			}
   184  			t.RebaseAutoID(val, true)
   185  		}
   186  
   187  		touched[colIndex] = true
   188  		assignExists = true
   189  	}
   190  
   191  	// If no assign list for this table, no need to update.
   192  	if !assignExists {
   193  		return nil
   194  	}
   195  
   196  	// Check whether new value is valid.
   197  	if err := column.CastValues(ctx, newData, cols); err != nil {
   198  		return errors.Trace(err)
   199  	}
   200  
   201  	if err := column.CheckNotNull(cols, newData); err != nil {
   202  		return errors.Trace(err)
   203  	}
   204  
   205  	// If row is not changed, we should do nothing.
   206  	rowChanged := false
   207  	for i := range oldData {
   208  		if !touched[i] {
   209  			continue
   210  		}
   211  
   212  		n, err := newData[i].CompareDatum(oldData[i])
   213  		if err != nil {
   214  			return errors.Trace(err)
   215  		}
   216  		if n != 0 {
   217  			rowChanged = true
   218  			break
   219  		}
   220  	}
   221  	if !rowChanged {
   222  		// See: https://dev.mysql.com/doc/refman/5.7/en/mysql-real-connect.html  CLIENT_FOUND_ROWS
   223  		if variable.GetSessionVars(ctx).ClientCapability&mysql.ClientFoundRows > 0 {
   224  			variable.GetSessionVars(ctx).AddAffectedRows(1)
   225  		}
   226  		return nil
   227  	}
   228  
   229  	var err error
   230  	if newHandle.Kind() != types.KindNull {
   231  		err = t.RemoveRecord(ctx, h, oldData)
   232  		if err != nil {
   233  			return errors.Trace(err)
   234  		}
   235  		_, err = t.AddRecord(ctx, newData)
   236  	} else {
   237  		// Update record to new value and update index.
   238  		err = t.UpdateRecord(ctx, h, oldData, newData, touched)
   239  	}
   240  	if err != nil {
   241  		return errors.Trace(err)
   242  	}
   243  
   244  	// Record affected rows.
   245  	if !onDuplicateUpdate {
   246  		variable.GetSessionVars(ctx).AddAffectedRows(1)
   247  	} else {
   248  		variable.GetSessionVars(ctx).AddAffectedRows(2)
   249  	}
   250  	return nil
   251  }
   252  
   253  // Fields implements Executor Fields interface.
   254  // Returns nil to indicate there is no output.
   255  func (e *UpdateExec) Fields() []*ast.ResultField {
   256  	return nil
   257  }
   258  
   259  // Close implements Executor Close interface.
   260  func (e *UpdateExec) Close() error {
   261  	return e.SelectExec.Close()
   262  }
   263  
   264  // DeleteExec represents a delete executor.
   265  // See: https://dev.mysql.com/doc/refman/5.7/en/delete.html
   266  type DeleteExec struct {
   267  	SelectExec Executor
   268  
   269  	ctx          context.Context
   270  	Tables       []*ast.TableName
   271  	IsMultiTable bool
   272  
   273  	finished bool
   274  }
   275  
   276  // Next implements Executor Next interface.
   277  func (e *DeleteExec) Next() (*Row, error) {
   278  	if e.finished {
   279  		return nil, nil
   280  	}
   281  	defer func() {
   282  		e.finished = true
   283  	}()
   284  	if e.IsMultiTable && len(e.Tables) == 0 {
   285  		return &Row{}, nil
   286  	}
   287  
   288  	tblMap := make(map[int64][]string, len(e.Tables))
   289  	// Get table alias map.
   290  	tblNames := make(map[string]string)
   291  	if e.IsMultiTable {
   292  		// Delete from multiple tables should consider table ident list.
   293  		fs := e.SelectExec.Fields()
   294  		for _, f := range fs {
   295  			if len(f.TableAsName.L) > 0 {
   296  				tblNames[f.TableAsName.L] = f.TableName.Name.L
   297  			} else {
   298  				tblNames[f.TableName.Name.L] = f.TableName.Name.L
   299  			}
   300  		}
   301  		for _, t := range e.Tables {
   302  			// Consider DBName.
   303  			_, ok := tblNames[t.Name.L]
   304  			if !ok {
   305  				return nil, errors.Errorf("Unknown table '%s' in MULTI DELETE", t.Name.O)
   306  			}
   307  			tblMap[t.TableInfo.ID] = append(tblMap[t.TableInfo.ID], t.Name.L)
   308  		}
   309  	}
   310  
   311  	// Map for unique (Table, handle) pair.
   312  	rowKeyMap := make(map[table.Table]map[int64]struct{})
   313  	for {
   314  		row, err := e.SelectExec.Next()
   315  		if err != nil {
   316  			return nil, errors.Trace(err)
   317  		}
   318  		if row == nil {
   319  			break
   320  		}
   321  
   322  		for _, entry := range row.RowKeys {
   323  			if e.IsMultiTable && !isMatchTableName(entry, tblMap) {
   324  				continue
   325  			}
   326  			if rowKeyMap[entry.Tbl] == nil {
   327  				rowKeyMap[entry.Tbl] = make(map[int64]struct{})
   328  			}
   329  			rowKeyMap[entry.Tbl][entry.Handle] = struct{}{}
   330  		}
   331  	}
   332  	for t, handleMap := range rowKeyMap {
   333  		for handle := range handleMap {
   334  			data, err := t.Row(e.ctx, handle)
   335  			if err != nil {
   336  				return nil, errors.Trace(err)
   337  			}
   338  			err = e.removeRow(e.ctx, t, handle, data)
   339  			if err != nil {
   340  				return nil, errors.Trace(err)
   341  			}
   342  		}
   343  	}
   344  	return nil, nil
   345  }
   346  
   347  func isMatchTableName(entry *RowKeyEntry, tblMap map[int64][]string) bool {
   348  	var name string
   349  	if entry.TableAsName != nil {
   350  		name = entry.TableAsName.L
   351  	}
   352  	if len(name) == 0 {
   353  		name = entry.Tbl.Meta().Name.L
   354  	}
   355  
   356  	names, ok := tblMap[entry.Tbl.Meta().ID]
   357  	if !ok {
   358  		return false
   359  	}
   360  	for _, n := range names {
   361  		if n == name {
   362  			return true
   363  		}
   364  	}
   365  
   366  	return false
   367  }
   368  
   369  func (e *DeleteExec) getTable(ctx context.Context, tableName *ast.TableName) (table.Table, error) {
   370  	return sessionctx.GetDomain(ctx).InfoSchema().TableByName(tableName.Schema, tableName.Name)
   371  }
   372  
   373  func (e *DeleteExec) removeRow(ctx context.Context, t table.Table, h int64, data []types.Datum) error {
   374  	err := t.RemoveRecord(ctx, h, data)
   375  	if err != nil {
   376  		return errors.Trace(err)
   377  	}
   378  	variable.GetSessionVars(ctx).AddAffectedRows(1)
   379  	return nil
   380  }
   381  
   382  // Fields implements Executor Fields interface.
   383  // Returns nil to indicate there is no output.
   384  func (e *DeleteExec) Fields() []*ast.ResultField {
   385  	return nil
   386  }
   387  
   388  // Close implements Executor Close interface.
   389  func (e *DeleteExec) Close() error {
   390  	return e.SelectExec.Close()
   391  }
   392  
   393  // InsertValues is the data to insert.
   394  type InsertValues struct {
   395  	currRow    int
   396  	ctx        context.Context
   397  	SelectExec Executor
   398  
   399  	Table     table.Table
   400  	Columns   []*ast.ColumnName
   401  	Lists     [][]ast.ExprNode
   402  	Setlist   []*ast.Assignment
   403  	IsPrepare bool
   404  }
   405  
   406  // InsertExec represents an insert executor.
   407  type InsertExec struct {
   408  	*InsertValues
   409  
   410  	OnDuplicate []*ast.Assignment
   411  	fields      []*ast.ResultField
   412  
   413  	Priority int
   414  
   415  	finished bool
   416  }
   417  
   418  // Next implements Executor Next interface.
   419  func (e *InsertExec) Next() (*Row, error) {
   420  	if e.finished {
   421  		return nil, nil
   422  	}
   423  	cols, err := e.getColumns(e.Table.Cols())
   424  	if err != nil {
   425  		return nil, errors.Trace(err)
   426  	}
   427  	txn, err := e.ctx.GetTxn(false)
   428  	if err != nil {
   429  		return nil, errors.Trace(err)
   430  	}
   431  	toUpdateColumns, err := getOnDuplicateUpdateColumns(e.OnDuplicate, e.Table)
   432  	if err != nil {
   433  		return nil, errors.Trace(err)
   434  	}
   435  
   436  	var rows [][]types.Datum
   437  	if e.SelectExec != nil {
   438  		rows, err = e.getRowsSelect(cols)
   439  	} else {
   440  		rows, err = e.getRows(cols)
   441  	}
   442  	if err != nil {
   443  		return nil, errors.Trace(err)
   444  	}
   445  
   446  	for _, row := range rows {
   447  		if len(e.OnDuplicate) == 0 {
   448  			txn.SetOption(kv.PresumeKeyNotExists, nil)
   449  		}
   450  		h, err := e.Table.AddRecord(e.ctx, row)
   451  		txn.DelOption(kv.PresumeKeyNotExists)
   452  		if err == nil {
   453  			continue
   454  		}
   455  
   456  		if len(e.OnDuplicate) == 0 || !terror.ErrorEqual(err, kv.ErrKeyExists) {
   457  			return nil, errors.Trace(err)
   458  		}
   459  		if err = e.onDuplicateUpdate(row, h, toUpdateColumns); err != nil {
   460  			return nil, errors.Trace(err)
   461  		}
   462  	}
   463  	e.finished = true
   464  	return nil, nil
   465  }
   466  
   467  // Fields implements Executor Fields interface.
   468  // Returns nil to indicate there is no output.
   469  func (e *InsertExec) Fields() []*ast.ResultField {
   470  	return nil
   471  }
   472  
   473  // Close implements Executor Close interface.
   474  func (e *InsertExec) Close() error {
   475  	if e.SelectExec != nil {
   476  		return e.SelectExec.Close()
   477  	}
   478  	return nil
   479  }
   480  
   481  // There are three types of insert statements:
   482  // 1 insert ... values(...)  --> name type column
   483  // 2 insert ... set x=y...   --> set type column
   484  // 3 insert ... (select ..)  --> name type column
   485  // See: https://dev.mysql.com/doc/refman/5.7/en/insert.html
   486  func (e *InsertValues) getColumns(tableCols []*column.Col) ([]*column.Col, error) {
   487  	var cols []*column.Col
   488  	var err error
   489  
   490  	if len(e.Setlist) > 0 {
   491  		// Process `set` type column.
   492  		columns := make([]string, 0, len(e.Setlist))
   493  		for _, v := range e.Setlist {
   494  			columns = append(columns, v.Column.Name.O)
   495  		}
   496  
   497  		cols, err = column.FindCols(tableCols, columns)
   498  		if err != nil {
   499  			return nil, errors.Errorf("INSERT INTO %s: %s", e.Table.Meta().Name.O, err)
   500  		}
   501  
   502  		if len(cols) == 0 {
   503  			return nil, errors.Errorf("INSERT INTO %s: empty column", e.Table.Meta().Name.O)
   504  		}
   505  	} else {
   506  		// Process `name` type column.
   507  		columns := make([]string, 0, len(e.Columns))
   508  		for _, v := range e.Columns {
   509  			columns = append(columns, v.Name.O)
   510  		}
   511  		cols, err = column.FindCols(tableCols, columns)
   512  		if err != nil {
   513  			return nil, errors.Errorf("INSERT INTO %s: %s", e.Table.Meta().Name.O, err)
   514  		}
   515  
   516  		// If cols are empty, use all columns instead.
   517  		if len(cols) == 0 {
   518  			cols = tableCols
   519  		}
   520  	}
   521  
   522  	// Check column whether is specified only once.
   523  	err = column.CheckOnce(cols)
   524  	if err != nil {
   525  		return nil, errors.Trace(err)
   526  	}
   527  
   528  	return cols, nil
   529  }
   530  
   531  func (e *InsertValues) fillValueList() error {
   532  	if len(e.Setlist) > 0 {
   533  		if len(e.Lists) > 0 {
   534  			return errors.Errorf("INSERT INTO %s: set type should not use values", e.Table)
   535  		}
   536  		var l []ast.ExprNode
   537  		for _, v := range e.Setlist {
   538  			l = append(l, v.Expr)
   539  		}
   540  		e.Lists = append(e.Lists, l)
   541  	}
   542  	return nil
   543  }
   544  
   545  func (e *InsertValues) checkValueCount(insertValueCount, valueCount, num int, cols []*column.Col) error {
   546  	if insertValueCount != valueCount {
   547  		// "insert into t values (), ()" is valid.
   548  		// "insert into t values (), (1)" is not valid.
   549  		// "insert into t values (1), ()" is not valid.
   550  		// "insert into t values (1,2), (1)" is not valid.
   551  		// So the value count must be same for all insert list.
   552  		return errors.Errorf("Column count doesn't match value count at row %d", num+1)
   553  	}
   554  	if valueCount == 0 && len(e.Columns) > 0 {
   555  		// "insert into t (c1) values ()" is not valid.
   556  		return errors.Errorf("INSERT INTO %s: expected %d value(s), have %d", e.Table.Meta().Name.O, len(e.Columns), 0)
   557  	} else if valueCount > 0 && valueCount != len(cols) {
   558  		return errors.Errorf("INSERT INTO %s: expected %d value(s), have %d", e.Table.Meta().Name.O, len(cols), valueCount)
   559  	}
   560  	return nil
   561  }
   562  
   563  func (e *InsertValues) getColumnDefaultValues(cols []*column.Col) (map[string]types.Datum, error) {
   564  	defaultValMap := map[string]types.Datum{}
   565  	for _, col := range cols {
   566  		if value, ok, err := table.GetColDefaultValue(e.ctx, &col.ColumnInfo); ok {
   567  			if err != nil {
   568  				return nil, errors.Trace(err)
   569  			}
   570  			defaultValMap[col.Name.L] = value
   571  		}
   572  	}
   573  	return defaultValMap, nil
   574  }
   575  
   576  func (e *InsertValues) getRows(cols []*column.Col) (rows [][]types.Datum, err error) {
   577  	// process `insert|replace ... set x=y...`
   578  	if err = e.fillValueList(); err != nil {
   579  		return nil, errors.Trace(err)
   580  	}
   581  
   582  	defaultVals, err := e.getColumnDefaultValues(e.Table.Cols())
   583  	if err != nil {
   584  		return nil, errors.Trace(err)
   585  	}
   586  
   587  	rows = make([][]types.Datum, len(e.Lists))
   588  	length := len(e.Lists[0])
   589  	for i, list := range e.Lists {
   590  		if err = e.checkValueCount(length, len(list), i, cols); err != nil {
   591  			return nil, errors.Trace(err)
   592  		}
   593  		e.currRow = i
   594  		rows[i], err = e.getRow(cols, list, defaultVals)
   595  		if err != nil {
   596  			return nil, errors.Trace(err)
   597  		}
   598  	}
   599  	return
   600  }
   601  
   602  func (e *InsertValues) getRow(cols []*column.Col, list []ast.ExprNode, defaultVals map[string]types.Datum) ([]types.Datum, error) {
   603  	vals := make([]types.Datum, len(list))
   604  	var err error
   605  	for i, expr := range list {
   606  		if d, ok := expr.(*ast.DefaultExpr); ok {
   607  			cn := d.Name
   608  			if cn != nil {
   609  				var found bool
   610  				vals[i], found = defaultVals[cn.Name.L]
   611  				if !found {
   612  					return nil, errors.Errorf("default column not found - %s", cn.Name.O)
   613  				}
   614  			} else {
   615  				vals[i] = defaultVals[cols[i].Name.L]
   616  			}
   617  		} else {
   618  			var val types.Datum
   619  			val, err = evaluator.Eval(e.ctx, expr)
   620  			vals[i] = val
   621  			if err != nil {
   622  				return nil, errors.Trace(err)
   623  			}
   624  		}
   625  	}
   626  	return e.fillRowData(cols, vals)
   627  }
   628  
   629  func (e *InsertValues) getRowsSelect(cols []*column.Col) ([][]types.Datum, error) {
   630  	// process `insert|replace into ... select ... from ...`
   631  	if len(e.SelectExec.Fields()) != len(cols) {
   632  		return nil, errors.Errorf("Column count %d doesn't match value count %d", len(cols), len(e.SelectExec.Fields()))
   633  	}
   634  	var rows [][]types.Datum
   635  	for {
   636  		innerRow, err := e.SelectExec.Next()
   637  		if err != nil {
   638  			return nil, errors.Trace(err)
   639  		}
   640  		if innerRow == nil {
   641  			break
   642  		}
   643  		e.currRow = len(rows)
   644  		row, err := e.fillRowData(cols, innerRow.Data)
   645  		if err != nil {
   646  			return nil, errors.Trace(err)
   647  		}
   648  		rows = append(rows, row)
   649  	}
   650  	return rows, nil
   651  }
   652  
   653  func (e *InsertValues) fillRowData(cols []*column.Col, vals []types.Datum) ([]types.Datum, error) {
   654  	row := make([]types.Datum, len(e.Table.Cols()))
   655  	marked := make(map[int]struct{}, len(vals))
   656  	for i, v := range vals {
   657  		offset := cols[i].Offset
   658  		row[offset] = v
   659  		marked[offset] = struct{}{}
   660  	}
   661  	err := e.initDefaultValues(row, marked)
   662  	if err != nil {
   663  		return nil, errors.Trace(err)
   664  	}
   665  	if err = column.CastValues(e.ctx, row, cols); err != nil {
   666  		return nil, errors.Trace(err)
   667  	}
   668  	if err = column.CheckNotNull(e.Table.Cols(), row); err != nil {
   669  		return nil, errors.Trace(err)
   670  	}
   671  	return row, nil
   672  }
   673  
   674  func (e *InsertValues) initDefaultValues(row []types.Datum, marked map[int]struct{}) error {
   675  	var defaultValueCols []*column.Col
   676  	for i, c := range e.Table.Cols() {
   677  		// It's used for retry.
   678  		if mysql.HasAutoIncrementFlag(c.Flag) && row[i].Kind() == types.KindNull &&
   679  			variable.GetSessionVars(e.ctx).RetryInfo.Retrying {
   680  			id, err := variable.GetSessionVars(e.ctx).RetryInfo.GetCurrAutoIncrementID()
   681  			if err != nil {
   682  				return errors.Trace(err)
   683  			}
   684  			row[i].SetInt64(id)
   685  		}
   686  		if row[i].Kind() != types.KindNull {
   687  			// Column value isn't nil and column isn't auto-increment, continue.
   688  			if !mysql.HasAutoIncrementFlag(c.Flag) {
   689  				continue
   690  			}
   691  			val, err := row[i].ToInt64()
   692  			if err != nil {
   693  				return errors.Trace(err)
   694  			}
   695  			if val != 0 {
   696  				e.Table.RebaseAutoID(val, true)
   697  				continue
   698  			}
   699  		}
   700  
   701  		// If the nil value is evaluated in insert list, we will use nil except auto increment column.
   702  		if _, ok := marked[i]; ok && !mysql.HasAutoIncrementFlag(c.Flag) && !mysql.HasTimestampFlag(c.Flag) {
   703  			continue
   704  		}
   705  
   706  		if mysql.HasAutoIncrementFlag(c.Flag) {
   707  			recordID, err := e.Table.AllocAutoID()
   708  			if err != nil {
   709  				return errors.Trace(err)
   710  			}
   711  			row[i].SetInt64(recordID)
   712  			// Notes: incompatible with mysql
   713  			// MySQL will set last insert id to the first row, as follows:
   714  			// `t(id int AUTO_INCREMENT, c1 int, PRIMARY KEY (id))`
   715  			// `insert t (c1) values(1),(2),(3);`
   716  			// Last insert id will be 1, not 3.
   717  			variable.GetSessionVars(e.ctx).SetLastInsertID(uint64(recordID))
   718  			// It's used for retry.
   719  			if !variable.GetSessionVars(e.ctx).RetryInfo.Retrying {
   720  				variable.GetSessionVars(e.ctx).RetryInfo.AddAutoIncrementID(recordID)
   721  			}
   722  		} else {
   723  			var err error
   724  			row[i], _, err = table.GetColDefaultValue(e.ctx, &c.ColumnInfo)
   725  			if err != nil {
   726  				return errors.Trace(err)
   727  			}
   728  		}
   729  
   730  		defaultValueCols = append(defaultValueCols, c)
   731  	}
   732  	if err := column.CastValues(e.ctx, row, defaultValueCols); err != nil {
   733  		return errors.Trace(err)
   734  	}
   735  
   736  	return nil
   737  }
   738  
   739  func (e *InsertExec) onDuplicateUpdate(row []types.Datum, h int64, cols map[int]*ast.Assignment) error {
   740  	// On duplicate key update the duplicate row.
   741  	// Evaluate the updated value.
   742  	// TODO: report rows affected and last insert id.
   743  	data, err := e.Table.Row(e.ctx, h)
   744  	if err != nil {
   745  		return errors.Trace(err)
   746  	}
   747  	// For evaluate ValuesExpr
   748  	// http://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_values
   749  	for i, rf := range e.fields {
   750  		rf.Expr.SetValue(row[i].GetValue())
   751  	}
   752  	// Evaluate assignment
   753  	newData := make([]types.Datum, len(data))
   754  	for i, c := range row {
   755  		asgn, ok := cols[i]
   756  		if !ok {
   757  			newData[i] = c
   758  			continue
   759  		}
   760  		var val types.Datum
   761  		val, err = evaluator.Eval(e.ctx, asgn.Expr)
   762  		if err != nil {
   763  			return errors.Trace(err)
   764  		}
   765  		newData[i] = val
   766  	}
   767  	if err = updateRecord(e.ctx, h, data, newData, cols, e.Table, 0, true); err != nil {
   768  		return errors.Trace(err)
   769  	}
   770  	return nil
   771  }
   772  
   773  func findColumnByName(t table.Table, name string) (*column.Col, error) {
   774  	_, tableName, colName := splitQualifiedName(name)
   775  	if len(tableName) > 0 && tableName != t.Meta().Name.O {
   776  		return nil, errors.Errorf("unknown field %s.%s", tableName, colName)
   777  	}
   778  
   779  	c := column.FindCol(t.Cols(), colName)
   780  	if c == nil {
   781  		return nil, errors.Errorf("unknown field %s", colName)
   782  	}
   783  	return c, nil
   784  }
   785  
   786  func getOnDuplicateUpdateColumns(assignList []*ast.Assignment, t table.Table) (map[int]*ast.Assignment, error) {
   787  	m := make(map[int]*ast.Assignment, len(assignList))
   788  
   789  	for _, v := range assignList {
   790  		col := v.Column
   791  		c, err := findColumnByName(t, joinQualifiedName("", col.Table.L, col.Name.L))
   792  		if err != nil {
   793  			return nil, errors.Trace(err)
   794  		}
   795  		m[c.Offset] = v
   796  	}
   797  	return m, nil
   798  }
   799  
   800  // ReplaceExec represents a replace executor.
   801  type ReplaceExec struct {
   802  	*InsertValues
   803  	Priority int
   804  	finished bool
   805  }
   806  
   807  // Fields implements Executor Fields interface.
   808  // Returns nil to indicate there is no output.
   809  func (e *ReplaceExec) Fields() []*ast.ResultField {
   810  	return nil
   811  }
   812  
   813  // Close implements Executor Close interface.
   814  func (e *ReplaceExec) Close() error {
   815  	if e.SelectExec != nil {
   816  		return e.SelectExec.Close()
   817  	}
   818  	return nil
   819  }
   820  
   821  // Next implements Executor Next interface.
   822  func (e *ReplaceExec) Next() (*Row, error) {
   823  	if e.finished {
   824  		return nil, nil
   825  	}
   826  	cols, err := e.getColumns(e.Table.Cols())
   827  	if err != nil {
   828  		return nil, errors.Trace(err)
   829  	}
   830  
   831  	var rows [][]types.Datum
   832  	if e.SelectExec != nil {
   833  		rows, err = e.getRowsSelect(cols)
   834  	} else {
   835  		rows, err = e.getRows(cols)
   836  	}
   837  	if err != nil {
   838  		return nil, errors.Trace(err)
   839  	}
   840  
   841  	/*
   842  	 * MySQL uses the following algorithm for REPLACE (and LOAD DATA ... REPLACE):
   843  	 *  1. Try to insert the new row into the table
   844  	 *  2. While the insertion fails because a duplicate-key error occurs for a primary key or unique index:
   845  	 *  3. Delete from the table the conflicting row that has the duplicate key value
   846  	 *  4. Try again to insert the new row into the table
   847  	 * See: http://dev.mysql.com/doc/refman/5.7/en/replace.html
   848  	 *
   849  	 * For REPLACE statements, the affected-rows value is 2 if the new row replaced an old row,
   850  	 * because in this case, one row was inserted after the duplicate was deleted.
   851  	 * See: http://dev.mysql.com/doc/refman/5.7/en/mysql-affected-rows.html
   852  	 */
   853  	idx := 0
   854  	rowsLen := len(rows)
   855  	for {
   856  		if idx >= rowsLen {
   857  			break
   858  		}
   859  		row := rows[idx]
   860  		h, err1 := e.Table.AddRecord(e.ctx, row)
   861  		if err1 == nil {
   862  			idx++
   863  			continue
   864  		}
   865  		if err1 != nil && !terror.ErrorEqual(err1, kv.ErrKeyExists) {
   866  			return nil, errors.Trace(err1)
   867  		}
   868  		oldRow, err1 := e.Table.Row(e.ctx, h)
   869  		if err1 != nil {
   870  			return nil, errors.Trace(err1)
   871  		}
   872  		rowUnchanged, err1 := types.EqualDatums(oldRow, row)
   873  		if err1 != nil {
   874  			return nil, errors.Trace(err1)
   875  		}
   876  		if rowUnchanged {
   877  			// If row unchanged, we do not need to do insert.
   878  			variable.GetSessionVars(e.ctx).AddAffectedRows(1)
   879  			idx++
   880  			continue
   881  		}
   882  		// Remove current row and try replace again.
   883  		err1 = e.Table.RemoveRecord(e.ctx, h, oldRow)
   884  		if err1 != nil {
   885  			return nil, errors.Trace(err1)
   886  		}
   887  		variable.GetSessionVars(e.ctx).AddAffectedRows(1)
   888  	}
   889  	e.finished = true
   890  	return nil, nil
   891  }
   892  
   893  // SplitQualifiedName splits an identifier name to db, table and field name.
   894  func splitQualifiedName(name string) (db string, table string, field string) {
   895  	seps := strings.Split(name, ".")
   896  
   897  	l := len(seps)
   898  	switch l {
   899  	case 1:
   900  		// `name` is field.
   901  		field = seps[0]
   902  	case 2:
   903  		// `name` is `table.field`.
   904  		table, field = seps[0], seps[1]
   905  	case 3:
   906  		// `name` is `db.table.field`.
   907  		db, table, field = seps[0], seps[1], seps[2]
   908  	default:
   909  		// `name` is `db.table.field`.
   910  		db, table, field = seps[l-3], seps[l-2], seps[l-1]
   911  	}
   912  
   913  	return
   914  }
   915  
   916  // JoinQualifiedName converts db, table, field to a qualified name.
   917  func joinQualifiedName(db string, table string, field string) string {
   918  	if len(db) > 0 {
   919  		return fmt.Sprintf("%s.%s.%s", db, table, field)
   920  	} else if len(table) > 0 {
   921  		return fmt.Sprintf("%s.%s", table, field)
   922  	} else {
   923  		return field
   924  	}
   925  }