diff --git a/CHANGELOG.md b/CHANGELOG.md index d1b58da0f4..1218caf414 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ ## PRs - [#2569](https://github.com/influxdb/influxdb/pull/2569): Add derivative functions - [#2598](https://github.com/influxdb/influxdb/pull/2598): Implement tag support in SELECT statements +- [#2624](https://github.com/influxdb/influxdb/pull/2624): Remove references to SeriesID in `DROP SERIES` handlers. ## v0.9.0-rc30 [2015-05-12] diff --git a/influxql/ast.go b/influxql/ast.go index 0a6ced7d24..b279a6d5fc 100644 --- a/influxql/ast.go +++ b/influxql/ast.go @@ -1448,11 +1448,8 @@ func (s *ShowSeriesStatement) RequiredPrivileges() ExecutionPrivileges { // DropSeriesStatement represents a command for removing a series from the database. type DropSeriesStatement struct { - // The Id of the series being dropped (optional) - SeriesID uint64 - // Data source that fields are extracted from (optional) - Source Source + Sources Sources // An expression evaluated on data point (optional) Condition Expr @@ -1461,20 +1458,15 @@ type DropSeriesStatement struct { // String returns a string representation of the drop series statement. func (s *DropSeriesStatement) String() string { var buf bytes.Buffer - i, _ := buf.WriteString("DROP SERIES") + buf.WriteString("DROP SERIES") - if s.Source != nil { - _, _ = buf.WriteString(" FROM ") - _, _ = buf.WriteString(s.Source.String()) + if s.Sources != nil { + buf.WriteString(" FROM ") + buf.WriteString(s.Sources.String()) } if s.Condition != nil { - _, _ = buf.WriteString(" WHERE ") - _, _ = buf.WriteString(s.Condition.String()) - } - - // If we haven't written any data since the initial statement, then this was a SeriesID statement - if len(buf.String()) == i { - _, _ = buf.WriteString(fmt.Sprintf(" %d", s.SeriesID)) + buf.WriteString(" WHERE ") + buf.WriteString(s.Condition.String()) } return buf.String() diff --git a/influxql/parser.go b/influxql/parser.go index 03179c39dd..2e48881219 100644 --- a/influxql/parser.go +++ b/influxql/parser.go @@ -1023,9 +1023,11 @@ func (p *Parser) parseDropSeriesStatement() (*DropSeriesStatement, error) { stmt := &DropSeriesStatement{} var err error - if tok, _, _ := p.scanIgnoreWhitespace(); tok == FROM { + tok, pos, lit := p.scanIgnoreWhitespace() + + if tok == FROM { // Parse source. - if stmt.Source, err = p.parseSource(); err != nil { + if stmt.Sources, err = p.parseSources(); err != nil { return nil, err } } else { @@ -1037,14 +1039,11 @@ func (p *Parser) parseDropSeriesStatement() (*DropSeriesStatement, error) { return nil, err } - // If they didn't provide a FROM or a WHERE, they need to provide the SeriesID - if stmt.Condition == nil && stmt.Source == nil { - id, err := p.parseUInt64() - if err != nil { - return nil, err - } - stmt.SeriesID = id + // If they didn't provide a FROM or a WHERE, this query is invalid + if stmt.Condition == nil && stmt.Sources == nil { + return nil, newParseError(tokstr(tok, lit), []string{"FROM", "WHERE"}, pos) } + return stmt, nil } diff --git a/influxql/parser_test.go b/influxql/parser_test.go index 3b40a2015d..b0d6955781 100644 --- a/influxql/parser_test.go +++ b/influxql/parser_test.go @@ -717,13 +717,9 @@ func TestParser_ParseStatement(t *testing.T) { }, // DROP SERIES statement - { - s: `DROP SERIES 1`, - stmt: &influxql.DropSeriesStatement{SeriesID: 1}, - }, { s: `DROP SERIES FROM src`, - stmt: &influxql.DropSeriesStatement{Source: &influxql.Measurement{Name: "src"}}, + stmt: &influxql.DropSeriesStatement{Sources: []influxql.Source{&influxql.Measurement{Name: "src"}}}, }, { s: `DROP SERIES WHERE host = 'hosta.influxdb.org'`, @@ -738,7 +734,7 @@ func TestParser_ParseStatement(t *testing.T) { { s: `DROP SERIES FROM src WHERE host = 'hosta.influxdb.org'`, stmt: &influxql.DropSeriesStatement{ - Source: &influxql.Measurement{Name: "src"}, + Sources: []influxql.Source{&influxql.Measurement{Name: "src"}}, Condition: &influxql.BinaryExpr{ Op: influxql.EQ, LHS: &influxql.VarRef{Val: "host"}, @@ -1158,7 +1154,7 @@ func TestParser_ParseStatement(t *testing.T) { {s: `DELETE FROM`, err: `found EOF, expected identifier at line 1, char 13`}, {s: `DELETE FROM myseries WHERE`, err: `found EOF, expected identifier, string, number, bool at line 1, char 28`}, {s: `DROP MEASUREMENT`, err: `found EOF, expected identifier at line 1, char 18`}, - {s: `DROP SERIES`, err: `found EOF, expected number at line 1, char 13`}, + {s: `DROP SERIES`, err: `found EOF, expected FROM, WHERE at line 1, char 13`}, {s: `DROP SERIES FROM`, err: `found EOF, expected identifier at line 1, char 18`}, {s: `DROP SERIES FROM src WHERE`, err: `found EOF, expected identifier, string, number, bool at line 1, char 28`}, {s: `SHOW CONTINUOUS`, err: `found EOF, expected QUERIES at line 1, char 17`}, @@ -1530,18 +1526,14 @@ func TestDropSeriesStatement_String(t *testing.T) { s string stmt influxql.Statement }{ - { - s: `DROP SERIES 1`, - stmt: &influxql.DropSeriesStatement{SeriesID: 1}, - }, { s: `DROP SERIES FROM src`, - stmt: &influxql.DropSeriesStatement{Source: &influxql.Measurement{Name: "src"}}, + stmt: &influxql.DropSeriesStatement{Sources: []influxql.Source{&influxql.Measurement{Name: "src"}}}, }, { s: `DROP SERIES FROM src WHERE host = 'hosta.influxdb.org'`, stmt: &influxql.DropSeriesStatement{ - Source: &influxql.Measurement{Name: "src"}, + Sources: []influxql.Source{&influxql.Measurement{Name: "src"}}, Condition: &influxql.BinaryExpr{ Op: influxql.EQ, LHS: &influxql.VarRef{Val: "host"}, @@ -1552,7 +1544,7 @@ func TestDropSeriesStatement_String(t *testing.T) { { s: `DROP SERIES FROM src WHERE host = 'hosta.influxdb.org'`, stmt: &influxql.DropSeriesStatement{ - Source: &influxql.Measurement{Name: "src"}, + Sources: []influxql.Source{&influxql.Measurement{Name: "src"}}, Condition: &influxql.BinaryExpr{ Op: influxql.EQ, LHS: &influxql.VarRef{Val: "host"}, diff --git a/server.go b/server.go index 2bd416a2a7..c2e5e1ef8a 100644 --- a/server.go +++ b/server.go @@ -2547,20 +2547,8 @@ func (s *Server) executeDropSeriesStatement(stmt *influxql.DropSeriesStatement, defer s.mu.RUnlock() seriesByMeasurement := make(map[string][]uint64) - // Handle the simple `DROP SERIES ` case. - if stmt.Source == nil && stmt.Condition == nil { - for _, db := range s.databases { - for _, m := range db.measurements { - if m.seriesByID[stmt.SeriesID] != nil { - seriesByMeasurement[m.Name] = []uint64{stmt.SeriesID} - } - } - } - return seriesByMeasurement, nil - } - - // Handle the more complicated `DROP SERIES` with sources and/or conditions... + // Handle `DROP SERIES` with sources and/or conditions... // Find the database. db := s.databases[database] @@ -2568,8 +2556,13 @@ func (s *Server) executeDropSeriesStatement(stmt *influxql.DropSeriesStatement, return nil, ErrDatabaseNotFound(database) } - // Get the list of measurements we're interested in. - measurements, err := measurementsFromSourceOrDB(stmt.Source, db) + // Expand regex expressions in the FROM clause. + sources, err := s.expandSources(stmt.Sources) + if err != nil { + return nil, err + } + + measurements, err := measurementsFromSourcesOrDB(db, sources...) if err != nil { return nil, err } @@ -3053,6 +3046,37 @@ func measurementsFromSourceOrDB(stmt influxql.Source, db *database) (Measurement return measurements, nil } +// measurementsFromSourcesOrDB returns a list of measurements from the +// sources passed in or, if sources is empty, a list of all +// measurement names from the database passed in. +func measurementsFromSourcesOrDB(db *database, sources ...influxql.Source) (Measurements, error) { + var measurements Measurements + if len(sources) > 0 { + for _, source := range sources { + if m, ok := source.(*influxql.Measurement); ok { + measurement := db.measurements[m.Name] + if measurement == nil { + return nil, ErrMeasurementNotFound(m.Name) + } + + measurements = append(measurements, measurement) + } else { + return nil, errors.New("identifiers in FROM clause must be measurement names") + } + } + } else { + // No measurements specified in FROM clause so get all measurements that have series. + for _, m := range db.Measurements() { + if len(m.seriesIDs) > 0 { + measurements = append(measurements, m) + } + } + } + sort.Sort(measurements) + + return measurements, nil +} + func (s *Server) executeShowUsersStatement(q *influxql.ShowUsersStatement, user *User) *Result { row := &influxql.Row{Columns: []string{"user", "admin"}} for _, user := range s.Users() {