influxdb/parser/query_spec.go

214 lines
5.4 KiB
Go

package parser
import (
"regexp"
"time"
"github.com/influxdb/influxdb/common"
)
type QuerySpec struct {
query *Query
database string
isRegex bool
regex *regexp.Regexp
names []string
user common.User
startTime time.Time
endTime time.Time
seriesValuesAndColumns map[*Value][]string
RunAgainstAllServersInShard bool
groupByInterval *time.Duration
groupByColumnCount int
}
func NewQuerySpec(user common.User, database string, query *Query) *QuerySpec {
return &QuerySpec{user: user, query: query, database: database}
}
func (self *QuerySpec) AllShardsQuery() bool {
return self.IsDropSeriesQuery()
}
func (self *QuerySpec) GetStartTime() time.Time {
if self.query.SelectQuery != nil {
return self.query.SelectQuery.GetStartTime()
} else if self.query.DeleteQuery != nil {
return self.query.DeleteQuery.GetStartTime()
}
return time.Now()
}
func (self *QuerySpec) GetEndTime() time.Time {
if self.query.SelectQuery != nil {
return self.query.SelectQuery.GetEndTime()
} else if self.query.DeleteQuery != nil {
return self.query.DeleteQuery.GetEndTime()
}
return time.Now()
}
func (self *QuerySpec) Database() string {
return self.database
}
func (self *QuerySpec) User() common.User {
return self.user
}
func (self *QuerySpec) DeleteQuery() *DeleteQuery {
return self.query.DeleteQuery
}
func (self *QuerySpec) TableNames() []string {
names, _ := self.TableNamesAndRegex()
return names
}
func (self *QuerySpec) TableNamesAndRegex() ([]string, *regexp.Regexp) {
if self.names != nil {
return self.names, self.regex
}
if self.query.SelectQuery == nil {
if self.query.DeleteQuery != nil {
self.names = make([]string, 0)
for _, n := range self.query.DeleteQuery.GetFromClause().Names {
self.names = append(self.names, n.Name.Name)
}
} else {
self.names = []string{}
}
return self.names, nil
}
namesAndColumns := self.query.SelectQuery.GetReferencedColumns()
names := make([]string, 0, len(namesAndColumns))
for name := range namesAndColumns {
if r, isRegex := name.GetCompiledRegex(); isRegex {
self.regex = r
self.isRegex = true
} else {
names = append(names, name.Name)
}
}
self.names = names
return names, self.regex
}
func (self *QuerySpec) SeriesValuesAndColumns() map[*Value][]string {
if self.seriesValuesAndColumns != nil {
return self.seriesValuesAndColumns
}
if self.query.SelectQuery != nil {
self.seriesValuesAndColumns = self.query.SelectQuery.GetReferencedColumns()
} else if self.query.DeleteQuery != nil {
self.seriesValuesAndColumns = make(map[*Value][]string)
for _, name := range self.query.DeleteQuery.GetFromClause().Names {
self.seriesValuesAndColumns[name.Name] = nil
}
} else if self.query.DropSeriesQuery != nil {
self.seriesValuesAndColumns = make(map[*Value][]string)
value := &Value{Name: self.query.DropSeriesQuery.GetTableName()}
self.seriesValuesAndColumns[value] = nil
}
return self.seriesValuesAndColumns
}
func (self *QuerySpec) GetFromClause() *FromClause {
if q := self.query.SelectQuery; q != nil {
return q.GetFromClause()
}
return nil
}
func (self *QuerySpec) GetGroupByInterval() *time.Duration {
if self.query.SelectQuery == nil {
return nil
}
if self.groupByInterval == nil {
self.groupByInterval, _ = self.query.SelectQuery.GetGroupByClause().GetGroupByTime()
}
return self.groupByInterval
}
func (self *QuerySpec) GetGroupByColumnCount() int {
if self.query.SelectQuery == nil {
return 0
}
if self.groupByColumnCount == 0 {
self.groupByColumnCount = len(self.query.SelectQuery.GetGroupByClause().Elems) - 1
}
return self.groupByColumnCount
}
func (self *QuerySpec) IsRegex() bool {
self.TableNames()
return self.isRegex
}
func (self *QuerySpec) HasReadAccess(name string) bool {
return self.user.HasReadAccess(name)
}
func (self *QuerySpec) IsSinglePointQuery() bool {
if self.query.SelectQuery != nil {
return self.query.SelectQuery.IsSinglePointQuery()
}
return false
}
func (self *QuerySpec) IsExplainQuery() bool {
if self.query.SelectQuery != nil {
return self.query.SelectQuery.IsExplainQuery()
}
return false
}
func (self *QuerySpec) SelectQuery() *SelectQuery {
return self.query.SelectQuery
}
func (self *QuerySpec) IsListSeriesQuery() bool {
return self.query.IsListSeriesQuery()
}
func (self *QuerySpec) IsDeleteFromSeriesQuery() bool {
return self.query.DeleteQuery != nil
}
func (self *QuerySpec) GetQueryString() string {
return self.query.GetQueryString()
}
func (self *QuerySpec) GetQueryStringWithTimeCondition() string {
return self.query.GetQueryStringWithTimeCondition()
}
func (self *QuerySpec) IsDropSeriesQuery() bool {
return self.query.DropSeriesQuery != nil
}
func (self *QuerySpec) Query() *Query {
return self.query
}
func (self *QuerySpec) IsAscending() bool {
if self.query.SelectQuery != nil {
return self.query.SelectQuery.Ascending
}
return false
}
func (self *QuerySpec) ReadsFromMultipleSeries() bool {
return len(self.SeriesValuesAndColumns()) > 1
}
func (self *QuerySpec) IsDestructiveQuery() bool {
return self.query.DeleteQuery != nil || self.query.DropQuery != nil || self.query.DropSeriesQuery != nil
}
func (self *QuerySpec) HasAggregates() bool {
return self.SelectQuery() != nil && self.SelectQuery().HasAggregates()
}