Don't group TagSets when tag values are identical

Fixes issue #3059
pull/3075/head
Philip O'Toole 2015-06-20 11:18:33 -07:00
parent 7873ccbb20
commit cb7baa6d9e
1 changed files with 36 additions and 24 deletions

View File

@ -469,43 +469,55 @@ func (m *Measurement) TagSets(stmt *influxql.SelectStatement, dimensions []strin
return nil, err return nil, err
} }
// build the tag sets // For every series, get the tag values for the requested tag keys i.e. dimensions. This is the
var tagStrings []string // TagSet for that series. Series with the same TagSet are then grouped together, because for the
// purpose of GROUP BY they are part of the same composite series.
tagSets := make(map[string]*influxql.TagSet) tagSets := make(map[string]*influxql.TagSet)
for id, filter := range filters { for id, filter := range filters {
// get the series and set the tag values for the dimensions we care about
s := m.seriesByID[id] s := m.seriesByID[id]
tags := make([]string, len(dimensions)) tags := make(map[string]string)
for i, dim := range dimensions {
tags[i] = s.Tags[dim] // Build the TagSet for this series.
for _, dim := range dimensions {
tags[dim] = s.Tags[dim]
} }
// marshal it into a string and put this series and its expr into the tagSets map // Convert the TagSet to a string, so it can be added to a map allowing TagSets to be handled
t := strings.Join(tags, "") // as a set.
set, ok := tagSets[t] tagsAsKey := string(marshalTags(tags))
tagSet, ok := tagSets[tagsAsKey]
if !ok { if !ok {
tagStrings = append(tagStrings, t) // This TagSet is new, create a new entry for it.
set = &influxql.TagSet{} tagSet = &influxql.TagSet{}
// set the tags for this set
tagsForSet := make(map[string]string) tagsForSet := make(map[string]string)
for i, dim := range dimensions { for k, v := range tags {
tagsForSet[dim] = tags[i] tagsForSet[k] = v
} }
set.Tags = tagsForSet tagSet.Tags = tagsForSet
set.Key = marshalTags(tagsForSet) tagSet.Key = marshalTags(tagsForSet)
} }
set.AddFilter(m.seriesByID[id].Key, filter)
tagSets[t] = set // Associate the series and filter with the Tagset.
tagSet.AddFilter(m.seriesByID[id].Key, filter)
// Ensure it's back in the map.
tagSets[tagsAsKey] = tagSet
} }
// return the tag sets in sorted order // The TagSets have been created, as a map of TagSets. Just send
a := make([]*influxql.TagSet, 0, len(tagSets)) // the values back as a slice, sorting for consistency.
sort.Strings(tagStrings) sortedTagSetKeys := make([]string, 0, len(tagSets))
for _, s := range tagStrings { for k, _ := range tagSets {
a = append(a, tagSets[s]) sortedTagSetKeys = append(sortedTagSetKeys, k)
}
sort.Strings(sortedTagSetKeys)
sortedTagsSets := make([]*influxql.TagSet, 0, len(sortedTagSetKeys))
for _, k := range sortedTagSetKeys {
sortedTagsSets = append(sortedTagsSets, tagSets[k])
} }
return a, nil return sortedTagsSets, nil
} }
// mergeSeriesFilters merges two sets of filter expressions and culls series IDs. // mergeSeriesFilters merges two sets of filter expressions and culls series IDs.