func getZeroValue(col *model.ColumnInfo) types.Datum { var d types.Datum switch col.Tp { case mysql.TypeTiny, mysql.TypeInt24, mysql.TypeShort, mysql.TypeLong, mysql.TypeLonglong, mysql.TypeYear: if mysql.HasUnsignedFlag(col.Flag) { d.SetUint64(0) } else { d.SetInt64(0) } case mysql.TypeFloat: d.SetFloat32(0) case mysql.TypeDouble: d.SetFloat64(0) case mysql.TypeNewDecimal: d.SetMysqlDecimal(mysql.NewDecimalFromInt(0, 0)) case mysql.TypeString, mysql.TypeVarString, mysql.TypeVarchar: d.SetString("") case mysql.TypeBlob, mysql.TypeTinyBlob, mysql.TypeMediumBlob, mysql.TypeLongBlob: d.SetBytes([]byte{}) case mysql.TypeDuration: d.SetMysqlDuration(mysql.ZeroDuration) case mysql.TypeDate, mysql.TypeNewDate: d.SetMysqlTime(mysql.ZeroDate) case mysql.TypeTimestamp: d.SetMysqlTime(mysql.ZeroTimestamp) case mysql.TypeDatetime: d.SetMysqlTime(mysql.ZeroDatetime) case mysql.TypeBit: d.SetMysqlBit(mysql.Bit{Value: 0, Width: mysql.MinBitWidth}) case mysql.TypeSet: d.SetMysqlSet(mysql.Set{}) } return d }
func (e *Evaluator) evalUint(val []byte) (types.Datum, error) { var d types.Datum _, u, err := codec.DecodeUint(val) if err != nil { return d, ErrInvalid.Gen("invalid uint % x", val) } d.SetUint64(u) return d, nil }
func flatten(data types.Datum) (types.Datum, error) { switch data.Kind() { case types.KindMysqlTime: // for mysql datetime, timestamp and date type v, err := data.GetMysqlTime().ToPackedUint() return types.NewUintDatum(v), errors.Trace(err) case types.KindMysqlDuration: // for mysql time type data.SetInt64(int64(data.GetMysqlDuration().Duration)) return data, nil case types.KindMysqlEnum: data.SetUint64(data.GetMysqlEnum().Value) return data, nil case types.KindMysqlSet: data.SetUint64(data.GetMysqlSet().Value) return data, nil case types.KindMysqlBit: data.SetUint64(data.GetMysqlBit().Value) return data, nil case types.KindMysqlHex: data.SetInt64(data.GetMysqlHex().Value) return data, nil default: return data, nil } }
func flatten(data types.Datum) (types.Datum, error) { switch data.Kind() { case types.KindMysqlTime: // for mysql datetime, timestamp and date type b, err := data.GetMysqlTime().Marshal() if err != nil { return types.NewDatum(nil), errors.Trace(err) } return types.NewDatum(b), nil case types.KindMysqlDuration: // for mysql time type data.SetInt64(int64(data.GetMysqlDuration().Duration)) return data, nil case types.KindMysqlDecimal: data.SetString(data.GetMysqlDecimal().String()) return data, nil case types.KindMysqlEnum: data.SetUint64(data.GetMysqlEnum().Value) return data, nil case types.KindMysqlSet: data.SetUint64(data.GetMysqlSet().Value) return data, nil case types.KindMysqlBit: data.SetUint64(data.GetMysqlBit().Value) return data, nil case types.KindMysqlHex: data.SetInt64(data.GetMysqlHex().Value) return data, nil default: return data, nil } }
func (rs *localRegion) getRowByHandle(ctx *selectContext, handle int64) (*tipb.Row, error) { tid := ctx.sel.TableInfo.GetTableId() columns := ctx.sel.TableInfo.Columns row := new(tipb.Row) var d types.Datum d.SetInt64(handle) var err error row.Handle, err = codec.EncodeValue(nil, d) if err != nil { return nil, errors.Trace(err) } rowData := make([][]byte, 0, len(columns)) for _, col := range columns { var colVal []byte if *col.PkHandle { if mysql.HasUnsignedFlag(uint(*col.Flag)) { // PK column is Unsigned var ud types.Datum ud.SetUint64(uint64(handle)) var err1 error colVal, err1 = codec.EncodeValue(nil, ud) if err1 != nil { return nil, errors.Trace(err1) } } else { colVal = row.Handle } } else { colID := col.GetColumnId() if ctx.whereColumns[colID] != nil { // The column is saved in evaluator, use it directly. datum := ctx.eval.Row[colID] var err1 error colVal, err1 = codec.EncodeValue(nil, datum) if err1 != nil { return nil, errors.Trace(err1) } } else { key := tablecodec.EncodeColumnKey(tid, handle, colID) var err1 error colVal, err1 = ctx.txn.Get(key) if err1 != nil { if !isDefaultNull(err1, col) { return nil, errors.Trace(err1) } colVal = []byte{codec.NilFlag} } } } rowData = append(rowData, colVal) } if ctx.aggregate { // Update aggregate functions. err = rs.aggregate(ctx, rowData) if err != nil { return nil, errors.Trace(err) } } else { // If without aggregate functions, just return raw row data. for _, d := range rowData { row.Data = append(row.Data, d...) } } return row, nil }
// handleRowData deals with raw row data: // 1. Decodes row from raw byte slice. // 2. Checks if it fit where condition. // 3. Update aggregate functions. func (rs *localRegion) handleRowData(ctx *selectContext, handle int64, value []byte) (*tipb.Row, error) { columns := ctx.sel.TableInfo.Columns row := new(tipb.Row) var d types.Datum d.SetInt64(handle) var err error row.Handle, err = codec.EncodeValue(nil, d) if err != nil { return nil, errors.Trace(err) } rowData := make([][]byte, len(columns)) values, err := rs.getRowData(value, ctx.colTps) if err != nil { return nil, errors.Trace(err) } for i, col := range columns { if *col.PkHandle { var colVal []byte if mysql.HasUnsignedFlag(uint(*col.Flag)) { // PK column is Unsigned var ud types.Datum ud.SetUint64(uint64(handle)) var err1 error colVal, err1 = codec.EncodeValue(nil, ud) if err1 != nil { return nil, errors.Trace(err1) } } else { colVal = row.Handle } rowData[i] = colVal continue } v, ok := values[col.GetColumnId()] if !ok { if mysql.HasNotNullFlag(uint(col.GetFlag())) { return nil, errors.New("Miss column") } v = []byte{codec.NilFlag} values[col.GetColumnId()] = v } rowData[i] = v } // Evalue where match, err := rs.evalWhereForRow(ctx, handle, values) if err != nil { return nil, errors.Trace(err) } if !match { return nil, nil } if ctx.aggregate { // Update aggregate functions. err = rs.aggregate(ctx, handle, values) if err != nil { return nil, errors.Trace(err) } } else { // If without aggregate functions, just return raw row data. for _, d := range rowData { row.Data = append(row.Data, d...) } } return row, nil }
func (h *rpcHandler) getRowByHandle(ctx *selectContext, handle int64) (*tipb.Row, error) { tid := ctx.sel.TableInfo.GetTableId() columns := ctx.sel.TableInfo.Columns row := new(tipb.Row) var d types.Datum d.SetInt64(handle) var err error row.Handle, err = codec.EncodeValue(nil, d) if err != nil { return nil, errors.Trace(err) } rowData := make([][]byte, len(columns)) colTps := make(map[int64]*types.FieldType, len(columns)) for i, col := range columns { var colVal []byte if col.GetPkHandle() { if mysql.HasUnsignedFlag(uint(*col.Flag)) { // PK column is Unsigned var ud types.Datum ud.SetUint64(uint64(handle)) var err1 error colVal, err1 = codec.EncodeValue(nil, ud) if err1 != nil { return nil, errors.Trace(err1) } } else { colVal = row.Handle } rowData[i] = colVal } else { colTps[col.GetColumnId()] = xapi.FieldTypeFromPBColumn(col) } } key := tablecodec.EncodeRowKeyWithHandle(tid, handle) value, err := h.mvccStore.Get(key, ctx.sel.GetStartTs()) if err != nil { return nil, errors.Trace(err) } values, err := h.getRowData(value, colTps) if err != nil { return nil, errors.Trace(err) } for i, col := range columns { if col.GetPkHandle() { continue } v, ok := values[col.GetColumnId()] if !ok { if mysql.HasNotNullFlag(uint(col.GetFlag())) { return nil, errors.New("Miss column") } v = []byte{codec.NilFlag} values[col.GetColumnId()] = v } rowData[i] = v } // Evalue where match, err := h.evalWhereForRow(ctx, handle, values) if err != nil { return nil, errors.Trace(err) } if !match { return nil, nil } for _, d := range rowData { row.Data = append(row.Data, d...) } return row, nil }