Remove unused functions in influxql/ast.go

pull/8745/head
Jonathan A. Sternberg 2017-08-25 07:33:48 -05:00
parent 905e7fe05e
commit ef0ad3292d
2 changed files with 0 additions and 449 deletions

View File

@ -81,15 +81,6 @@ func InspectDataType(v interface{}) DataType {
}
}
// InspectDataTypes returns all of the data types for an interface slice.
func InspectDataTypes(a []interface{}) []DataType {
dta := make([]DataType, len(a))
for i, v := range a {
dta[i] = InspectDataType(v)
}
return dta
}
// LessThan returns true if the other DataType has greater precedence than the
// current data type. Unknown has the lowest precedence.
//
@ -361,61 +352,6 @@ func (*SubQuery) source() {}
// Sources represents a list of sources.
type Sources []Source
// Names returns a list of source names.
func (a Sources) Names() []string {
names := make([]string, 0, len(a))
for _, s := range a {
switch s := s.(type) {
case *Measurement:
names = append(names, s.Name)
}
}
return names
}
// Filter returns a list of source names filtered by the database/retention policy.
func (a Sources) Filter(database, retentionPolicy string) []Source {
sources := make([]Source, 0, len(a))
for _, s := range a {
switch s := s.(type) {
case *Measurement:
if s.Database == database && s.RetentionPolicy == retentionPolicy {
sources = append(sources, s)
}
case *SubQuery:
filteredSources := s.Statement.Sources.Filter(database, retentionPolicy)
sources = append(sources, filteredSources...)
}
}
return sources
}
// HasSystemSource returns true if any of the sources are internal, system sources.
func (a Sources) HasSystemSource() bool {
for _, s := range a {
switch s := s.(type) {
case *Measurement:
if IsSystemName(s.Name) {
return true
}
}
}
return false
}
// HasRegex returns true if any of the sources are regex measurements.
func (a Sources) HasRegex() bool {
for _, s := range a {
switch s := s.(type) {
case *Measurement:
if s.Regex != nil {
return true
}
}
}
return false
}
// String returns a string representation of a Sources array.
func (a Sources) String() string {
var buf bytes.Buffer
@ -1070,46 +1006,6 @@ type SelectStatement struct {
Dedupe bool
}
// HasDerivative returns true if any function call in the statement is a
// derivative aggregate.
func (s *SelectStatement) HasDerivative() bool {
for _, f := range s.FunctionCalls() {
if f.Name == "derivative" || f.Name == "non_negative_derivative" {
return true
}
}
return false
}
// IsSimpleDerivative return true if any function call is a derivative function with a
// variable ref as the first arg.
func (s *SelectStatement) IsSimpleDerivative() bool {
for _, f := range s.FunctionCalls() {
if f.Name == "derivative" || f.Name == "non_negative_derivative" {
// it's nested if the first argument is an aggregate function
if _, ok := f.Args[0].(*VarRef); ok {
return true
}
}
}
return false
}
// HasSelector returns true if there is exactly one selector.
func (s *SelectStatement) HasSelector() bool {
var selector *Call
for _, f := range s.Fields {
if call, ok := f.Expr.(*Call); ok {
if selector != nil || !IsSelector(call) {
// This is an aggregate call or there is already a selector.
return false
}
selector = call
}
}
return selector != nil
}
// 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
@ -1529,42 +1425,6 @@ func (s *SelectStatement) RewriteTimeFields() {
}
}
// RewriteTimeCondition adds time constraints to aggregate queries.
func (s *SelectStatement) RewriteTimeCondition(now time.Time) error {
interval, err := s.GroupByInterval()
if err != nil {
return err
} else if interval > 0 && s.Condition != nil {
valuer := &NowValuer{Location: s.Location}
_, timeRange, err := ConditionExpr(s.Condition, valuer)
if err != nil {
return err
}
if timeRange.Max.IsZero() {
s.Condition = &BinaryExpr{
Op: AND,
LHS: s.Condition,
RHS: &BinaryExpr{
Op: LTE,
LHS: &VarRef{Val: "time"},
RHS: &TimeLiteral{Val: now},
},
}
}
}
for _, source := range s.Sources {
switch source := source.(type) {
case *SubQuery:
if err := source.Statement.RewriteTimeCondition(now); err != nil {
return err
}
}
}
return nil
}
// ColumnNames will walk all fields and functions and return the appropriate field names for the select statement
// while maintaining order of the field names.
func (s *SelectStatement) ColumnNames() []string {
@ -1674,17 +1534,6 @@ func (s *SelectStatement) Reduce(valuer Valuer) *SelectStatement {
return stmt
}
// 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
}
// String returns a string representation of the select statement.
func (s *SelectStatement) String() string {
var buf bytes.Buffer
@ -1889,37 +1738,6 @@ func (s *SelectStatement) rewriteWithoutTimeDimensions() string {
return n.String()
}
// NamesInWhere returns the field and tag names (idents) referenced in the where clause.
func (s *SelectStatement) NamesInWhere() []string {
var a []string
if s.Condition != nil {
a = walkNames(s.Condition)
}
return a
}
// NamesInSelect returns the field and tag names (idents) in the select clause.
func (s *SelectStatement) NamesInSelect() []string {
var a []string
for _, f := range s.Fields {
a = append(a, walkNames(f.Expr)...)
}
return a
}
// NamesInDimension returns the field and tag names (idents) in the group by clause.
func (s *SelectStatement) NamesInDimension() []string {
var a []string
for _, d := range s.Dimensions {
a = append(a, walkNames(d.Expr)...)
}
return a
}
func encodeMeasurement(mm *Measurement) *internal.Measurement {
pb := &internal.Measurement{
Database: proto.String(mm.Database),
@ -2023,57 +1841,6 @@ func ExprNames(expr Expr) []VarRef {
return a
}
// FunctionCalls returns the Call objects from the query.
func (s *SelectStatement) FunctionCalls() []*Call {
var a []*Call
for _, f := range s.Fields {
a = append(a, walkFunctionCalls(f.Expr)...)
}
return a
}
// FunctionCallsByPosition returns the Call objects from the query in the order they appear in the select statement.
func (s *SelectStatement) FunctionCallsByPosition() [][]*Call {
var a [][]*Call
for _, f := range s.Fields {
a = append(a, walkFunctionCalls(f.Expr))
}
return a
}
// walkFunctionCalls walks the Expr and returns any function calls made.
func walkFunctionCalls(exp Expr) []*Call {
switch expr := exp.(type) {
case *VarRef:
return nil
case *Call:
return []*Call{expr}
case *BinaryExpr:
var ret []*Call
ret = append(ret, walkFunctionCalls(expr.LHS)...)
ret = append(ret, walkFunctionCalls(expr.RHS)...)
return ret
case *ParenExpr:
return walkFunctionCalls(expr.Expr)
}
return nil
}
// MatchSource returns the source name that matches a field name.
// It returns a blank string if no sources match.
func MatchSource(sources Sources, name string) string {
for _, src := range sources {
switch src := src.(type) {
case *Measurement:
if strings.HasPrefix(name, src.Name) {
return src.Name
}
}
}
return ""
}
// Target represents a target (destination) policy, measurement, and DB.
type Target struct {
// Measurement to write into.
@ -4954,34 +4721,6 @@ func IsSelector(expr Expr) bool {
return false
}
// selectInfo represents an object that stores info about select fields.
type selectInfo struct {
calls map[*Call]struct{}
refs map[*VarRef]struct{}
}
// newSelectInfo creates a object with call and var ref info from stmt.
func newSelectInfo(stmt *SelectStatement) *selectInfo {
info := &selectInfo{
calls: make(map[*Call]struct{}),
refs: make(map[*VarRef]struct{}),
}
Walk(info, stmt.Fields)
return info
}
func (v *selectInfo) Visit(n Node) Visitor {
switch n := n.(type) {
case *Call:
v.calls[n] = struct{}{}
return nil
case *VarRef:
v.refs[n] = struct{}{}
return nil
}
return v
}
// stringSetSlice returns a sorted slice of keys from a string set.
func stringSetSlice(m map[string]struct{}) []string {
if m == nil {

View File

@ -229,24 +229,6 @@ func TestSelectStatement_SetTimeRange(t *testing.T) {
}
}
// Ensure the idents from the select clause can come out
func TestSelect_NamesInSelect(t *testing.T) {
s := MustParseSelectStatement("select count(asdf), count(bar) from cpu")
a := s.NamesInSelect()
if !reflect.DeepEqual(a, []string{"asdf", "bar"}) {
t.Fatal("expected names asdf and bar")
}
}
// Ensure the idents from the where clause can come out
func TestSelect_NamesInWhere(t *testing.T) {
s := MustParseSelectStatement("select * from cpu where time > 23s AND (asdf = 'jkl' OR (foo = 'bar' AND baz = 'bar'))")
a := s.NamesInWhere()
if !reflect.DeepEqual(a, []string{"time", "asdf", "foo", "baz"}) {
t.Fatalf("exp: time,asdf,foo,baz\ngot: %s\n", strings.Join(a, ","))
}
}
func TestSelectStatement_HasWildcard(t *testing.T) {
var tests = []struct {
stmt string
@ -708,133 +690,6 @@ func TestSelectStatement_IsRawQuerySet(t *testing.T) {
}
}
func TestSelectStatement_HasDerivative(t *testing.T) {
var tests = []struct {
stmt string
derivative bool
}{
// No derivatives
{
stmt: `SELECT value FROM cpu`,
derivative: false,
},
// Query derivative
{
stmt: `SELECT derivative(value) FROM cpu`,
derivative: true,
},
// No GROUP BY time only
{
stmt: `SELECT mean(value) FROM cpu where time < now() GROUP BY time(5ms)`,
derivative: false,
},
// No GROUP BY derivatives, time only
{
stmt: `SELECT derivative(mean(value)) FROM cpu where time < now() GROUP BY time(5ms)`,
derivative: true,
},
{
stmt: `SELECT value FROM cpu`,
derivative: false,
},
// Query derivative
{
stmt: `SELECT non_negative_derivative(value) FROM cpu`,
derivative: true,
},
// No GROUP BY derivatives, time only
{
stmt: `SELECT non_negative_derivative(mean(value)) FROM cpu where time < now() GROUP BY time(5ms)`,
derivative: true,
},
// Invalid derivative function name
{
stmt: `SELECT typoDerivative(value) FROM cpu where time < now()`,
derivative: false,
},
}
for i, tt := range tests {
// Parse statement.
t.Logf("index: %d, statement: %s", i, tt.stmt)
stmt, err := influxql.NewParser(strings.NewReader(tt.stmt)).ParseStatement()
if err != nil {
t.Fatalf("invalid statement: %q: %s", tt.stmt, err)
}
// Test derivative detection.
if d := stmt.(*influxql.SelectStatement).HasDerivative(); tt.derivative != d {
t.Errorf("%d. %q: unexpected derivative detection:\n\nexp=%v\n\ngot=%v\n\n", i, tt.stmt, tt.derivative, d)
continue
}
}
}
func TestSelectStatement_IsSimpleDerivative(t *testing.T) {
var tests = []struct {
stmt string
derivative bool
}{
// No derivatives
{
stmt: `SELECT value FROM cpu`,
derivative: false,
},
// Query derivative
{
stmt: `SELECT derivative(value) FROM cpu`,
derivative: true,
},
// Query derivative
{
stmt: `SELECT non_negative_derivative(value) FROM cpu`,
derivative: true,
},
// No GROUP BY time only
{
stmt: `SELECT mean(value) FROM cpu where time < now() GROUP BY time(5ms)`,
derivative: false,
},
// No GROUP BY derivatives, time only
{
stmt: `SELECT non_negative_derivative(mean(value)) FROM cpu where time < now() GROUP BY time(5ms)`,
derivative: false,
},
// Invalid derivative function name
{
stmt: `SELECT typoDerivative(value) FROM cpu where time < now()`,
derivative: false,
},
}
for i, tt := range tests {
// Parse statement.
t.Logf("index: %d, statement: %s", i, tt.stmt)
stmt, err := influxql.NewParser(strings.NewReader(tt.stmt)).ParseStatement()
if err != nil {
t.Fatalf("invalid statement: %q: %s", tt.stmt, err)
}
// Test derivative detection.
if d := stmt.(*influxql.SelectStatement).IsSimpleDerivative(); tt.derivative != d {
t.Errorf("%d. %q: unexpected derivative detection:\n\nexp=%v\n\ngot=%v\n\n", i, tt.stmt, tt.derivative, d)
continue
}
}
}
// Ensure binary expression names can be evaluated.
func TestBinaryExprName(t *testing.T) {
for i, tt := range []struct {
@ -1623,49 +1478,6 @@ func TestShow_Privileges(t *testing.T) {
}
}
func TestSources_Names(t *testing.T) {
sources := influxql.Sources([]influxql.Source{
&influxql.Measurement{
Name: "cpu",
},
&influxql.Measurement{
Name: "mem",
},
})
names := sources.Names()
if names[0] != "cpu" {
t.Errorf("expected cpu, got %s", names[0])
}
if names[1] != "mem" {
t.Errorf("expected mem, got %s", names[1])
}
}
func TestSources_HasSystemSource(t *testing.T) {
sources := influxql.Sources([]influxql.Source{
&influxql.Measurement{
Name: "_measurements",
},
})
ok := sources.HasSystemSource()
if !ok {
t.Errorf("expected to find a system source, found none")
}
sources = influxql.Sources([]influxql.Source{
&influxql.Measurement{
Name: "cpu",
},
})
ok = sources.HasSystemSource()
if ok {
t.Errorf("expected to find no system source, found one")
}
}
// This test checks to ensure that we have given thought to the database
// context required for security checks. If a new statement is added, this
// test will fail until it is categorized into the correct bucket below.