コード例 #1
0
ファイル: xapi.go プロジェクト: c4pt0r/tidb
// Next returns the next row of the sub result.
// If no more row to return, data would be nil.
func (pr *partialResult) Next() (handle int64, data []types.Datum, err error) {
	if !pr.fetched {
		select {
		case err = <-pr.done:
		}
		pr.fetched = true
		if err != nil {
			return 0, nil, err
		}
	}
	if pr.cursor >= len(pr.resp.Rows) {
		return 0, nil, nil
	}
	row := pr.resp.Rows[pr.cursor]
	data, err = tablecodec.DecodeValues(row.Data, pr.fields, pr.index)
	if err != nil {
		return 0, nil, errors.Trace(err)
	}
	if data == nil {
		// When no column is referenced, the data may be nil, like 'select count(*) from t'.
		// In this case, we need to create a zero length datum slice,
		// as caller will check if data is nil to finish iteration.
		data = make([]types.Datum, 0)
	}
	if !pr.aggregate {
		handleBytes := row.GetHandle()
		datums, err := codec.Decode(handleBytes)
		if err != nil {
			return 0, nil, errors.Trace(err)
		}
		handle = datums[0].GetInt64()
	}
	pr.cursor++
	return
}
コード例 #2
0
ファイル: index_iter.go プロジェクト: lovedboy/tidb
// Next returns current key and moves iterator to the next step.
func (c *indexIter) Next() (val []interface{}, h int64, err error) {
	if !c.it.Valid() {
		return nil, 0, errors.Trace(io.EOF)
	}
	if !c.it.Key().HasPrefix(c.prefix) {
		return nil, 0, errors.Trace(io.EOF)
	}
	// get indexedValues
	buf := c.it.Key()[len(c.prefix):]
	vv, err := codec.Decode(buf)
	if err != nil {
		return nil, 0, errors.Trace(err)
	}
	// if index is *not* unique, the handle is in keybuf
	if !c.idx.unique {
		h = vv[len(vv)-1].(int64)
		val = vv[0 : len(vv)-1]
	} else {
		// otherwise handle is value
		h, err = decodeHandle(c.it.Value())
		if err != nil {
			return nil, 0, errors.Trace(err)
		}
		val = vv
	}
	// update new iter to next
	err = c.it.Next()
	if err != nil {
		return nil, 0, errors.Trace(err)
	}
	return
}
コード例 #3
0
ファイル: eval.go プロジェクト: XuHuaiyu/tidb
func (e *Evaluator) decodeValueList(valueListExpr *tipb.Expr) (*decodedValueList, error) {
	if len(valueListExpr.Val) == 0 {
		// Empty value list.
		return &decodedValueList{}, nil
	}
	if e.valueLists == nil {
		e.valueLists = make(map[*tipb.Expr]*decodedValueList)
	}
	decoded := e.valueLists[valueListExpr]
	if decoded != nil {
		return decoded, nil
	}
	list, err := codec.Decode(valueListExpr.Val)
	if err != nil {
		return nil, errors.Trace(err)
	}
	var hasNull bool
	for _, v := range list {
		if v.IsNull() {
			hasNull = true
		}
	}
	decoded = &decodedValueList{values: list, hasNull: hasNull}
	e.valueLists[valueListExpr] = decoded
	return decoded, nil
}
コード例 #4
0
ファイル: tables.go プロジェクト: anywhy/tidb
// DecodeValue implements table.Table DecodeValue interface.
func DecodeValue(data []byte, tp *types.FieldType) (types.Datum, error) {
	values, err := codec.Decode(data)
	if err != nil {
		return types.Datum{}, errors.Trace(err)
	}
	return unflatten(values[0], tp)
}
コード例 #5
0
ファイル: tablecodec.go プロジェクト: yangxingnn/tidb
// DecodeRow decodes a byte slice into datums.
// TODO: We should only decode columns in the cols map.
// Row layout: colID1, value1, colID2, value2, .....
func DecodeRow(data []byte, cols map[int64]*types.FieldType) (map[int64]types.Datum, error) {
	if data == nil {
		return nil, nil
	}
	values, err := codec.Decode(data)
	if err != nil {
		return nil, errors.Trace(err)
	}
	if len(values)%2 != 0 {
		return nil, errors.New("Decoded row value length is not even number!")
	}
	row := make(map[int64]types.Datum, len(cols))
	for i := 0; i < len(values); i += 2 {
		cid := values[i]
		id := cid.GetInt64()
		ft, ok := cols[id]
		if ok {
			v := values[i+1]
			v, err = Unflatten(v, ft)
			if err != nil {
				return nil, errors.Trace(err)
			}
			row[id] = v
		}
	}
	return row, nil
}
コード例 #6
0
ファイル: common.go プロジェクト: xudongQiu/tidb
func decodeValue(data []byte, cols []*model.ColumnInfo) ([]interface{}, error) {
	values, err := codec.Decode(data)
	if err != nil {
		return nil, errors.Trace(err)
	}

	if len(values) != len(cols) {
		return nil, errors.Errorf("Column count does not match, expect %d, actual %d", len(cols), len(values))
	}

	var rvalues []interface{}
	for i, col := range cols {
		// TODO: support more types if we really need.
		switch col.Tp {
		case mysql.TypeString, mysql.TypeVarchar:
			val := string(values[i].([]byte))
			rvalues = append(rvalues, val)
		case mysql.TypeEnum:
			val, err := mysql.ParseEnumValue(col.Elems, values[i].(uint64))
			if err != nil {
				return nil, errors.Trace(err)
			}
			rvalues = append(rvalues, val.String())
		}
	}
	return rvalues, nil
}
コード例 #7
0
ファイル: tables.go プロジェクト: lovedboy/tidb
// DecodeValue implements table.Table DecodeValue interface.
func (t *Table) DecodeValue(data []byte, col *column.Col) (interface{}, error) {
	values, err := codec.Decode(data)
	if err != nil {
		return nil, errors.Trace(err)
	}

	return t.unflatten(values[0], col)
}
コード例 #8
0
ファイル: tablecodec.go プロジェクト: astaxie/tidb
// DecodeValues decodes a byte slice into datums with column types.
func DecodeValues(data []byte, fts []*types.FieldType) ([]types.Datum, error) {
	values, err := codec.Decode(data)
	if err != nil {
		return nil, errors.Trace(err)
	}
	if len(values) > len(fts) {
		return nil, errors.Errorf("invalid column count %d is less than value count %d", len(fts), len(values))
	}
	for i := range values {
		values[i], err = unflatten(values[i], fts[i])
		if err != nil {
			return nil, errors.Trace(err)
		}
	}
	return values, nil
}
コード例 #9
0
ファイル: binloginfo_test.go プロジェクト: pingcap/tidb
func mutationRowsToRows(c *C, mutationRows [][]byte, firstColumn, secondColumn int) [][]types.Datum {
	var rows [][]types.Datum
	for _, mutationRow := range mutationRows {
		datums, err := codec.Decode(mutationRow, 5)
		c.Assert(err, IsNil)
		for i := range datums {
			if i != firstColumn && i != secondColumn {
				// Column ID or handle
				c.Assert(datums[i].GetInt64(), Greater, int64(0))
			}
			if datums[i].Kind() == types.KindBytes {
				datums[i].SetBytesAsString(datums[i].GetBytes())
			}
		}
		row := []types.Datum{datums[firstColumn], datums[secondColumn]}
		rows = append(rows, row)
	}
	return rows
}
コード例 #10
0
ファイル: xapi.go プロジェクト: XuHuaiyu/tidb
// Next returns the next row of the sub result.
// If no more row to return, data would be nil.
func (r *SubResult) Next() (handle int64, data []types.Datum, err error) {
	if r.resp == nil {
		r.resp = new(tipb.SelectResponse)
		var b []byte
		b, err = ioutil.ReadAll(r.reader)
		r.reader.Close()
		if err != nil {
			return 0, nil, errors.Trace(err)
		}
		err = proto.Unmarshal(b, r.resp)
		if err != nil {
			return 0, nil, errors.Trace(err)
		}
		if r.resp.Error != nil {
			return 0, nil, errInvalidResp.Gen("[%d %s]", r.resp.Error.GetCode(), r.resp.Error.GetMsg())
		}
	}
	if r.cursor >= len(r.resp.Rows) {
		return 0, nil, nil
	}
	row := r.resp.Rows[r.cursor]
	data, err = tablecodec.DecodeValues(row.Data, r.fields, r.index)
	if err != nil {
		return 0, nil, errors.Trace(err)
	}
	if data == nil {
		// When no column is referenced, the data may be nil, like 'select count(*) from t'.
		// In this case, we need to create a zero length datum slice,
		// as caller will check if data is nil to finish iteration.
		data = make([]types.Datum, 0)
	}
	if !r.aggregate {
		handleBytes := row.GetHandle()
		datums, err := codec.Decode(handleBytes)
		if err != nil {
			return 0, nil, errors.Trace(err)
		}
		handle = datums[0].GetInt64()
	}
	r.cursor++
	return
}
コード例 #11
0
ファイル: tablecodec.go プロジェクト: pingcap/tidb
// DecodeValues decodes a byte slice into datums with column types.
func DecodeValues(data []byte, fts []*types.FieldType, inIndex bool) ([]types.Datum, error) {
	if len(data) == 0 {
		return nil, nil
	}
	values, err := codec.Decode(data, len(fts))
	if err != nil {
		return nil, errors.Trace(err)
	}
	if len(values) > len(fts) {
		return nil, errInvalidColumnCount.Gen("invalid column count %d is less than value count %d", len(fts), len(values))
	}

	for i := range values {
		values[i], err = Unflatten(values[i], fts[i], inIndex)
		if err != nil {
			return nil, errors.Trace(err)
		}
	}
	return values, nil
}
コード例 #12
0
ファイル: statistics.go プロジェクト: yubobo/tidb
// TableFromPB creates a table statistics from protobuffer.
func TableFromPB(ti *model.TableInfo, tpb *TablePB) (*Table, error) {
	if tpb.GetId() != ti.ID {
		return nil, errors.Errorf("table id not match, expected %d, got %d", ti.ID, tpb.GetId())
	}
	if len(tpb.Columns) != len(ti.Columns) {
		return nil, errors.Errorf("column count not match, expected %d, got %d", len(ti.Columns), len(tpb.Columns))
	}
	for i := range ti.Columns {
		if ti.Columns[i].ID != tpb.Columns[i].GetId() {
			return nil, errors.Errorf("column ID not match, expected %d, got %d", ti.Columns[i].ID, tpb.Columns[i].GetId())
		}
	}
	t := &Table{info: ti}
	t.TS = tpb.GetTs()
	t.Count = tpb.GetCount()
	t.Columns = make([]*Column, len(tpb.GetColumns()))
	for i, cInfo := range t.info.Columns {
		cpb := tpb.Columns[i]
		values, err := codec.Decode(cpb.GetValue())
		if err != nil {
			return nil, errors.Trace(err)
		}
		c := &Column{
			ID:      cpb.GetId(),
			NDV:     cpb.GetNdv(),
			Numbers: cpb.GetNumbers(),
			Values:  make([]types.Datum, len(values)),
			Repeats: cpb.GetRepeats(),
		}
		for i, val := range values {
			c.Values[i], err = tablecodec.Unflatten(val, &cInfo.FieldType)
			if err != nil {
				return nil, errors.Trace(err)
			}
		}
		t.Columns[i] = c
	}
	return t, nil
}
コード例 #13
0
ファイル: tablecodec.go プロジェクト: anywhy/tidb
// DecodeValues decodes a byte slice into datums with column types.
func DecodeValues(data []byte, fts []*types.FieldType, inIndex bool) ([]types.Datum, error) {
	if data == nil {
		return nil, nil
	}
	values, err := codec.Decode(data)
	if err != nil {
		return nil, errors.Trace(err)
	}
	if len(values) > len(fts) {
		return nil, errInvalidColumnCount.Gen("invalid column count %d is less than value count %d", len(fts), len(values))
	}
	if inIndex {
		// We don't need to unflatten index columns for now.
		return values, nil
	}

	for i := range values {
		values[i], err = unflatten(values[i], fts[i])
		if err != nil {
			return nil, errors.Trace(err)
		}
	}
	return values, nil
}
コード例 #14
0
ファイル: tablecodec.go プロジェクト: pingcap/tidb
// DecodeIndexKey decodes datums from an index key.
func DecodeIndexKey(key kv.Key) ([]types.Datum, error) {
	b := key[prefixLen+idLen:]
	return codec.Decode(b, 1)
}
コード例 #15
0
ファイル: xapi_test.go プロジェクト: c4pt0r/tidb
func (s *testXAPISuite) TestSelect(c *C) {
	defer testleak.AfterTest(c)()
	store := createMemStore(time.Now().Nanosecond())
	count := int64(10)
	err := prepareTableData(store, tbInfo, count, genValues)
	c.Check(err, IsNil)

	// Select Table request.
	txn, err := store.Begin()
	c.Check(err, IsNil)
	client := txn.GetClient()
	req, err := prepareSelectRequest(tbInfo, txn.StartTS())
	c.Check(err, IsNil)
	resp := client.Send(req)
	subResp, err := resp.Next()
	c.Check(err, IsNil)
	data, err := ioutil.ReadAll(subResp)
	c.Check(err, IsNil)
	selResp := new(tipb.SelectResponse)
	proto.Unmarshal(data, selResp)
	c.Check(selResp.Rows, HasLen, int(count))
	for i, row := range selResp.Rows {
		handle := int64(i + 1)
		expectedDatums := []types.Datum{types.NewDatum(handle)}
		expectedDatums = append(expectedDatums, genValues(handle, tbInfo)...)
		var expectedEncoded []byte
		expectedEncoded, err = codec.EncodeValue(nil, expectedDatums...)
		c.Assert(err, IsNil)
		c.Assert(row.Data, BytesEquals, expectedEncoded)
	}
	txn.Commit()

	// Select Index request.
	txn, err = store.Begin()
	c.Check(err, IsNil)
	client = txn.GetClient()
	req, err = prepareIndexRequest(tbInfo, txn.StartTS())
	c.Check(err, IsNil)
	resp = client.Send(req)
	subResp, err = resp.Next()
	c.Check(err, IsNil)
	data, err = ioutil.ReadAll(subResp)
	c.Check(err, IsNil)
	idxResp := new(tipb.SelectResponse)
	proto.Unmarshal(data, idxResp)
	c.Check(idxResp.Rows, HasLen, int(count))
	handles := make([]int, 0, 10)
	for _, row := range idxResp.Rows {
		var err error
		datums, err := codec.Decode(row.Handle)
		c.Check(err, IsNil)
		c.Check(datums, HasLen, 1)
		handles = append(handles, int(datums[0].GetInt64()))
	}
	sort.Ints(handles)
	for i, h := range handles {
		c.Assert(h, Equals, i+1)
	}
	txn.Commit()

	store.Close()
}