// Return the number of dropped ticks from filtering. if the series // had more than one alias, returns the min of all dropped ticks func (self *LevelDbDatastore) sendBatch(query *parser.Query, series *protocol.Series, yield func(series *protocol.Series) error) (int, error) { dropped := int(math.MaxInt32) for _, alias := range query.GetTableAliases(*series.Name) { _alias := alias newSeries := &protocol.Series{Name: &_alias, Points: series.Points, Fields: series.Fields} lengthBeforeFiltering := len(newSeries.Points) var filteredResult *protocol.Series if query.GetFromClause().Type == parser.FromClauseInnerJoin { filteredResult = newSeries } else { filteredResult, _ = Filter(query, newSeries) } _dropped := lengthBeforeFiltering - len(filteredResult.Points) if _dropped < dropped { dropped = _dropped } if err := yield(filteredResult); err != nil { return 0, err } } return dropped, nil }
func getJoinYield(query *parser.Query, yield func(*protocol.Series) error) func(*protocol.Series) error { var lastPoint1 *protocol.Point var lastFields1 []string var lastPoint2 *protocol.Point var lastFields2 []string table1 := query.GetFromClause().Names[0].GetAlias() table2 := query.GetFromClause().Names[1].GetAlias() name := table1 + "_join_" + table2 return mergeYield(table1, table2, false, query.Ascending, func(s *protocol.Series) error { if *s.Name == table1 { lastPoint1 = s.Points[len(s.Points)-1] if lastFields1 == nil { for _, f := range s.Fields { lastFields1 = append(lastFields1, table1+"."+f) } } } if *s.Name == table2 { lastPoint2 = s.Points[len(s.Points)-1] if lastFields2 == nil { for _, f := range s.Fields { lastFields2 = append(lastFields2, table2+"."+f) } } } if lastPoint1 == nil || lastPoint2 == nil { return nil } newSeries := &protocol.Series{ Name: &name, Fields: append(lastFields1, lastFields2...), Points: []*protocol.Point{ &protocol.Point{ Values: append(lastPoint1.Values, lastPoint2.Values...), Timestamp: lastPoint2.Timestamp, SequenceNumber: lastPoint2.SequenceNumber, }, }, } lastPoint1 = nil lastPoint2 = nil filteredSeries, _ := datastore.Filter(query, newSeries) if len(filteredSeries.Points) > 0 { return yield(newSeries) } return nil }) }
// distribute query and possibly do the merge/join before yielding the points func (self *QueryEngine) distributeQuery(user common.User, database string, query *parser.Query, yield func(*protocol.Series) error) (err error) { // see if this is a merge query fromClause := query.GetFromClause() if fromClause.Type == parser.FromClauseMerge { yield = getMergeYield(fromClause.Names[0].Name.Name, fromClause.Names[1].Name.Name, query.Ascending, yield) } if fromClause.Type == parser.FromClauseInnerJoin { yield = getJoinYield(query, yield) } return self.coordinator.DistributeQuery(user, database, query, yield) }