示例#1
0
func touchedMap(t table.Table) map[int]bool {
	touched := make(map[int]bool)
	for _, col := range t.Cols() {
		touched[col.Offset] = true
	}
	return touched
}
示例#2
0
文件: index.go 项目: jmptrader/tidb
func fetchRowColVals(txn kv.Transaction, t table.Table, handle int64, indexInfo *model.IndexInfo) (
	kv.Key, []types.Datum, error) {
	// fetch datas
	cols := t.Cols()
	colMap := make(map[int64]*types.FieldType)
	for _, v := range indexInfo.Columns {
		col := cols[v.Offset]
		colMap[col.ID] = &col.FieldType
	}
	rowKey := tablecodec.EncodeRecordKey(t.RecordPrefix(), handle)
	rowVal, err := txn.Get(rowKey)
	if err != nil {
		return nil, nil, errors.Trace(err)
	}
	row, err := tablecodec.DecodeRow(rowVal, colMap)
	if err != nil {
		return nil, nil, errors.Trace(err)
	}
	vals := make([]types.Datum, 0, len(indexInfo.Columns))
	for _, v := range indexInfo.Columns {
		col := cols[v.Offset]
		vals = append(vals, row[col.ID])
	}
	return rowKey, vals, nil
}
示例#3
0
func (s *testColumnChangeSuite) testColumnDrop(c *C, ctx context.Context, d *ddl, tbl table.Table) {
	d.close()
	dropCol := tbl.Cols()[2]
	tc := &testDDLCallback{}
	// set up hook
	prevState := model.StateNone
	var checkErr error
	tc.onJobUpdated = func(job *model.Job) {
		if job.SchemaState == prevState {
			return
		}
		prevState = job.SchemaState
		currentTbl, err := getCurrentTable(d, s.dbInfo.ID, tbl.Meta().ID)
		if err != nil {
			checkErr = errors.Trace(err)
		}
		for _, col := range currentTbl.Cols() {
			if col.ID == dropCol.ID {
				checkErr = errors.Errorf("column is not dropped")
			}
		}
	}
	d.hook = tc
	d.start()
	testDropColumn(c, ctx, d, s.dbInfo, tbl.Meta(), dropCol.Name.L, false)
}
示例#4
0
func checkRecordAndIndex(txn kv.Transaction, t table.Table, idx table.Index) error {
	cols := make([]*table.Column, len(idx.Meta().Columns))
	for i, col := range idx.Meta().Columns {
		cols[i] = t.Cols()[col.Offset]
	}

	startKey := t.RecordKey(0, nil)
	filterFunc := func(h1 int64, vals1 []types.Datum, cols []*table.Column) (bool, error) {
		isExist, h2, err := idx.Exist(txn, vals1, h1)
		if terror.ErrorEqual(err, kv.ErrKeyExists) {
			record1 := &RecordData{Handle: h1, Values: vals1}
			record2 := &RecordData{Handle: h2, Values: vals1}
			return false, errDateNotEqual.Gen("index:%v != record:%v", record2, record1)
		}
		if err != nil {
			return false, errors.Trace(err)
		}
		if !isExist {
			record := &RecordData{Handle: h1, Values: vals1}
			return false, errDateNotEqual.Gen("index:%v != record:%v", nil, record)
		}

		return true, nil
	}
	err := iterRecords(txn, t, startKey, cols, filterFunc)

	if err != nil {
		return errors.Trace(err)
	}

	return nil
}
示例#5
0
func checkRecordAndIndex(txn kv.Transaction, t table.Table, idx *column.IndexedCol) error {
	cols := make([]*column.Col, len(idx.Columns))
	for i, col := range idx.Columns {
		cols[i] = t.Cols()[col.Offset]
	}

	startKey := t.RecordKey(0, nil)
	kvIndex := kv.NewKVIndex(t.IndexPrefix(), idx.Name.L, idx.ID, idx.Unique)
	filterFunc := func(h1 int64, vals1 []interface{}, cols []*column.Col) (bool, error) {
		isExist, h2, err := kvIndex.Exist(txn, vals1, h1)
		if terror.ErrorEqual(err, kv.ErrKeyExists) {
			record1 := &RecordData{Handle: h1, Values: vals1}
			record2 := &RecordData{Handle: h2, Values: vals1}
			return false, errors.Errorf("index:%v != record:%v", record2, record1)
		}
		if err != nil {
			return false, errors.Trace(err)
		}
		if !isExist {
			record := &RecordData{Handle: h1, Values: vals1}
			return false, errors.Errorf("index:%v != record:%v", nil, record)
		}

		return true, nil
	}
	err := t.IterRecords(txn, startKey, cols, filterFunc)

	if err != nil {
		return errors.Trace(err)
	}

	return nil
}
示例#6
0
文件: insert.go 项目: lovedboy/tidb
func (s *InsertValues) getRows(ctx context.Context, t table.Table, cols []*column.Col) (rows [][]interface{}, err error) {
	// process `insert|replace ... set x=y...`
	if err = s.fillValueList(); err != nil {
		return nil, errors.Trace(err)
	}

	evalMap, err := s.getColumnDefaultValues(ctx, t.Cols())
	if err != nil {
		return nil, errors.Trace(err)
	}

	rows = make([][]interface{}, len(s.Lists))
	for i, list := range s.Lists {
		if err = s.checkValueCount(len(s.Lists[0]), len(list), i, cols); err != nil {
			return nil, errors.Trace(err)
		}

		vals := make([]interface{}, len(list))
		for j, expr := range list {
			// For "insert into t values (default)" Default Eval.
			evalMap[expression.ExprEvalDefaultName] = cols[j].Name.O

			vals[j], err = expr.Eval(ctx, evalMap)
			if err != nil {
				return nil, errors.Trace(err)
			}
		}

		rows[i], err = s.fillRowData(ctx, t, cols, vals)
		if err != nil {
			return nil, errors.Trace(err)
		}
	}
	return
}
示例#7
0
文件: insert.go 项目: huozhe3136/tidb
func (s *InsertValues) getRow(ctx context.Context, t table.Table, cols []*column.Col, list []expression.Expression, m map[interface{}]interface{}) ([]interface{}, error) {
	r := make([]interface{}, len(t.Cols()))
	marked := make(map[int]struct{}, len(list))
	for i, expr := range list {
		// For "insert into t values (default)" Default Eval.
		m[expression.ExprEvalDefaultName] = cols[i].Name.O

		val, err := expr.Eval(ctx, m)
		if err != nil {
			return nil, errors.Trace(err)
		}
		r[cols[i].Offset] = val
		marked[cols[i].Offset] = struct{}{}
	}

	// Clear last insert id.
	variable.GetSessionVars(ctx).SetLastInsertID(0)

	err := s.initDefaultValues(ctx, t, r, marked)
	if err != nil {
		return nil, errors.Trace(err)
	}
	if err = column.CastValues(ctx, r, cols); err != nil {
		return nil, errors.Trace(err)
	}
	if err = column.CheckNotNull(t.Cols(), r); err != nil {
		return nil, errors.Trace(err)
	}

	return r, nil
}
示例#8
0
文件: update.go 项目: Alienero/tidb
func getUpdateColumns(t table.Table, assignList []expression.Assignment, isMultipleTable bool, tblAliasMap map[string]string) ([]*column.Col, []expression.Assignment, error) {
	// TODO: We should check the validate if assignList in somewhere else. Maybe in building plan.
	// TODO: We should use field.GetFieldIndex to replace this function.
	tcols := make([]*column.Col, 0, len(assignList))
	tAsgns := make([]expression.Assignment, 0, len(assignList))
	tname := t.TableName()
	for _, asgn := range assignList {
		if isMultipleTable {
			if tblAliasMap != nil {
				if alias, ok := tblAliasMap[asgn.TableName]; ok {
					if !strings.EqualFold(tname.O, alias) {
						continue
					}
				}
			} else if !strings.EqualFold(tname.O, asgn.TableName) {
				continue
			}
		}
		col := column.FindCol(t.Cols(), asgn.ColName)
		if col == nil {
			if isMultipleTable {
				continue
			}
			return nil, nil, errors.Errorf("UPDATE: unknown column %s", asgn.ColName)
		}
		tcols = append(tcols, col)
		tAsgns = append(tAsgns, asgn)
	}
	return tcols, tAsgns, nil
}
示例#9
0
func (s *testIndexChangeSuite) checkAddPublic(d *ddl, ctx context.Context, writeTbl, publicTbl table.Table) error {
	// WriteOnlyTable: insert t values (6, 6)
	_, err := writeTbl.AddRecord(ctx, types.MakeDatums(6, 6))
	if err != nil {
		return errors.Trace(err)
	}
	err = checkIndexExists(ctx, publicTbl, 6, 6, true)
	if err != nil {
		return errors.Trace(err)
	}
	// PublicTable: insert t values (7, 7)
	_, err = publicTbl.AddRecord(ctx, types.MakeDatums(7, 7))
	if err != nil {
		return errors.Trace(err)
	}
	err = checkIndexExists(ctx, publicTbl, 7, 7, true)
	if err != nil {
		return errors.Trace(err)
	}

	// WriteOnlyTable: update t set c2 = 5 where c1 = 7 and c2 = 7
	err = writeTbl.UpdateRecord(ctx, 7, types.MakeDatums(7, 7), types.MakeDatums(7, 5), touchedMap(writeTbl))
	if err != nil {
		return errors.Trace(err)
	}
	err = checkIndexExists(ctx, publicTbl, 5, 7, true)
	if err != nil {
		return errors.Trace(err)
	}
	err = checkIndexExists(ctx, publicTbl, 7, 7, false)
	if err != nil {
		return errors.Trace(err)
	}
	// WriteOnlyTable: delete t where c1 = 6
	err = writeTbl.RemoveRecord(ctx, 6, types.MakeDatums(6, 6))
	if err != nil {
		return errors.Trace(err)
	}
	err = checkIndexExists(ctx, publicTbl, 6, 6, false)

	var rows [][]types.Datum
	publicTbl.IterRecords(ctx, publicTbl.FirstKey(), publicTbl.Cols(),
		func(h int64, data []types.Datum, cols []*table.Column) (bool, error) {
			rows = append(rows, data)
			return true, nil
		})
	if len(rows) == 0 {
		return errors.New("table is empty")
	}
	for _, row := range rows {
		idxVal := row[1].GetInt64()
		handle := row[0].GetInt64()
		err = checkIndexExists(ctx, publicTbl, idxVal, handle, true)
		if err != nil {
			return errors.Trace(err)
		}
	}
	return nil
}
示例#10
0
func (s *testColumnSuite) testGetColumn(c *C, t table.Table, name string, isExist bool) {
	col := column.FindCol(t.Cols(), name)
	if isExist {
		c.Assert(col, NotNil)
	} else {
		c.Assert(col, IsNil)
	}
}
示例#11
0
文件: insert.go 项目: huozhe3136/tidb
// execExecSelect implements `insert table select ... from ...`.
func (s *InsertValues) execSelect(t table.Table, cols []*column.Col, ctx context.Context) (rset.Recordset, error) {
	r, err := s.Sel.Plan(ctx)
	if err != nil {
		return nil, errors.Trace(err)
	}
	defer r.Close()
	if len(r.GetFields()) != len(cols) {
		return nil, errors.Errorf("Column count %d doesn't match value count %d", len(cols), len(r.GetFields()))
	}

	var bufRecords [][]interface{}
	var lastInsertIds []uint64
	for {
		var row *plan.Row
		row, err = r.Next(ctx)
		if err != nil {
			return nil, errors.Trace(err)
		}
		if row == nil {
			break
		}
		data0 := make([]interface{}, len(t.Cols()))
		marked := make(map[int]struct{}, len(cols))
		for i, d := range row.Data {
			data0[cols[i].Offset] = d
			marked[cols[i].Offset] = struct{}{}
		}

		if err = s.initDefaultValues(ctx, t, data0, marked); err != nil {
			return nil, errors.Trace(err)
		}

		if err = column.CastValues(ctx, data0, cols); err != nil {
			return nil, errors.Trace(err)
		}

		if err = column.CheckNotNull(t.Cols(), data0); err != nil {
			return nil, errors.Trace(err)
		}
		var v interface{}
		v, err = types.Clone(data0)
		if err != nil {
			return nil, errors.Trace(err)
		}

		bufRecords = append(bufRecords, v.([]interface{}))
		lastInsertIds = append(lastInsertIds, variable.GetSessionVars(ctx).LastInsertID)
	}

	for i, r := range bufRecords {
		variable.GetSessionVars(ctx).SetLastInsertID(lastInsertIds[i])
		if _, err = t.AddRecord(ctx, r); err != nil {
			return nil, errors.Trace(err)
		}
	}
	return nil, nil
}
示例#12
0
文件: ddl.go 项目: WilliamRen/tidb
// Add a column into table
func (d *ddl) addColumn(ctx context.Context, schema model.CIStr, tbl table.Table, spec *AlterSpecification) error {
	// Find position
	cols := tbl.Cols()
	position := len(cols)
	name := spec.Column.Name
	// Check column name duplicate
	dc := column.FindCol(cols, name)
	if dc != nil {
		return errors.Errorf("Try to add a column with the same name of an already exists column.")
	}
	if spec.Position.Type == ColumnPositionFirst {
		position = 0
	} else if spec.Position.Type == ColumnPositionAfter {
		// Find the mentioned column
		c := column.FindCol(cols, spec.Position.RelativeColumn)
		if c == nil {
			return errors.Errorf("No such column: %v", name)
		}
		// insert position is after the mentioned column
		position = c.Offset + 1
	}
	// TODO: Set constraint
	col, _, err := d.buildColumnAndConstraint(position, spec.Column)
	if err != nil {
		return errors.Trace(err)
	}
	// insert col into the right place of the column list
	newCols := make([]*column.Col, 0, len(cols)+1)
	newCols = append(newCols, cols[:position]...)
	newCols = append(newCols, col)
	newCols = append(newCols, cols[position:]...)
	// adjust position
	if position != len(cols) {
		offsetChange := make(map[int]int)
		for i := position + 1; i < len(newCols); i++ {
			offsetChange[newCols[i].Offset] = i
			newCols[i].Offset = i
		}
		// Update index offset info
		for _, idx := range tbl.Indices() {
			for _, c := range idx.Columns {
				newOffset, ok := offsetChange[c.Offset]
				if ok {
					c.Offset = newOffset
				}
			}
		}
	}
	tb := tbl.(*tables.Table)
	tb.Columns = newCols
	// TODO: update index
	// TODO: update default value
	// update infomation schema
	err = d.updateInfoSchema(ctx, schema, tb.Meta())
	return errors.Trace(err)
}
示例#13
0
文件: ddl.go 项目: botvs/tidb
func (d *ddl) buildIndex(ctx context.Context, t table.Table, idxInfo *model.IndexInfo, unique bool) error {
	firstKey := t.FirstKey()
	prefix := t.KeyPrefix()

	txn, err := ctx.GetTxn(false)
	if err != nil {
		return errors.Trace(err)
	}
	it, err := txn.Seek([]byte(firstKey))
	if err != nil {
		return errors.Trace(err)
	}
	defer it.Close()
	for it.Valid() && strings.HasPrefix(it.Key(), prefix) {
		var err error
		handle, err := util.DecodeHandleFromRowKey(it.Key())
		log.Info("building index...", handle)
		if err != nil {
			return errors.Trace(err)
		}
		// TODO: v is timestamp ?
		// fetch datas
		cols := t.Cols()
		var vals []interface{}
		for _, v := range idxInfo.Columns {
			var (
				data []byte
				val  interface{}
			)
			col := cols[v.Offset]
			k := t.RecordKey(handle, col)
			data, err = txn.Get([]byte(k))
			if err != nil {
				return errors.Trace(err)
			}
			val, err = t.DecodeValue(data, col)
			if err != nil {
				return errors.Trace(err)
			}
			vals = append(vals, val)
		}
		// build index
		kvX := kv.NewKVIndex(t.IndexPrefix(), idxInfo.Name.L, unique)
		err = kvX.Create(txn, vals, handle)
		if err != nil {
			return errors.Trace(err)
		}

		rk := []byte(t.RecordKey(handle, nil))
		it, err = kv.NextUntil(it, util.RowKeyPrefixFilter(rk))
		if err != nil {
			return errors.Trace(err)
		}
	}
	return nil
}
示例#14
0
func findColumnByName(t table.Table, tableName, colName string) (*table.Column, error) {
	if len(tableName) > 0 && tableName != t.Meta().Name.O {
		return nil, errors.Errorf("unknown field %s.%s", tableName, colName)
	}

	c := table.FindCol(t.Cols(), colName)
	if c == nil {
		return nil, errors.Errorf("unknown field %s", colName)
	}
	return c, nil
}
示例#15
0
文件: update.go 项目: Brian110/tidb
func findColumnByName(t table.Table, name string) (*column.Col, error) {
	_, tableName, colName := field.SplitQualifiedName(name)
	if len(tableName) > 0 && tableName != t.TableName().O {
		return nil, errors.Errorf("unknown field %s.%s", tableName, colName)
	}

	c := column.FindCol(t.Cols(), colName)
	if c == nil {
		return nil, errors.Errorf("unknown field %s", colName)
	}
	return c, nil
}
示例#16
0
文件: update.go 项目: no2key/tidb
func getUpdateColumns(t table.Table, assignList []expressions.Assignment) ([]*column.Col, error) {
	tcols := make([]*column.Col, len(assignList))
	for i, asgn := range assignList {
		col := column.FindCol(t.Cols(), asgn.ColName)
		if col == nil {
			return nil, errors.Errorf("UPDATE: unknown column %s", asgn.ColName)
		}
		tcols[i] = col
	}

	return tcols, nil
}
示例#17
0
func (s *testColumnSuite) testGetColumn(t table.Table, name string, isExist bool) error {
	col := table.FindCol(t.Cols(), name)
	if isExist {
		if col == nil {
			return errors.Errorf("column should not be nil")
		}
	} else {
		if col != nil {
			return errors.Errorf("column should be nil")
		}
	}
	return nil
}
示例#18
0
文件: index.go 项目: pingcap/tidb
func (d *ddl) fetchRowColVals(txn kv.Transaction, t table.Table, handles []int64, indexInfo *model.IndexInfo) (
	[]*indexRecord, error) {
	// Through handles access to get all row keys.
	handlesLen := len(handles)
	rowKeys := make([]kv.Key, 0, handlesLen)
	for _, h := range handles {
		rowKey := tablecodec.EncodeRecordKey(t.RecordPrefix(), h)
		rowKeys = append(rowKeys, rowKey)
	}

	// Get corresponding raw values for rowKeys.
	ver := kv.Version{Ver: txn.StartTS()}
	snap, err := d.store.GetSnapshot(ver)
	if err != nil {
		return nil, errors.Trace(err)
	}
	pairMap, err := snap.BatchGet(rowKeys)
	if err != nil {
		return nil, errors.Trace(err)
	}

	// Get corresponding values for pairMap.
	cols := t.Cols()
	colMap := make(map[int64]*types.FieldType)
	for _, v := range indexInfo.Columns {
		col := cols[v.Offset]
		colMap[col.ID] = &col.FieldType
	}
	idxRecords := make([]*indexRecord, 0, handlesLen)
	for i, rowKey := range rowKeys {
		rawVal, ok := pairMap[string(rowKey)]
		if !ok {
			// Row doesn't exist, skip it.
			continue
		}
		row, err := tablecodec.DecodeRow(rawVal, colMap)
		if err != nil {
			return nil, errors.Trace(err)
		}
		rowVal := make([]types.Datum, 0, len(indexInfo.Columns))
		for _, v := range indexInfo.Columns {
			col := cols[v.Offset]
			rowVal = append(rowVal, row[col.ID])
		}
		idxRecord := &indexRecord{handle: handles[i], key: rowKey, vals: rowVal}
		idxRecords = append(idxRecords, idxRecord)
	}
	return idxRecords, nil
}
示例#19
0
func (s *DeleteStmt) hitWhere(ctx context.Context, t table.Table, data []interface{}) (bool, error) {
	if s.Where == nil {
		return true, nil
	}
	m := map[interface{}]interface{}{}

	// Set parameter for evaluating expression.
	for _, col := range t.Cols() {
		m[col.Name.L] = data[col.Offset]
	}
	ok, err := expressions.EvalBoolExpr(ctx, s.Where, m)
	if err != nil {
		return false, errors.Trace(err)
	}
	return ok, nil
}
示例#20
0
文件: insert.go 项目: lovedboy/tidb
func (s *InsertValues) initDefaultValues(ctx context.Context, t table.Table, row []interface{}, marked map[int]struct{}) error {
	var defaultValueCols []*column.Col
	for i, c := range t.Cols() {
		if row[i] != nil {
			// Column value is not nil, continue.
			continue
		}

		// If the nil value is evaluated in insert list, we will use nil except auto increment column.
		if _, ok := marked[i]; ok && !mysql.HasAutoIncrementFlag(c.Flag) && !mysql.HasTimestampFlag(c.Flag) {
			continue
		}

		if mysql.HasAutoIncrementFlag(c.Flag) {
			recordID, err := t.AllocAutoID()
			if err != nil {
				return errors.Trace(err)
			}
			row[i] = recordID
			if c.IsPKHandleColumn(t.Meta()) {
				// Notes: incompatible with mysql
				// MySQL will set last insert id to the first row, as follows:
				// `t(id int AUTO_INCREMENT, c1 int, PRIMARY KEY (id))`
				// `insert t (c1) values(1),(2),(3);`
				// Last insert id will be 1, not 3.
				variable.GetSessionVars(ctx).SetLastInsertID(uint64(recordID))
			}
		} else {
			var value interface{}
			value, _, err := tables.GetColDefaultValue(ctx, &c.ColumnInfo)
			if err != nil {
				return errors.Trace(err)
			}

			row[i] = value
		}

		defaultValueCols = append(defaultValueCols, c)
	}

	if err := column.CastValues(ctx, row, defaultValueCols); err != nil {
		return errors.Trace(err)
	}

	return nil
}
示例#21
0
// CompareTableRecord compares data and the corresponding table data one by one.
// It returns nil if data is equal to the data that scans from table, otherwise
// it returns an error with a different set of records. If exact is false, only compares handle.
func CompareTableRecord(txn kv.Transaction, t table.Table, data []*RecordData, exact bool) error {
	m := make(map[int64][]types.Datum, len(data))
	for _, r := range data {
		if _, ok := m[r.Handle]; ok {
			return errRepeatHandle.Gen("handle:%d is repeated in data", r.Handle)
		}
		m[r.Handle] = r.Values
	}

	startKey := t.RecordKey(0, nil)
	filterFunc := func(h int64, vals []types.Datum, cols []*table.Column) (bool, error) {
		vals2, ok := m[h]
		if !ok {
			record := &RecordData{Handle: h, Values: vals}
			return false, errDateNotEqual.Gen("data:%v != record:%v", nil, record)
		}
		if !exact {
			delete(m, h)
			return true, nil
		}

		if !reflect.DeepEqual(vals, vals2) {
			record1 := &RecordData{Handle: h, Values: vals2}
			record2 := &RecordData{Handle: h, Values: vals}
			return false, errDateNotEqual.Gen("data:%v != record:%v", record1, record2)
		}

		delete(m, h)

		return true, nil
	}
	err := iterRecords(txn, t, startKey, t.Cols(), filterFunc)
	if err != nil {
		return errors.Trace(err)
	}

	for h, vals := range m {
		record := &RecordData{Handle: h, Values: vals}
		return errDateNotEqual.Gen("data:%v != record:%v", record, nil)
	}

	return nil
}
示例#22
0
文件: insert.go 项目: lovedboy/tidb
func (s *InsertValues) fillRowData(ctx context.Context, t table.Table, cols []*column.Col, vals []interface{}) ([]interface{}, error) {
	row := make([]interface{}, len(t.Cols()))
	marked := make(map[int]struct{}, len(vals))
	for i, v := range vals {
		offset := cols[i].Offset
		row[offset] = v
		marked[offset] = struct{}{}
	}
	err := s.initDefaultValues(ctx, t, row, marked)
	if err != nil {
		return nil, errors.Trace(err)
	}
	if err = column.CastValues(ctx, row, cols); err != nil {
		return nil, errors.Trace(err)
	}
	if err = column.CheckNotNull(t.Cols(), row); err != nil {
		return nil, errors.Trace(err)
	}
	return row, nil
}
示例#23
0
文件: index.go 项目: astaxie/tidb
func fetchRowColVals(txn kv.Transaction, t table.Table, handle int64, indexInfo *model.IndexInfo) ([]types.Datum, error) {
	// fetch datas
	cols := t.Cols()
	vals := make([]types.Datum, 0, len(indexInfo.Columns))
	for _, v := range indexInfo.Columns {
		col := cols[v.Offset]
		k := t.RecordKey(handle, col)
		data, err := txn.Get(k)
		if err != nil {
			return nil, errors.Trace(err)
		}
		val, err := tables.DecodeValue(data, &col.FieldType)
		if err != nil {
			return nil, errors.Trace(err)
		}
		vals = append(vals, val)
	}

	return vals, nil
}
示例#24
0
文件: update.go 项目: hulunbier/tidb
func getUpdateColumns(t table.Table, assignList []expressions.Assignment, multipleTable bool) ([]*column.Col, error) {
	// TODO: We should check the validate if assignList in somewhere else. Maybe in building plan.
	tcols := make([]*column.Col, 0, len(assignList))
	tname := t.TableName()
	for _, asgn := range assignList {
		if multipleTable {
			if !strings.EqualFold(tname.O, asgn.TableName) {
				continue
			}
		}
		col := column.FindCol(t.Cols(), asgn.ColName)
		if col == nil {
			if multipleTable {
				continue
			}
			return nil, errors.Errorf("UPDATE: unknown column %s", asgn.ColName)
		}
		tcols = append(tcols, col)
	}
	return tcols, nil
}
示例#25
0
文件: insert.go 项目: huozhe3136/tidb
func (s *InsertValues) initDefaultValues(ctx context.Context, t table.Table, row []interface{}, marked map[int]struct{}) error {
	var err error
	var defaultValueCols []*column.Col
	for i, c := range t.Cols() {
		if row[i] != nil {
			// Column value is not nil, continue.
			continue
		}

		// If the nil value is evaluated in insert list, we will use nil except auto increment column.
		if _, ok := marked[i]; ok && !mysql.HasAutoIncrementFlag(c.Flag) && !mysql.HasTimestampFlag(c.Flag) {
			continue
		}

		if mysql.HasAutoIncrementFlag(c.Flag) {
			var id int64
			if id, err = t.AllocAutoID(); err != nil {
				return errors.Trace(err)
			}
			row[i] = id
			variable.GetSessionVars(ctx).SetLastInsertID(uint64(id))
		} else {
			var value interface{}
			value, _, err = getDefaultValue(ctx, c)
			if err != nil {
				return errors.Trace(err)
			}

			row[i] = value
		}

		defaultValueCols = append(defaultValueCols, c)
	}

	if err = column.CastValues(ctx, row, defaultValueCols); err != nil {
		return errors.Trace(err)
	}

	return nil
}
示例#26
0
文件: index.go 项目: youprofit/tidb
func fetchRowColVals(txn kv.Transaction, t table.Table, handle int64, indexInfo *model.IndexInfo) ([]interface{}, error) {
	// fetch datas
	cols := t.Cols()
	var vals []interface{}
	for _, v := range indexInfo.Columns {
		var val interface{}

		col := cols[v.Offset]
		k := t.RecordKey(handle, col)
		data, err := txn.Get(k)
		if err != nil {
			return nil, errors.Trace(err)
		}
		val, err = t.DecodeValue(data, col)
		if err != nil {
			return nil, errors.Trace(err)
		}
		vals = append(vals, val)
	}

	return vals, nil
}
示例#27
0
func checkIndexAndRecord(txn kv.Transaction, t table.Table, idx *column.IndexedCol) error {
	kvIndex := kv.NewKVIndex(t.IndexPrefix(), idx.Name.L, idx.ID, idx.Unique)
	it, err := kvIndex.SeekFirst(txn)
	if err != nil {
		return errors.Trace(err)
	}
	defer it.Close()

	cols := make([]*column.Col, len(idx.Columns))
	for i, col := range idx.Columns {
		cols[i] = t.Cols()[col.Offset]
	}

	for {
		vals1, h, err := it.Next()
		if terror.ErrorEqual(err, io.EOF) {
			break
		} else if err != nil {
			return errors.Trace(err)
		}

		vals2, err := t.RowWithCols(txn, h, cols)
		if terror.ErrorEqual(err, kv.ErrNotExist) {
			record := &RecordData{Handle: h, Values: vals1}
			err = errors.Errorf("index:%v != record:%v", record, nil)
		}
		if err != nil {
			return errors.Trace(err)
		}
		if !reflect.DeepEqual(vals1, vals2) {
			record1 := &RecordData{Handle: h, Values: vals1}
			record2 := &RecordData{Handle: h, Values: vals2}
			return errors.Errorf("index:%v != record:%v", record1, record2)
		}
	}

	return nil
}
示例#28
0
func checkIndexAndRecord(txn kv.Transaction, t table.Table, idx table.Index) error {
	it, err := idx.SeekFirst(txn)
	if err != nil {
		return errors.Trace(err)
	}
	defer it.Close()

	cols := make([]*table.Column, len(idx.Meta().Columns))
	for i, col := range idx.Meta().Columns {
		cols[i] = t.Cols()[col.Offset]
	}

	for {
		vals1, h, err := it.Next()
		if terror.ErrorEqual(err, io.EOF) {
			break
		} else if err != nil {
			return errors.Trace(err)
		}

		vals2, err := rowWithCols(txn, t, h, cols)
		if terror.ErrorEqual(err, kv.ErrNotExist) {
			record := &RecordData{Handle: h, Values: vals1}
			err = errDateNotEqual.Gen("index:%v != record:%v", record, nil)
		}
		if err != nil {
			return errors.Trace(err)
		}
		if !reflect.DeepEqual(vals1, vals2) {
			record1 := &RecordData{Handle: h, Values: vals1}
			record2 := &RecordData{Handle: h, Values: vals2}
			return errDateNotEqual.Gen("index:%v != record:%v", record1, record2)
		}
	}

	return nil
}
示例#29
0
func (s *InsertValues) initDefaultValues(ctx context.Context, t table.Table, row []interface{}, marked map[int]struct{}) (recordID int64, err error) {
	var defaultValueCols []*column.Col
	for i, c := range t.Cols() {
		if row[i] != nil {
			// Column value is not nil, continue.
			continue
		}

		// If the nil value is evaluated in insert list, we will use nil except auto increment column.
		if _, ok := marked[i]; ok && !mysql.HasAutoIncrementFlag(c.Flag) && !mysql.HasTimestampFlag(c.Flag) {
			continue
		}

		if mysql.HasAutoIncrementFlag(c.Flag) {
			if recordID, err = t.AllocAutoID(); err != nil {
				return 0, errors.Trace(err)
			}
			row[i] = recordID
		} else {
			var value interface{}
			value, _, err = tables.GetColDefaultValue(ctx, &c.ColumnInfo)
			if err != nil {
				return 0, errors.Trace(err)
			}

			row[i] = value
		}

		defaultValueCols = append(defaultValueCols, c)
	}

	if err = column.CastValues(ctx, row, defaultValueCols); err != nil {
		return 0, errors.Trace(err)
	}

	return
}
示例#30
0
func fetchRowColVals(txn kv.Transaction, t table.Table, handle int64, indexInfo *model.IndexInfo) ([]types.Datum, error) {
	// fetch datas
	cols := t.Cols()
	vals := make([]types.Datum, 0, len(indexInfo.Columns))
	for _, v := range indexInfo.Columns {
		col := cols[v.Offset]
		k := t.RecordKey(handle, col)
		data, err := txn.Get(k)
		if err != nil {
			if terror.ErrorEqual(err, kv.ErrNotExist) && !mysql.HasNotNullFlag(col.Flag) {
				vals = append(vals, types.Datum{})
				continue
			}
			return nil, errors.Trace(err)
		}
		val, err := tables.DecodeValue(data, &col.FieldType)
		if err != nil {
			return nil, errors.Trace(err)
		}
		vals = append(vals, val)
	}

	return vals, nil
}