func encodeColumnKV(tid, handle, cid int64, value types.Datum) (kv.Key, []byte, error) { key := tablecodec.EncodeColumnKey(tid, handle, cid) val, err := codec.EncodeValue(nil, value) if err != nil { return nil, nil, errors.Trace(err) } return key, val, 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) } for _, col := range columns { if col.GetPkHandle() { if mysql.HasUnsignedFlag(uint(col.GetFlag())) { row.Data, err = codec.EncodeValue(row.Data, types.NewUintDatum(uint64(handle))) if err != nil { return nil, errors.Trace(err) } } else { row.Data = append(row.Data, 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] row.Data, err = codec.EncodeValue(row.Data, datum) if err != nil { return nil, errors.Trace(err) } } else { key := tablecodec.EncodeColumnKey(tid, handle, colID) data, err1 := h.mvccStore.Get(key, ctx.sel.GetStartTs()) if err1 != nil { return nil, errors.Trace(err1) } if data == nil { if mysql.HasNotNullFlag(uint(col.GetFlag())) { return nil, errors.Trace(kv.ErrNotExist) } row.Data = append(row.Data, codec.NilFlag) } else { row.Data = append(row.Data, data...) } } } } return row, nil }
func (h *rpcHandler) evalWhereForRow(ctx *selectContext, handle int64) (bool, error) { if ctx.sel.Where == nil { return true, nil } tid := ctx.sel.TableInfo.GetTableId() for colID, col := range ctx.whereColumns { if col.GetPkHandle() { if mysql.HasUnsignedFlag(uint(col.GetFlag())) { ctx.eval.Row[colID] = types.NewUintDatum(uint64(handle)) } else { ctx.eval.Row[colID] = types.NewIntDatum(handle) } } else { key := tablecodec.EncodeColumnKey(tid, handle, colID) data, err := h.mvccStore.Get(key, ctx.sel.GetStartTs()) if err != nil { return false, errors.Trace(err) } if data == nil { if mysql.HasNotNullFlag(uint(col.GetFlag())) { return false, errors.Trace(kv.ErrNotExist) } ctx.eval.Row[colID] = types.Datum{} } else { var d types.Datum d, err = tablecodec.DecodeColumnValue(data, col) if err != nil { return false, errors.Trace(err) } ctx.eval.Row[colID] = d } } } result, err := ctx.eval.Eval(ctx.sel.Where) if err != nil { return false, errors.Trace(err) } if result.IsNull() { return false, nil } boolResult, err := result.ToBool() if err != nil { return false, errors.Trace(err) } return boolResult == 1, nil }
func (rs *localRegion) evalWhereForRow(ctx *selectContext, h int64) (bool, error) { if ctx.sel.Where == nil { return true, nil } tid := ctx.sel.TableInfo.GetTableId() for colID, col := range ctx.whereColumns { if col.GetPkHandle() { ctx.eval.Row[colID] = types.NewIntDatum(h) } else { key := tablecodec.EncodeColumnKey(tid, h, colID) data, err := ctx.txn.Get(key) if isDefaultNull(err, col) { ctx.eval.Row[colID] = types.Datum{} continue } else if err != nil { return false, errors.Trace(err) } datum, err := tablecodec.DecodeColumnValue(data, col) if err != nil { return false, errors.Trace(err) } ctx.eval.Row[colID] = datum } } result, err := ctx.eval.Eval(ctx.sel.Where) if err != nil { return false, errors.Trace(err) } if result.IsNull() { return false, nil } boolResult, err := result.ToBool() if err != nil { return false, errors.Trace(err) } return boolResult == 1, 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 }