diff --git a/executor.go b/executor.go index 72c6da626..25dfbf4c1 100644 --- a/executor.go +++ b/executor.go @@ -694,7 +694,8 @@ func (e *executor) executeGenericField(ctx context.Context, index string, c *pql span.LogKV("name", c.Name) defer span.Finish() - if field := c.Args["field"]; field == "" { + field := c.Args["field"] + if field == "" { return SignedRow{}, fmt.Errorf("plugin operation %s(): field required", c.Name) } @@ -714,6 +715,7 @@ func (e *executor) executeGenericField(ctx context.Context, index string, c *pql return SignedRow{}, err } other, _ := result.(SignedRow) + other.field = field.(string) return other, nil } @@ -3776,12 +3778,18 @@ func needsShards(calls []*pql.Call) bool { // SignedRow represents a signed *Row with two (neg/pos) *Rows. type SignedRow struct { - Neg *Row `json:"neg"` - Pos *Row `json:"pos"` + Neg *Row `json:"neg"` + Pos *Row `json:"pos"` + field string +} + +// Field returns the field name associated to the signed row. +func (s *SignedRow) Field() string { + return s.field } func (sr *SignedRow) union(other SignedRow) SignedRow { - ret := SignedRow{&Row{}, &Row{}} + ret := SignedRow{&Row{}, &Row{}, ""} // merge in sr if sr != nil { diff --git a/server/grpc.go b/server/grpc.go index 81060b6a3..cb1856b9f 100644 --- a/server/grpc.go +++ b/server/grpc.go @@ -573,6 +573,27 @@ func makeRows(resp pilosa.QueryResponse, logger logger.Logger) chan *pb.RowRespo &pb.ColumnResponse{ColumnVal: &pb.ColumnResponse_Int64Val{Int64Val: r.Val}}, &pb.ColumnResponse{ColumnVal: &pb.ColumnResponse_Int64Val{Int64Val: r.Count}}, }} + case pilosa.SignedRow: + // TODO: address the overflow issue with values outside the int64 range + ci := []*pb.ColumnInfo{{Name: r.Field(), Datatype: "int64"}} + negs := r.Neg.Columns() + for i := len(negs) - 1; i >= 0; i-- { + results <- &pb.RowResponse{ + Headers: ci, + Columns: []*pb.ColumnResponse{ + &pb.ColumnResponse{ColumnVal: &pb.ColumnResponse_Int64Val{Int64Val: -1 * int64(negs[i])}}, + }} + ci = nil + } + for _, id := range r.Pos.Columns() { + results <- &pb.RowResponse{ + Headers: ci, + Columns: []*pb.ColumnResponse{ + &pb.ColumnResponse{ColumnVal: &pb.ColumnResponse_Int64Val{Int64Val: int64(id)}}, + }} + ci = nil + } + default: logger.Printf("unhandled %T\n", r) breakLoop = true