// Execute sends the query to VTTablet. func (conn *gRPCQueryClient) Execute(ctx context.Context, query string, bindVars map[string]interface{}, transactionID int64) (*mproto.QueryResult, error) { conn.mu.RLock() defer conn.mu.RUnlock() if conn.cc == nil { return nil, tabletconn.ConnClosed } req := &pb.ExecuteRequest{ Query: tproto.BoundQueryToProto3(query, bindVars), TransactionId: transactionID, SessionId: conn.sessionID, } er, err := conn.c.Execute(ctx, req) if err != nil { return nil, tabletErrorFromGRPC(err) } if er.Error != nil { return nil, tabletErrorFromRPCError(er.Error) } return tproto.Proto3ToQueryResult(er.Result), nil }
// StreamExecute starts a streaming query to VTTablet. func (conn *gRPCQueryClient) StreamExecute(ctx context.Context, query string, bindVars map[string]interface{}, transactionID int64) (<-chan *mproto.QueryResult, tabletconn.ErrFunc, error) { conn.mu.RLock() defer conn.mu.RUnlock() if conn.cc == nil { return nil, nil, tabletconn.ConnClosed } req := &pb.StreamExecuteRequest{ Query: tproto.BoundQueryToProto3(query, bindVars), SessionId: conn.sessionID, } stream, err := conn.c.StreamExecute(ctx, req) if err != nil { return nil, nil, tabletErrorFromGRPC(err) } sr := make(chan *mproto.QueryResult, 10) var finalError error go func() { for { ser, err := stream.Recv() if err != nil { if err != io.EOF { finalError = tabletErrorFromGRPC(err) } close(sr) return } if ser.Error != nil { finalError = tabletErrorFromRPCError(ser.Error) close(sr) return } sr <- tproto.Proto3ToQueryResult(ser.Result) } }() return sr, func() error { return finalError }, nil }