Skip to content

Commit

Permalink
Merge pull request #6371 from influxdata/js-5707-deprecated-message
Browse files Browse the repository at this point in the history
Return a deprecated message when IF NOT EXISTS is used
  • Loading branch information
jsternberg committed Apr 15, 2016
2 parents 8838843 + 42b68d9 commit e2cf94e
Show file tree
Hide file tree
Showing 10 changed files with 107 additions and 15 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
- [#6263](https://github.com/influxdata/influxdb/pull/6263): Reduce UDP Service allocation size.
- [#6228](https://github.com/influxdata/influxdb/pull/6228): Support for multiple listeners for collectd and OpenTSDB inputs.
- [#6292](https://github.com/influxdata/influxdb/issues/6292): Allow percentile to be used as a selector.
- [#5707](https://github.com/influxdata/influxdb/issues/5707): Return a deprecated message when IF NOT EXISTS is used.

### Bugfixes

Expand Down
23 changes: 17 additions & 6 deletions client/influxdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -387,22 +387,31 @@ func (c *Client) Ping() (time.Duration, string, error) {

// Structs

// Message represents a user message.
type Message struct {
Level string `json:"level,omitempty"`
Text string `json:"text,omitempty"`
}

// Result represents a resultset returned from a single statement.
type Result struct {
Series []models.Row
Err error
Series []models.Row
Messages []*Message
Err error
}

// MarshalJSON encodes the result into JSON.
func (r *Result) MarshalJSON() ([]byte, error) {
// Define a struct that outputs "error" as a string.
var o struct {
Series []models.Row `json:"series,omitempty"`
Err string `json:"error,omitempty"`
Series []models.Row `json:"series,omitempty"`
Messages []*Message `json:"messages,omitempty"`
Err string `json:"error,omitempty"`
}

// Copy fields to output struct.
o.Series = r.Series
o.Messages = r.Messages
if r.Err != nil {
o.Err = r.Err.Error()
}
Expand All @@ -413,8 +422,9 @@ func (r *Result) MarshalJSON() ([]byte, error) {
// UnmarshalJSON decodes the data into the Result struct
func (r *Result) UnmarshalJSON(b []byte) error {
var o struct {
Series []models.Row `json:"series,omitempty"`
Err string `json:"error,omitempty"`
Series []models.Row `json:"series,omitempty"`
Messages []*Message `json:"messages,omitempty"`
Err string `json:"error,omitempty"`
}

dec := json.NewDecoder(bytes.NewBuffer(b))
Expand All @@ -424,6 +434,7 @@ func (r *Result) UnmarshalJSON(b []byte) error {
return err
}
r.Series = o.Series
r.Messages = o.Messages
if o.Err != "" {
r.Err = errors.New(o.Err)
}
Expand Down
38 changes: 38 additions & 0 deletions client/influxdb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,44 @@ func TestClient_UserAgent(t *testing.T) {
}
}

func TestClient_Messages(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"results":[{"messages":[{"level":"warning","text":"deprecation test"}]}]}`))
}))
defer ts.Close()

u, _ := url.Parse(ts.URL)
config := client.Config{URL: *u}
c, err := client.NewClient(config)
if err != nil {
t.Fatalf("unexpected error. expected %v, actual %v", nil, err)
}

query := client.Query{}
resp, err := c.Query(query)
if err != nil {
t.Fatalf("unexpected error. expected %v, actual %v", nil, err)
}

if got, exp := len(resp.Results), 1; got != exp {
t.Fatalf("unexpected number of results. expected %v, actual %v", exp, got)
}

r := resp.Results[0]
if got, exp := len(r.Messages), 1; got != exp {
t.Fatalf("unexpected number of messages. expected %v, actual %v", exp, got)
}

m := r.Messages[0]
if got, exp := m.Level, "warning"; got != exp {
t.Errorf("unexpected message level. expected %v, actual %v", exp, got)
}
if got, exp := m.Text, "deprecation test"; got != exp {
t.Errorf("unexpected message text. expected %v, actual %v", exp, got)
}
}

func TestPoint_UnmarshalEpoch(t *testing.T) {
now := time.Now()
tests := []struct {
Expand Down
11 changes: 9 additions & 2 deletions client/v2/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -516,10 +516,17 @@ func (r *Response) Error() error {
return nil
}

// Message represents a user message.
type Message struct {
Level string
Text string
}

// Result represents a resultset returned from a single statement.
type Result struct {
Series []models.Row
Err string `json:"error,omitempty"`
Series []models.Row
Messages []*Message
Err string `json:"error,omitempty"`
}

func (uc *udpclient) Query(q Query) (*Response, error) {
Expand Down
9 changes: 9 additions & 0 deletions cluster/statement_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,21 @@ func (e *StatementExecutor) ExecuteStatement(stmt influxql.Statement, ctx *influ
}

var rows models.Rows
var messages []*influxql.Message
var err error
switch stmt := stmt.(type) {
case *influxql.AlterRetentionPolicyStatement:
err = e.executeAlterRetentionPolicyStatement(stmt)
case *influxql.CreateContinuousQueryStatement:
err = e.executeCreateContinuousQueryStatement(stmt)
case *influxql.CreateDatabaseStatement:
if stmt.IfNotExists {
ctx.Log.Println("WARNING: IF NOT EXISTS is deprecated as of v0.13.0 and will be removed in v1.0")
messages = append(messages, &influxql.Message{
Level: influxql.WarningLevel,
Text: "IF NOT EXISTS is deprecated as of v0.13.0 and will be removed in v1.0",
})
}
err = e.executeCreateDatabaseStatement(stmt)
case *influxql.CreateRetentionPolicyStatement:
err = e.executeCreateRetentionPolicyStatement(stmt)
Expand Down Expand Up @@ -115,6 +123,7 @@ func (e *StatementExecutor) ExecuteStatement(stmt influxql.Statement, ctx *influ
ctx.Results <- &influxql.Result{
StatementID: ctx.StatementID,
Series: rows,
Messages: messages,
}
return nil
}
Expand Down
7 changes: 6 additions & 1 deletion cmd/influx/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,12 @@ func (c *CommandLine) writeCSV(response *client.Response, w io.Writer) {

func (c *CommandLine) writeColumns(response *client.Response, w io.Writer) {
for _, result := range response.Results {
// Create a tabbed writer for each result a they won't always line up
// Print out all messages first
for _, m := range result.Messages {
fmt.Fprintf(w, "%s: %s.\n", m.Level, m.Text)
}

// Create a tabbed writer for each result as they won't always line up
w := new(tabwriter.Writer)
w.Init(os.Stdout, 0, 8, 1, '\t', 0)
csv := c.formatResults(result, "\t")
Expand Down
4 changes: 2 additions & 2 deletions cmd/influxd/run/server_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,12 @@ func init() {
&Query{
name: "create database should not error with existing database with IF NOT EXISTS",
command: `CREATE DATABASE IF NOT EXISTS db0`,
exp: `{"results":[{}]}`,
exp: `{"results":[{"messages":[{"level":"warning","text":"IF NOT EXISTS is deprecated as of v0.13.0 and will be removed in v1.0"}]}]}`,
},
&Query{
name: "create database should create non-existing database with IF NOT EXISTS",
command: `CREATE DATABASE IF NOT EXISTS db1`,
exp: `{"results":[{}]}`,
exp: `{"results":[{"messages":[{"level":"warning","text":"IF NOT EXISTS is deprecated as of v0.13.0 and will be removed in v1.0"}]}]}`,
},
&Query{
name: "create database with retention duration should error if retention policy is different with IF NOT EXISTS",
Expand Down
4 changes: 4 additions & 0 deletions influxql/query_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ type ExecutionContext struct {
// The requested maximum number of points to return in each result.
ChunkSize int

// Hold the query executor's logger.
Log *log.Logger

// A channel that is closed when the query is interrupted.
InterruptCh <-chan struct{}
}
Expand Down Expand Up @@ -176,6 +179,7 @@ func (e *QueryExecutor) executeQuery(query *Query, database string, chunkSize in
Results: results,
Database: database,
ChunkSize: chunkSize,
Log: logger,
InterruptCh: task.closing,
}

Expand Down
24 changes: 20 additions & 4 deletions influxql/result.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ import (
"github.com/influxdata/influxdb/models"
)

const (
// WarningLevel is the message level for a warning.
WarningLevel = "warning"
)

// TagSet is a fundamental concept within the query system. It represents a composite series,
// composed of multiple individual series that share a set of tag attributes.
type TagSet struct {
Expand All @@ -22,26 +27,35 @@ func (t *TagSet) AddFilter(key string, filter Expr) {
t.Filters = append(t.Filters, filter)
}

// Message represents a user-facing message to be included with the result.
type Message struct {
Level string `json:"level"`
Text string `json:"text"`
}

// Result represents a resultset returned from a single statement.
// Rows represents a list of rows that can be sorted consistently by name/tag.
type Result struct {
// StatementID is just the statement's position in the query. It's used
// to combine statement results if they're being buffered in memory.
StatementID int `json:"-"`
Series models.Rows
Messages []*Message
Err error
}

// MarshalJSON encodes the result into JSON.
func (r *Result) MarshalJSON() ([]byte, error) {
// Define a struct that outputs "error" as a string.
var o struct {
Series []*models.Row `json:"series,omitempty"`
Err string `json:"error,omitempty"`
Series []*models.Row `json:"series,omitempty"`
Messages []*Message `json:"messages,omitempty"`
Err string `json:"error,omitempty"`
}

// Copy fields to output struct.
o.Series = r.Series
o.Messages = r.Messages
if r.Err != nil {
o.Err = r.Err.Error()
}
Expand All @@ -52,15 +66,17 @@ func (r *Result) MarshalJSON() ([]byte, error) {
// UnmarshalJSON decodes the data into the Result struct
func (r *Result) UnmarshalJSON(b []byte) error {
var o struct {
Series []*models.Row `json:"series,omitempty"`
Err string `json:"error,omitempty"`
Series []*models.Row `json:"series,omitempty"`
Messages []*Message `json:"messages,omitempty"`
Err string `json:"error,omitempty"`
}

err := json.Unmarshal(b, &o)
if err != nil {
return err
}
r.Series = o.Series
r.Messages = o.Messages
if o.Err != "" {
r.Err = errors.New(o.Err)
}
Expand Down
1 change: 1 addition & 0 deletions services/httpd/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,7 @@ func (h *Handler) serveQuery(w http.ResponseWriter, r *http.Request, user *meta.
// Append remaining rows as new rows.
r.Series = r.Series[rowsMerged:]
cr.Series = append(cr.Series, r.Series...)
cr.Messages = append(cr.Messages, r.Messages...)
} else {
resp.Results = append(resp.Results, r)
}
Expand Down

0 comments on commit e2cf94e

Please sign in to comment.