/vendor/github.com/influxdb/influxdb/influxql/ast.go
https://gitlab.com/github-cloud-corporation/bootkube · Go · 1743 lines · 1216 code · 250 blank · 277 comment · 232 complexity · b102a21efe61014f0ee1bca4913cbfa2 MD5 · raw file
- package influxql
- import (
- "bytes"
- "errors"
- "fmt"
- "regexp"
- "sort"
- "strconv"
- "strings"
- "time"
- )
- // DataType represents the primitive data types available in InfluxQL.
- type DataType int
- const (
- // Unknown primitive data type.
- Unknown DataType = 0
- // Float means the data type is a float
- Float = 1
- // Integer means the data type is a integer
- Integer = 2
- // Boolean means the data type is a boolean.
- Boolean = 3
- // String means the data type is a string of text.
- String = 4
- // Time means the data type is a time.
- Time = 5
- // Duration means the data type is a duration of time.
- Duration = 6
- )
- // InspectDataType returns the data type of a given value.
- func InspectDataType(v interface{}) DataType {
- switch v.(type) {
- case float64:
- return Float
- case int64, int32, int:
- return Integer
- case bool:
- return Boolean
- case string:
- return String
- case time.Time:
- return Time
- case time.Duration:
- return Duration
- default:
- return Unknown
- }
- }
- func (d DataType) String() string {
- switch d {
- case Float:
- return "float"
- case Integer:
- return "integer"
- case Boolean:
- return "boolean"
- case String:
- return "string"
- case Time:
- return "time"
- case Duration:
- return "duration"
- }
- return "unknown"
- }
- // Node represents a node in the InfluxDB abstract syntax tree.
- type Node interface {
- node()
- String() string
- }
- func (*Query) node() {}
- func (Statements) node() {}
- func (*AlterRetentionPolicyStatement) node() {}
- func (*CreateContinuousQueryStatement) node() {}
- func (*CreateDatabaseStatement) node() {}
- func (*CreateRetentionPolicyStatement) node() {}
- func (*CreateUserStatement) node() {}
- func (*Distinct) node() {}
- func (*DeleteStatement) node() {}
- func (*DropContinuousQueryStatement) node() {}
- func (*DropDatabaseStatement) node() {}
- func (*DropMeasurementStatement) node() {}
- func (*DropRetentionPolicyStatement) node() {}
- func (*DropSeriesStatement) node() {}
- func (*DropUserStatement) node() {}
- func (*GrantStatement) node() {}
- func (*GrantAdminStatement) node() {}
- func (*RevokeStatement) node() {}
- func (*RevokeAdminStatement) node() {}
- func (*SelectStatement) node() {}
- func (*SetPasswordUserStatement) node() {}
- func (*ShowContinuousQueriesStatement) node() {}
- func (*ShowGrantsForUserStatement) node() {}
- func (*ShowServersStatement) node() {}
- func (*ShowDatabasesStatement) node() {}
- func (*ShowFieldKeysStatement) node() {}
- func (*ShowRetentionPoliciesStatement) node() {}
- func (*ShowMeasurementsStatement) node() {}
- func (*ShowSeriesStatement) node() {}
- func (*ShowStatsStatement) node() {}
- func (*ShowDiagnosticsStatement) node() {}
- func (*ShowTagKeysStatement) node() {}
- func (*ShowTagValuesStatement) node() {}
- func (*ShowUsersStatement) node() {}
- func (*BinaryExpr) node() {}
- func (*BooleanLiteral) node() {}
- func (*Call) node() {}
- func (*Dimension) node() {}
- func (Dimensions) node() {}
- func (*DurationLiteral) node() {}
- func (*Field) node() {}
- func (Fields) node() {}
- func (*Measurement) node() {}
- func (Measurements) node() {}
- func (*nilLiteral) node() {}
- func (*NumberLiteral) node() {}
- func (*ParenExpr) node() {}
- func (*RegexLiteral) node() {}
- func (*SortField) node() {}
- func (SortFields) node() {}
- func (Sources) node() {}
- func (*StringLiteral) node() {}
- func (*Target) node() {}
- func (*TimeLiteral) node() {}
- func (*VarRef) node() {}
- func (*Wildcard) node() {}
- // Query represents a collection of ordered statements.
- type Query struct {
- Statements Statements
- }
- // String returns a string representation of the query.
- func (q *Query) String() string { return q.Statements.String() }
- // Statements represents a list of statements.
- type Statements []Statement
- // String returns a string representation of the statements.
- func (a Statements) String() string {
- var str []string
- for _, stmt := range a {
- str = append(str, stmt.String())
- }
- return strings.Join(str, ";\n")
- }
- // Statement represents a single command in InfluxQL.
- type Statement interface {
- Node
- stmt()
- RequiredPrivileges() ExecutionPrivileges
- }
- // HasDefaultDatabase provides an interface to get the default database from a Statement.
- type HasDefaultDatabase interface {
- Node
- stmt()
- DefaultDatabase() string
- }
- // ExecutionPrivilege is a privilege required for a user to execute
- // a statement on a database or resource.
- type ExecutionPrivilege struct {
- // Admin privilege required.
- Admin bool
- // Name of the database.
- Name string
- // Database privilege required.
- Privilege Privilege
- }
- // ExecutionPrivileges is a list of privileges required to execute a statement.
- type ExecutionPrivileges []ExecutionPrivilege
- func (*AlterRetentionPolicyStatement) stmt() {}
- func (*CreateContinuousQueryStatement) stmt() {}
- func (*CreateDatabaseStatement) stmt() {}
- func (*CreateRetentionPolicyStatement) stmt() {}
- func (*CreateUserStatement) stmt() {}
- func (*DeleteStatement) stmt() {}
- func (*DropContinuousQueryStatement) stmt() {}
- func (*DropDatabaseStatement) stmt() {}
- func (*DropMeasurementStatement) stmt() {}
- func (*DropRetentionPolicyStatement) stmt() {}
- func (*DropSeriesStatement) stmt() {}
- func (*DropUserStatement) stmt() {}
- func (*GrantStatement) stmt() {}
- func (*GrantAdminStatement) stmt() {}
- func (*ShowContinuousQueriesStatement) stmt() {}
- func (*ShowGrantsForUserStatement) stmt() {}
- func (*ShowServersStatement) stmt() {}
- func (*ShowDatabasesStatement) stmt() {}
- func (*ShowFieldKeysStatement) stmt() {}
- func (*ShowMeasurementsStatement) stmt() {}
- func (*ShowRetentionPoliciesStatement) stmt() {}
- func (*ShowSeriesStatement) stmt() {}
- func (*ShowStatsStatement) stmt() {}
- func (*ShowDiagnosticsStatement) stmt() {}
- func (*ShowTagKeysStatement) stmt() {}
- func (*ShowTagValuesStatement) stmt() {}
- func (*ShowUsersStatement) stmt() {}
- func (*RevokeStatement) stmt() {}
- func (*RevokeAdminStatement) stmt() {}
- func (*SelectStatement) stmt() {}
- func (*SetPasswordUserStatement) stmt() {}
- // Expr represents an expression that can be evaluated to a value.
- type Expr interface {
- Node
- expr()
- }
- func (*BinaryExpr) expr() {}
- func (*BooleanLiteral) expr() {}
- func (*Call) expr() {}
- func (*Distinct) expr() {}
- func (*DurationLiteral) expr() {}
- func (*nilLiteral) expr() {}
- func (*NumberLiteral) expr() {}
- func (*ParenExpr) expr() {}
- func (*RegexLiteral) expr() {}
- func (*StringLiteral) expr() {}
- func (*TimeLiteral) expr() {}
- func (*VarRef) expr() {}
- func (*Wildcard) expr() {}
- // Source represents a source of data for a statement.
- type Source interface {
- Node
- source()
- }
- func (*Measurement) source() {}
- // Sources represents a list of sources.
- type Sources []Source
- // String returns a string representation of a Sources array.
- func (a Sources) String() string {
- var buf bytes.Buffer
- ubound := len(a) - 1
- for i, src := range a {
- _, _ = buf.WriteString(src.String())
- if i < ubound {
- _, _ = buf.WriteString(", ")
- }
- }
- return buf.String()
- }
- // SortField represents a field to sort results by.
- type SortField struct {
- // Name of the field
- Name string
- // Sort order.
- Ascending bool
- }
- // String returns a string representation of a sort field
- func (field *SortField) String() string {
- var buf bytes.Buffer
- if field.Name == "" {
- _, _ = buf.WriteString(field.Name)
- _, _ = buf.WriteString(" ")
- }
- if field.Ascending {
- _, _ = buf.WriteString("ASC")
- } else {
- _, _ = buf.WriteString("DESC")
- }
- return buf.String()
- }
- // SortFields represents an ordered list of ORDER BY fields
- type SortFields []*SortField
- // String returns a string representation of sort fields
- func (a SortFields) String() string {
- fields := make([]string, 0, len(a))
- for _, field := range a {
- fields = append(fields, field.String())
- }
- return strings.Join(fields, ", ")
- }
- // CreateDatabaseStatement represents a command for creating a new database.
- type CreateDatabaseStatement struct {
- // Name of the database to be created.
- Name string
- }
- // String returns a string representation of the create database statement.
- func (s *CreateDatabaseStatement) String() string {
- var buf bytes.Buffer
- _, _ = buf.WriteString("CREATE DATABASE ")
- _, _ = buf.WriteString(s.Name)
- return buf.String()
- }
- // RequiredPrivileges returns the privilege required to execute a CreateDatabaseStatement.
- func (s *CreateDatabaseStatement) RequiredPrivileges() ExecutionPrivileges {
- return ExecutionPrivileges{{Admin: true, Name: "", Privilege: AllPrivileges}}
- }
- // DropDatabaseStatement represents a command to drop a database.
- type DropDatabaseStatement struct {
- // Name of the database to be dropped.
- Name string
- }
- // String returns a string representation of the drop database statement.
- func (s *DropDatabaseStatement) String() string {
- var buf bytes.Buffer
- _, _ = buf.WriteString("DROP DATABASE ")
- _, _ = buf.WriteString(s.Name)
- return buf.String()
- }
- // RequiredPrivileges returns the privilege required to execute a DropDatabaseStatement.
- func (s *DropDatabaseStatement) RequiredPrivileges() ExecutionPrivileges {
- return ExecutionPrivileges{{Admin: true, Name: "", Privilege: AllPrivileges}}
- }
- // DropRetentionPolicyStatement represents a command to drop a retention policy from a database.
- type DropRetentionPolicyStatement struct {
- // Name of the policy to drop.
- Name string
- // Name of the database to drop the policy from.
- Database string
- }
- // String returns a string representation of the drop retention policy statement.
- func (s *DropRetentionPolicyStatement) String() string {
- var buf bytes.Buffer
- _, _ = buf.WriteString("DROP RETENTION POLICY ")
- _, _ = buf.WriteString(s.Name)
- _, _ = buf.WriteString(" ON ")
- _, _ = buf.WriteString(s.Database)
- return buf.String()
- }
- // RequiredPrivileges returns the privilege required to execute a DropRetentionPolicyStatement.
- func (s *DropRetentionPolicyStatement) RequiredPrivileges() ExecutionPrivileges {
- return ExecutionPrivileges{{Admin: false, Name: s.Database, Privilege: WritePrivilege}}
- }
- // CreateUserStatement represents a command for creating a new user.
- type CreateUserStatement struct {
- // Name of the user to be created.
- Name string
- // User's password.
- Password string
- // User's admin privilege.
- Admin bool
- }
- // String returns a string representation of the create user statement.
- func (s *CreateUserStatement) String() string {
- var buf bytes.Buffer
- _, _ = buf.WriteString("CREATE USER ")
- _, _ = buf.WriteString(s.Name)
- _, _ = buf.WriteString(" WITH PASSWORD ")
- _, _ = buf.WriteString("[REDACTED]")
- if s.Admin {
- _, _ = buf.WriteString(" WITH ALL PRIVILEGES")
- }
- return buf.String()
- }
- // RequiredPrivileges returns the privilege(s) required to execute a CreateUserStatement.
- func (s *CreateUserStatement) RequiredPrivileges() ExecutionPrivileges {
- return ExecutionPrivileges{{Admin: true, Name: "", Privilege: AllPrivileges}}
- }
- // DropUserStatement represents a command for dropping a user.
- type DropUserStatement struct {
- // Name of the user to drop.
- Name string
- }
- // String returns a string representation of the drop user statement.
- func (s *DropUserStatement) String() string {
- var buf bytes.Buffer
- _, _ = buf.WriteString("DROP USER ")
- _, _ = buf.WriteString(s.Name)
- return buf.String()
- }
- // RequiredPrivileges returns the privilege(s) required to execute a DropUserStatement.
- func (s *DropUserStatement) RequiredPrivileges() ExecutionPrivileges {
- return ExecutionPrivileges{{Admin: true, Name: "", Privilege: AllPrivileges}}
- }
- // Privilege is a type of action a user can be granted the right to use.
- type Privilege int
- const (
- // NoPrivileges means no privileges required / granted / revoked.
- NoPrivileges Privilege = iota
- // ReadPrivilege means read privilege required / granted / revoked.
- ReadPrivilege
- // WritePrivilege means write privilege required / granted / revoked.
- WritePrivilege
- // AllPrivileges means all privileges required / granted / revoked.
- AllPrivileges
- )
- // NewPrivilege returns an initialized *Privilege.
- func NewPrivilege(p Privilege) *Privilege { return &p }
- // String returns a string representation of a Privilege.
- func (p Privilege) String() string {
- switch p {
- case NoPrivileges:
- return "NO PRIVILEGES"
- case ReadPrivilege:
- return "READ"
- case WritePrivilege:
- return "WRITE"
- case AllPrivileges:
- return "ALL PRIVILEGES"
- }
- return ""
- }
- // GrantStatement represents a command for granting a privilege.
- type GrantStatement struct {
- // The privilege to be granted.
- Privilege Privilege
- // Database to grant the privilege to.
- On string
- // Who to grant the privilege to.
- User string
- }
- // String returns a string representation of the grant statement.
- func (s *GrantStatement) String() string {
- var buf bytes.Buffer
- _, _ = buf.WriteString("GRANT ")
- _, _ = buf.WriteString(s.Privilege.String())
- _, _ = buf.WriteString(" ON ")
- _, _ = buf.WriteString(s.On)
- _, _ = buf.WriteString(" TO ")
- _, _ = buf.WriteString(s.User)
- return buf.String()
- }
- // RequiredPrivileges returns the privilege required to execute a GrantStatement.
- func (s *GrantStatement) RequiredPrivileges() ExecutionPrivileges {
- return ExecutionPrivileges{{Admin: true, Name: "", Privilege: AllPrivileges}}
- }
- // GrantAdminStatement represents a command for granting admin privilege.
- type GrantAdminStatement struct {
- // Who to grant the privilege to.
- User string
- }
- // String returns a string representation of the grant admin statement.
- func (s *GrantAdminStatement) String() string {
- var buf bytes.Buffer
- _, _ = buf.WriteString("GRANT ALL PRIVILEGES TO ")
- _, _ = buf.WriteString(s.User)
- return buf.String()
- }
- // RequiredPrivileges returns the privilege required to execute a GrantAdminStatement.
- func (s *GrantAdminStatement) RequiredPrivileges() ExecutionPrivileges {
- return ExecutionPrivileges{{Admin: true, Name: "", Privilege: AllPrivileges}}
- }
- // SetPasswordUserStatement represents a command for changing user password.
- type SetPasswordUserStatement struct {
- // Plain Password
- Password string
- // Who to grant the privilege to.
- Name string
- }
- // String returns a string representation of the set password statement.
- func (s *SetPasswordUserStatement) String() string {
- var buf bytes.Buffer
- _, _ = buf.WriteString("SET PASSWORD FOR ")
- _, _ = buf.WriteString(s.Name)
- _, _ = buf.WriteString(" = ")
- _, _ = buf.WriteString("[REDACTED]")
- return buf.String()
- }
- // RequiredPrivileges returns the privilege required to execute a SetPasswordUserStatement.
- func (s *SetPasswordUserStatement) RequiredPrivileges() ExecutionPrivileges {
- return ExecutionPrivileges{{Admin: true, Name: "", Privilege: AllPrivileges}}
- }
- // RevokeStatement represents a command to revoke a privilege from a user.
- type RevokeStatement struct {
- // The privilege to be revoked.
- Privilege Privilege
- // Database to revoke the privilege from.
- On string
- // Who to revoke privilege from.
- User string
- }
- // String returns a string representation of the revoke statement.
- func (s *RevokeStatement) String() string {
- var buf bytes.Buffer
- _, _ = buf.WriteString("REVOKE ")
- _, _ = buf.WriteString(s.Privilege.String())
- _, _ = buf.WriteString(" ON ")
- _, _ = buf.WriteString(s.On)
- _, _ = buf.WriteString(" FROM ")
- _, _ = buf.WriteString(s.User)
- return buf.String()
- }
- // RequiredPrivileges returns the privilege required to execute a RevokeStatement.
- func (s *RevokeStatement) RequiredPrivileges() ExecutionPrivileges {
- return ExecutionPrivileges{{Admin: true, Name: "", Privilege: AllPrivileges}}
- }
- // RevokeAdminStatement represents a command to revoke admin privilege from a user.
- type RevokeAdminStatement struct {
- // Who to revoke admin privilege from.
- User string
- }
- // String returns a string representation of the revoke admin statement.
- func (s *RevokeAdminStatement) String() string {
- var buf bytes.Buffer
- _, _ = buf.WriteString("REVOKE ALL PRIVILEGES FROM ")
- _, _ = buf.WriteString(s.User)
- return buf.String()
- }
- // RequiredPrivileges returns the privilege required to execute a RevokeAdminStatement.
- func (s *RevokeAdminStatement) RequiredPrivileges() ExecutionPrivileges {
- return ExecutionPrivileges{{Admin: true, Name: "", Privilege: AllPrivileges}}
- }
- // CreateRetentionPolicyStatement represents a command to create a retention policy.
- type CreateRetentionPolicyStatement struct {
- // Name of policy to create.
- Name string
- // Name of database this policy belongs to.
- Database string
- // Duration data written to this policy will be retained.
- Duration time.Duration
- // Replication factor for data written to this policy.
- Replication int
- // Should this policy be set as default for the database?
- Default bool
- }
- // String returns a string representation of the create retention policy.
- func (s *CreateRetentionPolicyStatement) String() string {
- var buf bytes.Buffer
- _, _ = buf.WriteString("CREATE RETENTION POLICY ")
- _, _ = buf.WriteString(s.Name)
- _, _ = buf.WriteString(" ON ")
- _, _ = buf.WriteString(s.Database)
- _, _ = buf.WriteString(" DURATION ")
- _, _ = buf.WriteString(FormatDuration(s.Duration))
- _, _ = buf.WriteString(" REPLICATION ")
- _, _ = buf.WriteString(strconv.Itoa(s.Replication))
- if s.Default {
- _, _ = buf.WriteString(" DEFAULT")
- }
- return buf.String()
- }
- // RequiredPrivileges returns the privilege required to execute a CreateRetentionPolicyStatement.
- func (s *CreateRetentionPolicyStatement) RequiredPrivileges() ExecutionPrivileges {
- return ExecutionPrivileges{{Admin: true, Name: "", Privilege: AllPrivileges}}
- }
- // AlterRetentionPolicyStatement represents a command to alter an existing retention policy.
- type AlterRetentionPolicyStatement struct {
- // Name of policy to alter.
- Name string
- // Name of the database this policy belongs to.
- Database string
- // Duration data written to this policy will be retained.
- Duration *time.Duration
- // Replication factor for data written to this policy.
- Replication *int
- // Should this policy be set as defalut for the database?
- Default bool
- }
- // String returns a string representation of the alter retention policy statement.
- func (s *AlterRetentionPolicyStatement) String() string {
- var buf bytes.Buffer
- _, _ = buf.WriteString("ALTER RETENTION POLICY ")
- _, _ = buf.WriteString(s.Name)
- _, _ = buf.WriteString(" ON ")
- _, _ = buf.WriteString(s.Database)
- if s.Duration != nil {
- _, _ = buf.WriteString(" DURATION ")
- _, _ = buf.WriteString(FormatDuration(*s.Duration))
- }
- if s.Replication != nil {
- _, _ = buf.WriteString(" REPLICATION ")
- _, _ = buf.WriteString(strconv.Itoa(*s.Replication))
- }
- if s.Default {
- _, _ = buf.WriteString(" DEFAULT")
- }
- return buf.String()
- }
- // RequiredPrivileges returns the privilege required to execute an AlterRetentionPolicyStatement.
- func (s *AlterRetentionPolicyStatement) RequiredPrivileges() ExecutionPrivileges {
- return ExecutionPrivileges{{Admin: true, Name: "", Privilege: AllPrivileges}}
- }
- type FillOption int
- const (
- // NullFill means that empty aggregate windows will just have null values.
- NullFill FillOption = iota
- // NoFill means that empty aggregate windows will be purged from the result.
- NoFill
- // NumberFill means that empty aggregate windows will be filled with the given number
- NumberFill
- // PreviousFill means that empty aggregate windows will be filled with whatever the previous aggregate window had
- PreviousFill
- )
- // SelectStatement represents a command for extracting data from the database.
- type SelectStatement struct {
- // Expressions returned from the selection.
- Fields Fields
- // Target (destination) for the result of the select.
- Target *Target
- // Expressions used for grouping the selection.
- Dimensions Dimensions
- // Data sources that fields are extracted from.
- Sources Sources
- // An expression evaluated on data point.
- Condition Expr
- // Fields to sort results by
- SortFields SortFields
- // Maximum number of rows to be returned. Unlimited if zero.
- Limit int
- // Returns rows starting at an offset from the first row.
- Offset int
- // Maxiumum number of series to be returned. Unlimited if zero.
- SLimit int
- // Returns series starting at an offset from the first one.
- SOffset int
- // memoize the group by interval
- groupByInterval time.Duration
- // if it's a query for raw data values (i.e. not an aggregate)
- IsRawQuery bool
- // What fill option the select statement uses, if any
- Fill FillOption
- // The value to fill empty aggregate buckets with, if any
- FillValue interface{}
- }
- // HasDerivative returns true if one of the function calls in the statement is a
- // derivative aggregate
- func (s *SelectStatement) HasDerivative() bool {
- for _, f := range s.FunctionCalls() {
- if strings.HasSuffix(f.Name, "derivative") {
- return true
- }
- }
- return false
- }
- // IsSimpleDerivative return true if one of the function call is a derivative function with a
- // variable ref as the first arg
- func (s *SelectStatement) IsSimpleDerivative() bool {
- for _, f := range s.FunctionCalls() {
- if strings.HasSuffix(f.Name, "derivative") {
- // it's nested if the first argument is an aggregate function
- if _, ok := f.Args[0].(*VarRef); ok {
- return true
- }
- }
- }
- return false
- }
- // Clone returns a deep copy of the statement.
- func (s *SelectStatement) Clone() *SelectStatement {
- clone := &SelectStatement{
- Fields: make(Fields, 0, len(s.Fields)),
- Dimensions: make(Dimensions, 0, len(s.Dimensions)),
- Sources: cloneSources(s.Sources),
- SortFields: make(SortFields, 0, len(s.SortFields)),
- Condition: CloneExpr(s.Condition),
- Limit: s.Limit,
- Offset: s.Offset,
- SLimit: s.SLimit,
- SOffset: s.SOffset,
- Fill: s.Fill,
- FillValue: s.FillValue,
- IsRawQuery: s.IsRawQuery,
- }
- if s.Target != nil {
- clone.Target = &Target{
- Measurement: &Measurement{
- Database: s.Target.Measurement.Database,
- RetentionPolicy: s.Target.Measurement.RetentionPolicy,
- Name: s.Target.Measurement.Name,
- Regex: CloneRegexLiteral(s.Target.Measurement.Regex),
- },
- }
- }
- for _, f := range s.Fields {
- clone.Fields = append(clone.Fields, &Field{Expr: CloneExpr(f.Expr), Alias: f.Alias})
- }
- for _, d := range s.Dimensions {
- clone.Dimensions = append(clone.Dimensions, &Dimension{Expr: CloneExpr(d.Expr)})
- }
- for _, f := range s.SortFields {
- clone.SortFields = append(clone.SortFields, &SortField{Name: f.Name, Ascending: f.Ascending})
- }
- return clone
- }
- func cloneSources(sources Sources) Sources {
- clone := make(Sources, 0, len(sources))
- for _, s := range sources {
- clone = append(clone, cloneSource(s))
- }
- return clone
- }
- func cloneSource(s Source) Source {
- if s == nil {
- return nil
- }
- switch s := s.(type) {
- case *Measurement:
- m := &Measurement{Database: s.Database, RetentionPolicy: s.RetentionPolicy, Name: s.Name}
- if s.Regex != nil {
- m.Regex = &RegexLiteral{Val: regexp.MustCompile(s.Regex.Val.String())}
- }
- return m
- default:
- panic("unreachable")
- }
- }
- // RewriteWildcards returns the re-written form of the select statement. Any wildcard query
- // fields are replaced with the supplied fields, and any wildcard GROUP BY fields are replaced
- // with the supplied dimensions.
- func (s *SelectStatement) RewriteWildcards(fields Fields, dimensions Dimensions) *SelectStatement {
- other := s.Clone()
- selectWildcard, groupWildcard := false, false
- // Rewrite all wildcard query fields
- rwFields := make(Fields, 0, len(s.Fields))
- for _, f := range s.Fields {
- switch f.Expr.(type) {
- case *Wildcard:
- // Sort wildcard fields for consistent output
- sort.Sort(fields)
- rwFields = append(rwFields, fields...)
- selectWildcard = true
- default:
- rwFields = append(rwFields, f)
- }
- }
- other.Fields = rwFields
- // Rewrite all wildcard GROUP BY fields
- rwDimensions := make(Dimensions, 0, len(s.Dimensions))
- for _, d := range s.Dimensions {
- switch d.Expr.(type) {
- case *Wildcard:
- rwDimensions = append(rwDimensions, dimensions...)
- groupWildcard = true
- default:
- rwDimensions = append(rwDimensions, d)
- }
- }
- if selectWildcard && !groupWildcard {
- rwDimensions = append(rwDimensions, dimensions...)
- }
- other.Dimensions = rwDimensions
- return other
- }
- // RewriteDistinct rewrites the expression to be a call for map/reduce to work correctly
- // This method assumes all validation has passed
- func (s *SelectStatement) RewriteDistinct() {
- for i, f := range s.Fields {
- if d, ok := f.Expr.(*Distinct); ok {
- s.Fields[i].Expr = d.NewCall()
- s.IsRawQuery = false
- }
- }
- }
- // String returns a string representation of the select statement.
- func (s *SelectStatement) String() string {
- var buf bytes.Buffer
- _, _ = buf.WriteString("SELECT ")
- _, _ = buf.WriteString(s.Fields.String())
- if s.Target != nil {
- _, _ = buf.WriteString(" ")
- _, _ = buf.WriteString(s.Target.String())
- }
- if len(s.Sources) > 0 {
- _, _ = buf.WriteString(" FROM ")
- _, _ = buf.WriteString(s.Sources.String())
- }
- if s.Condition != nil {
- _, _ = buf.WriteString(" WHERE ")
- _, _ = buf.WriteString(s.Condition.String())
- }
- if len(s.Dimensions) > 0 {
- _, _ = buf.WriteString(" GROUP BY ")
- _, _ = buf.WriteString(s.Dimensions.String())
- }
- switch s.Fill {
- case NoFill:
- _, _ = buf.WriteString(" fill(none)")
- case NumberFill:
- _, _ = buf.WriteString(fmt.Sprintf(" fill(%v)", s.FillValue))
- case PreviousFill:
- _, _ = buf.WriteString(" fill(previous)")
- }
- if len(s.SortFields) > 0 {
- _, _ = buf.WriteString(" ORDER BY ")
- _, _ = buf.WriteString(s.SortFields.String())
- }
- if s.Limit > 0 {
- _, _ = fmt.Fprintf(&buf, " LIMIT %d", s.Limit)
- }
- if s.Offset > 0 {
- _, _ = buf.WriteString(" OFFSET ")
- _, _ = buf.WriteString(strconv.Itoa(s.Offset))
- }
- if s.SLimit > 0 {
- _, _ = fmt.Fprintf(&buf, " SLIMIT %d", s.SLimit)
- }
- if s.SOffset > 0 {
- _, _ = fmt.Fprintf(&buf, " SOFFSET %d", s.SOffset)
- }
- return buf.String()
- }
- // RequiredPrivileges returns the privilege required to execute the SelectStatement.
- func (s *SelectStatement) RequiredPrivileges() ExecutionPrivileges {
- ep := ExecutionPrivileges{{Admin: false, Name: "", Privilege: ReadPrivilege}}
- if s.Target != nil {
- p := ExecutionPrivilege{Admin: false, Name: s.Target.Measurement.Database, Privilege: WritePrivilege}
- ep = append(ep, p)
- }
- return ep
- }
- // OnlyTimeDimensions returns true if the statement has a where clause with only time constraints
- func (s *SelectStatement) OnlyTimeDimensions() bool {
- return s.walkForTime(s.Condition)
- }
- // walkForTime is called by the OnlyTimeDimensions method to walk the where clause to determine if
- // the only things specified are based on time
- func (s *SelectStatement) walkForTime(node Node) bool {
- switch n := node.(type) {
- case *BinaryExpr:
- if n.Op == AND || n.Op == OR {
- return s.walkForTime(n.LHS) && s.walkForTime(n.RHS)
- }
- if ref, ok := n.LHS.(*VarRef); ok && strings.ToLower(ref.Val) == "time" {
- return true
- }
- return false
- case *ParenExpr:
- // walk down the tree
- return s.walkForTime(n.Expr)
- default:
- return false
- }
- }
- // HasWildcard returns whether or not the select statement has at least 1 wildcard
- func (s *SelectStatement) HasWildcard() bool {
- for _, f := range s.Fields {
- _, ok := f.Expr.(*Wildcard)
- if ok {
- return true
- }
- }
- for _, d := range s.Dimensions {
- _, ok := d.Expr.(*Wildcard)
- if ok {
- return true
- }
- }
- return false
- }
- // hasTimeDimensions returns whether or not the select statement has at least 1
- // where condition with time as the condition
- func (s *SelectStatement) hasTimeDimensions(node Node) bool {
- switch n := node.(type) {
- case *BinaryExpr:
- if n.Op == AND || n.Op == OR {
- return s.hasTimeDimensions(n.LHS) || s.hasTimeDimensions(n.RHS)
- }
- if ref, ok := n.LHS.(*VarRef); ok && strings.ToLower(ref.Val) == "time" {
- return true
- }
- return false
- case *ParenExpr:
- // walk down the tree
- return s.hasTimeDimensions(n.Expr)
- default:
- return false
- }
- }
- func (s *SelectStatement) validate(tr targetRequirement) error {
- if err := s.validateDistinct(); err != nil {
- return err
- }
- if err := s.validateCountDistinct(); err != nil {
- return err
- }
- if err := s.validateAggregates(tr); err != nil {
- return err
- }
- if err := s.validateDerivative(); err != nil {
- return err
- }
- return nil
- }
- func (s *SelectStatement) validateAggregates(tr targetRequirement) error {
- // First, determine if specific calls have at least one and only one argument
- for _, f := range s.Fields {
- if c, ok := f.Expr.(*Call); ok {
- switch c.Name {
- case "derivative", "non_negative_derivative":
- if min, max, got := 1, 2, len(c.Args); got > max || got < min {
- return fmt.Errorf("invalid number of arguments for %s, expected at least %d but no more than %d, got %d", c.Name, min, max, got)
- }
- case "percentile":
- if exp, got := 2, len(c.Args); got != exp {
- return fmt.Errorf("invalid number of arguments for %s, expected %d, got %d", c.Name, exp, got)
- }
- default:
- if exp, got := 1, len(c.Args); got != exp {
- return fmt.Errorf("invalid number of arguments for %s, expected %d, got %d", c.Name, exp, got)
- }
- }
- }
- }
- // Now, check that we have valid duration and where clauses for aggregates
- // fetch the group by duration
- groupByDuration, _ := s.GroupByInterval()
- // If we have a group by interval, but no aggregate function, it's an invalid statement
- if s.IsRawQuery && groupByDuration > 0 {
- return fmt.Errorf("GROUP BY requires at least one aggregate function")
- }
- // If we have an aggregate function with a group by time without a where clause, it's an invalid statement
- if tr == targetNotRequired { // ignore create continuous query statements
- if !s.IsRawQuery && groupByDuration > 0 && !s.hasTimeDimensions(s.Condition) {
- return fmt.Errorf("aggregate functions with GROUP BY time require a WHERE time clause")
- }
- }
- return nil
- }
- func (s *SelectStatement) HasDistinct() bool {
- // determine if we have a call named distinct
- for _, f := range s.Fields {
- switch c := f.Expr.(type) {
- case *Call:
- if c.Name == "distinct" {
- return true
- }
- case *Distinct:
- return true
- }
- }
- return false
- }
- func (s *SelectStatement) validateDistinct() error {
- if !s.HasDistinct() {
- return nil
- }
- if len(s.Fields) > 1 {
- return fmt.Errorf("aggregate function distinct() can not be combined with other functions or fields")
- }
- switch c := s.Fields[0].Expr.(type) {
- case *Call:
- if len(c.Args) == 0 {
- return fmt.Errorf("distinct function requires at least one argument")
- }
- if len(c.Args) != 1 {
- return fmt.Errorf("distinct function can only have one argument")
- }
- }
- return nil
- }
- func (s *SelectStatement) HasCountDistinct() bool {
- for _, f := range s.Fields {
- if c, ok := f.Expr.(*Call); ok {
- if c.Name == "count" {
- for _, a := range c.Args {
- if _, ok := a.(*Distinct); ok {
- return true
- }
- if c, ok := a.(*Call); ok {
- if c.Name == "distinct" {
- return true
- }
- }
- }
- }
- }
- }
- return false
- }
- func (s *SelectStatement) validateCountDistinct() error {
- if !s.HasCountDistinct() {
- return nil
- }
- valid := func(e Expr) bool {
- c, ok := e.(*Call)
- if !ok {
- return true
- }
- if c.Name != "count" {
- return true
- }
- for _, a := range c.Args {
- if _, ok := a.(*Distinct); ok {
- return len(c.Args) == 1
- }
- if d, ok := a.(*Call); ok {
- if d.Name == "distinct" {
- return len(d.Args) == 1
- }
- }
- }
- return true
- }
- for _, f := range s.Fields {
- if !valid(f.Expr) {
- return fmt.Errorf("count(distinct <field>) can only have one argument")
- }
- }
- return nil
- }
- func (s *SelectStatement) validateDerivative() error {
- if !s.HasDerivative() {
- return nil
- }
- // If a derivative is requested, it must be the only field in the query. We don't support
- // multiple fields in combination w/ derivaties yet.
- if len(s.Fields) != 1 {
- return fmt.Errorf("derivative cannot be used with other fields")
- }
- aggr := s.FunctionCalls()
- if len(aggr) != 1 {
- return fmt.Errorf("derivative cannot be used with other fields")
- }
- // Derivative requires two arguments
- derivativeCall := aggr[0]
- if len(derivativeCall.Args) == 0 {
- return fmt.Errorf("derivative requires a field argument")
- }
- // First arg must be a field or aggr over a field e.g. (mean(field))
- _, callOk := derivativeCall.Args[0].(*Call)
- _, varOk := derivativeCall.Args[0].(*VarRef)
- if !(callOk || varOk) {
- return fmt.Errorf("derivative requires a field argument")
- }
- // If a duration arg is pased, make sure it's a duration
- if len(derivativeCall.Args) == 2 {
- // Second must be a duration .e.g (1h)
- if _, ok := derivativeCall.Args[1].(*DurationLiteral); !ok {
- return fmt.Errorf("derivative requires a duration argument")
- }
- }
- return nil
- }
- // GroupByIterval extracts the time interval, if specified.
- func (s *SelectStatement) GroupByInterval() (time.Duration, error) {
- // return if we've already pulled it out
- if s.groupByInterval != 0 {
- return s.groupByInterval, nil
- }
- // Ignore if there are no dimensions.
- if len(s.Dimensions) == 0 {
- return 0, nil
- }
- for _, d := range s.Dimensions {
- if call, ok := d.Expr.(*Call); ok && call.Name == "time" {
- // Make sure there is exactly one argument.
- if len(call.Args) != 1 {
- return 0, errors.New("time dimension expected one argument")
- }
- // Ensure the argument is a duration.
- lit, ok := call.Args[0].(*DurationLiteral)
- if !ok {
- return 0, errors.New("time dimension must have one duration argument")
- }
- s.groupByInterval = lit.Val
- return lit.Val, nil
- }
- }
- return 0, nil
- }
- // SetTimeRange sets the start and end time of the select statement to [start, end). i.e. start inclusive, end exclusive.
- // This is used commonly for continuous queries so the start and end are in buckets.
- func (s *SelectStatement) SetTimeRange(start, end time.Time) error {
- cond := fmt.Sprintf("time >= '%s' AND time < '%s'", start.UTC().Format(time.RFC3339Nano), end.UTC().Format(time.RFC3339Nano))
- if s.Condition != nil {
- cond = fmt.Sprintf("%s AND %s", s.rewriteWithoutTimeDimensions(), cond)
- }
- expr, err := NewParser(strings.NewReader(cond)).ParseExpr()
- if err != nil {
- return err
- }
- // fold out any previously replaced time dimensios and set the condition
- s.Condition = Reduce(expr, nil)
- return nil
- }
- // rewriteWithoutTimeDimensions will remove any WHERE time... clauses from the select statement
- // This is necessary when setting an explicit time range to override any that previously existed.
- func (s *SelectStatement) rewriteWithoutTimeDimensions() string {
- n := RewriteFunc(s.Condition, func(n Node) Node {
- switch n := n.(type) {
- case *BinaryExpr:
- if n.LHS.String() == "time" {
- return &BooleanLiteral{Val: true}
- }
- return n
- case *Call:
- return &BooleanLiteral{Val: true}
- default:
- return n
- }
- })
- return n.String()
- }
- /*
- BinaryExpr
- SELECT mean(xxx.value) + avg(yyy.value) FROM xxx JOIN yyy WHERE xxx.host = 123
- from xxx where host = 123
- select avg(value) from yyy where host = 123
- SELECT xxx.value FROM xxx WHERE xxx.host = 123
- SELECT yyy.value FROM yyy
- ---
- SELECT MEAN(xxx.value) + MEAN(cpu.load.value)
- FROM xxx JOIN yyy
- GROUP BY host
- WHERE (xxx.region == "uswest" OR yyy.region == "uswest") AND xxx.otherfield == "XXX"
- select * from (
- select mean + mean from xxx join yyy
- group by time(5m), host
- ) (xxx.region == "uswest" OR yyy.region == "uswest") AND xxx.otherfield == "XXX"
- (seriesIDS for xxx.region = 'uswest' union seriesIDs for yyy.regnion = 'uswest') | seriesIDS xxx.otherfield = 'XXX'
- WHERE xxx.region == "uswest" AND xxx.otherfield == "XXX"
- WHERE yyy.region == "uswest"
- */
- // Substatement returns a single-series statement for a given variable reference.
- func (s *SelectStatement) Substatement(ref *VarRef) (*SelectStatement, error) {
- // Copy dimensions and properties to new statement.
- other := &SelectStatement{
- Fields: Fields{{Expr: ref}},
- Dimensions: s.Dimensions,
- Limit: s.Limit,
- Offset: s.Offset,
- SortFields: s.SortFields,
- }
- // If there is only one series source then return it with the whole condition.
- if len(s.Sources) == 1 {
- other.Sources = s.Sources
- other.Condition = s.Condition
- return other, nil
- }
- // Find the matching source.
- name := MatchSource(s.Sources, ref.Val)
- if name == "" {
- return nil, fmt.Errorf("field source not found: %s", ref.Val)
- }
- other.Sources = append(other.Sources, &Measurement{Name: name})
- // Filter out conditions.
- if s.Condition != nil {
- other.Condition = filterExprBySource(name, s.Condition)
- }
- return other, nil
- }
- // NamesInWhere returns the field and tag names (idents) referenced in the where clause
- func (s *SelectStatement) NamesInWhere() []string {
- var a []string
- if s.Condition != nil {
- a = walkNames(s.Condition)
- }
- return a
- }
- // NamesInSelect returns the field and tag names (idents) in the select clause
- func (s *SelectStatement) NamesInSelect() []string {
- var a []string
- for _, f := range s.Fields {
- a = append(a, walkNames(f.Expr)...)
- }
- return a
- }
- // walkNames will walk the Expr and return the database fields
- func walkNames(exp Expr) []string {
- switch expr := exp.(type) {
- case *VarRef:
- return []string{expr.Val}
- case *Call:
- if len(expr.Args) == 0 {
- return nil
- }
- lit, ok := expr.Args[0].(*VarRef)
- if !ok {
- return nil
- }
- return []string{lit.Val}
- case *BinaryExpr:
- var ret []string
- ret = append(ret, walkNames(expr.LHS)...)
- ret = append(ret, walkNames(expr.RHS)...)
- return ret
- case *ParenExpr:
- return walkNames(expr.Expr)
- }
- return nil
- }
- // FunctionCalls returns the Call objects from the query
- func (s *SelectStatement) FunctionCalls() []*Call {
- var a []*Call
- for _, f := range s.Fields {
- a = append(a, walkFunctionCalls(f.Expr)...)
- }
- return a
- }
- // walkFunctionCalls walks the Field of a query for any function calls made
- func walkFunctionCalls(exp Expr) []*Call {
- switch expr := exp.(type) {
- case *VarRef:
- return nil
- case *Call:
- return []*Call{expr}
- case *BinaryExpr:
- var ret []*Call
- ret = append(ret, walkFunctionCalls(expr.LHS)...)
- ret = append(ret, walkFunctionCalls(expr.RHS)...)
- return ret
- case *ParenExpr:
- return walkFunctionCalls(expr.Expr)
- }
- return nil
- }
- // filters an expression to exclude expressions unrelated to a source.
- func filterExprBySource(name string, expr Expr) Expr {
- switch expr := expr.(type) {
- case *VarRef:
- if !strings.HasPrefix(expr.Val, name) {
- return nil
- }
- case *BinaryExpr:
- lhs := filterExprBySource(name, expr.LHS)
- rhs := filterExprBySource(name, expr.RHS)
- // If an expr is logical then return either LHS/RHS or both.
- // If an expr is arithmetic or comparative then require both sides.
- if expr.Op == AND || expr.Op == OR {
- if lhs == nil && rhs == nil {
- return nil
- } else if lhs != nil && rhs == nil {
- return lhs
- } else if lhs == nil && rhs != nil {
- return rhs
- }
- } else {
- if lhs == nil || rhs == nil {
- return nil
- }
- }
- return &BinaryExpr{Op: expr.Op, LHS: lhs, RHS: rhs}
- case *ParenExpr:
- exp := filterExprBySource(name, expr.Expr)
- if exp == nil {
- return nil
- }
- return &ParenExpr{Expr: exp}
- }
- return expr
- }
- // MatchSource returns the source name that matches a field name.
- // Returns a blank string if no sources match.
- func MatchSource(sources Sources, name string) string {
- for _, src := range sources {
- switch src := src.(type) {
- case *Measurement:
- if strings.HasPrefix(name, src.Name) {
- return src.Name
- }
- }
- }
- return ""
- }
- // Target represents a target (destination) policy, measurement, and DB.
- type Target struct {
- // Measurement to write into.
- Measurement *Measurement
- }
- // String returns a string representation of the Target.
- func (t *Target) String() string {
- if t == nil {
- return ""
- }
- var buf bytes.Buffer
- _, _ = buf.WriteString("INTO ")
- _, _ = buf.WriteString(t.Measurement.String())
- return buf.String()
- }
- // DeleteStatement represents a command for removing data from the database.
- type DeleteStatement struct {
- // Data source that values are removed from.
- Source Source
- // An expression evaluated on data point.
- Condition Expr
- }
- // String returns a string representation of the delete statement.
- func (s *DeleteStatement) String() string {
- var buf bytes.Buffer
- _, _ = buf.WriteString("DELETE ")
- _, _ = buf.WriteString(s.Source.String())
- if s.Condition != nil {
- _, _ = buf.WriteString(" WHERE ")
- _, _ = buf.WriteString(s.Condition.String())
- }
- return s.String()
- }
- // RequiredPrivileges returns the privilege required to execute a DeleteStatement.
- func (s *DeleteStatement) RequiredPrivileges() ExecutionPrivileges {
- return ExecutionPrivileges{{Admin: false, Name: "", Privilege: WritePrivilege}}
- }
- // ShowSeriesStatement represents a command for listing series in the database.
- type ShowSeriesStatement struct {
- // Measurement(s) the series are listed for.
- Sources Sources
- // An expression evaluated on a series name or tag.
- Condition Expr
- // Fields to sort results by
- SortFields SortFields
- // Maximum number of rows to be returned.
- // Unlimited if zero.
- Limit int
- // Returns rows starting at an offset from the first row.
- Offset int
- }
- // String returns a string representation of the list series statement.
- func (s *ShowSeriesStatement) String() string {
- var buf bytes.Buffer
- _, _ = buf.WriteString("SHOW SERIES")
- if s.Sources != nil {
- _, _ = buf.WriteString(" FROM ")
- _, _ = buf.WriteString(s.Sources.String())
- }
- if s.Condition != nil {
- _, _ = buf.WriteString(" WHERE ")
- _, _ = buf.WriteString(s.Condition.String())
- }
- if len(s.SortFields) > 0 {
- _, _ = buf.WriteString(" ORDER BY ")
- _, _ = buf.WriteString(s.SortFields.String())
- }
- if s.Limit > 0 {
- _, _ = buf.WriteString(" LIMIT ")
- _, _ = buf.WriteString(strconv.Itoa(s.Limit))
- }
- if s.Offset > 0 {
- _, _ = buf.WriteString(" OFFSET ")
- _, _ = buf.WriteString(strconv.Itoa(s.Offset))
- }
- return buf.String()
- }
- // RequiredPrivileges returns the privilege required to execute a ShowSeriesStatement.
- func (s *ShowSeriesStatement) RequiredPrivileges() ExecutionPrivileges {
- return ExecutionPrivileges{{Admin: false, Name: "", Privilege: ReadPrivilege}}
- }
- // DropSeriesStatement represents a command for removing a series from the database.
- type DropSeriesStatement struct {
- // Data source that fields are extracted from (optional)
- Sources Sources
- // An expression evaluated on data point (optional)
- Condition Expr
- }
- // String returns a string representation of the drop series statement.
- func (s *DropSeriesStatement) String() string {
- var buf bytes.Buffer
- buf.WriteString("DROP SERIES")
- if s.Sources != nil {
- buf.WriteString(" FROM ")
- buf.WriteString(s.Sources.String())
- }
- if s.Condition != nil {
- buf.WriteString(" WHERE ")
- buf.WriteString(s.Condition.String())
- }
- return buf.String()
- }
- // RequiredPrivileges returns the privilege required to execute a DropSeriesStatement.
- func (s DropSeriesStatement) RequiredPrivileges() ExecutionPrivileges {
- return ExecutionPrivileges{{Admin: false, Name: "", Privilege: WritePrivilege}}
- }
- // ShowContinuousQueriesStatement represents a command for listing continuous queries.
- type ShowContinuousQueriesStatement struct{}
- // String returns a string representation of the list continuous queries statement.
- func (s *ShowContinuousQueriesStatement) String() string { return "SHOW CONTINUOUS QUERIES" }
- // RequiredPrivileges returns the privilege required to execute a ShowContinuousQueriesStatement.
- func (s *ShowContinuousQueriesStatement) RequiredPrivileges() ExecutionPrivileges {
- return ExecutionPrivileges{{Admin: false, Name: "", Privilege: ReadPrivilege}}
- }
- // ShowGrantsForUserStatement represents a command for listing user privileges.
- type ShowGrantsForUserStatement struct {
- // Name of the user to display privileges.
- Name string
- }
- // String returns a string representation of the show grants for user.
- func (s *ShowGrantsForUserStatement) String() string {
- var buf bytes.Buffer
- _, _ = buf.WriteString("SHOW GRANTS FOR ")
- _, _ = buf.WriteString(s.Name)
- return buf.String()
- }
- // RequiredPrivileges returns the privilege required to execute a ShowGrantsForUserStatement
- func (s *ShowGrantsForUserStatement) RequiredPrivileges() ExecutionPrivileges {
- return ExecutionPrivileges{{Admin: true, Name: "", Privilege: AllPrivileges}}
- }
- // ShowServersStatement represents a command for listing all servers.
- type ShowServersStatement struct{}
- // String returns a string representation of the show servers command.
- func (s *ShowServersStatement) String() string { return "SHOW SERVERS" }
- // RequiredPrivileges returns the privilege required to execute a ShowServersStatement
- func (s *ShowServersStatement) RequiredPrivileges() ExecutionPrivileges {
- return ExecutionPrivileges{{Admin: true, Name: "", Privilege: AllPrivileges}}
- }
- // ShowDatabasesStatement represents a command for listing all databases in the cluster.
- type ShowDatabasesStatement struct{}
- // String returns a string representation of the list databases command.
- func (s *ShowDatabasesStatement) String() string { return "SHOW DATABASES" }
- // RequiredPrivileges returns the privilege required to execute a ShowDatabasesStatement
- func (s *ShowDatabasesStatement) RequiredPrivileges() ExecutionPrivileges {
- return ExecutionPrivileges{{Admin: true, Name: "", Privilege: AllPrivileges}}
- }
- // CreateContinuousQueryStatement represents a command for creating a continuous query.
- type CreateContinuousQueryStatement struct {
- // Name of the continuous query to be created.
- Name string
- // Name of the database to create the continuous query on.
- Database string
- // Source of data (SELECT statement).
- Source *SelectStatement
- }
- // String returns a string representation of the statement.
- func (s *CreateContinuousQueryStatement) String() string {
- return fmt.Sprintf("CREATE CONTINUOUS QUERY %s ON %s BEGIN %s END", QuoteIdent(s.Name), QuoteIdent(s.Database), s.Source.String())
- }
- // DefaultDatabase returns the default database from the statement.
- func (s *CreateContinuousQueryStatement) DefaultDatabase() string {
- return s.Database
- }
- // RequiredPrivileges returns the privilege required to execute a CreateContinuousQueryStatement.
- func (s *CreateContinuousQueryStatement) RequiredPrivileges() ExecutionPrivileges {
- ep := ExecutionPrivileges{{Admin: false, Name: s.Database, Privilege: ReadPrivilege}}
- // Selecting into a database that's different from the source?
- if s.Source.Target.Measurement.Database != "" {
- // Change source database privilege requirement to read.
- ep[0].Privilege = ReadPrivilege
- // Add destination database privilege requirement and set it to write.
- p := ExecutionPrivilege{
- Admin: false,
- Name: s.Source.Target.Measurement.Database,
- Privilege: WritePrivilege,
- }
- ep = append(ep, p)
- }
- return ep
- }
- // DropContinuousQueryStatement represents a command for removing a continuous query.
- type DropContinuousQueryStatement struct {
- Name string
- Database string
- }
- // String returns a string representation of the statement.
- func (s *DropContinuousQueryStatement) String() string {
- return fmt.Sprintf("DROP CONTINUOUS QUERY %s", s.Name)
- }
- // RequiredPrivileges returns the privilege(s) required to execute a DropContinuousQueryStatement
- func (s *DropContinuousQueryStatement) RequiredPrivileges() ExecutionPrivileges {
- return ExecutionPrivileges{{Admin: false, Name: "", Privilege: WritePrivilege}}
- }
- // ShowMeasurementsStatement represents a command for listing measurements.
- type ShowMeasurementsStatement struct {
- // An expression evaluated on data point.
- Condition Expr
- // Fields to sort results by
- SortFields SortFields
- // Maximum number of rows to be returned.
- // Unlimited if zero.
- Limit int
- // Returns rows starting at an offset from the first row.
- Offset int
- }
- // String returns a string representation of the statement.
- func (s *ShowMeasurementsStatement) String() string {
- var buf bytes.Buffer
- _, _ = buf.WriteString("SHOW MEASUREMENTS")
- if s.Condition != nil {
- _, _ = buf.WriteString(" WHERE ")
- _, _ = buf.WriteString(s.Condition.String())
- }
- if len(s.SortFields) > 0 {
- _, _ = buf.WriteString(" ORDER BY ")
- _, _ = buf.WriteString(s.SortFields.String())
- }
- if s.Limit > 0 {
- _, _ = buf.WriteString(" LIMIT ")
- _, _ = buf.WriteString(strconv.Itoa(s.Limit))
- }
- if s.Offset > 0 {
- _, _ = buf.WriteString(" OFFSET ")
- _, _ = buf.WriteString(strconv.Itoa(s.Offset))
- }
- return buf.String()
- }
- // RequiredPrivileges returns the privilege(s) required to execute a ShowMeasurementsStatement
- func (s *ShowMeasurementsStatement) RequiredPrivileges() ExecutionPrivileges {
- return ExecutionPrivileges{{Admin: false, Name: "", Privilege: ReadPrivilege}}
- }
- // DropMeasurementStatement represents a command to drop a measurement.
- type DropMeasurementStatement struct {
- // Name of the measurement to be dropped.
- Name string
- }
- // String returns a string representation of the drop measurement statement.
- func (s *DropMeasurementStatement) String() string {
- var buf bytes.Buffer
- _, _ = buf.WriteString("DROP MEASUREMENT ")
- _, _ = buf.WriteString(s.Name)
- return buf.String()
- }
- // RequiredPrivileges returns the privilege(s) required to execute a DropMeasurementStatement
- func (s *DropMeasurementStatement) RequiredPrivileges() ExecutionPrivileges {
- return ExecutionPrivileges{{Admin: true, Name: "", Privilege: AllPrivileges}}
- }
- // ShowRetentionPoliciesStatement represents a command for listing retention policies.
- type ShowRetentionPoliciesStatement struct {
- // Name of the database to list policies for.
- Database string
- }
- // String returns a string representation of a ShowRetent