func (h *rpcHandler) handleCopRequest(req *coprocessor.Request) (*coprocessor.Response, error) { resp := &coprocessor.Response{} if err := h.checkContext(req.GetContext()); err != nil { resp.RegionError = err return resp, nil } if len(req.Ranges) == 0 { return resp, nil } if req.GetTp() == kv.ReqTypeSelect || req.GetTp() == kv.ReqTypeIndex { sel := new(tipb.SelectRequest) err := proto.Unmarshal(req.Data, sel) if err != nil { return nil, errors.Trace(err) } ctx := &selectContext{ sel: sel, } ctx.eval = &xeval.Evaluator{Row: make(map[int64]types.Datum)} if sel.Where != nil { ctx.whereColumns = make(map[int64]*tipb.ColumnInfo) collectColumnsInWhere(sel.Where, ctx) } ctx.aggregate = len(sel.Aggregates) > 0 || len(sel.GetGroupBy()) > 0 if ctx.aggregate { // compose aggregateFuncExpr ctx.aggregates = make([]*aggregateFuncExpr, 0, len(sel.Aggregates)) for _, agg := range sel.Aggregates { aggExpr := &aggregateFuncExpr{expr: agg} ctx.aggregates = append(ctx.aggregates, aggExpr) } ctx.groups = make(map[string]bool) ctx.groupKeys = make([][]byte, 0) } var rows []*tipb.Row if req.GetTp() == kv.ReqTypeSelect { rows, err = h.getRowsFromSelectReq(ctx) } else { rows, err = h.getRowsFromIndexReq(ctx) } selResp := new(tipb.SelectResponse) selResp.Error = toPBError(err) selResp.Rows = rows if err != nil { resp.OtherError = proto.String(err.Error()) } data, err := proto.Marshal(selResp) if err != nil { return nil, errors.Trace(err) } resp.Data = data } return resp, nil }
func (h *rpcHandler) handleCopRequest(req *coprocessor.Request) (*coprocessor.Response, error) { resp := &coprocessor.Response{} if err := h.checkContext(req.GetContext()); err != nil { resp.RegionError = err return resp, nil } if len(req.Ranges) == 0 { return resp, nil } if req.GetTp() == kv.ReqTypeSelect || req.GetTp() == kv.ReqTypeIndex { sel := new(tipb.SelectRequest) err := proto.Unmarshal(req.Data, sel) if err != nil { return nil, errors.Trace(err) } ctx := &selectContext{ sel: sel, } if sel.Where != nil { ctx.eval = &xeval.Evaluator{Row: make(map[int64]types.Datum)} ctx.whereColumns = make(map[int64]*tipb.ColumnInfo) collectColumnsInWhere(sel.Where, ctx) } var rows []*tipb.Row if req.GetTp() == kv.ReqTypeSelect { rows, err = h.getRowsFromSelectReq(ctx) } else { rows, err = h.getRowsFromIndexReq(ctx) } selResp := new(tipb.SelectResponse) selResp.Error = toPBError(err) selResp.Rows = rows if err != nil { resp.OtherError = proto.String(err.Error()) } data, err := proto.Marshal(selResp) if err != nil { return nil, errors.Trace(err) } resp.Data = data } return resp, nil }
func (h *rpcHandler) handleCopRequest(req *coprocessor.Request) (*coprocessor.Response, error) { resp := &coprocessor.Response{} if err := h.checkContext(req.GetContext()); err != nil { resp.RegionError = err return resp, nil } if len(req.Ranges) == 0 { return resp, nil } if req.GetTp() == kv.ReqTypeSelect || req.GetTp() == kv.ReqTypeIndex { sel := new(tipb.SelectRequest) err := proto.Unmarshal(req.Data, sel) if err != nil { return nil, errors.Trace(err) } ctx := &selectContext{ sel: sel, keyRanges: req.Ranges, } ctx.eval = &xeval.Evaluator{Row: make(map[int64]types.Datum)} if sel.Where != nil { ctx.whereColumns = make(map[int64]*tipb.ColumnInfo) collectColumnsInExpr(sel.Where, ctx, ctx.whereColumns) } ctx.aggregate = len(sel.Aggregates) > 0 || len(sel.GetGroupBy()) > 0 if ctx.aggregate { // compose aggregateFuncExpr ctx.aggregates = make([]*aggregateFuncExpr, 0, len(sel.Aggregates)) ctx.aggColumns = make(map[int64]*tipb.ColumnInfo) for _, agg := range sel.Aggregates { aggExpr := &aggregateFuncExpr{expr: agg} ctx.aggregates = append(ctx.aggregates, aggExpr) collectColumnsInExpr(agg, ctx, ctx.aggColumns) } ctx.groups = make(map[string]bool) ctx.groupKeys = make([][]byte, 0) for _, item := range ctx.sel.GetGroupBy() { collectColumnsInExpr(item.Expr, ctx, ctx.aggColumns) } for k := range ctx.whereColumns { // It is will be handled in where. delete(ctx.aggColumns, k) } } var rows []*tipb.Row if req.GetTp() == kv.ReqTypeSelect { rows, err = h.getRowsFromSelectReq(ctx) } else { // The PKHandle column info has been collected in ctx, so we can remove it in IndexInfo. length := len(sel.IndexInfo.Columns) if sel.IndexInfo.Columns[length-1].GetPkHandle() { sel.IndexInfo.Columns = sel.IndexInfo.Columns[:length-1] } rows, err = h.getRowsFromIndexReq(ctx) } selResp := new(tipb.SelectResponse) selResp.Error = toPBError(err) selResp.Rows = rows if err != nil { resp.OtherError = err.Error() } data, err := proto.Marshal(selResp) if err != nil { return nil, errors.Trace(err) } resp.Data = data } return resp, nil }
func (h *rpcHandler) handleCopRequest(req *coprocessor.Request) (*coprocessor.Response, error) { resp := &coprocessor.Response{} if err := h.checkContext(req.GetContext()); err != nil { resp.RegionError = err return resp, nil } if len(req.Ranges) == 0 { return resp, nil } if req.GetTp() == kv.ReqTypeSelect || req.GetTp() == kv.ReqTypeIndex { sel := new(tipb.SelectRequest) err := proto.Unmarshal(req.Data, sel) if err != nil { return nil, errors.Trace(err) } ctx := &selectContext{ sel: sel, keyRanges: req.Ranges, sc: xeval.FlagsToStatementContext(sel.Flags), } ctx.eval = xeval.NewEvaluator(ctx.sc) if sel.Where != nil { ctx.whereColumns = make(map[int64]*tipb.ColumnInfo) collectColumnsInExpr(sel.Where, ctx, ctx.whereColumns) } ctx.aggregate = len(sel.Aggregates) > 0 || len(sel.GetGroupBy()) > 0 if ctx.aggregate { // compose aggregateFuncExpr ctx.aggregates = make([]*aggregateFuncExpr, 0, len(sel.Aggregates)) ctx.aggColumns = make(map[int64]*tipb.ColumnInfo) for _, agg := range sel.Aggregates { aggExpr := &aggregateFuncExpr{expr: agg} ctx.aggregates = append(ctx.aggregates, aggExpr) collectColumnsInExpr(agg, ctx, ctx.aggColumns) } ctx.groups = make(map[string]bool) ctx.groupKeys = make([][]byte, 0) for _, item := range ctx.sel.GetGroupBy() { collectColumnsInExpr(item.Expr, ctx, ctx.aggColumns) } for k := range ctx.whereColumns { // It is will be handled in where. delete(ctx.aggColumns, k) } } var chunks []tipb.Chunk if req.GetTp() == kv.ReqTypeSelect { chunks, err = h.getChunksFromSelectReq(ctx) } else { // The PKHandle column info has been collected in ctx, so we can remove it in IndexInfo. length := len(sel.IndexInfo.Columns) if sel.IndexInfo.Columns[length-1].GetPkHandle() { sel.IndexInfo.Columns = sel.IndexInfo.Columns[:length-1] } chunks, err = h.getChunksFromIndexReq(ctx) } selResp := new(tipb.SelectResponse) selResp.Error = toPBError(err) selResp.Chunks = chunks if err != nil { if locked, ok := errors.Cause(err).(*ErrLocked); ok { resp.Locked = &kvrpcpb.LockInfo{ Key: locked.Key, PrimaryLock: locked.Primary, LockVersion: locked.StartTS, LockTtl: locked.TTL, } } else { resp.OtherError = err.Error() } } data, err := proto.Marshal(selResp) if err != nil { return nil, errors.Trace(err) } resp.Data = data } return resp, nil }