2014-11-15 19:04:30 +00:00
package influxql
import (
2014-12-06 18:17:58 +00:00
"bytes"
2015-01-23 09:44:56 +00:00
"errors"
2014-12-06 18:17:58 +00:00
"fmt"
2015-02-13 18:25:48 +00:00
"regexp"
2015-03-13 22:51:18 +00:00
"sort"
2014-12-06 18:17:58 +00:00
"strconv"
"strings"
2014-11-15 19:04:30 +00:00
"time"
2015-09-02 22:33:16 +00:00
2015-09-04 16:11:10 +00:00
"github.com/influxdb/influxdb/pkg/slices"
2014-11-15 19:04:30 +00:00
)
// DataType represents the primitive data types available in InfluxQL.
2015-06-10 20:02:26 +00:00
type DataType int
2014-11-15 19:04:30 +00:00
const (
2015-02-01 18:47:48 +00:00
// Unknown primitive data type.
2015-06-10 20:09:23 +00:00
Unknown DataType = 0
2015-04-13 04:36:00 +00:00
// Float means the data type is a float
2015-06-10 20:09:23 +00:00
Float = 1
2015-04-13 04:36:00 +00:00
// Integer means the data type is a integer
2015-06-10 20:09:23 +00:00
Integer = 2
2015-02-01 18:47:48 +00:00
// Boolean means the data type is a boolean.
2015-06-10 20:09:23 +00:00
Boolean = 3
2015-02-01 18:47:48 +00:00
// String means the data type is a string of text.
2015-06-10 20:09:23 +00:00
String = 4
2015-02-01 18:47:48 +00:00
// Time means the data type is a time.
2015-06-10 20:09:23 +00:00
Time = 5
2015-02-01 18:47:48 +00:00
// Duration means the data type is a duration of time.
2015-06-10 20:09:23 +00:00
Duration = 6
2014-11-15 19:04:30 +00:00
)
2014-12-09 15:45:29 +00:00
// InspectDataType returns the data type of a given value.
func InspectDataType ( v interface { } ) DataType {
switch v . ( type ) {
case float64 :
2015-04-13 04:36:00 +00:00
return Float
case int64 , int32 , int :
return Integer
2014-12-09 15:45:29 +00:00
case bool :
return Boolean
case string :
return String
case time . Time :
return Time
case time . Duration :
return Duration
default :
return Unknown
}
}
2015-06-11 14:30:01 +00:00
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"
}
2014-11-15 19:04:30 +00:00
// Node represents a node in the InfluxDB abstract syntax tree.
type Node interface {
node ( )
2014-12-06 18:17:58 +00:00
String ( ) string
2014-11-15 19:04:30 +00:00
}
2015-02-01 18:47:48 +00:00
func ( * Query ) node ( ) { }
func ( Statements ) node ( ) { }
func ( * AlterRetentionPolicyStatement ) node ( ) { }
func ( * CreateContinuousQueryStatement ) node ( ) { }
func ( * CreateDatabaseStatement ) node ( ) { }
func ( * CreateRetentionPolicyStatement ) node ( ) { }
func ( * CreateUserStatement ) node ( ) { }
2015-05-18 21:36:50 +00:00
func ( * Distinct ) node ( ) { }
2015-02-01 18:47:48 +00:00
func ( * DeleteStatement ) node ( ) { }
func ( * DropContinuousQueryStatement ) node ( ) { }
func ( * DropDatabaseStatement ) node ( ) { }
2015-02-23 20:51:52 +00:00
func ( * DropMeasurementStatement ) node ( ) { }
2015-02-01 18:47:48 +00:00
func ( * DropRetentionPolicyStatement ) node ( ) { }
func ( * DropSeriesStatement ) node ( ) { }
2015-10-03 02:49:11 +00:00
func ( * DropServerStatement ) node ( ) { }
2015-02-01 18:47:48 +00:00
func ( * DropUserStatement ) node ( ) { }
func ( * GrantStatement ) node ( ) { }
2015-07-10 20:39:33 +00:00
func ( * GrantAdminStatement ) node ( ) { }
2015-06-26 19:30:00 +00:00
func ( * RevokeStatement ) node ( ) { }
2015-07-10 20:39:33 +00:00
func ( * RevokeAdminStatement ) node ( ) { }
2015-06-26 19:30:00 +00:00
func ( * SelectStatement ) node ( ) { }
func ( * SetPasswordUserStatement ) node ( ) { }
2015-02-01 18:47:48 +00:00
func ( * ShowContinuousQueriesStatement ) node ( ) { }
2015-05-24 07:27:02 +00:00
func ( * ShowGrantsForUserStatement ) node ( ) { }
2015-03-10 19:46:05 +00:00
func ( * ShowServersStatement ) node ( ) { }
2015-02-01 18:47:48 +00:00
func ( * ShowDatabasesStatement ) node ( ) { }
func ( * ShowFieldKeysStatement ) node ( ) { }
func ( * ShowRetentionPoliciesStatement ) node ( ) { }
func ( * ShowMeasurementsStatement ) node ( ) { }
func ( * ShowSeriesStatement ) node ( ) { }
2015-08-24 19:29:17 +00:00
func ( * ShowShardsStatement ) node ( ) { }
2015-03-12 23:07:41 +00:00
func ( * ShowStatsStatement ) node ( ) { }
2015-03-24 03:13:54 +00:00
func ( * ShowDiagnosticsStatement ) node ( ) { }
2015-02-01 18:47:48 +00:00
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 ( ) { }
2015-02-13 18:25:48 +00:00
func ( * RegexLiteral ) node ( ) { }
2015-02-01 18:47:48 +00:00
func ( * SortField ) node ( ) { }
func ( SortFields ) node ( ) { }
2015-03-06 13:52:25 +00:00
func ( Sources ) node ( ) { }
2015-02-01 18:47:48 +00:00
func ( * StringLiteral ) node ( ) { }
func ( * Target ) node ( ) { }
func ( * TimeLiteral ) node ( ) { }
func ( * VarRef ) node ( ) { }
func ( * Wildcard ) node ( ) { }
2014-11-15 19:04:30 +00:00
2014-12-15 00:54:51 +00:00
// Query represents a collection of ordered statements.
2014-11-22 04:12:48 +00:00
type Query struct {
Statements Statements
2014-11-15 19:04:30 +00:00
}
2014-12-06 18:17:58 +00:00
// String returns a string representation of the query.
func ( q * Query ) String ( ) string { return q . Statements . String ( ) }
2014-11-22 04:12:48 +00:00
// Statements represents a list of statements.
type Statements [ ] Statement
2014-12-15 00:54:51 +00:00
// String returns a string representation of the statements.
2014-12-06 18:17:58 +00:00
func ( a Statements ) String ( ) string {
var str [ ] string
for _ , stmt := range a {
str = append ( str , stmt . String ( ) )
}
return strings . Join ( str , ";\n" )
}
2014-11-22 04:12:48 +00:00
// Statement represents a single command in InfluxQL.
type Statement interface {
Node
stmt ( )
2015-01-19 20:12:48 +00:00
RequiredPrivileges ( ) ExecutionPrivileges
2014-11-22 04:12:48 +00:00
}
2015-03-28 00:40:21 +00:00
// HasDefaultDatabase provides an interface to get the default database from a Statement.
type HasDefaultDatabase interface {
Node
stmt ( )
DefaultDatabase ( ) string
}
2015-01-19 20:12:48 +00:00
// ExecutionPrivilege is a privilege required for a user to execute
// a statement on a database or resource.
type ExecutionPrivilege struct {
2015-07-10 20:39:33 +00:00
// Admin privilege required.
Admin bool
// Name of the database.
2015-01-19 20:12:48 +00:00
Name string
2015-07-10 20:39:33 +00:00
// Database privilege required.
2015-01-19 20:12:48 +00:00
Privilege Privilege
}
// ExecutionPrivileges is a list of privileges required to execute a statement.
type ExecutionPrivileges [ ] ExecutionPrivilege
2015-02-01 18:47:48 +00:00
func ( * AlterRetentionPolicyStatement ) stmt ( ) { }
func ( * CreateContinuousQueryStatement ) stmt ( ) { }
func ( * CreateDatabaseStatement ) stmt ( ) { }
func ( * CreateRetentionPolicyStatement ) stmt ( ) { }
func ( * CreateUserStatement ) stmt ( ) { }
func ( * DeleteStatement ) stmt ( ) { }
func ( * DropContinuousQueryStatement ) stmt ( ) { }
func ( * DropDatabaseStatement ) stmt ( ) { }
2015-02-23 20:51:52 +00:00
func ( * DropMeasurementStatement ) stmt ( ) { }
2015-02-01 18:47:48 +00:00
func ( * DropRetentionPolicyStatement ) stmt ( ) { }
func ( * DropSeriesStatement ) stmt ( ) { }
2015-10-03 02:49:11 +00:00
func ( * DropServerStatement ) stmt ( ) { }
2015-02-01 18:47:48 +00:00
func ( * DropUserStatement ) stmt ( ) { }
func ( * GrantStatement ) stmt ( ) { }
2015-07-10 20:39:33 +00:00
func ( * GrantAdminStatement ) stmt ( ) { }
2015-02-01 18:47:48 +00:00
func ( * ShowContinuousQueriesStatement ) stmt ( ) { }
2015-05-24 07:27:02 +00:00
func ( * ShowGrantsForUserStatement ) stmt ( ) { }
2015-03-10 19:46:05 +00:00
func ( * ShowServersStatement ) stmt ( ) { }
2015-02-01 18:47:48 +00:00
func ( * ShowDatabasesStatement ) stmt ( ) { }
func ( * ShowFieldKeysStatement ) stmt ( ) { }
func ( * ShowMeasurementsStatement ) stmt ( ) { }
func ( * ShowRetentionPoliciesStatement ) stmt ( ) { }
func ( * ShowSeriesStatement ) stmt ( ) { }
2015-08-24 19:29:17 +00:00
func ( * ShowShardsStatement ) stmt ( ) { }
2015-03-12 23:07:41 +00:00
func ( * ShowStatsStatement ) stmt ( ) { }
2015-03-24 03:13:54 +00:00
func ( * ShowDiagnosticsStatement ) stmt ( ) { }
2015-02-01 18:47:48 +00:00
func ( * ShowTagKeysStatement ) stmt ( ) { }
func ( * ShowTagValuesStatement ) stmt ( ) { }
func ( * ShowUsersStatement ) stmt ( ) { }
func ( * RevokeStatement ) stmt ( ) { }
2015-07-10 20:39:33 +00:00
func ( * RevokeAdminStatement ) stmt ( ) { }
2015-02-01 18:47:48 +00:00
func ( * SelectStatement ) stmt ( ) { }
2015-04-03 14:14:09 +00:00
func ( * SetPasswordUserStatement ) stmt ( ) { }
2014-11-15 19:04:30 +00:00
// Expr represents an expression that can be evaluated to a value.
type Expr interface {
Node
expr ( )
}
2015-02-01 18:47:48 +00:00
func ( * BinaryExpr ) expr ( ) { }
func ( * BooleanLiteral ) expr ( ) { }
func ( * Call ) expr ( ) { }
2015-05-18 21:36:50 +00:00
func ( * Distinct ) expr ( ) { }
2015-02-01 18:47:48 +00:00
func ( * DurationLiteral ) expr ( ) { }
func ( * nilLiteral ) expr ( ) { }
func ( * NumberLiteral ) expr ( ) { }
func ( * ParenExpr ) expr ( ) { }
2015-02-13 18:25:48 +00:00
func ( * RegexLiteral ) expr ( ) { }
2015-02-01 18:47:48 +00:00
func ( * StringLiteral ) expr ( ) { }
func ( * TimeLiteral ) expr ( ) { }
func ( * VarRef ) expr ( ) { }
func ( * Wildcard ) expr ( ) { }
2014-11-15 19:04:30 +00:00
2014-11-22 04:12:48 +00:00
// Source represents a source of data for a statement.
type Source interface {
2014-11-15 19:04:30 +00:00
Node
2014-11-22 04:12:48 +00:00
source ( )
2014-11-15 19:04:30 +00:00
}
2015-03-16 23:45:39 +00:00
func ( * Measurement ) source ( ) { }
2015-03-06 13:52:25 +00:00
// 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 ( )
}
2014-11-15 19:04:30 +00:00
2015-01-21 13:28:24 +00:00
// SortField represents a field to sort results by.
2014-12-15 00:54:51 +00:00
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
2015-08-27 17:52:22 +00:00
if field . Name != "" {
2015-07-21 19:07:56 +00:00
_ , _ = buf . WriteString ( field . Name )
_ , _ = buf . WriteString ( " " )
}
if field . Ascending {
_ , _ = buf . WriteString ( "ASC" )
} else {
_ , _ = buf . WriteString ( "DESC" )
}
2014-12-15 00:54:51 +00:00
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 , ", " )
}
2014-12-31 13:47:21 +00:00
// CreateDatabaseStatement represents a command for creating a new database.
type CreateDatabaseStatement struct {
// Name of the database to be created.
Name string
2015-08-29 00:41:43 +00:00
// IfNotExists indicates whether to return without error if the database
// already exists.
IfNotExists bool
2014-12-31 13:47:21 +00:00
}
// String returns a string representation of the create database statement.
func ( s * CreateDatabaseStatement ) String ( ) string {
var buf bytes . Buffer
_ , _ = buf . WriteString ( "CREATE DATABASE " )
2015-08-29 00:41:43 +00:00
if s . IfNotExists {
_ , _ = buf . WriteString ( "IF NOT EXISTS " )
}
2014-12-31 13:47:21 +00:00
_ , _ = buf . WriteString ( s . Name )
return buf . String ( )
}
2015-02-01 18:47:48 +00:00
// RequiredPrivileges returns the privilege required to execute a CreateDatabaseStatement.
2015-01-19 20:12:48 +00:00
func ( s * CreateDatabaseStatement ) RequiredPrivileges ( ) ExecutionPrivileges {
2015-07-10 20:39:33 +00:00
return ExecutionPrivileges { { Admin : true , Name : "" , Privilege : AllPrivileges } }
2015-01-19 20:12:48 +00:00
}
2015-01-05 03:32:49 +00:00
// 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 ( )
}
2015-02-01 18:47:48 +00:00
// RequiredPrivileges returns the privilege required to execute a DropDatabaseStatement.
2015-01-19 20:12:48 +00:00
func ( s * DropDatabaseStatement ) RequiredPrivileges ( ) ExecutionPrivileges {
2015-07-10 20:39:33 +00:00
return ExecutionPrivileges { { Admin : true , Name : "" , Privilege : AllPrivileges } }
2015-01-19 20:12:48 +00:00
}
2015-01-13 21:46:07 +00:00
// 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 ( )
}
2015-02-01 18:47:48 +00:00
// RequiredPrivileges returns the privilege required to execute a DropRetentionPolicyStatement.
2015-01-19 20:12:48 +00:00
func ( s * DropRetentionPolicyStatement ) RequiredPrivileges ( ) ExecutionPrivileges {
2015-07-10 20:39:33 +00:00
return ExecutionPrivileges { { Admin : false , Name : s . Database , Privilege : WritePrivilege } }
2015-01-19 20:12:48 +00:00
}
2014-12-31 16:22:07 +00:00
// CreateUserStatement represents a command for creating a new user.
type CreateUserStatement struct {
// Name of the user to be created.
Name string
2015-07-10 20:39:33 +00:00
// User's password.
2014-12-31 16:22:07 +00:00
Password string
2015-01-09 22:50:33 +00:00
2015-07-10 20:39:33 +00:00
// User's admin privilege.
Admin bool
2014-12-31 16:22:07 +00:00
}
// 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 " )
2015-07-22 00:53:21 +00:00
_ , _ = buf . WriteString ( "[REDACTED]" )
2015-07-10 20:39:33 +00:00
if s . Admin {
_ , _ = buf . WriteString ( " WITH ALL PRIVILEGES" )
2015-01-09 22:50:33 +00:00
}
2014-12-31 16:22:07 +00:00
return buf . String ( )
}
2015-02-01 18:47:48 +00:00
// RequiredPrivileges returns the privilege(s) required to execute a CreateUserStatement.
2015-01-19 20:12:48 +00:00
func ( s * CreateUserStatement ) RequiredPrivileges ( ) ExecutionPrivileges {
2015-07-10 20:39:33 +00:00
return ExecutionPrivileges { { Admin : true , Name : "" , Privilege : AllPrivileges } }
2015-01-19 20:12:48 +00:00
}
2015-01-05 03:56:25 +00:00
// 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 ( )
}
2015-02-01 18:47:48 +00:00
// RequiredPrivileges returns the privilege(s) required to execute a DropUserStatement.
2015-01-19 20:12:48 +00:00
func ( s * DropUserStatement ) RequiredPrivileges ( ) ExecutionPrivileges {
2015-07-10 20:39:33 +00:00
return ExecutionPrivileges { { Admin : true , Name : "" , Privilege : AllPrivileges } }
2015-01-19 20:12:48 +00:00
}
2015-01-03 03:56:26 +00:00
// Privilege is a type of action a user can be granted the right to use.
type Privilege int
const (
2015-02-01 18:47:48 +00:00
// NoPrivileges means no privileges required / granted / revoked.
2015-01-19 20:12:48 +00:00
NoPrivileges Privilege = iota
2015-02-01 18:47:48 +00:00
// ReadPrivilege means read privilege required / granted / revoked.
2015-01-19 20:12:48 +00:00
ReadPrivilege
2015-02-01 18:47:48 +00:00
// WritePrivilege means write privilege required / granted / revoked.
2015-01-03 03:56:26 +00:00
WritePrivilege
2015-02-01 18:47:48 +00:00
// AllPrivileges means all privileges required / granted / revoked.
2015-01-03 03:56:26 +00:00
AllPrivileges
)
2015-01-09 22:50:33 +00:00
// NewPrivilege returns an initialized *Privilege.
func NewPrivilege ( p Privilege ) * Privilege { return & p }
2015-01-03 03:56:26 +00:00
// String returns a string representation of a Privilege.
func ( p Privilege ) String ( ) string {
switch p {
2015-01-19 20:12:48 +00:00
case NoPrivileges :
return "NO PRIVILEGES"
2015-01-03 03:56:26 +00:00
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
2015-07-10 20:39:33 +00:00
// Database to grant the privilege to.
2015-01-03 03:56:26 +00:00
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 ( ) )
2015-07-10 20:39:33 +00:00
_ , _ = buf . WriteString ( " ON " )
_ , _ = buf . WriteString ( s . On )
2015-01-03 03:56:26 +00:00
_ , _ = buf . WriteString ( " TO " )
_ , _ = buf . WriteString ( s . User )
return buf . String ( )
}
2015-02-01 18:47:48 +00:00
// RequiredPrivileges returns the privilege required to execute a GrantStatement.
2015-01-19 20:12:48 +00:00
func ( s * GrantStatement ) RequiredPrivileges ( ) ExecutionPrivileges {
2015-07-10 20:39:33 +00:00
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 } }
2015-01-19 20:12:48 +00:00
}
2015-06-28 06:54:34 +00:00
// SetPasswordUserStatement represents a command for changing user password.
2015-04-03 14:14:09 +00:00
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 ( " = " )
2015-07-22 00:53:21 +00:00
_ , _ = buf . WriteString ( "[REDACTED]" )
2015-04-03 14:14:09 +00:00
return buf . String ( )
}
2015-07-10 20:39:33 +00:00
// RequiredPrivileges returns the privilege required to execute a SetPasswordUserStatement.
2015-04-03 14:14:09 +00:00
func ( s * SetPasswordUserStatement ) RequiredPrivileges ( ) ExecutionPrivileges {
2015-07-10 20:39:33 +00:00
return ExecutionPrivileges { { Admin : true , Name : "" , Privilege : AllPrivileges } }
2015-04-03 14:14:09 +00:00
}
2015-01-03 07:06:18 +00:00
// RevokeStatement represents a command to revoke a privilege from a user.
type RevokeStatement struct {
2015-07-10 20:39:33 +00:00
// The privilege to be revoked.
2015-01-03 07:06:18 +00:00
Privilege Privilege
2015-07-10 20:39:33 +00:00
// Database to revoke the privilege from.
2015-01-03 07:06:18 +00:00
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 ( ) )
2015-07-10 20:39:33 +00:00
_ , _ = buf . WriteString ( " ON " )
_ , _ = buf . WriteString ( s . On )
2015-01-03 07:06:18 +00:00
_ , _ = buf . WriteString ( " FROM " )
_ , _ = buf . WriteString ( s . User )
return buf . String ( )
}
2015-02-01 18:47:48 +00:00
// RequiredPrivileges returns the privilege required to execute a RevokeStatement.
2015-01-19 20:12:48 +00:00
func ( s * RevokeStatement ) RequiredPrivileges ( ) ExecutionPrivileges {
2015-07-10 20:39:33 +00:00
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 } }
2015-01-19 20:12:48 +00:00
}
2015-01-05 02:50:56 +00:00
// CreateRetentionPolicyStatement represents a command to create a retention policy.
type CreateRetentionPolicyStatement struct {
// Name of policy to create.
Name string
2015-01-05 18:24:50 +00:00
// Name of database this policy belongs to.
2015-01-09 22:50:33 +00:00
Database string
2015-01-05 02:50:56 +00:00
// Duration data written to this policy will be retained.
Duration time . Duration
// Replication factor for data written to this policy.
Replication int
2015-01-05 18:24:50 +00:00
// Should this policy be set as default for the database?
2015-01-05 02:50:56 +00:00
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 )
2015-01-05 18:24:50 +00:00
_ , _ = buf . WriteString ( " ON " )
2015-01-09 22:50:33 +00:00
_ , _ = buf . WriteString ( s . Database )
2015-01-05 02:50:56 +00:00
_ , _ = buf . WriteString ( " DURATION " )
2015-01-05 18:24:50 +00:00
_ , _ = buf . WriteString ( FormatDuration ( s . Duration ) )
2015-01-05 02:50:56 +00:00
_ , _ = buf . WriteString ( " REPLICATION " )
2015-01-05 20:37:18 +00:00
_ , _ = buf . WriteString ( strconv . Itoa ( s . Replication ) )
2015-01-05 02:50:56 +00:00
if s . Default {
_ , _ = buf . WriteString ( " DEFAULT" )
}
return buf . String ( )
}
2015-02-01 18:47:48 +00:00
// RequiredPrivileges returns the privilege required to execute a CreateRetentionPolicyStatement.
2015-01-19 20:12:48 +00:00
func ( s * CreateRetentionPolicyStatement ) RequiredPrivileges ( ) ExecutionPrivileges {
2015-07-10 20:39:33 +00:00
return ExecutionPrivileges { { Admin : true , Name : "" , Privilege : AllPrivileges } }
2015-01-19 20:12:48 +00:00
}
2015-01-05 18:24:50 +00:00
// 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.
2015-01-09 22:50:33 +00:00
Database string
2015-01-05 18:24:50 +00:00
// 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 " )
2015-01-09 22:50:33 +00:00
_ , _ = buf . WriteString ( s . Database )
2015-01-05 18:24:50 +00:00
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 ( )
}
2015-02-01 18:47:48 +00:00
// RequiredPrivileges returns the privilege required to execute an AlterRetentionPolicyStatement.
2015-01-19 20:12:48 +00:00
func ( s * AlterRetentionPolicyStatement ) RequiredPrivileges ( ) ExecutionPrivileges {
2015-07-10 20:39:33 +00:00
return ExecutionPrivileges { { Admin : true , Name : "" , Privilege : AllPrivileges } }
2015-01-19 20:12:48 +00:00
}
2015-03-12 01:05:31 +00:00
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
2015-03-12 01:20:20 +00:00
// NumberFill means that empty aggregate windows will be filled with the given number
2015-03-12 01:05:31 +00:00
NumberFill
// PreviousFill means that empty aggregate windows will be filled with whatever the previous aggregate window had
PreviousFill
)
2014-11-22 04:12:48 +00:00
// SelectStatement represents a command for extracting data from the database.
type SelectStatement struct {
2014-11-15 19:04:30 +00:00
// Expressions returned from the selection.
Fields Fields
2015-01-06 21:30:27 +00:00
// Target (destination) for the result of the select.
Target * Target
2014-11-15 19:04:30 +00:00
// Expressions used for grouping the selection.
Dimensions Dimensions
2015-03-06 13:52:25 +00:00
// Data sources that fields are extracted from.
Sources Sources
2014-11-15 19:04:30 +00:00
// An expression evaluated on data point.
Condition Expr
2014-12-15 00:54:51 +00:00
// Fields to sort results by
SortFields SortFields
2015-03-10 01:46:05 +00:00
// Maximum number of rows to be returned. Unlimited if zero.
2014-11-15 19:04:30 +00:00
Limit int
2015-01-25 20:34:49 +00:00
// Returns rows starting at an offset from the first row.
Offset int
2015-01-20 02:44:47 +00:00
2015-03-10 01:46:05 +00:00
// Maxiumum number of series to be returned. Unlimited if zero.
2015-03-10 03:09:47 +00:00
SLimit int
2015-03-10 01:46:05 +00:00
// Returns series starting at an offset from the first one.
2015-03-10 03:09:47 +00:00
SOffset int
2015-03-10 01:46:05 +00:00
2015-01-20 02:44:47 +00:00
// memoize the group by interval
groupByInterval time . Duration
2015-02-24 03:51:43 +00:00
// if it's a query for raw data values (i.e. not an aggregate)
2015-03-19 15:41:18 +00:00
IsRawQuery bool
2015-03-12 01:05:31 +00:00
// What fill option the select statement uses, if any
Fill FillOption
// The value to fill empty aggregate buckets with, if any
FillValue interface { }
2014-11-15 19:04:30 +00:00
}
2015-09-20 22:27:22 +00:00
// SourceNames returns a list of source names.
func ( s * SelectStatement ) SourceNames ( ) [ ] string {
a := make ( [ ] string , 0 , len ( s . Sources ) )
for _ , src := range s . Sources {
switch src := src . ( type ) {
case * Measurement :
a = append ( a , src . Name )
}
}
return a
}
2015-05-14 20:53:17 +00:00
// HasDerivative returns true if one of the function calls in the statement is a
2015-05-12 22:51:19 +00:00
// derivative aggregate
func ( s * SelectStatement ) HasDerivative ( ) bool {
2015-05-14 20:53:17 +00:00
for _ , f := range s . FunctionCalls ( ) {
if strings . HasSuffix ( f . Name , "derivative" ) {
2015-05-12 19:03:34 +00:00
return true
}
}
return false
}
2015-05-14 20:53:17 +00:00
// IsSimpleDerivative return true if one of the function call is a derivative function with a
2015-05-12 22:51:19 +00:00
// variable ref as the first arg
func ( s * SelectStatement ) IsSimpleDerivative ( ) bool {
2015-05-14 20:53:17 +00:00
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
2015-05-12 22:51:19 +00:00
}
}
}
return false
}
2015-09-16 20:17:58 +00:00
// TimeAscending returns true if the time field is sorted in chronological order.
func ( s * SelectStatement ) TimeAscending ( ) bool {
return len ( s . SortFields ) == 0 || s . SortFields [ 0 ] . Ascending
}
2015-01-26 12:19:35 +00:00
// Clone returns a deep copy of the statement.
2015-02-01 18:47:48 +00:00
func ( s * SelectStatement ) Clone ( ) * SelectStatement {
2015-03-06 13:52:25 +00:00
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 ) ) ,
2015-02-01 18:47:48 +00:00
Condition : CloneExpr ( s . Condition ) ,
Limit : s . Limit ,
2015-02-24 06:42:11 +00:00
Offset : s . Offset ,
2015-03-10 03:09:47 +00:00
SLimit : s . SLimit ,
SOffset : s . SOffset ,
2015-03-12 02:29:18 +00:00
Fill : s . Fill ,
FillValue : s . FillValue ,
2015-03-19 21:07:51 +00:00
IsRawQuery : s . IsRawQuery ,
2015-01-26 12:19:35 +00:00
}
2015-02-01 18:47:48 +00:00
if s . Target != nil {
2015-03-28 00:40:21 +00:00
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 ) ,
} ,
}
2015-01-26 12:19:35 +00:00
}
2015-03-06 13:52:25 +00:00
for _ , f := range s . Fields {
clone . Fields = append ( clone . Fields , & Field { Expr : CloneExpr ( f . Expr ) , Alias : f . Alias } )
2015-01-26 12:19:35 +00:00
}
2015-03-06 13:52:25 +00:00
for _ , d := range s . Dimensions {
clone . Dimensions = append ( clone . Dimensions , & Dimension { Expr : CloneExpr ( d . Expr ) } )
2015-01-26 12:19:35 +00:00
}
2015-03-06 13:52:25 +00:00
for _ , f := range s . SortFields {
clone . SortFields = append ( clone . SortFields , & SortField { Name : f . Name , Ascending : f . Ascending } )
2015-01-26 12:19:35 +00:00
}
2015-03-06 13:52:25 +00:00
return clone
}
func cloneSources ( sources Sources ) Sources {
clone := make ( Sources , 0 , len ( sources ) )
for _ , s := range sources {
clone = append ( clone , cloneSource ( s ) )
}
return clone
2015-01-26 12:19:35 +00:00
}
func cloneSource ( s Source ) Source {
if s == nil {
return nil
}
switch s := s . ( type ) {
case * Measurement :
2015-03-28 00:40:21 +00:00
m := & Measurement { Database : s . Database , RetentionPolicy : s . RetentionPolicy , Name : s . Name }
2015-03-06 13:52:25 +00:00
if s . Regex != nil {
m . Regex = & RegexLiteral { Val : regexp . MustCompile ( s . Regex . Val . String ( ) ) }
2015-01-26 12:19:35 +00:00
}
2015-03-06 13:52:25 +00:00
return m
2015-01-26 12:19:35 +00:00
default :
panic ( "unreachable" )
}
}
2015-02-18 06:02:03 +00:00
// 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 ( )
2015-05-22 20:38:28 +00:00
selectWildcard , groupWildcard := false , false
2015-02-18 06:02:03 +00:00
// Rewrite all wildcard query fields
rwFields := make ( Fields , 0 , len ( s . Fields ) )
for _ , f := range s . Fields {
switch f . Expr . ( type ) {
case * Wildcard :
2015-03-13 22:51:18 +00:00
// Sort wildcard fields for consistent output
sort . Sort ( fields )
2015-02-18 06:02:03 +00:00
rwFields = append ( rwFields , fields ... )
2015-05-22 20:38:28 +00:00
selectWildcard = true
2015-02-18 06:02:03 +00:00
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 ... )
2015-05-22 20:38:28 +00:00
groupWildcard = true
2015-02-18 06:02:03 +00:00
default :
rwDimensions = append ( rwDimensions , d )
}
}
2015-05-22 20:38:28 +00:00
if selectWildcard && ! groupWildcard {
rwDimensions = append ( rwDimensions , dimensions ... )
}
2015-02-18 06:02:03 +00:00
other . Dimensions = rwDimensions
return other
}
2015-06-28 06:54:34 +00:00
// RewriteDistinct rewrites the expression to be a call for map/reduce to work correctly
2015-05-18 21:36:50 +00:00
// This method assumes all validation has passed
2015-05-19 15:09:05 +00:00
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
2015-05-18 21:36:50 +00:00
}
}
}
2015-09-02 17:26:40 +00:00
// ColumnNames will walk all fields and functions and return the appropriate field names for the select statement
2015-09-04 18:41:46 +00:00
// while maintaining order of the field names
2015-09-02 17:26:40 +00:00
func ( s * SelectStatement ) ColumnNames ( ) [ ] string {
// Always set the first column to be time, even if they didn't specify it
columnNames := [ ] string { "time" }
// First walk each field
for _ , field := range s . Fields {
switch f := field . Expr . ( type ) {
case * Call :
if f . Name == "top" || f . Name == "bottom" {
if len ( f . Args ) == 2 {
columnNames = append ( columnNames , f . Name )
continue
}
// We have a special case now where we have to add the column names for the fields TOP or BOTTOM asked for as well
2015-09-02 22:33:16 +00:00
columnNames = slices . Union ( columnNames , f . Fields ( ) , true )
continue
2015-09-02 17:26:40 +00:00
}
columnNames = append ( columnNames , field . Name ( ) )
default :
2015-09-04 12:48:57 +00:00
// time is always first, and we already added it, so ignore it if they asked for it anywhere else.
2015-09-02 17:26:40 +00:00
if field . Name ( ) != "time" {
columnNames = append ( columnNames , field . Name ( ) )
}
}
}
return columnNames
}
// HasTimeFieldSpecified will walk all fields and determine if the user explicitly asked for time
// This is needed to determine re-write behaviors for functions like TOP and BOTTOM
func ( s * SelectStatement ) HasTimeFieldSpecified ( ) bool {
for _ , f := range s . Fields {
if f . Name ( ) == "time" {
return true
}
}
return false
}
2014-12-06 18:17:58 +00:00
// 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 ( ) )
2015-01-06 21:30:27 +00:00
if s . Target != nil {
_ , _ = buf . WriteString ( " " )
_ , _ = buf . WriteString ( s . Target . String ( ) )
}
2015-03-06 13:52:25 +00:00
if len ( s . Sources ) > 0 {
_ , _ = buf . WriteString ( " FROM " )
_ , _ = buf . WriteString ( s . Sources . String ( ) )
}
2014-12-06 18:17:58 +00:00
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 ( ) )
}
2015-03-12 02:29:18 +00:00
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)" )
}
2014-12-15 00:54:51 +00:00
if len ( s . SortFields ) > 0 {
_ , _ = buf . WriteString ( " ORDER BY " )
_ , _ = buf . WriteString ( s . SortFields . String ( ) )
2014-12-06 18:17:58 +00:00
}
2014-12-16 02:48:22 +00:00
if s . Limit > 0 {
_ , _ = fmt . Fprintf ( & buf , " LIMIT %d" , s . Limit )
}
2015-01-25 20:34:49 +00:00
if s . Offset > 0 {
_ , _ = buf . WriteString ( " OFFSET " )
_ , _ = buf . WriteString ( strconv . Itoa ( s . Offset ) )
}
2015-07-15 16:40:23 +00:00
if s . SLimit > 0 {
_ , _ = fmt . Fprintf ( & buf , " SLIMIT %d" , s . SLimit )
}
if s . SOffset > 0 {
_ , _ = fmt . Fprintf ( & buf , " SOFFSET %d" , s . SOffset )
}
2014-12-06 18:17:58 +00:00
return buf . String ( )
}
2015-02-01 18:47:48 +00:00
// RequiredPrivileges returns the privilege required to execute the SelectStatement.
2015-01-19 20:12:48 +00:00
func ( s * SelectStatement ) RequiredPrivileges ( ) ExecutionPrivileges {
2015-07-10 20:39:33 +00:00
ep := ExecutionPrivileges { { Admin : false , Name : "" , Privilege : ReadPrivilege } }
2015-01-19 20:12:48 +00:00
if s . Target != nil {
2015-07-10 20:39:33 +00:00
p := ExecutionPrivilege { Admin : false , Name : s . Target . Measurement . Database , Privilege : WritePrivilege }
2015-01-19 20:12:48 +00:00
ep = append ( ep , p )
}
return ep
}
2015-02-05 06:29:19 +00:00
// 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
}
}
2015-02-18 16:47:59 +00:00
// HasWildcard returns whether or not the select statement has at least 1 wildcard
func ( s * SelectStatement ) HasWildcard ( ) bool {
2015-08-14 02:24:15 +00:00
return s . HasFieldWildcard ( ) || s . HasDimensionWildcard ( )
2015-05-11 21:49:04 +00:00
}
2015-08-10 18:31:04 +00:00
// HasFieldWildcard returns whether or not the select statement has at least 1 wildcard in the fields
func ( s * SelectStatement ) HasFieldWildcard ( ) bool {
for _ , f := range s . Fields {
_ , ok := f . Expr . ( * Wildcard )
if ok {
return true
}
}
return false
}
// HasDimensionWildcard returns whether or not the select statement has
// at least 1 wildcard in the dimensions aka `GROUP BY`
func ( s * SelectStatement ) HasDimensionWildcard ( ) bool {
for _ , d := range s . Dimensions {
_ , ok := d . Expr . ( * Wildcard )
if ok {
return true
}
}
return false
}
2015-05-11 22:22:50 +00:00
// hasTimeDimensions returns whether or not the select statement has at least 1
2015-05-11 21:49:04 +00:00
// where condition with time as the condition
2015-05-11 22:22:50 +00:00
func ( s * SelectStatement ) hasTimeDimensions ( node Node ) bool {
2015-05-11 21:49:04 +00:00
switch n := node . ( type ) {
case * BinaryExpr :
if n . Op == AND || n . Op == OR {
2015-05-14 21:45:13 +00:00
return s . hasTimeDimensions ( n . LHS ) || s . hasTimeDimensions ( n . RHS )
2015-05-11 21:49:04 +00:00
}
if ref , ok := n . LHS . ( * VarRef ) ; ok && strings . ToLower ( ref . Val ) == "time" {
return true
}
return false
case * ParenExpr :
// walk down the tree
2015-05-14 21:45:13 +00:00
return s . hasTimeDimensions ( n . Expr )
2015-05-11 21:49:04 +00:00
default :
return false
}
}
2015-05-19 15:11:12 +00:00
func ( s * SelectStatement ) validate ( tr targetRequirement ) error {
2015-08-20 23:13:35 +00:00
if err := s . validateFields ( ) ; err != nil {
return err
}
2015-09-10 18:08:03 +00:00
if err := s . validateDimensions ( ) ; err != nil {
return err
}
2015-05-19 15:11:12 +00:00
if err := s . validateDistinct ( ) ; err != nil {
2015-05-12 20:30:01 +00:00
return err
}
2015-05-19 00:13:44 +00:00
if err := s . validateCountDistinct ( ) ; err != nil {
return err
}
2015-05-19 15:11:12 +00:00
if err := s . validateAggregates ( tr ) ; err != nil {
2015-05-12 20:30:01 +00:00
return err
}
if err := s . validateDerivative ( ) ; err != nil {
return err
}
return nil
}
2015-08-20 23:13:35 +00:00
func ( s * SelectStatement ) validateFields ( ) error {
2015-08-20 23:37:41 +00:00
ns := s . NamesInSelect ( )
if len ( ns ) == 1 && ns [ 0 ] == "time" {
return fmt . Errorf ( "at least 1 non-time field must be queried" )
2015-08-20 23:13:35 +00:00
}
return nil
}
2015-09-10 18:08:03 +00:00
func ( s * SelectStatement ) validateDimensions ( ) error {
var dur time . Duration
for _ , dim := range s . Dimensions {
switch expr := dim . Expr . ( type ) {
case * Call :
// Ensure the call is time() and it only has one duration argument.
// If we already have a duration
if expr . Name != "time" {
return errors . New ( "only time() calls allowed in dimensions" )
} else if len ( expr . Args ) != 1 {
return errors . New ( "time dimension expected one argument" )
} else if lit , ok := expr . Args [ 0 ] . ( * DurationLiteral ) ; ! ok {
return errors . New ( "time dimension must have one duration argument" )
} else if dur != 0 {
return errors . New ( "multiple time dimensions not allowed" )
} else {
dur = lit . Val
}
case * VarRef :
if strings . ToLower ( expr . Val ) == "time" {
return errors . New ( "time() is a function and expects at least one argument" )
}
case * Wildcard :
default :
return errors . New ( "only time and tag dimensions allowed" )
}
}
return nil
}
2015-09-04 18:41:46 +00:00
// validSelectWithAggregate determines if a SELECT statement has the correct
// combination of aggregate functions combined with selected fields and tags
// Currently we don't have support for all aggregates, but aggregates that
// can be combined with fields/tags are:
// TOP, BOTTOM, MAX, MIN, FIRST, LAST
2015-09-18 14:57:10 +00:00
func ( s * SelectStatement ) validSelectWithAggregate ( ) error {
calls := map [ string ] struct { } { }
numAggregates := 0
for _ , f := range s . Fields {
if c , ok := f . Expr . ( * Call ) ; ok {
calls [ c . Name ] = struct { } { }
numAggregates ++
}
}
// For TOP, BOTTOM, MAX, MIN, FIRST, LAST (selector functions) it is ok to ask for fields and tags
// but only if one function is specified. Combining multiple functions and fields and tags is not currently supported
onlySelectors := true
for k := range calls {
switch k {
case "top" , "bottom" , "max" , "min" , "first" , "last" :
default :
onlySelectors = false
2015-09-23 20:27:43 +00:00
break
2015-09-18 14:57:10 +00:00
}
}
if onlySelectors {
// If they only have one selector, they can have as many fields or tags as they want
if numAggregates == 1 {
return nil
}
// If they have multiple selectors, they are not allowed to have any other fields or tags specified
if numAggregates > 1 && len ( s . Fields ) != numAggregates {
return fmt . Errorf ( "mixing multiple selector functions with tags or fields is not supported" )
}
}
2015-09-04 12:56:00 +00:00
if numAggregates != 0 && numAggregates != len ( s . Fields ) {
return fmt . Errorf ( "mixing aggregate and non-aggregate queries is not supported" )
}
return nil
}
2015-05-19 15:11:12 +00:00
func ( s * SelectStatement ) validateAggregates ( tr targetRequirement ) error {
2015-05-19 16:18:50 +00:00
for _ , f := range s . Fields {
2015-09-03 21:40:10 +00:00
switch expr := f . Expr . ( type ) {
case * Call :
switch expr . Name {
2015-05-19 16:18:50 +00:00
case "derivative" , "non_negative_derivative" :
2015-09-18 14:57:10 +00:00
if err := s . validSelectWithAggregate ( ) ; err != nil {
2015-08-27 21:12:11 +00:00
return err
}
2015-09-03 21:40:10 +00:00
if min , max , got := 1 , 2 , len ( expr . 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" , expr . Name , min , max , got )
2015-05-19 16:18:50 +00:00
}
2015-09-17 17:52:54 +00:00
// Validate that if they have grouping by time, they need a sub-call like min/max, etc.
groupByInterval , _ := s . GroupByInterval ( )
if groupByInterval > 0 {
2015-09-11 14:37:35 +00:00
if _ , ok := expr . Args [ 0 ] . ( * Call ) ; ! ok {
return fmt . Errorf ( "aggregate function required inside the call to %s" , expr . Name )
}
}
2015-05-19 16:18:50 +00:00
case "percentile" :
2015-09-18 14:57:10 +00:00
if err := s . validSelectWithAggregate ( ) ; err != nil {
2015-08-27 21:12:11 +00:00
return err
}
2015-09-03 21:40:10 +00:00
if exp , got := 2 , len ( expr . Args ) ; got != exp {
return fmt . Errorf ( "invalid number of arguments for %s, expected %d, got %d" , expr . Name , exp , got )
2015-05-19 16:18:50 +00:00
}
2015-09-03 21:40:10 +00:00
_ , ok := expr . Args [ 1 ] . ( * NumberLiteral )
2015-08-31 16:10:00 +00:00
if ! ok {
return fmt . Errorf ( "expected float argument in percentile()" )
}
2015-08-27 21:12:11 +00:00
case "top" , "bottom" :
2015-09-03 21:40:10 +00:00
if exp , got := 2 , len ( expr . Args ) ; got < exp {
return fmt . Errorf ( "invalid number of arguments for %s, expected at least %d, got %d" , expr . Name , exp , got )
2015-08-27 21:12:11 +00:00
}
2015-09-03 21:40:10 +00:00
if len ( expr . Args ) > 1 {
callLimit , ok := expr . Args [ len ( expr . Args ) - 1 ] . ( * NumberLiteral )
2015-08-27 21:12:11 +00:00
if ! ok {
2015-09-03 21:40:10 +00:00
return fmt . Errorf ( "expected integer as last argument in %s(), found %s" , expr . Name , expr . Args [ len ( expr . Args ) - 1 ] )
2015-08-27 21:12:11 +00:00
}
2015-09-03 17:18:47 +00:00
// Check if they asked for a limit smaller than what they passed into the call
if int64 ( callLimit . Val ) > int64 ( s . Limit ) && s . Limit != 0 {
2015-09-03 21:40:10 +00:00
return fmt . Errorf ( "limit (%d) in %s function can not be larger than the LIMIT (%d) in the select statement" , int64 ( callLimit . Val ) , expr . Name , int64 ( s . Limit ) )
2015-09-03 17:18:47 +00:00
}
2015-09-03 21:40:10 +00:00
for _ , v := range expr . Args [ : len ( expr . Args ) - 1 ] {
2015-08-27 21:12:11 +00:00
if _ , ok := v . ( * VarRef ) ; ! ok {
2015-09-03 21:40:10 +00:00
return fmt . Errorf ( "only fields or tags are allowed in %s(), found %s" , expr . Name , v )
2015-08-27 21:12:11 +00:00
}
}
}
2015-05-19 16:18:50 +00:00
default :
2015-09-18 14:57:10 +00:00
if err := s . validSelectWithAggregate ( ) ; err != nil {
2015-08-27 21:12:11 +00:00
return err
}
2015-09-03 21:40:10 +00:00
if exp , got := 1 , len ( expr . Args ) ; got != exp {
return fmt . Errorf ( "invalid number of arguments for %s, expected %d, got %d" , expr . Name , exp , got )
2015-05-19 16:18:50 +00:00
}
2015-09-03 21:40:10 +00:00
switch fc := expr . Args [ 0 ] . ( type ) {
2015-08-31 21:04:53 +00:00
case * VarRef :
2015-09-03 21:40:10 +00:00
// do nothing
2015-08-31 21:04:53 +00:00
case * Call :
if fc . Name != "distinct" {
2015-09-03 21:40:10 +00:00
return fmt . Errorf ( "expected field argument in %s()" , expr . Name )
}
case * Distinct :
if expr . Name != "count" {
return fmt . Errorf ( "expected field argument in %s()" , expr . Name )
2015-08-31 21:04:53 +00:00
}
default :
2015-09-03 21:40:10 +00:00
return fmt . Errorf ( "expected field argument in %s()" , expr . Name )
2015-08-31 21:04:53 +00:00
}
}
2015-05-19 16:18:50 +00:00
}
}
2015-09-04 12:56:00 +00:00
// Check that we have valid duration and where clauses for aggregates
2015-05-19 16:18:50 +00:00
2015-05-12 14:56:38 +00:00
// fetch the group by duration
groupByDuration , _ := s . GroupByInterval ( )
2015-05-12 14:42:39 +00:00
// If we have a group by interval, but no aggregate function, it's an invalid statement
2015-05-15 21:48:16 +00:00
if s . IsRawQuery && groupByDuration > 0 {
2015-05-12 14:42:39 +00:00
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
2015-05-15 21:48:16 +00:00
if ! s . IsRawQuery && groupByDuration > 0 && ! s . hasTimeDimensions ( s . Condition ) {
2015-05-12 14:42:39 +00:00
return fmt . Errorf ( "aggregate functions with GROUP BY time require a WHERE time clause" )
}
}
2015-05-12 20:30:01 +00:00
return nil
}
2015-05-18 22:28:13 +00:00
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
}
2015-05-19 15:11:12 +00:00
func ( s * SelectStatement ) validateDistinct ( ) error {
2015-05-18 22:28:13 +00:00
if ! s . HasDistinct ( ) {
return nil
}
2015-05-12 14:42:39 +00:00
2015-05-14 15:37:30 +00:00
if len ( s . Fields ) > 1 {
2015-05-15 21:48:16 +00:00
return fmt . Errorf ( "aggregate function distinct() can not be combined with other functions or fields" )
2015-05-12 20:34:12 +00:00
}
2015-05-18 21:36:50 +00:00
switch c := s . Fields [ 0 ] . Expr . ( type ) {
case * Call :
if len ( c . Args ) == 0 {
return fmt . Errorf ( "distinct function requires at least one argument" )
}
2015-05-15 21:58:00 +00:00
2015-05-18 21:36:50 +00:00
if len ( c . Args ) != 1 {
return fmt . Errorf ( "distinct function can only have one argument" )
}
2015-05-15 21:58:00 +00:00
}
2015-05-12 20:34:12 +00:00
return nil
}
2015-05-19 00:13:44 +00:00
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
}
2015-05-19 18:43:16 +00:00
if c , ok := a . ( * Call ) ; ok {
if c . Name == "distinct" {
return true
}
}
2015-05-19 00:13:44 +00:00
}
}
}
}
return false
}
func ( s * SelectStatement ) validateCountDistinct ( ) error {
if ! s . HasCountDistinct ( ) {
return nil
}
2015-05-19 18:43:16 +00:00
valid := func ( e Expr ) bool {
2015-05-19 00:13:44 +00:00
c , ok := e . ( * Call )
if ! ok {
2015-05-19 18:43:16 +00:00
return true
2015-05-19 00:13:44 +00:00
}
if c . Name != "count" {
2015-05-19 18:43:16 +00:00
return true
2015-05-19 00:13:44 +00:00
}
for _ , a := range c . Args {
if _ , ok := a . ( * Distinct ) ; ok {
2015-05-19 18:43:16 +00:00
return len ( c . Args ) == 1
}
if d , ok := a . ( * Call ) ; ok {
if d . Name == "distinct" {
return len ( d . Args ) == 1
}
2015-05-19 00:13:44 +00:00
}
}
2015-05-19 18:43:16 +00:00
return true
2015-05-19 00:13:44 +00:00
}
for _ , f := range s . Fields {
2015-05-19 18:43:16 +00:00
if ! valid ( f . Expr ) {
return fmt . Errorf ( "count(distinct <field>) can only have one argument" )
2015-05-19 00:13:44 +00:00
}
}
return nil
}
2015-05-12 20:34:12 +00:00
func ( s * SelectStatement ) validateDerivative ( ) error {
2015-05-12 22:51:19 +00:00
if ! s . HasDerivative ( ) {
2015-05-12 20:34:12 +00:00
return nil
}
2015-05-12 19:03:34 +00:00
// 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.
2015-05-12 20:34:12 +00:00
if len ( s . Fields ) != 1 {
return fmt . Errorf ( "derivative cannot be used with other fields" )
}
aggr := s . FunctionCalls ( )
if len ( aggr ) != 1 {
2015-05-12 19:03:34 +00:00
return fmt . Errorf ( "derivative cannot be used with other fields" )
}
2015-05-12 20:34:12 +00:00
// Derivative requires two arguments
derivativeCall := aggr [ 0 ]
2015-05-14 21:11:00 +00:00
if len ( derivativeCall . Args ) == 0 {
return fmt . Errorf ( "derivative requires a field argument" )
2015-05-12 20:34:12 +00:00
}
// 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" )
}
2015-05-14 21:11:00 +00:00
// 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" )
}
2015-05-12 20:34:12 +00:00
}
2015-05-12 14:42:39 +00:00
return nil
}
2015-02-12 00:57:50 +00:00
// GroupByIterval extracts the time interval, if specified.
2015-01-20 02:44:47 +00:00
func ( s * SelectStatement ) GroupByInterval ( ) ( time . Duration , error ) {
2015-02-12 00:57:50 +00:00
// return if we've already pulled it out
2015-01-20 02:44:47 +00:00
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 {
2015-05-01 15:29:39 +00:00
if call , ok := d . Expr . ( * Call ) ; ok && call . Name == "time" {
2015-01-20 02:44:47 +00:00
// 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
}
2015-01-22 04:40:03 +00:00
// 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 {
2015-02-08 11:06:30 +00:00
cond := fmt . Sprintf ( "time >= '%s' AND time < '%s'" , start . UTC ( ) . Format ( time . RFC3339Nano ) , end . UTC ( ) . Format ( time . RFC3339Nano ) )
2015-01-22 04:40:03 +00:00
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
}
2015-01-25 21:41:39 +00:00
// fold out any previously replaced time dimensios and set the condition
s . Condition = Reduce ( expr , nil )
2015-01-22 04:40:03 +00:00
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
2015-01-28 05:11:48 +00:00
case * Call :
return & BooleanLiteral { Val : true }
2015-01-22 04:40:03 +00:00
default :
return n
}
} )
2015-01-28 05:11:48 +00:00
2015-01-22 04:40:03 +00:00
return n . String ( )
}
2014-12-10 14:44:52 +00:00
/ *
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 ( 5 m ) , 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"
* /
2014-12-06 18:17:58 +00:00
// 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 ,
2015-02-24 06:42:11 +00:00
Offset : s . Offset ,
2014-12-16 14:06:28 +00:00
SortFields : s . SortFields ,
2014-12-06 18:17:58 +00:00
}
// If there is only one series source then return it with the whole condition.
2015-03-06 13:52:25 +00:00
if len ( s . Sources ) == 1 {
other . Sources = s . Sources
2014-12-06 18:17:58 +00:00
other . Condition = s . Condition
return other , nil
}
// Find the matching source.
2015-03-06 13:52:25 +00:00
name := MatchSource ( s . Sources , ref . Val )
2014-12-06 18:17:58 +00:00
if name == "" {
return nil , fmt . Errorf ( "field source not found: %s" , ref . Val )
}
2015-03-06 13:52:25 +00:00
other . Sources = append ( other . Sources , & Measurement { Name : name } )
2014-12-06 18:17:58 +00:00
// Filter out conditions.
if s . Condition != nil {
other . Condition = filterExprBySource ( name , s . Condition )
}
return other , nil
}
2015-03-06 19:23:58 +00:00
// 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 {
2015-03-09 23:59:03 +00:00
a = walkNames ( s . Condition )
2015-03-06 19:23:58 +00:00
}
return a
2015-03-02 06:37:09 +00:00
}
2015-03-06 19:23:58 +00:00
// NamesInSelect returns the field and tag names (idents) in the select clause
func ( s * SelectStatement ) NamesInSelect ( ) [ ] string {
var a [ ] string
2015-03-02 06:37:09 +00:00
2015-02-23 23:07:01 +00:00
for _ , f := range s . Fields {
2015-03-09 23:59:03 +00:00
a = append ( a , walkNames ( f . Expr ) ... )
2015-02-23 23:07:01 +00:00
}
2015-03-02 06:37:09 +00:00
2015-03-06 19:23:58 +00:00
return a
2015-02-23 23:07:01 +00:00
}
2015-08-10 18:31:04 +00:00
// NamesInDimension returns the field and tag names (idents) in the group by
func ( s * SelectStatement ) NamesInDimension ( ) [ ] string {
var a [ ] string
for _ , d := range s . Dimensions {
a = append ( a , walkNames ( d . Expr ) ... )
}
return a
}
2015-09-20 22:27:22 +00:00
// LimitTagSets returns a tag set list with SLIMIT and SOFFSET applied.
func ( s * SelectStatement ) LimitTagSets ( a [ ] * TagSet ) [ ] * TagSet {
// Ignore if no limit or offset is specified.
if s . SLimit == 0 && s . SOffset == 0 {
return a
}
// If offset is beyond the number of tag sets then return nil.
if s . SOffset > len ( a ) {
return nil
}
// Clamp limit to the max number of tag sets.
if s . SOffset + s . SLimit > len ( a ) {
s . SLimit = len ( a ) - s . SOffset
}
return a [ s . SOffset : s . SOffset + s . SLimit ]
}
2015-03-09 23:59:03 +00:00
// walkNames will walk the Expr and return the database fields
func walkNames ( exp Expr ) [ ] string {
2015-03-02 06:37:09 +00:00
switch expr := exp . ( type ) {
2015-02-23 23:07:01 +00:00
case * VarRef :
2015-03-06 19:23:58 +00:00
return [ ] string { expr . Val }
2015-02-23 23:07:01 +00:00
case * Call :
2015-03-02 06:37:09 +00:00
if len ( expr . Args ) == 0 {
return nil
}
lit , ok := expr . Args [ 0 ] . ( * VarRef )
if ! ok {
return nil
}
2015-03-06 19:23:58 +00:00
return [ ] string { lit . Val }
2015-02-23 23:07:01 +00:00
case * BinaryExpr :
2015-03-06 19:23:58 +00:00
var ret [ ] string
2015-03-09 23:59:03 +00:00
ret = append ( ret , walkNames ( expr . LHS ) ... )
ret = append ( ret , walkNames ( expr . RHS ) ... )
2015-02-23 23:07:01 +00:00
return ret
case * ParenExpr :
2015-03-09 23:59:03 +00:00
return walkNames ( expr . Expr )
2015-02-23 23:07:01 +00:00
}
return nil
}
2015-03-10 00:03:49 +00:00
// FunctionCalls returns the Call objects from the query
func ( s * SelectStatement ) FunctionCalls ( ) [ ] * Call {
2015-02-23 23:07:01 +00:00
var a [ ] * Call
for _ , f := range s . Fields {
2015-03-10 00:03:49 +00:00
a = append ( a , walkFunctionCalls ( f . Expr ) ... )
2015-02-23 23:07:01 +00:00
}
return a
}
2015-09-23 14:47:24 +00:00
// FunctionCallsByPosition returns the Call objects from the query in the order they appear in the select statement
func ( s * SelectStatement ) FunctionCallsByPosition ( ) [ ] [ ] * Call {
2015-09-18 14:57:10 +00:00
var a [ ] [ ] * Call
for _ , f := range s . Fields {
a = append ( a , walkFunctionCalls ( f . Expr ) )
}
return a
}
2015-03-10 00:03:49 +00:00
// walkFunctionCalls walks the Field of a query for any function calls made
func walkFunctionCalls ( exp Expr ) [ ] * Call {
2015-03-02 06:37:09 +00:00
switch expr := exp . ( type ) {
2015-02-23 23:07:01 +00:00
case * VarRef :
return nil
case * Call :
return [ ] * Call { expr }
case * BinaryExpr :
var ret [ ] * Call
2015-03-10 00:03:49 +00:00
ret = append ( ret , walkFunctionCalls ( expr . LHS ) ... )
ret = append ( ret , walkFunctionCalls ( expr . RHS ) ... )
2015-02-23 23:07:01 +00:00
return ret
case * ParenExpr :
2015-03-10 00:03:49 +00:00
return walkFunctionCalls ( expr . Expr )
2015-02-23 23:07:01 +00:00
}
return nil
}
2014-12-31 22:34:46 +00:00
// filters an expression to exclude expressions unrelated to a source.
2014-12-06 18:17:58 +00:00
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
}
}
2014-12-29 02:33:41 +00:00
return & BinaryExpr { Op : expr . Op , LHS : lhs , RHS : rhs }
2014-12-06 18:17:58 +00:00
case * ParenExpr :
2014-12-29 02:33:41 +00:00
exp := filterExprBySource ( name , expr . Expr )
if exp == nil {
2014-12-06 18:17:58 +00:00
return nil
}
2014-12-29 02:33:41 +00:00
return & ParenExpr { Expr : exp }
2014-12-06 18:17:58 +00:00
}
return expr
}
// MatchSource returns the source name that matches a field name.
// Returns a blank string if no sources match.
2015-03-06 13:52:25 +00:00
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
2014-12-20 04:36:52 +00:00
}
2014-12-06 18:17:58 +00:00
}
}
return ""
}
2015-06-11 11:48:26 +00:00
// Target represents a target (destination) policy, measurement, and DB.
2015-01-06 21:30:27 +00:00
type Target struct {
// Measurement to write into.
2015-03-28 00:40:21 +00:00
Measurement * Measurement
2015-01-06 21:30:27 +00:00
}
// String returns a string representation of the Target.
func ( t * Target ) String ( ) string {
2015-03-28 00:40:21 +00:00
if t == nil {
return ""
}
2015-01-06 21:30:27 +00:00
var buf bytes . Buffer
_ , _ = buf . WriteString ( "INTO " )
2015-03-28 00:40:21 +00:00
_ , _ = buf . WriteString ( t . Measurement . String ( ) )
2015-08-27 23:23:21 +00:00
if t . Measurement . Name == "" {
_ , _ = buf . WriteString ( ":MEASUREMENT" )
}
2015-01-06 21:30:27 +00:00
return buf . String ( )
}
2014-11-22 04:12:48 +00:00
// DeleteStatement represents a command for removing data from the database.
type DeleteStatement struct {
2014-11-15 19:04:30 +00:00
// Data source that values are removed from.
2014-11-22 04:12:48 +00:00
Source Source
2014-11-15 19:04:30 +00:00
// An expression evaluated on data point.
Condition Expr
}
2014-12-06 18:17:58 +00:00
// 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 ( )
}
2015-02-01 18:47:48 +00:00
// RequiredPrivileges returns the privilege required to execute a DeleteStatement.
2015-01-19 20:12:48 +00:00
func ( s * DeleteStatement ) RequiredPrivileges ( ) ExecutionPrivileges {
2015-07-10 20:39:33 +00:00
return ExecutionPrivileges { { Admin : false , Name : "" , Privilege : WritePrivilege } }
2015-01-19 20:12:48 +00:00
}
2015-01-26 03:40:50 +00:00
// ShowSeriesStatement represents a command for listing series in the database.
type ShowSeriesStatement struct {
2015-01-28 04:36:19 +00:00
// Measurement(s) the series are listed for.
2015-05-24 10:30:47 +00:00
Sources Sources
2015-01-28 04:36:19 +00:00
2014-12-10 14:37:15 +00:00
// An expression evaluated on a series name or tag.
Condition Expr
2014-12-16 02:48:22 +00:00
// Fields to sort results by
SortFields SortFields
2014-12-10 14:37:15 +00:00
// Maximum number of rows to be returned.
// Unlimited if zero.
Limit int
2015-01-25 20:34:49 +00:00
// Returns rows starting at an offset from the first row.
Offset int
2014-12-10 14:37:15 +00:00
}
2014-11-22 23:33:21 +00:00
2014-12-06 18:17:58 +00:00
// String returns a string representation of the list series statement.
2015-01-26 03:40:50 +00:00
func ( s * ShowSeriesStatement ) String ( ) string {
2014-12-16 02:48:22 +00:00
var buf bytes . Buffer
2015-01-26 03:40:50 +00:00
_ , _ = buf . WriteString ( "SHOW SERIES" )
2014-12-16 02:48:22 +00:00
2015-05-24 10:30:47 +00:00
if s . Sources != nil {
_ , _ = buf . WriteString ( " FROM " )
_ , _ = buf . WriteString ( s . Sources . String ( ) )
}
2014-12-16 02:48:22 +00:00
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 ) )
}
2015-01-25 20:34:49 +00:00
if s . Offset > 0 {
_ , _ = buf . WriteString ( " OFFSET " )
_ , _ = buf . WriteString ( strconv . Itoa ( s . Offset ) )
}
2014-12-16 02:48:22 +00:00
return buf . String ( )
}
2014-12-06 18:17:58 +00:00
2015-02-01 18:47:48 +00:00
// RequiredPrivileges returns the privilege required to execute a ShowSeriesStatement.
2015-01-26 03:40:50 +00:00
func ( s * ShowSeriesStatement ) RequiredPrivileges ( ) ExecutionPrivileges {
2015-07-10 20:39:33 +00:00
return ExecutionPrivileges { { Admin : false , Name : "" , Privilege : ReadPrivilege } }
2015-01-19 20:12:48 +00:00
}
2014-11-22 23:33:21 +00:00
// DropSeriesStatement represents a command for removing a series from the database.
type DropSeriesStatement struct {
2015-02-17 23:29:25 +00:00
// Data source that fields are extracted from (optional)
2015-05-21 18:18:21 +00:00
Sources Sources
2015-02-17 23:29:25 +00:00
// An expression evaluated on data point (optional)
Condition Expr
2014-11-22 23:33:21 +00:00
}
2014-12-06 18:17:58 +00:00
// String returns a string representation of the drop series statement.
2015-02-17 23:29:25 +00:00
func ( s * DropSeriesStatement ) String ( ) string {
var buf bytes . Buffer
2015-05-20 21:27:33 +00:00
buf . WriteString ( "DROP SERIES" )
2015-02-17 23:29:25 +00:00
2015-05-21 18:18:21 +00:00
if s . Sources != nil {
2015-05-20 21:27:33 +00:00
buf . WriteString ( " FROM " )
2015-05-21 18:18:21 +00:00
buf . WriteString ( s . Sources . String ( ) )
2015-02-18 22:20:07 +00:00
}
if s . Condition != nil {
2015-05-20 21:27:33 +00:00
buf . WriteString ( " WHERE " )
buf . WriteString ( s . Condition . String ( ) )
2015-02-17 23:29:25 +00:00
}
return buf . String ( )
}
2014-12-06 18:17:58 +00:00
2015-06-28 06:54:34 +00:00
// RequiredPrivileges returns the privilege required to execute a DropSeriesStatement.
2015-01-19 20:12:48 +00:00
func ( s DropSeriesStatement ) RequiredPrivileges ( ) ExecutionPrivileges {
2015-07-10 20:39:33 +00:00
return ExecutionPrivileges { { Admin : false , Name : "" , Privilege : WritePrivilege } }
2015-01-19 20:12:48 +00:00
}
2015-10-03 02:49:11 +00:00
// DropServerStatement represents a command for removing a server from the cluster.
type DropServerStatement struct {
// ID of the node to be dropped.
NodeID uint64
// Force will force the server to drop even it it means losing data
Force bool
}
// String returns a string representation of the drop series statement.
func ( s * DropServerStatement ) String ( ) string {
var buf bytes . Buffer
_ , _ = buf . WriteString ( "DROP SERVER " )
_ , _ = buf . WriteString ( strconv . FormatUint ( s . NodeID , 10 ) )
if s . Force {
_ , _ = buf . WriteString ( " FORCE" )
}
return buf . String ( )
}
// RequiredPrivileges returns the privilege required to execute a DropServerStatement.
func ( s * DropServerStatement ) RequiredPrivileges ( ) ExecutionPrivileges {
return ExecutionPrivileges { { Name : "" , Privilege : AllPrivileges } }
}
2015-01-26 03:40:50 +00:00
// ShowContinuousQueriesStatement represents a command for listing continuous queries.
type ShowContinuousQueriesStatement struct { }
2014-11-22 23:33:21 +00:00
2014-12-06 18:17:58 +00:00
// String returns a string representation of the list continuous queries statement.
2015-01-26 03:40:50 +00:00
func ( s * ShowContinuousQueriesStatement ) String ( ) string { return "SHOW CONTINUOUS QUERIES" }
2014-12-06 18:17:58 +00:00
2015-02-01 18:47:48 +00:00
// RequiredPrivileges returns the privilege required to execute a ShowContinuousQueriesStatement.
2015-01-26 03:40:50 +00:00
func ( s * ShowContinuousQueriesStatement ) RequiredPrivileges ( ) ExecutionPrivileges {
2015-07-10 20:39:33 +00:00
return ExecutionPrivileges { { Admin : false , Name : "" , Privilege : ReadPrivilege } }
2015-01-19 20:12:48 +00:00
}
2015-05-24 07:27:02 +00:00
// 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 {
2015-07-10 20:39:33 +00:00
return ExecutionPrivileges { { Admin : true , Name : "" , Privilege : AllPrivileges } }
2015-05-24 07:27:02 +00:00
}
2015-03-10 19:46:05 +00:00
// 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 {
2015-07-10 20:39:33 +00:00
return ExecutionPrivileges { { Admin : true , Name : "" , Privilege : AllPrivileges } }
2015-03-10 19:46:05 +00:00
}
2015-01-26 03:40:50 +00:00
// ShowDatabasesStatement represents a command for listing all databases in the cluster.
type ShowDatabasesStatement struct { }
2015-01-09 15:47:57 +00:00
// String returns a string representation of the list databases command.
2015-01-26 03:40:50 +00:00
func ( s * ShowDatabasesStatement ) String ( ) string { return "SHOW DATABASES" }
2015-01-09 15:47:57 +00:00
2015-02-01 18:47:48 +00:00
// RequiredPrivileges returns the privilege required to execute a ShowDatabasesStatement
2015-01-26 03:40:50 +00:00
func ( s * ShowDatabasesStatement ) RequiredPrivileges ( ) ExecutionPrivileges {
2015-07-10 20:39:33 +00:00
return ExecutionPrivileges { { Admin : true , Name : "" , Privilege : AllPrivileges } }
2015-01-19 20:12:48 +00:00
}
2015-02-01 18:47:48 +00:00
// CreateContinuousQueryStatement represents a command for creating a continuous query.
2014-11-25 04:49:09 +00:00
type CreateContinuousQueryStatement struct {
2015-01-06 21:30:27 +00:00
// Name of the continuous query to be created.
Name string
// Name of the database to create the continuous query on.
2015-01-09 22:50:33 +00:00
Database string
2015-01-06 21:30:27 +00:00
// Source of data (SELECT statement).
2014-11-25 04:49:09 +00:00
Source * SelectStatement
}
2014-12-06 18:17:58 +00:00
// String returns a string representation of the statement.
func ( s * CreateContinuousQueryStatement ) String ( ) string {
2015-04-17 20:33:22 +00:00
return fmt . Sprintf ( "CREATE CONTINUOUS QUERY %s ON %s BEGIN %s END" , QuoteIdent ( s . Name ) , QuoteIdent ( s . Database ) , s . Source . String ( ) )
2014-12-06 18:17:58 +00:00
}
2015-03-28 00:40:21 +00:00
// DefaultDatabase returns the default database from the statement.
func ( s * CreateContinuousQueryStatement ) DefaultDatabase ( ) string {
return s . Database
}
2015-02-01 18:47:48 +00:00
// RequiredPrivileges returns the privilege required to execute a CreateContinuousQueryStatement.
2015-01-19 20:12:48 +00:00
func ( s * CreateContinuousQueryStatement ) RequiredPrivileges ( ) ExecutionPrivileges {
2015-07-10 20:39:33 +00:00
ep := ExecutionPrivileges { { Admin : false , Name : s . Database , Privilege : ReadPrivilege } }
2015-01-21 04:45:18 +00:00
// Selecting into a database that's different from the source?
2015-03-28 00:40:21 +00:00
if s . Source . Target . Measurement . Database != "" {
2015-01-21 04:45:18 +00:00
// Change source database privilege requirement to read.
ep [ 0 ] . Privilege = ReadPrivilege
// Add destination database privilege requirement and set it to write.
p := ExecutionPrivilege {
2015-07-10 20:39:33 +00:00
Admin : false ,
2015-03-28 00:40:21 +00:00
Name : s . Source . Target . Measurement . Database ,
2015-01-21 04:45:18 +00:00
Privilege : WritePrivilege ,
}
ep = append ( ep , p )
}
return ep
2015-01-19 20:12:48 +00:00
}
2015-02-01 18:47:48 +00:00
// DropContinuousQueryStatement represents a command for removing a continuous query.
2014-11-22 23:33:21 +00:00
type DropContinuousQueryStatement struct {
2015-03-25 00:11:26 +00:00
Name string
Database string
2014-11-22 23:33:21 +00:00
}
2014-12-06 18:17:58 +00:00
// String returns a string representation of the statement.
func ( s * DropContinuousQueryStatement ) String ( ) string {
return fmt . Sprintf ( "DROP CONTINUOUS QUERY %s" , s . Name )
}
2015-01-19 20:12:48 +00:00
// RequiredPrivileges returns the privilege(s) required to execute a DropContinuousQueryStatement
func ( s * DropContinuousQueryStatement ) RequiredPrivileges ( ) ExecutionPrivileges {
2015-07-10 20:39:33 +00:00
return ExecutionPrivileges { { Admin : false , Name : "" , Privilege : WritePrivilege } }
2015-01-19 20:12:48 +00:00
}
2015-01-26 03:40:50 +00:00
// ShowMeasurementsStatement represents a command for listing measurements.
type ShowMeasurementsStatement struct {
2014-12-16 02:48:22 +00:00
// 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
2015-01-25 20:34:49 +00:00
// Returns rows starting at an offset from the first row.
Offset int
2014-12-16 02:48:22 +00:00
}
// String returns a string representation of the statement.
2015-01-26 03:40:50 +00:00
func ( s * ShowMeasurementsStatement ) String ( ) string {
2014-12-16 14:06:28 +00:00
var buf bytes . Buffer
2015-01-26 03:40:50 +00:00
_ , _ = buf . WriteString ( "SHOW MEASUREMENTS" )
2014-12-16 02:48:22 +00:00
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 ) )
}
2015-01-25 20:34:49 +00:00
if s . Offset > 0 {
_ , _ = buf . WriteString ( " OFFSET " )
_ , _ = buf . WriteString ( strconv . Itoa ( s . Offset ) )
}
2014-12-16 02:48:22 +00:00
return buf . String ( )
}
2015-01-26 03:40:50 +00:00
// RequiredPrivileges returns the privilege(s) required to execute a ShowMeasurementsStatement
func ( s * ShowMeasurementsStatement ) RequiredPrivileges ( ) ExecutionPrivileges {
2015-07-10 20:39:33 +00:00
return ExecutionPrivileges { { Admin : false , Name : "" , Privilege : ReadPrivilege } }
2015-01-19 20:12:48 +00:00
}
2015-06-11 11:48:26 +00:00
// DropMeasurementStatement represents a command to drop a measurement.
2015-02-23 20:51:52 +00:00
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 {
2015-07-10 20:39:33 +00:00
return ExecutionPrivileges { { Admin : true , Name : "" , Privilege : AllPrivileges } }
2015-02-23 20:51:52 +00:00
}
2015-01-26 03:40:50 +00:00
// ShowRetentionPoliciesStatement represents a command for listing retention policies.
type ShowRetentionPoliciesStatement struct {
2015-01-13 20:21:06 +00:00
// Name of the database to list policies for.
Database string
}
2015-01-26 03:40:50 +00:00
// String returns a string representation of a ShowRetentionPoliciesStatement.
func ( s * ShowRetentionPoliciesStatement ) String ( ) string {
2015-01-13 20:21:06 +00:00
var buf bytes . Buffer
2015-01-26 03:40:50 +00:00
_ , _ = buf . WriteString ( "SHOW RETENTION POLICIES " )
2015-01-13 20:21:06 +00:00
_ , _ = buf . WriteString ( s . Database )
return buf . String ( )
}
2015-01-26 03:40:50 +00:00
// RequiredPrivileges returns the privilege(s) required to execute a ShowRetentionPoliciesStatement
func ( s * ShowRetentionPoliciesStatement ) RequiredPrivileges ( ) ExecutionPrivileges {
2015-07-10 20:39:33 +00:00
return ExecutionPrivileges { { Admin : false , Name : "" , Privilege : ReadPrivilege } }
2015-01-19 20:12:48 +00:00
}
2015-09-22 23:28:24 +00:00
// ShowStats statement displays statistics for a given module.
2015-03-12 23:07:41 +00:00
type ShowStatsStatement struct {
2015-09-22 23:28:24 +00:00
// Module
Module string
2015-03-12 23:07:41 +00:00
}
// String returns a string representation of a ShowStatsStatement.
func ( s * ShowStatsStatement ) String ( ) string {
var buf bytes . Buffer
_ , _ = buf . WriteString ( "SHOW STATS " )
2015-09-22 23:28:24 +00:00
if s . Module != "" {
2015-09-23 04:57:20 +00:00
_ , _ = buf . WriteString ( "FOR " )
2015-09-22 23:28:24 +00:00
_ , _ = buf . WriteString ( s . Module )
2015-03-12 23:07:41 +00:00
}
return buf . String ( )
}
// RequiredPrivileges returns the privilege(s) required to execute a ShowStatsStatement
func ( s * ShowStatsStatement ) RequiredPrivileges ( ) ExecutionPrivileges {
2015-07-10 20:39:33 +00:00
return ExecutionPrivileges { { Admin : true , Name : "" , Privilege : AllPrivileges } }
2015-08-24 19:29:17 +00:00
}
// ShowShardsStatement represents a command for displaying shards in the cluster.
type ShowShardsStatement struct { }
// String returns a string representation.
func ( s * ShowShardsStatement ) String ( ) string { return "SHOW SHARDS" }
// RequiredPrivileges returns the privileges required to execute the statement.
func ( s * ShowShardsStatement ) RequiredPrivileges ( ) ExecutionPrivileges {
return ExecutionPrivileges { { Admin : true , Name : "" , Privilege : AllPrivileges } }
2015-03-12 23:07:41 +00:00
}
2015-03-24 03:13:54 +00:00
// ShowDiagnosticsStatement represents a command for show node diagnostics.
2015-09-23 04:50:31 +00:00
type ShowDiagnosticsStatement struct {
// Module
Module string
}
2015-03-24 03:13:54 +00:00
// String returns a string representation of the ShowDiagnosticsStatement.
2015-09-23 04:50:31 +00:00
func ( s * ShowDiagnosticsStatement ) String ( ) string {
var buf bytes . Buffer
_ , _ = buf . WriteString ( "SHOW DIAGNOSTICS " )
if s . Module != "" {
_ , _ = buf . WriteString ( "FOR " )
_ , _ = buf . WriteString ( s . Module )
}
return buf . String ( )
}
2015-03-24 03:13:54 +00:00
// RequiredPrivileges returns the privilege required to execute a ShowDiagnosticsStatement
func ( s * ShowDiagnosticsStatement ) RequiredPrivileges ( ) ExecutionPrivileges {
2015-07-10 20:39:33 +00:00
return ExecutionPrivileges { { Admin : true , Name : "" , Privilege : AllPrivileges } }
2015-03-24 03:13:54 +00:00
}
2015-01-26 03:40:50 +00:00
// ShowTagKeysStatement represents a command for listing tag keys.
type ShowTagKeysStatement struct {
2015-05-24 09:30:15 +00:00
// Data sources that fields are extracted from.
Sources Sources
2014-12-16 02:48:22 +00:00
// An expression evaluated on data point.
Condition Expr
// Fields to sort results by
SortFields SortFields
2015-09-16 15:44:05 +00:00
// Maximum number of tag keys per measurement. Unlimited if zero.
2014-12-16 02:48:22 +00:00
Limit int
2015-01-25 20:34:49 +00:00
2015-09-16 15:44:05 +00:00
// Returns tag keys starting at an offset from the first row.
2015-01-25 20:34:49 +00:00
Offset int
2015-09-16 15:44:05 +00:00
// Maxiumum number of series to be returned. Unlimited if zero.
SLimit int
// Returns series starting at an offset from the first one.
SOffset int
2014-12-16 02:48:22 +00:00
}
// String returns a string representation of the statement.
2015-01-26 03:40:50 +00:00
func ( s * ShowTagKeysStatement ) String ( ) string {
2014-12-16 14:06:28 +00:00
var buf bytes . Buffer
2015-01-26 03:40:50 +00:00
_ , _ = buf . WriteString ( "SHOW TAG KEYS" )
2014-12-16 02:48:22 +00:00
2015-05-24 09:30:15 +00:00
if s . Sources != nil {
2014-12-16 02:48:22 +00:00
_ , _ = buf . WriteString ( " FROM " )
2015-05-24 09:30:15 +00:00
_ , _ = buf . WriteString ( s . Sources . String ( ) )
2014-12-16 02:48:22 +00:00
}
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 ) )
}
2015-01-25 20:34:49 +00:00
if s . Offset > 0 {
_ , _ = buf . WriteString ( " OFFSET " )
_ , _ = buf . WriteString ( strconv . Itoa ( s . Offset ) )
}
2015-09-16 15:44:05 +00:00
if s . SLimit > 0 {
_ , _ = buf . WriteString ( " SLIMIT " )
_ , _ = buf . WriteString ( strconv . Itoa ( s . SLimit ) )
}
if s . SOffset > 0 {
_ , _ = buf . WriteString ( " SOFFSET " )
_ , _ = buf . WriteString ( strconv . Itoa ( s . SOffset ) )
}
2014-12-16 02:48:22 +00:00
return buf . String ( )
}
2015-01-26 03:40:50 +00:00
// RequiredPrivileges returns the privilege(s) required to execute a ShowTagKeysStatement
func ( s * ShowTagKeysStatement ) RequiredPrivileges ( ) ExecutionPrivileges {
2015-07-10 20:39:33 +00:00
return ExecutionPrivileges { { Admin : false , Name : "" , Privilege : ReadPrivilege } }
2015-01-19 20:12:48 +00:00
}
2015-01-26 03:40:50 +00:00
// ShowTagValuesStatement represents a command for listing tag values.
type ShowTagValuesStatement struct {
2014-12-16 02:48:22 +00:00
// Data source that fields are extracted from.
2015-05-24 10:02:56 +00:00
Sources Sources
2014-12-16 02:48:22 +00:00
2015-01-29 17:09:05 +00:00
// Tag key(s) to pull values from.
TagKeys [ ] string
2014-12-16 02:48:22 +00:00
// 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
2015-01-25 20:34:49 +00:00
// Returns rows starting at an offset from the first row.
Offset int
2014-12-16 02:48:22 +00:00
}
// String returns a string representation of the statement.
2015-01-26 03:40:50 +00:00
func ( s * ShowTagValuesStatement ) String ( ) string {
2014-12-16 14:06:28 +00:00
var buf bytes . Buffer
2015-01-26 03:40:50 +00:00
_ , _ = buf . WriteString ( "SHOW TAG VALUES" )
2014-12-16 02:48:22 +00:00
2015-05-24 10:02:56 +00:00
if s . Sources != nil {
2014-12-16 02:48:22 +00:00
_ , _ = buf . WriteString ( " FROM " )
2015-05-24 10:02:56 +00:00
_ , _ = buf . WriteString ( s . Sources . String ( ) )
2014-12-16 02:48:22 +00:00
}
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 ) )
}
2015-01-25 20:34:49 +00:00
if s . Offset > 0 {
_ , _ = buf . WriteString ( " OFFSET " )
_ , _ = buf . WriteString ( strconv . Itoa ( s . Offset ) )
}
2014-12-16 02:48:22 +00:00
return buf . String ( )
}
2015-01-26 03:40:50 +00:00
// RequiredPrivileges returns the privilege(s) required to execute a ShowTagValuesStatement
func ( s * ShowTagValuesStatement ) RequiredPrivileges ( ) ExecutionPrivileges {
2015-07-10 20:39:33 +00:00
return ExecutionPrivileges { { Admin : false , Name : "" , Privilege : ReadPrivilege } }
2015-01-19 20:12:48 +00:00
}
2015-01-26 03:40:50 +00:00
// ShowUsersStatement represents a command for listing users.
type ShowUsersStatement struct { }
2015-01-14 16:53:17 +00:00
2015-06-28 06:54:34 +00:00
// String returns a string representation of the ShowUsersStatement.
2015-01-26 03:40:50 +00:00
func ( s * ShowUsersStatement ) String ( ) string {
return "SHOW USERS"
2015-01-14 16:53:17 +00:00
}
2015-01-26 03:40:50 +00:00
// RequiredPrivileges returns the privilege(s) required to execute a ShowUsersStatement
func ( s * ShowUsersStatement ) RequiredPrivileges ( ) ExecutionPrivileges {
2015-07-10 20:39:33 +00:00
return ExecutionPrivileges { { Admin : true , Name : "" , Privilege : AllPrivileges } }
2015-01-19 20:12:48 +00:00
}
2015-02-01 18:47:48 +00:00
// ShowFieldKeysStatement represents a command for listing field keys.
2015-01-26 03:40:50 +00:00
type ShowFieldKeysStatement struct {
2015-05-24 11:05:42 +00:00
// Data sources that fields are extracted from.
Sources Sources
2014-12-16 02:48:22 +00:00
// Fields to sort results by
SortFields SortFields
// Maximum number of rows to be returned.
// Unlimited if zero.
Limit int
2015-01-25 20:34:49 +00:00
// Returns rows starting at an offset from the first row.
Offset int
2014-12-16 02:48:22 +00:00
}
// String returns a string representation of the statement.
2015-01-26 03:40:50 +00:00
func ( s * ShowFieldKeysStatement ) String ( ) string {
2014-12-16 14:06:28 +00:00
var buf bytes . Buffer
2015-01-26 03:40:50 +00:00
_ , _ = buf . WriteString ( "SHOW FIELD KEYS" )
2014-12-16 02:48:22 +00:00
2015-05-24 11:05:42 +00:00
if s . Sources != nil {
2014-12-16 02:48:22 +00:00
_ , _ = buf . WriteString ( " FROM " )
2015-05-24 11:05:42 +00:00
_ , _ = buf . WriteString ( s . Sources . String ( ) )
2014-12-16 02:48:22 +00:00
}
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 ) )
}
2015-01-25 20:34:49 +00:00
if s . Offset > 0 {
_ , _ = buf . WriteString ( " OFFSET " )
_ , _ = buf . WriteString ( strconv . Itoa ( s . Offset ) )
}
2014-12-16 02:48:22 +00:00
return buf . String ( )
}
2015-01-26 03:40:50 +00:00
// RequiredPrivileges returns the privilege(s) required to execute a ShowFieldKeysStatement
func ( s * ShowFieldKeysStatement ) RequiredPrivileges ( ) ExecutionPrivileges {
2015-07-10 20:39:33 +00:00
return ExecutionPrivileges { { Admin : false , Name : "" , Privilege : ReadPrivilege } }
2015-01-19 20:12:48 +00:00
}
2014-11-15 19:04:30 +00:00
// Fields represents a list of fields.
type Fields [ ] * Field
2015-08-05 18:37:02 +00:00
// AliasNames returns a list of calculated field names in
// order of alias, function name, then field.
func ( a Fields ) AliasNames ( ) [ ] string {
names := [ ] string { }
for _ , f := range a {
names = append ( names , f . Name ( ) )
}
return names
}
// Names returns a list of raw field names.
func ( a Fields ) Names ( ) [ ] string {
names := [ ] string { }
for _ , f := range a {
var name string
switch expr := f . Expr . ( type ) {
case * Call :
name = expr . Name
case * VarRef :
name = expr . Val
}
names = append ( names , name )
}
return names
}
2014-12-06 18:17:58 +00:00
// String returns a string representation of the fields.
func ( a Fields ) String ( ) string {
var str [ ] string
for _ , f := range a {
str = append ( str , f . String ( ) )
}
return strings . Join ( str , ", " )
}
2014-11-22 04:12:48 +00:00
// Field represents an expression retrieved from a select statement.
2014-11-15 19:04:30 +00:00
type Field struct {
Expr Expr
Alias string
2014-12-08 05:08:39 +00:00
}
// Name returns the name of the field. Returns alias, if set.
// Otherwise uses the function name or variable name.
func ( f * Field ) Name ( ) string {
// Return alias, if set.
if f . Alias != "" {
return f . Alias
}
// Return the function name or variable name, if available.
switch expr := f . Expr . ( type ) {
case * Call :
return expr . Name
case * VarRef :
return expr . Val
}
// Otherwise return a blank name.
return ""
2014-11-15 19:04:30 +00:00
}
2014-12-06 18:17:58 +00:00
// String returns a string representation of the field.
func ( f * Field ) String ( ) string {
2015-07-22 19:49:17 +00:00
str := f . Expr . String ( )
2014-12-06 18:17:58 +00:00
if f . Alias == "" {
2015-07-22 19:49:17 +00:00
return str
2014-12-06 18:17:58 +00:00
}
2015-07-22 19:49:17 +00:00
return fmt . Sprintf ( "%s AS %s" , str , fmt . Sprintf ( ` "%s" ` , f . Alias ) )
2014-12-06 18:17:58 +00:00
}
2015-03-13 22:52:49 +00:00
// Sort Interface for Fields
2015-03-13 22:51:18 +00:00
func ( f Fields ) Len ( ) int { return len ( f ) }
func ( f Fields ) Less ( i , j int ) bool { return f [ i ] . Name ( ) < f [ j ] . Name ( ) }
func ( f Fields ) Swap ( i , j int ) { f [ i ] , f [ j ] = f [ j ] , f [ i ] }
2014-11-15 19:04:30 +00:00
// Dimensions represents a list of dimensions.
type Dimensions [ ] * Dimension
2014-12-06 18:17:58 +00:00
// String returns a string representation of the dimensions.
func ( a Dimensions ) String ( ) string {
var str [ ] string
for _ , d := range a {
str = append ( str , d . String ( ) )
}
return strings . Join ( str , ", " )
}
2015-01-23 09:44:56 +00:00
// Normalize returns the interval and tag dimensions separately.
// Returns 0 if no time interval is specified.
2015-09-10 18:08:03 +00:00
func ( a Dimensions ) Normalize ( ) ( time . Duration , [ ] string ) {
2015-01-23 09:44:56 +00:00
var dur time . Duration
var tags [ ] string
for _ , dim := range a {
switch expr := dim . Expr . ( type ) {
case * Call :
2015-09-10 18:08:03 +00:00
lit , _ := expr . Args [ 0 ] . ( * DurationLiteral )
dur = lit . Val
2015-01-23 09:44:56 +00:00
case * VarRef :
tags = append ( tags , expr . Val )
}
}
2015-09-10 18:08:03 +00:00
return dur , tags
2015-01-23 09:44:56 +00:00
}
2014-11-22 04:12:48 +00:00
// Dimension represents an expression that a select statement is grouped by.
2014-11-15 19:04:30 +00:00
type Dimension struct {
2014-11-22 04:12:48 +00:00
Expr Expr
2014-11-15 19:04:30 +00:00
}
2014-12-06 18:17:58 +00:00
// String returns a string representation of the dimension.
func ( d * Dimension ) String ( ) string { return d . Expr . String ( ) }
2014-12-20 04:36:52 +00:00
// Measurements represents a list of measurements.
type Measurements [ ] * Measurement
// String returns a string representation of the measurements.
func ( a Measurements ) String ( ) string {
var str [ ] string
for _ , m := range a {
str = append ( str , m . String ( ) )
}
return strings . Join ( str , ", " )
}
// Measurement represents a single measurement used as a datasource.
type Measurement struct {
2015-03-28 00:40:21 +00:00
Database string
RetentionPolicy string
Name string
Regex * RegexLiteral
2015-08-28 11:17:37 +00:00
IsTarget bool
2014-11-15 19:04:30 +00:00
}
2014-12-20 04:36:52 +00:00
// String returns a string representation of the measurement.
2015-03-06 13:52:25 +00:00
func ( m * Measurement ) String ( ) string {
var buf bytes . Buffer
2015-03-28 00:40:21 +00:00
if m . Database != "" {
_ , _ = buf . WriteString ( ` " ` )
_ , _ = buf . WriteString ( m . Database )
_ , _ = buf . WriteString ( ` ". ` )
2015-03-06 13:52:25 +00:00
}
2015-03-28 00:40:21 +00:00
if m . RetentionPolicy != "" {
_ , _ = buf . WriteString ( ` " ` )
_ , _ = buf . WriteString ( m . RetentionPolicy )
_ , _ = buf . WriteString ( ` " ` )
}
2014-12-06 18:17:58 +00:00
2015-03-28 00:40:21 +00:00
if m . Database != "" || m . RetentionPolicy != "" {
_ , _ = buf . WriteString ( ` . ` )
}
2014-11-15 19:04:30 +00:00
2015-03-28 00:40:21 +00:00
if m . Name != "" {
_ , _ = buf . WriteString ( QuoteIdent ( m . Name ) )
} else if m . Regex != nil {
_ , _ = buf . WriteString ( m . Regex . String ( ) )
}
2014-12-06 18:17:58 +00:00
2015-03-28 00:40:21 +00:00
return buf . String ( )
2014-11-15 19:04:30 +00:00
}
2014-11-22 04:12:48 +00:00
// VarRef represents a reference to a variable.
2014-11-15 19:04:30 +00:00
type VarRef struct {
Val string
}
2014-12-06 18:17:58 +00:00
// String returns a string representation of the variable reference.
2015-08-05 16:40:42 +00:00
func ( r * VarRef ) String ( ) string {
return QuoteIdent ( r . Val )
}
2014-12-06 18:17:58 +00:00
2014-11-15 19:04:30 +00:00
// Call represents a function call.
type Call struct {
Name string
2014-11-25 03:43:23 +00:00
Args [ ] Expr
2014-11-15 19:04:30 +00:00
}
2014-12-06 18:17:58 +00:00
// String returns a string representation of the call.
func ( c * Call ) String ( ) string {
// Join arguments.
var str [ ] string
for _ , arg := range c . Args {
str = append ( str , arg . String ( ) )
}
// Write function name and args.
return fmt . Sprintf ( "%s(%s)" , c . Name , strings . Join ( str , ", " ) )
}
2015-09-02 17:26:40 +00:00
// Fields will extract any field names from the call. Only specific calls support this.
func ( c * Call ) Fields ( ) [ ] string {
switch c . Name {
case "top" , "bottom" :
2015-09-04 18:41:46 +00:00
// maintain the order the user specified in the query
2015-09-02 17:26:40 +00:00
keyMap := make ( map [ string ] struct { } )
keys := [ ] string { }
2015-09-02 22:33:16 +00:00
for i , a := range c . Args {
if i == 0 {
2015-09-04 18:41:46 +00:00
// special case, first argument is always the name of the function regardless of the field name
2015-09-02 22:33:16 +00:00
keys = append ( keys , c . Name )
continue
}
2015-09-02 17:26:40 +00:00
switch v := a . ( type ) {
case * VarRef :
if _ , ok := keyMap [ v . Val ] ; ! ok {
keyMap [ v . Val ] = struct { } { }
keys = append ( keys , v . Val )
}
}
}
return keys
2015-09-18 14:57:10 +00:00
case "min" , "max" , "first" , "last" , "sum" , "mean" :
// maintain the order the user specified in the query
keyMap := make ( map [ string ] struct { } )
keys := [ ] string { }
for _ , a := range c . Args {
switch v := a . ( type ) {
case * VarRef :
if _ , ok := keyMap [ v . Val ] ; ! ok {
keyMap [ v . Val ] = struct { } { }
keys = append ( keys , v . Val )
}
}
}
return keys
2015-09-02 17:26:40 +00:00
default :
2015-09-18 14:57:10 +00:00
panic ( fmt . Sprintf ( "*call.Fields is unable to provide information on %s" , c . Name ) )
2015-09-02 17:26:40 +00:00
}
}
2015-05-18 21:36:50 +00:00
// Distinct represents a DISTINCT expression.
type Distinct struct {
// Identifier following DISTINCT
Val string
}
// String returns a string representation of the expression.
func ( d * Distinct ) String ( ) string {
return fmt . Sprintf ( "DISTINCT %s" , d . Val )
}
// NewCall returns a new call expression from this expressions.
func ( d * Distinct ) NewCall ( ) * Call {
return & Call {
Name : "distinct" ,
Args : [ ] Expr {
& VarRef { Val : d . Val } ,
} ,
}
}
2014-11-22 04:12:48 +00:00
// NumberLiteral represents a numeric literal.
type NumberLiteral struct {
2014-11-15 19:04:30 +00:00
Val float64
}
2014-12-06 18:17:58 +00:00
// String returns a string representation of the literal.
func ( l * NumberLiteral ) String ( ) string { return strconv . FormatFloat ( l . Val , 'f' , 3 , 64 ) }
2014-11-22 04:12:48 +00:00
// BooleanLiteral represents a boolean literal.
2014-11-15 19:04:30 +00:00
type BooleanLiteral struct {
Val bool
}
2014-12-06 18:17:58 +00:00
// String returns a string representation of the literal.
func ( l * BooleanLiteral ) String ( ) string {
if l . Val {
return "true"
}
return "false"
}
2015-01-23 09:44:56 +00:00
// isTrueLiteral returns true if the expression is a literal "true" value.
func isTrueLiteral ( expr Expr ) bool {
if expr , ok := expr . ( * BooleanLiteral ) ; ok {
return expr . Val == true
}
return false
}
// isFalseLiteral returns true if the expression is a literal "false" value.
func isFalseLiteral ( expr Expr ) bool {
if expr , ok := expr . ( * BooleanLiteral ) ; ok {
return expr . Val == false
}
return false
}
2014-11-22 04:12:48 +00:00
// StringLiteral represents a string literal.
2014-11-15 19:04:30 +00:00
type StringLiteral struct {
Val string
}
2014-12-06 18:17:58 +00:00
// String returns a string representation of the literal.
2015-01-19 20:01:32 +00:00
func ( l * StringLiteral ) String ( ) string { return QuoteString ( l . Val ) }
2014-12-06 18:17:58 +00:00
2014-11-22 04:12:48 +00:00
// TimeLiteral represents a point-in-time literal.
2014-11-15 19:04:30 +00:00
type TimeLiteral struct {
Val time . Time
}
2014-12-06 18:17:58 +00:00
// String returns a string representation of the literal.
2014-12-11 06:32:45 +00:00
func ( l * TimeLiteral ) String ( ) string {
2015-07-29 19:33:03 +00:00
return ` ' ` + l . Val . UTC ( ) . Format ( time . RFC3339Nano ) + ` ' `
2014-12-11 06:32:45 +00:00
}
2014-12-06 18:17:58 +00:00
2014-11-22 04:12:48 +00:00
// DurationLiteral represents a duration literal.
2014-11-15 19:04:30 +00:00
type DurationLiteral struct {
Val time . Duration
}
2014-12-06 18:17:58 +00:00
// String returns a string representation of the literal.
func ( l * DurationLiteral ) String ( ) string { return FormatDuration ( l . Val ) }
2015-01-23 09:44:56 +00:00
// nilLiteral represents a nil literal.
// This is not available to the query language itself. It's only used internally.
type nilLiteral struct { }
// String returns a string representation of the literal.
func ( l * nilLiteral ) String ( ) string { return ` nil ` }
2014-11-15 19:04:30 +00:00
// BinaryExpr represents an operation between two expressions.
type BinaryExpr struct {
Op Token
LHS Expr
RHS Expr
}
2014-12-06 18:17:58 +00:00
// String returns a string representation of the binary expression.
func ( e * BinaryExpr ) String ( ) string {
return fmt . Sprintf ( "%s %s %s" , e . LHS . String ( ) , e . Op . String ( ) , e . RHS . String ( ) )
}
2014-11-25 06:12:32 +00:00
// ParenExpr represents a parenthesized expression.
type ParenExpr struct {
Expr Expr
}
2014-12-06 18:17:58 +00:00
// String returns a string representation of the parenthesized expression.
func ( e * ParenExpr ) String ( ) string { return fmt . Sprintf ( "(%s)" , e . Expr . String ( ) ) }
2015-02-13 18:25:48 +00:00
// RegexLiteral represents a regular expression.
type RegexLiteral struct {
Val * regexp . Regexp
}
// String returns a string representation of the literal.
2015-03-06 13:52:25 +00:00
func ( r * RegexLiteral ) String ( ) string {
if r . Val != nil {
return fmt . Sprintf ( "/%s/" , r . Val . String ( ) )
}
return ""
}
2015-02-13 18:25:48 +00:00
2015-03-28 00:40:21 +00:00
// CloneRegexLiteral returns a clone of the RegexLiteral.
func CloneRegexLiteral ( r * RegexLiteral ) * RegexLiteral {
if r == nil {
return nil
}
clone := & RegexLiteral { }
if r . Val != nil {
clone . Val = regexp . MustCompile ( r . Val . String ( ) )
}
return clone
}
2014-11-25 23:23:10 +00:00
// Wildcard represents a wild card expression.
2014-12-06 18:17:58 +00:00
type Wildcard struct { }
// String returns a string representation of the wildcard.
func ( e * Wildcard ) String ( ) string { return "*" }
2014-11-25 22:43:22 +00:00
2015-01-23 09:44:56 +00:00
// CloneExpr returns a deep copy of the expression.
func CloneExpr ( expr Expr ) Expr {
if expr == nil {
return nil
}
2014-12-11 06:32:45 +00:00
switch expr := expr . ( type ) {
case * BinaryExpr :
2015-01-23 09:44:56 +00:00
return & BinaryExpr { Op : expr . Op , LHS : CloneExpr ( expr . LHS ) , RHS : CloneExpr ( expr . RHS ) }
2014-12-11 06:32:45 +00:00
case * BooleanLiteral :
2015-01-23 09:44:56 +00:00
return & BooleanLiteral { Val : expr . Val }
case * Call :
args := make ( [ ] Expr , len ( expr . Args ) )
for i , arg := range expr . Args {
args [ i ] = CloneExpr ( arg )
2014-12-11 06:32:45 +00:00
}
2015-01-23 09:44:56 +00:00
return & Call { Name : expr . Name , Args : args }
2015-05-18 21:36:50 +00:00
case * Distinct :
return & Distinct { Val : expr . Val }
2014-12-11 06:32:45 +00:00
case * DurationLiteral :
2015-01-23 09:44:56 +00:00
return & DurationLiteral { Val : expr . Val }
case * NumberLiteral :
return & NumberLiteral { Val : expr . Val }
case * ParenExpr :
return & ParenExpr { Expr : CloneExpr ( expr . Expr ) }
2015-02-16 20:30:58 +00:00
case * RegexLiteral :
return & RegexLiteral { Val : expr . Val }
2014-12-11 06:32:45 +00:00
case * StringLiteral :
2015-01-23 09:44:56 +00:00
return & StringLiteral { Val : expr . Val }
case * TimeLiteral :
return & TimeLiteral { Val : expr . Val }
case * VarRef :
return & VarRef { Val : expr . Val }
case * Wildcard :
return & Wildcard { }
2014-12-11 06:32:45 +00:00
}
2015-01-23 09:44:56 +00:00
panic ( "unreachable" )
2014-12-11 06:32:45 +00:00
}
2014-12-15 15:34:32 +00:00
// TimeRange returns the minimum and maximum times specified by an expression.
2014-12-16 15:50:30 +00:00
// Returns zero times if there is no bound.
2014-12-15 15:34:32 +00:00
func TimeRange ( expr Expr ) ( min , max time . Time ) {
WalkFunc ( expr , func ( n Node ) {
if n , ok := n . ( * BinaryExpr ) ; ok {
// Extract literal expression & operator on LHS.
// Check for "time" on the left-hand side first.
// Otherwise check for for the right-hand side and flip the operator.
value , op := timeExprValue ( n . LHS , n . RHS ) , n . Op
if value . IsZero ( ) {
if value = timeExprValue ( n . RHS , n . LHS ) ; value . IsZero ( ) {
return
} else if op == LT {
op = GT
} else if op == LTE {
op = GTE
} else if op == GT {
op = LT
} else if op == GTE {
op = LTE
}
}
// Update the min/max depending on the operator.
2015-07-29 19:33:03 +00:00
// The GT & LT update the value by +/- 1ns not make them "not equal".
2014-12-15 15:34:32 +00:00
switch op {
case GT :
if min . IsZero ( ) || value . After ( min ) {
2015-07-29 19:33:03 +00:00
min = value . Add ( time . Nanosecond )
2014-12-15 15:34:32 +00:00
}
case GTE :
if min . IsZero ( ) || value . After ( min ) {
min = value
}
case LT :
if max . IsZero ( ) || value . Before ( max ) {
2015-07-29 19:33:03 +00:00
max = value . Add ( - time . Nanosecond )
2014-12-15 15:34:32 +00:00
}
case LTE :
if max . IsZero ( ) || value . Before ( max ) {
max = value
}
case EQ :
if min . IsZero ( ) || value . After ( min ) {
min = value
}
if max . IsZero ( ) || value . Before ( max ) {
max = value
}
}
}
} )
return
}
2015-07-06 12:31:52 +00:00
// TimeRange returns the minimum and maximum times, as epoch nano, specified by
// and expression. If there is no lower bound, the start of the epoch is returned
// for minimum. If there is no higher bound, now is returned for maximum.
func TimeRangeAsEpochNano ( expr Expr ) ( min , max int64 ) {
tmin , tmax := TimeRange ( expr )
if tmin . IsZero ( ) {
min = time . Unix ( 0 , 0 ) . UnixNano ( )
} else {
min = tmin . UnixNano ( )
}
if tmax . IsZero ( ) {
max = time . Now ( ) . UnixNano ( )
} else {
max = tmax . UnixNano ( )
}
return
}
2014-12-15 15:34:32 +00:00
// timeExprValue returns the time literal value of a "time == <TimeLiteral>" expression.
// Returns zero time if the expression is not a time expression.
func timeExprValue ( ref Expr , lit Expr ) time . Time {
if ref , ok := ref . ( * VarRef ) ; ok && strings . ToLower ( ref . Val ) == "time" {
2014-12-21 18:07:14 +00:00
switch lit := lit . ( type ) {
case * TimeLiteral :
2014-12-15 15:34:32 +00:00
return lit . Val
2014-12-21 18:07:14 +00:00
case * DurationLiteral :
return time . Unix ( 0 , int64 ( lit . Val ) ) . UTC ( )
2015-08-18 21:17:18 +00:00
case * NumberLiteral :
return time . Unix ( 0 , int64 ( lit . Val ) ) . UTC ( )
2014-12-15 15:34:32 +00:00
}
}
return time . Time { }
}
2014-12-21 22:18:55 +00:00
// Visitor can be called by Walk to traverse an AST hierarchy.
// The Visit() function is called once per node.
type Visitor interface {
Visit ( Node ) Visitor
}
2014-11-15 19:04:30 +00:00
// Walk traverses a node hierarchy in depth-first order.
func Walk ( v Visitor , node Node ) {
2015-03-28 00:40:21 +00:00
if node == nil {
return
}
2014-11-15 19:04:30 +00:00
if v = v . Visit ( node ) ; v == nil {
return
}
switch n := node . ( type ) {
2015-03-28 00:40:21 +00:00
case * BinaryExpr :
Walk ( v , n . LHS )
Walk ( v , n . RHS )
2014-11-22 04:12:48 +00:00
2015-03-28 00:40:21 +00:00
case * Call :
for _ , expr := range n . Args {
Walk ( v , expr )
}
case * CreateContinuousQueryStatement :
Walk ( v , n . Source )
case * Dimension :
Walk ( v , n . Expr )
case Dimensions :
for _ , c := range n {
Walk ( v , c )
}
case * Field :
Walk ( v , n . Expr )
case Fields :
for _ , c := range n {
Walk ( v , c )
2014-11-15 19:04:30 +00:00
}
2015-03-28 00:40:21 +00:00
case * ParenExpr :
Walk ( v , n . Expr )
case * Query :
Walk ( v , n . Statements )
2014-11-22 04:12:48 +00:00
case * SelectStatement :
Walk ( v , n . Fields )
2015-03-28 00:40:21 +00:00
Walk ( v , n . Target )
2014-11-22 04:12:48 +00:00
Walk ( v , n . Dimensions )
2015-03-06 13:52:25 +00:00
Walk ( v , n . Sources )
2014-11-22 04:12:48 +00:00
Walk ( v , n . Condition )
2015-03-28 00:40:21 +00:00
Walk ( v , n . SortFields )
2014-11-22 04:12:48 +00:00
2015-01-28 04:36:19 +00:00
case * ShowSeriesStatement :
2015-05-24 10:30:47 +00:00
Walk ( v , n . Sources )
2015-01-28 04:36:19 +00:00
Walk ( v , n . Condition )
2015-01-29 01:26:15 +00:00
case * ShowTagKeysStatement :
2015-05-24 09:30:15 +00:00
Walk ( v , n . Sources )
2015-01-29 01:26:15 +00:00
Walk ( v , n . Condition )
Walk ( v , n . SortFields )
case * ShowTagValuesStatement :
2015-05-24 10:02:56 +00:00
Walk ( v , n . Sources )
2015-01-29 01:26:15 +00:00
Walk ( v , n . Condition )
Walk ( v , n . SortFields )
2015-05-24 11:05:42 +00:00
case * ShowFieldKeysStatement :
Walk ( v , n . Sources )
Walk ( v , n . SortFields )
2015-03-28 00:40:21 +00:00
case SortFields :
for _ , sf := range n {
Walk ( v , sf )
}
2015-03-13 22:35:36 +00:00
case Sources :
for _ , s := range n {
Walk ( v , s )
}
2015-03-28 00:40:21 +00:00
case Statements :
for _ , s := range n {
Walk ( v , s )
2014-11-15 19:04:30 +00:00
}
2015-03-28 00:40:21 +00:00
case * Target :
if n != nil {
Walk ( v , n . Measurement )
2014-11-25 03:43:23 +00:00
}
2014-11-15 19:04:30 +00:00
}
}
// WalkFunc traverses a node hierarchy in depth-first order.
func WalkFunc ( node Node , fn func ( Node ) ) {
Walk ( walkFuncVisitor ( fn ) , node )
}
type walkFuncVisitor func ( Node )
func ( fn walkFuncVisitor ) Visit ( n Node ) Visitor { fn ( n ) ; return fn }
2014-12-21 22:18:55 +00:00
// Rewriter can be called by Rewrite to replace nodes in the AST hierarchy.
// The Rewrite() function is called once per node.
type Rewriter interface {
Rewrite ( Node ) Node
}
// Rewrite recursively invokes the rewriter to replace each node.
// Nodes are traversed depth-first and rewritten from leaf to root.
func Rewrite ( r Rewriter , node Node ) Node {
switch n := node . ( type ) {
case * Query :
n . Statements = Rewrite ( r , n . Statements ) . ( Statements )
case Statements :
for i , s := range n {
n [ i ] = Rewrite ( r , s ) . ( Statement )
}
case * SelectStatement :
n . Fields = Rewrite ( r , n . Fields ) . ( Fields )
n . Dimensions = Rewrite ( r , n . Dimensions ) . ( Dimensions )
2015-03-06 13:52:25 +00:00
n . Sources = Rewrite ( r , n . Sources ) . ( Sources )
2014-12-21 22:18:55 +00:00
n . Condition = Rewrite ( r , n . Condition ) . ( Expr )
case Fields :
for i , f := range n {
n [ i ] = Rewrite ( r , f ) . ( * Field )
}
case * Field :
n . Expr = Rewrite ( r , n . Expr ) . ( Expr )
case Dimensions :
for i , d := range n {
n [ i ] = Rewrite ( r , d ) . ( * Dimension )
}
case * Dimension :
n . Expr = Rewrite ( r , n . Expr ) . ( Expr )
case * BinaryExpr :
n . LHS = Rewrite ( r , n . LHS ) . ( Expr )
n . RHS = Rewrite ( r , n . RHS ) . ( Expr )
case * ParenExpr :
n . Expr = Rewrite ( r , n . Expr ) . ( Expr )
case * Call :
for i , expr := range n . Args {
n . Args [ i ] = Rewrite ( r , expr ) . ( Expr )
}
}
return r . Rewrite ( node )
}
// RewriteFunc rewrites a node hierarchy.
func RewriteFunc ( node Node , fn func ( Node ) Node ) Node {
return Rewrite ( rewriterFunc ( fn ) , node )
}
type rewriterFunc func ( Node ) Node
func ( fn rewriterFunc ) Rewrite ( n Node ) Node { return fn ( n ) }
2015-01-23 09:44:56 +00:00
2015-01-28 00:20:34 +00:00
// Eval evaluates expr against a map.
func Eval ( expr Expr , m map [ string ] interface { } ) interface { } {
if expr == nil {
return nil
}
switch expr := expr . ( type ) {
case * BinaryExpr :
return evalBinaryExpr ( expr , m )
case * BooleanLiteral :
return expr . Val
case * NumberLiteral :
return expr . Val
case * ParenExpr :
return Eval ( expr . Expr , m )
case * StringLiteral :
return expr . Val
case * VarRef :
return m [ expr . Val ]
default :
return nil
}
}
func evalBinaryExpr ( expr * BinaryExpr , m map [ string ] interface { } ) interface { } {
lhs := Eval ( expr . LHS , m )
rhs := Eval ( expr . RHS , m )
// Evaluate if both sides are simple types.
switch lhs := lhs . ( type ) {
case bool :
rhs , _ := rhs . ( bool )
switch expr . Op {
case AND :
return lhs && rhs
case OR :
return lhs || rhs
2015-05-24 09:00:59 +00:00
case EQ :
return lhs == rhs
case NEQ :
return lhs != rhs
2015-01-28 00:20:34 +00:00
}
case float64 :
rhs , _ := rhs . ( float64 )
switch expr . Op {
case EQ :
return lhs == rhs
case NEQ :
return lhs != rhs
case LT :
return lhs < rhs
case LTE :
return lhs <= rhs
case GT :
return lhs > rhs
case GTE :
return lhs >= rhs
case ADD :
return lhs + rhs
case SUB :
return lhs - rhs
case MUL :
return lhs * rhs
case DIV :
if rhs == 0 {
return float64 ( 0 )
}
return lhs / rhs
}
2015-06-09 20:08:34 +00:00
case int64 :
// we parse all number literals as float 64, so we have to convert from
// an interface to the float64, then cast to an int64 for comparison
rhsf , _ := rhs . ( float64 )
rhs := int64 ( rhsf )
switch expr . Op {
case EQ :
return lhs == rhs
case NEQ :
return lhs != rhs
case LT :
return lhs < rhs
case LTE :
return lhs <= rhs
case GT :
return lhs > rhs
case GTE :
return lhs >= rhs
case ADD :
return lhs + rhs
case SUB :
return lhs - rhs
case MUL :
return lhs * rhs
case DIV :
if rhs == 0 {
return int64 ( 0 )
}
return lhs / rhs
}
2015-01-28 00:20:34 +00:00
case string :
rhs , _ := rhs . ( string )
switch expr . Op {
case EQ :
return lhs == rhs
case NEQ :
return lhs != rhs
}
}
return nil
}
2015-09-16 20:17:58 +00:00
// EvalBool evaluates expr and returns true if result is a boolean true.
// Otherwise returns false.
func EvalBool ( expr Expr , m map [ string ] interface { } ) bool {
v , _ := Eval ( expr , m ) . ( bool )
return v
}
2015-01-23 09:44:56 +00:00
// Reduce evaluates expr using the available values in valuer.
// References that don't exist in valuer are ignored.
func Reduce ( expr Expr , valuer Valuer ) Expr {
expr = reduce ( expr , valuer )
// Unwrap parens at top level.
if expr , ok := expr . ( * ParenExpr ) ; ok {
return expr . Expr
}
return expr
}
func reduce ( expr Expr , valuer Valuer ) Expr {
if expr == nil {
return nil
}
switch expr := expr . ( type ) {
case * BinaryExpr :
return reduceBinaryExpr ( expr , valuer )
case * Call :
return reduceCall ( expr , valuer )
case * ParenExpr :
return reduceParenExpr ( expr , valuer )
case * VarRef :
return reduceVarRef ( expr , valuer )
default :
return CloneExpr ( expr )
}
}
func reduceBinaryExpr ( expr * BinaryExpr , valuer Valuer ) Expr {
// Reduce both sides first.
op := expr . Op
lhs := reduce ( expr . LHS , valuer )
rhs := reduce ( expr . RHS , valuer )
// Do not evaluate if one side is nil.
if lhs == nil || rhs == nil {
return & BinaryExpr { LHS : lhs , RHS : rhs , Op : expr . Op }
}
// If we have a logical operator (AND, OR) and one side is a boolean literal
// then we need to have special handling.
if op == AND {
if isFalseLiteral ( lhs ) || isFalseLiteral ( rhs ) {
return & BooleanLiteral { Val : false }
} else if isTrueLiteral ( lhs ) {
return rhs
} else if isTrueLiteral ( rhs ) {
return lhs
}
} else if op == OR {
if isTrueLiteral ( lhs ) || isTrueLiteral ( rhs ) {
return & BooleanLiteral { Val : true }
} else if isFalseLiteral ( lhs ) {
return rhs
} else if isFalseLiteral ( rhs ) {
return lhs
}
}
// Evaluate if both sides are simple types.
switch lhs := lhs . ( type ) {
case * BooleanLiteral :
return reduceBinaryExprBooleanLHS ( op , lhs , rhs )
case * DurationLiteral :
return reduceBinaryExprDurationLHS ( op , lhs , rhs )
case * nilLiteral :
return reduceBinaryExprNilLHS ( op , lhs , rhs )
case * NumberLiteral :
return reduceBinaryExprNumberLHS ( op , lhs , rhs )
case * StringLiteral :
return reduceBinaryExprStringLHS ( op , lhs , rhs )
case * TimeLiteral :
return reduceBinaryExprTimeLHS ( op , lhs , rhs )
default :
return & BinaryExpr { Op : op , LHS : lhs , RHS : rhs }
}
}
func reduceBinaryExprBooleanLHS ( op Token , lhs * BooleanLiteral , rhs Expr ) Expr {
switch rhs := rhs . ( type ) {
case * BooleanLiteral :
switch op {
case EQ :
return & BooleanLiteral { Val : lhs . Val == rhs . Val }
case NEQ :
return & BooleanLiteral { Val : lhs . Val != rhs . Val }
case AND :
return & BooleanLiteral { Val : lhs . Val && rhs . Val }
case OR :
return & BooleanLiteral { Val : lhs . Val || rhs . Val }
}
case * nilLiteral :
return & BooleanLiteral { Val : false }
}
return & BinaryExpr { Op : op , LHS : lhs , RHS : rhs }
}
func reduceBinaryExprDurationLHS ( op Token , lhs * DurationLiteral , rhs Expr ) Expr {
switch rhs := rhs . ( type ) {
case * DurationLiteral :
switch op {
case ADD :
return & DurationLiteral { Val : lhs . Val + rhs . Val }
case SUB :
return & DurationLiteral { Val : lhs . Val - rhs . Val }
case EQ :
return & BooleanLiteral { Val : lhs . Val == rhs . Val }
case NEQ :
return & BooleanLiteral { Val : lhs . Val != rhs . Val }
case GT :
return & BooleanLiteral { Val : lhs . Val > rhs . Val }
case GTE :
return & BooleanLiteral { Val : lhs . Val >= rhs . Val }
case LT :
return & BooleanLiteral { Val : lhs . Val < rhs . Val }
case LTE :
return & BooleanLiteral { Val : lhs . Val <= rhs . Val }
}
case * NumberLiteral :
switch op {
case MUL :
return & DurationLiteral { Val : lhs . Val * time . Duration ( rhs . Val ) }
case DIV :
if rhs . Val == 0 {
return & DurationLiteral { Val : 0 }
}
return & DurationLiteral { Val : lhs . Val / time . Duration ( rhs . Val ) }
}
case * TimeLiteral :
switch op {
case ADD :
return & TimeLiteral { Val : rhs . Val . Add ( lhs . Val ) }
}
case * nilLiteral :
return & BooleanLiteral { Val : false }
}
return & BinaryExpr { Op : op , LHS : lhs , RHS : rhs }
}
func reduceBinaryExprNilLHS ( op Token , lhs * nilLiteral , rhs Expr ) Expr {
switch op {
case EQ , NEQ :
return & BooleanLiteral { Val : false }
}
return & BinaryExpr { Op : op , LHS : lhs , RHS : rhs }
}
func reduceBinaryExprNumberLHS ( op Token , lhs * NumberLiteral , rhs Expr ) Expr {
switch rhs := rhs . ( type ) {
case * NumberLiteral :
switch op {
case ADD :
return & NumberLiteral { Val : lhs . Val + rhs . Val }
case SUB :
return & NumberLiteral { Val : lhs . Val - rhs . Val }
case MUL :
return & NumberLiteral { Val : lhs . Val * rhs . Val }
case DIV :
if rhs . Val == 0 {
return & NumberLiteral { Val : 0 }
}
return & NumberLiteral { Val : lhs . Val / rhs . Val }
case EQ :
return & BooleanLiteral { Val : lhs . Val == rhs . Val }
case NEQ :
return & BooleanLiteral { Val : lhs . Val != rhs . Val }
case GT :
return & BooleanLiteral { Val : lhs . Val > rhs . Val }
case GTE :
return & BooleanLiteral { Val : lhs . Val >= rhs . Val }
case LT :
return & BooleanLiteral { Val : lhs . Val < rhs . Val }
case LTE :
return & BooleanLiteral { Val : lhs . Val <= rhs . Val }
}
case * nilLiteral :
return & BooleanLiteral { Val : false }
}
return & BinaryExpr { Op : op , LHS : lhs , RHS : rhs }
}
func reduceBinaryExprStringLHS ( op Token , lhs * StringLiteral , rhs Expr ) Expr {
switch rhs := rhs . ( type ) {
case * StringLiteral :
switch op {
case EQ :
return & BooleanLiteral { Val : lhs . Val == rhs . Val }
case NEQ :
return & BooleanLiteral { Val : lhs . Val != rhs . Val }
case ADD :
return & StringLiteral { Val : lhs . Val + rhs . Val }
}
case * nilLiteral :
switch op {
case EQ , NEQ :
return & BooleanLiteral { Val : false }
}
}
return & BinaryExpr { Op : op , LHS : lhs , RHS : rhs }
}
func reduceBinaryExprTimeLHS ( op Token , lhs * TimeLiteral , rhs Expr ) Expr {
switch rhs := rhs . ( type ) {
case * DurationLiteral :
switch op {
case ADD :
return & TimeLiteral { Val : lhs . Val . Add ( rhs . Val ) }
case SUB :
return & TimeLiteral { Val : lhs . Val . Add ( - rhs . Val ) }
}
case * TimeLiteral :
switch op {
case SUB :
return & DurationLiteral { Val : lhs . Val . Sub ( rhs . Val ) }
case EQ :
return & BooleanLiteral { Val : lhs . Val . Equal ( rhs . Val ) }
case NEQ :
return & BooleanLiteral { Val : ! lhs . Val . Equal ( rhs . Val ) }
case GT :
return & BooleanLiteral { Val : lhs . Val . After ( rhs . Val ) }
case GTE :
return & BooleanLiteral { Val : lhs . Val . After ( rhs . Val ) || lhs . Val . Equal ( rhs . Val ) }
case LT :
return & BooleanLiteral { Val : lhs . Val . Before ( rhs . Val ) }
case LTE :
return & BooleanLiteral { Val : lhs . Val . Before ( rhs . Val ) || lhs . Val . Equal ( rhs . Val ) }
}
case * nilLiteral :
return & BooleanLiteral { Val : false }
}
return & BinaryExpr { Op : op , LHS : lhs , RHS : rhs }
}
func reduceCall ( expr * Call , valuer Valuer ) Expr {
// Evaluate "now()" if valuer is set.
2015-05-01 15:29:39 +00:00
if expr . Name == "now" && len ( expr . Args ) == 0 && valuer != nil {
2015-01-23 09:44:56 +00:00
if v , ok := valuer . Value ( "now()" ) ; ok {
v , _ := v . ( time . Time )
return & TimeLiteral { Val : v }
}
}
// Otherwise reduce arguments.
args := make ( [ ] Expr , len ( expr . Args ) )
for i , arg := range expr . Args {
args [ i ] = reduce ( arg , valuer )
}
return & Call { Name : expr . Name , Args : args }
}
func reduceParenExpr ( expr * ParenExpr , valuer Valuer ) Expr {
subexpr := reduce ( expr . Expr , valuer )
if subexpr , ok := subexpr . ( * BinaryExpr ) ; ok {
return & ParenExpr { Expr : subexpr }
}
return subexpr
}
func reduceVarRef ( expr * VarRef , valuer Valuer ) Expr {
// Ignore if there is no valuer.
if valuer == nil {
return & VarRef { Val : expr . Val }
}
// Retrieve the value of the ref.
// Ignore if the value doesn't exist.
v , ok := valuer . Value ( expr . Val )
if ! ok {
return & VarRef { Val : expr . Val }
}
// Return the value as a literal.
switch v := v . ( type ) {
case bool :
return & BooleanLiteral { Val : v }
case time . Duration :
return & DurationLiteral { Val : v }
case float64 :
return & NumberLiteral { Val : v }
case string :
return & StringLiteral { Val : v }
case time . Time :
return & TimeLiteral { Val : v }
default :
return & nilLiteral { }
}
}
// Valuer is the interface that wraps the Value() method.
//
// Value returns the value and existence flag for a given key.
type Valuer interface {
Value ( key string ) ( interface { } , bool )
}
// nowValuer returns only the value for "now()".
2015-04-15 15:26:36 +00:00
type NowValuer struct {
2015-01-23 09:44:56 +00:00
Now time . Time
}
2015-04-15 15:26:36 +00:00
func ( v * NowValuer ) Value ( key string ) ( interface { } , bool ) {
2015-01-23 09:44:56 +00:00
if key == "now()" {
return v . Now , true
}
return nil , false
}