pvt #59075198. GetReferencedColumns returns a map from Value to column names where value can be a regex or a table name.

pull/17/head
John Shahid 2013-10-17 16:46:56 -04:00
parent e006e37b04
commit 488103a4cd
3 changed files with 68 additions and 22 deletions

View File

@ -45,8 +45,8 @@ func (self *Value) IsFunctionCall() bool {
return self.Type == ValueFunctionCall
}
func (self *Value) GetCompiledRegex() *regexp.Regexp {
return self.compiledRegex
func (self *Value) GetCompiledRegex() (*regexp.Regexp, bool) {
return self.compiledRegex, self.Type == ValueRegex
}
type Expression struct {

View File

@ -21,11 +21,24 @@ var (
}
)
func uniq(slice []string) []string {
// TODO: optimize this, maybe ?
uniqueMap := map[string]bool{}
for _, name := range slice {
uniqueMap[name] = true
}
slice = []string{}
for name, _ := range uniqueMap {
slice = append(slice, name)
}
sort.Strings(slice)
return slice
}
// Returns a mapping from the time series names (or regex) to the
// column names that are references
func (self *Query) GetReferencedColumns() (mapping map[string][]string) {
mapping = make(map[string][]string)
mapping[self.GetFromClause().Name] = []string{}
func (self *Query) GetReferencedColumns() map[*Value][]string {
mapping := make(map[string][]string)
notPrefixedColumns := []string{}
for _, value := range self.GetColumnNames() {
@ -40,23 +53,27 @@ func (self *Query) GetReferencedColumns() (mapping map[string][]string) {
notPrefixedColumns = append(notPrefixedColumns, getReferencedColumnsFromValue(groupBy, mapping)...)
}
for name, _ := range mapping {
mapping[name] = append(mapping[name], notPrefixedColumns...)
allNames := map[string]bool{}
for _, column := range mapping[name] {
allNames[column] = true
notPrefixedColumns = uniq(notPrefixedColumns)
returnedMapping := make(map[*Value][]string)
for _, value := range []*Value{self.GetFromClause()} {
if _, ok := value.GetCompiledRegex(); ok {
// this is a regex table, cannot be referenced, only unreferenced
// columns will be attached to regex table names
returnedMapping[value] = notPrefixedColumns
continue
}
mapping[name] = []string{}
for column, _ := range allNames {
mapping[name] = append(mapping[name], column)
}
sort.Strings(mapping[name])
if len(mapping[name]) > 1 && mapping[name][0] == "*" {
mapping[name] = mapping[name][1:]
name := value.Name
returnedMapping[value] = uniq(append(mapping[name], notPrefixedColumns...))
if len(returnedMapping[value]) > 1 && returnedMapping[value][0] == "*" {
returnedMapping[value] = returnedMapping[value][1:]
}
delete(mapping, name)
}
return
return returnedMapping
}
// Returns the start time of the query. Queries can only have

View File

@ -44,7 +44,11 @@ func (self *QueryApiSuite) TestGetReferencedColumns(c *C) {
query, err := ParseQuery(queryStr)
c.Assert(err, IsNil)
columns := query.GetReferencedColumns()
c.Assert(columns, DeepEquals, map[string][]string{"t": []string{"value", "value1", "value2", "value3"}})
c.Assert(columns, HasLen, 1)
for v, columns := range columns {
c.Assert(columns, DeepEquals, []string{"value", "value1", "value2", "value3"})
c.Assert(v.Name, Equals, "t")
}
}
func (self *QueryApiSuite) TestGetReferencedColumnsReturnsTheStarAsAColumn(c *C) {
@ -52,7 +56,11 @@ func (self *QueryApiSuite) TestGetReferencedColumnsReturnsTheStarAsAColumn(c *C)
query, err := ParseQuery(queryStr)
c.Assert(err, IsNil)
columns := query.GetReferencedColumns()
c.Assert(columns, DeepEquals, map[string][]string{"events": []string{"*"}})
c.Assert(columns, HasLen, 1)
for v, columns := range columns {
c.Assert(v.Name, Equals, "events")
c.Assert(columns, DeepEquals, []string{"*"})
}
}
func (self *QueryApiSuite) TestGetReferencedColumnsReturnsEmptyArrayIfQueryIsAggregateStar(c *C) {
@ -60,7 +68,24 @@ func (self *QueryApiSuite) TestGetReferencedColumnsReturnsEmptyArrayIfQueryIsAgg
query, err := ParseQuery(queryStr)
c.Assert(err, IsNil)
columns := query.GetReferencedColumns()
c.Assert(columns, DeepEquals, map[string][]string{"events": []string{}})
c.Assert(columns, HasLen, 1)
for v, columns := range columns {
c.Assert(v.Name, Equals, "events")
c.Assert(columns, DeepEquals, []string{})
}
}
func (self *QueryApiSuite) TestGetReferencedColumnsWithARegexTable(c *C) {
queryStr := "select count(*), region from /events.*/ group by time(1h), region;"
query, err := ParseQuery(queryStr)
c.Assert(err, IsNil)
columns := query.GetReferencedColumns()
c.Assert(columns, HasLen, 1)
for v, columns := range columns {
c.Assert(v.compiledRegex, NotNil)
c.Assert(v.Name, Equals, "events.*")
c.Assert(columns, DeepEquals, []string{"region"})
}
}
func (self *QueryApiSuite) TestGetReferencedColumnsReturnsGroupByColumn(c *C) {
@ -68,7 +93,11 @@ func (self *QueryApiSuite) TestGetReferencedColumnsReturnsGroupByColumn(c *C) {
query, err := ParseQuery(queryStr)
c.Assert(err, IsNil)
columns := query.GetReferencedColumns()
c.Assert(columns, DeepEquals, map[string][]string{"events": []string{"region"}})
c.Assert(columns, HasLen, 1)
for v, columns := range columns {
c.Assert(v.Name, Equals, "events")
c.Assert(columns, DeepEquals, []string{"region"})
}
}
func (self *QueryApiSuite) TestGetStartTimeWithOr(c *C) {