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"
"strconv"
"strings"
2014-11-15 19:04:30 +00:00
"time"
)
// DataType represents the primitive data types available in InfluxQL.
type DataType string
const (
2015-02-01 18:47:48 +00:00
// Unknown primitive data type.
Unknown = DataType ( "" )
// Number means the data type is an int or float.
Number = DataType ( "number" )
// Boolean means the data type is a boolean.
Boolean = DataType ( "boolean" )
// String means the data type is a string of text.
String = DataType ( "string" )
// Time means the data type is a time.
Time = DataType ( "time" )
// Duration means the data type is a duration of time.
2014-11-15 19:04:30 +00:00
Duration = DataType ( "duration" )
)
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 :
return Number
2015-02-14 00:28:12 +00:00
case int :
return Number
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
}
}
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 ( ) { }
func ( * DeleteStatement ) node ( ) { }
func ( * DropContinuousQueryStatement ) node ( ) { }
func ( * DropDatabaseStatement ) node ( ) { }
func ( * DropRetentionPolicyStatement ) node ( ) { }
func ( * DropSeriesStatement ) node ( ) { }
func ( * DropUserStatement ) node ( ) { }
func ( * GrantStatement ) node ( ) { }
func ( * ShowContinuousQueriesStatement ) node ( ) { }
func ( * ShowDatabasesStatement ) node ( ) { }
func ( * ShowFieldKeysStatement ) node ( ) { }
func ( * ShowRetentionPoliciesStatement ) node ( ) { }
func ( * ShowMeasurementsStatement ) node ( ) { }
func ( * ShowSeriesStatement ) node ( ) { }
func ( * ShowTagKeysStatement ) node ( ) { }
func ( * ShowTagValuesStatement ) node ( ) { }
func ( * ShowUsersStatement ) node ( ) { }
func ( * RevokeStatement ) node ( ) { }
func ( * SelectStatement ) 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 ( * Join ) node ( ) { }
func ( * Measurement ) node ( ) { }
func ( Measurements ) node ( ) { }
func ( * nilLiteral ) node ( ) { }
func ( * Merge ) node ( ) { }
func ( * NumberLiteral ) node ( ) { }
func ( * ParenExpr ) node ( ) { }
func ( * SortField ) node ( ) { }
func ( SortFields ) node ( ) { }
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-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 {
// Name of the database or resource.
// If "", then the resource is the cluster.
Name string
// Privilege required.
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 ( ) { }
func ( * DropRetentionPolicyStatement ) stmt ( ) { }
func ( * DropSeriesStatement ) stmt ( ) { }
func ( * DropUserStatement ) stmt ( ) { }
func ( * GrantStatement ) stmt ( ) { }
func ( * ShowContinuousQueriesStatement ) stmt ( ) { }
func ( * ShowDatabasesStatement ) stmt ( ) { }
func ( * ShowFieldKeysStatement ) stmt ( ) { }
func ( * ShowMeasurementsStatement ) stmt ( ) { }
func ( * ShowRetentionPoliciesStatement ) stmt ( ) { }
func ( * ShowSeriesStatement ) stmt ( ) { }
func ( * ShowTagKeysStatement ) stmt ( ) { }
func ( * ShowTagValuesStatement ) stmt ( ) { }
func ( * ShowUsersStatement ) stmt ( ) { }
func ( * RevokeStatement ) stmt ( ) { }
func ( * SelectStatement ) 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 ( ) { }
func ( * DurationLiteral ) expr ( ) { }
func ( * nilLiteral ) expr ( ) { }
func ( * NumberLiteral ) expr ( ) { }
func ( * ParenExpr ) expr ( ) { }
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-02-01 18:47:48 +00:00
func ( * Join ) source ( ) { }
func ( * Measurement ) source ( ) { }
func ( * Merge ) source ( ) { }
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
_ , _ = buf . WriteString ( field . Name )
_ , _ = buf . WriteString ( " " )
_ , _ = buf . WriteString ( strconv . FormatBool ( field . Ascending ) )
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
}
// String returns a string representation of the create database statement.
func ( s * CreateDatabaseStatement ) String ( ) string {
var buf bytes . Buffer
_ , _ = buf . WriteString ( "CREATE DATABASE " )
_ , _ = buf . WriteString ( s . Name )
return buf . String ( )
}
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-01-21 18:06:59 +00:00
return ExecutionPrivileges { { 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-01-21 18:06:59 +00:00
return ExecutionPrivileges { { 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-01-21 18:06:59 +00:00
return ExecutionPrivileges { { 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
// User's password
Password string
2015-01-09 22:50:33 +00:00
// User's privilege level.
Privilege * Privilege
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 " )
_ , _ = buf . WriteString ( s . Password )
2015-01-09 22:50:33 +00:00
if s . Privilege != nil {
_ , _ = buf . WriteString ( " WITH " )
_ , _ = buf . WriteString ( s . Privilege . String ( ) )
}
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-01-21 18:06:59 +00:00
return ExecutionPrivileges { { 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-01-21 18:06:59 +00:00
return ExecutionPrivileges { { 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
// Thing to grant privilege on (e.g., a DB).
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-01-03 07:06:18 +00:00
if s . On != "" {
_ , _ = 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-01-21 18:06:59 +00:00
return ExecutionPrivileges { { Name : "" , Privilege : AllPrivileges } }
2015-01-19 20:12:48 +00:00
}
2015-01-03 07:06:18 +00:00
// RevokeStatement represents a command to revoke a privilege from a user.
type RevokeStatement struct {
// Privilege to be revoked.
Privilege Privilege
// Thing to revoke privilege to (e.g., a DB)
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 ( ) )
if s . On != "" {
_ , _ = buf . WriteString ( " ON " )
_ , _ = buf . WriteString ( s . On )
}
_ , _ = 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-01-21 18:06:59 +00:00
return ExecutionPrivileges { { 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-01-21 18:06:59 +00:00
return ExecutionPrivileges { { 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-01-21 18:06:59 +00:00
return ExecutionPrivileges { { Name : "" , Privilege : AllPrivileges } }
2015-01-19 20:12:48 +00:00
}
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
// Data source that fields are extracted 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-15 00:54:51 +00:00
// Fields to sort results by
SortFields SortFields
2014-11-15 19:04:30 +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
2015-01-20 02:44:47 +00:00
// memoize the group by interval
groupByInterval time . Duration
2014-11-15 19:04:30 +00:00
}
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-01-26 12:19:35 +00:00
other := & SelectStatement {
2015-02-01 18:47:48 +00:00
Fields : make ( Fields , len ( s . Fields ) ) ,
Dimensions : make ( Dimensions , len ( s . Dimensions ) ) ,
Source : cloneSource ( s . Source ) ,
SortFields : make ( SortFields , len ( s . SortFields ) ) ,
Condition : CloneExpr ( s . Condition ) ,
Limit : s . Limit ,
2015-01-26 12:19:35 +00:00
}
2015-02-01 18:47:48 +00:00
if s . Target != nil {
other . Target = & Target { Measurement : s . Target . Measurement , Database : s . Target . Database }
2015-01-26 12:19:35 +00:00
}
2015-02-01 18:47:48 +00:00
for i , f := range s . Fields {
2015-01-26 12:19:35 +00:00
other . Fields [ i ] = & Field { Expr : CloneExpr ( f . Expr ) , Alias : f . Alias }
}
2015-02-01 18:47:48 +00:00
for i , d := range s . Dimensions {
2015-01-26 12:19:35 +00:00
other . Dimensions [ i ] = & Dimension { Expr : CloneExpr ( d . Expr ) }
}
// TODO: Copy sources.
2015-02-01 18:47:48 +00:00
for i , f := range s . SortFields {
2015-01-26 12:19:35 +00:00
other . SortFields [ i ] = & SortField { Name : f . Name , Ascending : f . Ascending }
}
return other
}
func cloneSource ( s Source ) Source {
if s == nil {
return nil
}
switch s := s . ( type ) {
case * Measurement :
return & Measurement { Name : s . Name }
case * Join :
other := & Join { Measurements : make ( Measurements , len ( s . Measurements ) ) }
for i , m := range s . Measurements {
other . Measurements [ i ] = & Measurement { Name : m . Name }
}
return other
case * Merge :
other := & Merge { Measurements : make ( Measurements , len ( s . Measurements ) ) }
for i , m := range s . Measurements {
other . Measurements [ i ] = & Measurement { Name : m . Name }
}
return other
default :
panic ( "unreachable" )
}
}
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 ( ) )
}
2014-12-06 18:17:58 +00:00
_ , _ = buf . WriteString ( " FROM " )
_ , _ = buf . WriteString ( s . Source . String ( ) )
if s . Condition != nil {
_ , _ = buf . WriteString ( " WHERE " )
_ , _ = buf . WriteString ( s . Condition . String ( ) )
}
if len ( s . Dimensions ) > 0 {
_ , _ = buf . WriteString ( " GROUP BY " )
_ , _ = buf . WriteString ( s . Dimensions . String ( ) )
}
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 ) )
}
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-01-21 18:06:59 +00:00
ep := ExecutionPrivileges { { Name : "" , Privilege : ReadPrivilege } }
2015-01-19 20:12:48 +00:00
if s . Target != nil {
2015-01-21 18:06:59 +00:00
p := ExecutionPrivilege { Name : s . Target . Database , Privilege : WritePrivilege }
2015-01-19 20:12:48 +00:00
ep = append ( ep , p )
}
return ep
}
2014-11-30 22:52:00 +00:00
// Aggregated returns true if the statement uses aggregate functions.
func ( s * SelectStatement ) Aggregated ( ) bool {
var v bool
WalkFunc ( s . Fields , func ( n Node ) {
if _ , ok := n . ( * Call ) ; ok {
v = true
}
} )
return v
}
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-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 {
if call , ok := d . Expr . ( * Call ) ; ok && strings . ToLower ( call . Name ) == "time" {
// Make sure there is exactly one argument.
if len ( call . Args ) != 1 {
return 0 , errors . New ( "time dimension expected one argument" )
}
// Ensure the argument is a duration.
lit , ok := call . Args [ 0 ] . ( * DurationLiteral )
if ! ok {
return 0 , errors . New ( "time dimension must have one duration argument" )
}
s . groupByInterval = lit . Val
return lit . Val , nil
}
}
return 0 , nil
}
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 ,
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.
2014-12-20 04:36:52 +00:00
if _ , ok := s . Source . ( * Measurement ) ; ok {
2014-12-06 18:17:58 +00:00
other . Source = s . Source
other . Condition = s . Condition
return other , nil
}
// Find the matching source.
name := MatchSource ( s . Source , ref . Val )
if name == "" {
return nil , fmt . Errorf ( "field source not found: %s" , ref . Val )
}
2014-12-20 04:36:52 +00:00
other . Source = & 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
}
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.
func MatchSource ( src Source , name string ) string {
switch src := src . ( type ) {
2014-12-20 04:36:52 +00:00
case * Measurement :
2014-12-06 18:17:58 +00:00
if strings . HasPrefix ( name , src . Name ) {
return src . Name
}
case * Join :
2014-12-20 04:36:52 +00:00
for _ , m := range src . Measurements {
if strings . HasPrefix ( name , m . Name ) {
return m . Name
}
2014-12-06 18:17:58 +00:00
}
case * Merge :
2014-12-20 04:36:52 +00:00
for _ , m := range src . Measurements {
if strings . HasPrefix ( name , m . Name ) {
return m . Name
}
2014-12-06 18:17:58 +00:00
}
}
return ""
}
2015-02-08 11:06:30 +00:00
// TODO pauldix: Target should actually have a Database, RetentionPolicy, and Measurement. These should be set based on the ON part of the query, and the SplitIdent of the INTO name
2015-01-06 21:30:27 +00:00
// Target represents a target (destination) policy, measurment, and DB.
type Target struct {
// Measurement to write into.
Measurement string
// Database to write into.
2015-01-09 22:50:33 +00:00
Database string
2015-01-06 21:30:27 +00:00
}
// String returns a string representation of the Target.
func ( t * Target ) String ( ) string {
var buf bytes . Buffer
_ , _ = buf . WriteString ( "INTO " )
_ , _ = buf . WriteString ( t . Measurement )
2015-01-09 22:50:33 +00:00
if t . Database != "" {
2015-01-06 21:30:27 +00:00
_ , _ = buf . WriteString ( " ON " )
2015-01-09 22:50:33 +00:00
_ , _ = buf . WriteString ( t . Database )
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-01-21 18:06:59 +00:00
return ExecutionPrivileges { { 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.
Source Source
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
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-01-21 18:06:59 +00:00
return ExecutionPrivileges { { 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 {
Name string
}
2014-12-06 18:17:58 +00:00
// String returns a string representation of the drop series statement.
func ( s * DropSeriesStatement ) String ( ) string { return fmt . Sprintf ( "DROP SERIES %s" , s . Name ) }
2015-02-01 18:47:48 +00:00
// RequiredPrivileges returns the privilige reqired to execute a DropSeriesStatement.
2015-01-19 20:12:48 +00:00
func ( s DropSeriesStatement ) RequiredPrivileges ( ) ExecutionPrivileges {
2015-01-21 18:06:59 +00:00
return ExecutionPrivileges { { Name : "" , Privilege : WritePrivilege } }
2015-01-19 20:12:48 +00:00
}
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-01-21 18:06:59 +00:00
return ExecutionPrivileges { { Name : "" , Privilege : ReadPrivilege } }
2015-01-19 20:12:48 +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-01-21 18:06:59 +00:00
return ExecutionPrivileges { { 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-01-09 22:50:33 +00:00
return fmt . Sprintf ( "CREATE CONTINUOUS QUERY %s ON %s BEGIN %s END" , s . Name , s . Database , s . Source . 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 CreateContinuousQueryStatement.
2015-01-19 20:12:48 +00:00
func ( s * CreateContinuousQueryStatement ) RequiredPrivileges ( ) ExecutionPrivileges {
2015-01-21 18:06:59 +00:00
ep := ExecutionPrivileges { { Name : s . Database , Privilege : ReadPrivilege } }
2015-01-21 04:45:18 +00:00
// Selecting into a database that's different from the source?
if s . Source . Target . Database != "" {
// Change source database privilege requirement to read.
ep [ 0 ] . Privilege = ReadPrivilege
// Add destination database privilege requirement and set it to write.
p := ExecutionPrivilege {
2015-01-21 18:06:59 +00:00
Name : s . Source . Target . 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 {
2014-11-25 00:58:21 +00:00
Name 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-01-21 18:06:59 +00:00
return ExecutionPrivileges { { 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-01-21 18:06:59 +00:00
return ExecutionPrivileges { { Name : "" , Privilege : ReadPrivilege } }
2015-01-19 20:12:48 +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-01-21 18:06:59 +00:00
return ExecutionPrivileges { { Name : "" , Privilege : ReadPrivilege } }
2015-01-19 20:12:48 +00:00
}
2015-01-26 03:40:50 +00:00
// ShowTagKeysStatement represents a command for listing tag keys.
type ShowTagKeysStatement struct {
2014-12-16 02:48:22 +00:00
// Data source that fields are extracted from.
Source Source
// 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 * 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
if s . Source != nil {
_ , _ = buf . WriteString ( " FROM " )
_ , _ = buf . WriteString ( s . Source . String ( ) )
}
if s . Condition != nil {
_ , _ = buf . WriteString ( " WHERE " )
_ , _ = buf . WriteString ( s . Condition . String ( ) )
}
if len ( s . SortFields ) > 0 {
_ , _ = buf . WriteString ( " ORDER BY " )
_ , _ = buf . WriteString ( s . SortFields . String ( ) )
}
if s . Limit > 0 {
_ , _ = buf . WriteString ( " LIMIT " )
_ , _ = buf . WriteString ( strconv . Itoa ( s . Limit ) )
}
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 ShowTagKeysStatement
func ( s * ShowTagKeysStatement ) RequiredPrivileges ( ) ExecutionPrivileges {
2015-01-21 18:06:59 +00:00
return ExecutionPrivileges { { 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.
Source Source
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
if s . Source != nil {
_ , _ = buf . WriteString ( " FROM " )
_ , _ = buf . WriteString ( s . Source . String ( ) )
}
if s . Condition != nil {
_ , _ = buf . WriteString ( " WHERE " )
_ , _ = buf . WriteString ( s . Condition . String ( ) )
}
if len ( s . SortFields ) > 0 {
_ , _ = buf . WriteString ( " ORDER BY " )
_ , _ = buf . WriteString ( s . SortFields . String ( ) )
}
if s . Limit > 0 {
_ , _ = buf . WriteString ( " LIMIT " )
_ , _ = buf . WriteString ( strconv . Itoa ( s . Limit ) )
}
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-01-21 18:06:59 +00:00
return ExecutionPrivileges { { 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-01-26 03:40:50 +00:00
// String retuns a string representation of the ShowUsersStatement.
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-01-21 18:06:59 +00:00
return ExecutionPrivileges { { 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 {
2014-12-16 02:48:22 +00:00
// Data source that fields are extracted from.
Source Source
// 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 * 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
if s . Source != nil {
_ , _ = buf . WriteString ( " FROM " )
_ , _ = buf . WriteString ( s . Source . String ( ) )
}
if s . Condition != nil {
_ , _ = buf . WriteString ( " WHERE " )
_ , _ = buf . WriteString ( s . Condition . String ( ) )
}
if len ( s . SortFields ) > 0 {
_ , _ = buf . WriteString ( " ORDER BY " )
_ , _ = buf . WriteString ( s . SortFields . String ( ) )
}
if s . Limit > 0 {
_ , _ = buf . WriteString ( " LIMIT " )
_ , _ = buf . WriteString ( strconv . Itoa ( s . Limit ) )
}
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-01-21 18:06:59 +00:00
return ExecutionPrivileges { { 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
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 {
if f . Alias == "" {
return f . Expr . String ( )
}
2015-01-18 21:45:22 +00:00
return fmt . Sprintf ( "%s AS %s" , f . Expr . String ( ) , f . Alias )
2014-12-06 18:17:58 +00:00
}
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.
// Returns an error if multiple time dimensions exist or if non-VarRef dimensions are specified.
func ( a Dimensions ) Normalize ( ) ( time . Duration , [ ] string , error ) {
var dur time . Duration
var tags [ ] string
for _ , dim := range a {
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 strings . ToLower ( expr . Name ) != "time" {
return 0 , nil , errors . New ( "only time() calls allowed in dimensions" )
} else if len ( expr . Args ) != 1 {
return 0 , nil , errors . New ( "time dimension expected one argument" )
} else if lit , ok := expr . Args [ 0 ] . ( * DurationLiteral ) ; ! ok {
return 0 , nil , errors . New ( "time dimension must have one duration argument" )
} else if dur != 0 {
return 0 , nil , errors . New ( "multiple time dimensions not allowed" )
} else {
dur = lit . Val
}
case * VarRef :
tags = append ( tags , expr . Val )
default :
return 0 , nil , errors . New ( "only time and tag dimensions allowed" )
}
}
return dur , tags , nil
}
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 {
2014-11-22 04:12:48 +00:00
Name string
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-01-18 21:45:22 +00:00
func ( m * Measurement ) String ( ) string { return m . Name }
2014-12-06 18:17:58 +00:00
// Join represents two datasources joined together.
type Join struct {
2014-12-20 04:36:52 +00:00
Measurements Measurements
2014-12-06 18:17:58 +00:00
}
// String returns a string representation of the join.
func ( j * Join ) String ( ) string {
2014-12-20 04:36:52 +00:00
return fmt . Sprintf ( "join(%s)" , j . Measurements . String ( ) )
2014-11-15 19:04:30 +00:00
}
2014-11-22 04:12:48 +00:00
// Merge represents a datasource created by merging two datasources.
type Merge struct {
2014-12-20 04:36:52 +00:00
Measurements Measurements
2014-12-06 18:17:58 +00:00
}
// String returns a string representation of the merge.
func ( m * Merge ) String ( ) string {
2014-12-20 04:36:52 +00:00
return fmt . Sprintf ( "merge(%s)" , m . Measurements . 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-01-18 21:45:22 +00:00
func ( r * VarRef ) String ( ) string { return 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 , ", " ) )
}
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 {
2014-12-21 17:59:36 +00:00
return ` " ` + l . Val . UTC ( ) . Format ( DateTimeFormat ) + ` " `
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 ( ) ) }
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 }
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 ) }
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.
// The GT & LT update the value by +/- 1µs not make them "not equal".
switch op {
case GT :
if min . IsZero ( ) || value . After ( min ) {
min = value . Add ( time . Microsecond )
}
case GTE :
if min . IsZero ( ) || value . After ( min ) {
min = value
}
case LT :
if max . IsZero ( ) || value . Before ( max ) {
max = value . Add ( - time . Microsecond )
}
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
}
// 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 ( )
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 ) {
if v = v . Visit ( node ) ; v == nil {
return
}
switch n := node . ( type ) {
2014-11-22 04:12:48 +00:00
case * Query :
Walk ( v , n . Statements )
case Statements :
for _ , s := range n {
Walk ( v , s )
2014-11-15 19:04:30 +00:00
}
2014-11-22 04:12:48 +00:00
case * SelectStatement :
Walk ( v , n . Fields )
Walk ( v , n . Dimensions )
Walk ( v , n . Source )
Walk ( v , n . Condition )
2015-01-28 04:36:19 +00:00
case * ShowSeriesStatement :
Walk ( v , n . Source )
Walk ( v , n . Condition )
2015-01-29 01:26:15 +00:00
case * ShowTagKeysStatement :
Walk ( v , n . Source )
Walk ( v , n . Condition )
Walk ( v , n . SortFields )
case * ShowTagValuesStatement :
Walk ( v , n . Source )
Walk ( v , n . Condition )
Walk ( v , n . SortFields )
2014-11-15 19:04:30 +00:00
case Fields :
for _ , c := range n {
Walk ( v , c )
}
case * Field :
Walk ( v , n . Expr )
case Dimensions :
for _ , c := range n {
Walk ( v , c )
}
case * Dimension :
Walk ( v , n . Expr )
case * BinaryExpr :
Walk ( v , n . LHS )
Walk ( v , n . RHS )
2014-11-25 06:12:32 +00:00
case * ParenExpr :
Walk ( v , n . Expr )
2014-11-15 19:04:30 +00:00
case * Call :
2014-11-25 03:43:23 +00:00
for _ , expr := range n . Args {
Walk ( v , expr )
}
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 )
n . Source = Rewrite ( r , n . Source ) . ( Source )
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
}
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
}
case string :
rhs , _ := rhs . ( string )
switch expr . Op {
case EQ :
return lhs == rhs
case NEQ :
return lhs != rhs
}
}
return nil
}
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.
if strings . ToLower ( expr . Name ) == "now" && len ( expr . Args ) == 0 && valuer != nil {
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()".
type nowValuer struct {
Now time . Time
}
func ( v * nowValuer ) Value ( key string ) ( interface { } , bool ) {
if key == "now()" {
return v . Now , true
}
return nil , false
}