// mustParseStmt parses a single statement or panics. func mustParseStmt(stmt string) influxql.Statement { q, err := influxql.ParseQuery(stmt) if err != nil { panic(err) } else if len(q.Statements) != 1 { panic(fmt.Sprintf("expected 1 statement but got %d", len(q.Statements))) } return q.Statements[0] }
func (s *Service) processMapShardRequest(w io.Writer, buf []byte) error { // Decode request var req MapShardRequest if err := req.UnmarshalBinary(buf); err != nil { return err } // Parse the statement. q, err := influxql.ParseQuery(req.Query()) if err != nil { return fmt.Errorf("processing map shard: %s", err) } else if len(q.Statements) != 1 { return fmt.Errorf("processing map shard: expected 1 statement but got %d", len(q.Statements)) } m, err := s.TSDBStore.CreateMapper(req.ShardID(), q.Statements[0], int(req.ChunkSize())) if err != nil { return fmt.Errorf("create mapper: %s", err) } if m == nil { return writeMapShardResponseMessage(w, NewMapShardResponse(0, "")) } if err := m.Open(); err != nil { return fmt.Errorf("mapper open: %s", err) } defer m.Close() var metaSent bool for { var resp MapShardResponse if !metaSent { resp.SetTagSets(m.TagSets()) resp.SetFields(m.Fields()) metaSent = true } chunk, err := m.NextChunk() if err != nil { return fmt.Errorf("next chunk: %s", err) } // NOTE: Even if the chunk is nil, we still need to send one // empty response to let the other side know we're out of data. if chunk != nil { b, err := json.Marshal(chunk) if err != nil { return fmt.Errorf("encoding: %s", err) } resp.SetData(b) } // Write to connection. resp.SetCode(0) if err := writeMapShardResponseMessage(w, &resp); err != nil { return err } if chunk == nil { // All mapper data sent. return nil } } }