コード例 #1
0
ファイル: driver.go プロジェクト: szctop/tidb
func newdriverRows(rs rset.Recordset) *driverRows {
	r := &driverRows{
		rs:   rs,
		done: make(chan int),
		rows: make(chan interface{}, 500),
	}
	go func() {
		err := io.EOF
		if e := r.rs.Do(func(data []interface{}) (bool, error) {
			vv, cloneErr := types.Clone(data)
			if cloneErr != nil {
				return false, errors.Trace(cloneErr)
			}
			select {
			case r.rows <- vv:
				return true, nil
			case <-r.done:
				return false, nil
			}
		}); e != nil {
			err = e
		}

		select {
		case r.rows <- err:
		case <-r.done:
		}
	}()
	return r
}
コード例 #2
0
ファイル: temp.go プロジェクト: lovedboy/tidb
func (t *memTemp) Set(k, v []interface{}) (err error) {
	vv, err := types.Clone(v)
	if err != nil {
		return err
	}
	t.tree.Set(append([]interface{}(nil), k...), vv.([]interface{}))
	return
}
コード例 #3
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
}
コード例 #4
0
ファイル: insert.go プロジェクト: ninefive/tidb
// execExecSelect implements `insert table select ... from ...`.
func (s *InsertIntoStmt) execSelect(t table.Table, cols []*column.Col, ctx context.Context) (_ rset.Recordset, err error) {
	r, err := s.Sel.Plan(ctx)
	if err != nil {
		return nil, errors.Trace(err)
	} else 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
	err = r.Do(ctx, func(_ interface{}, data []interface{}) (more bool, err error) {
		data0 := make([]interface{}, len(t.Cols()))
		marked := make(map[int]struct{}, len(cols))
		for i, d := range data {
			data0[cols[i].Offset] = d
			marked[cols[i].Offset] = struct{}{}
		}

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

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

		if err = column.CheckNotNull(t.Cols(), data0); err != nil {
			return false, errors.Trace(err)
		}

		v, err := types.Clone(data0)
		if err != nil {
			return false, errors.Trace(err)
		}

		bufRecords = append(bufRecords, v.([]interface{}))
		lastInsertIds = append(lastInsertIds, variable.GetSessionVars(ctx).LastInsertID)
		return true, nil
	})
	if err != nil {
		return nil, errors.Trace(err)
	}

	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
}
コード例 #5
0
ファイル: driver.go プロジェクト: romanticode/tidb
func newdriverRows(rs rset.Recordset) *driverRows {
	r := &driverRows{
		rs:   rs,
		done: make(chan int),
		rows: make(chan interface{}, 500),
	}
	r.wg.Add(1)
	go func() {
		// TODO: We may change the whole implementation later, so here just using WaitGroup
		// to solve issue https://github.com/pingcap/tidb/issues/57
		// But if we forget close rows and do commit later, we may still meet this panic
		// with very little probability.
		defer r.wg.Done()
		err := io.EOF
		if e := r.rs.Do(func(data []interface{}) (bool, error) {
			vv, cloneErr := types.Clone(data)
			if cloneErr != nil {
				return false, errors.Trace(cloneErr)
			}
			select {
			case r.rows <- vv:
				return true, nil
			case <-r.done:
				return false, nil
			}
		}); e != nil {
			err = e
		}

		select {
		case r.rows <- err:
		case <-r.done:
		}
	}()
	return r
}