Merge pull request #2622 from influxdb/select-distinct-tag-customer-error-2612
Select distinct tag custom errorpull/2501/head
commit
de77ee1896
|
@ -16,6 +16,7 @@
|
|||
- [#2596](https://github.com/influxdb/influxdb/pull/2596): RC30: `panic: runtime error: index out of range` when insert data points.
|
||||
- [#2592](https://github.com/influxdb/influxdb/pull/2592): Should return an error if user attempts to group by a field.
|
||||
- [#2499](https://github.com/influxdb/influxdb/pull/2499): Issuing a select query with tag as a values causes panic.
|
||||
- [#2612](https://github.com/influxdb/influxdb/pull/2612): Query planner should validate distinct is passed a field.
|
||||
|
||||
## PRs
|
||||
- [#2569](https://github.com/influxdb/influxdb/pull/2569): Add derivative functions
|
||||
|
|
|
@ -705,29 +705,59 @@ func runTestsData(t *testing.T, testName string, nodes Cluster, database, retent
|
|||
},
|
||||
{
|
||||
reset: true,
|
||||
name: "distincts",
|
||||
name: "distinct as call",
|
||||
write: `{"database" : "%DB%", "retentionPolicy" : "%RP%", "points": [
|
||||
{"name": "cpu", "time": "2000-01-01T00:00:00Z", "fields": {"value": 30}},
|
||||
{"name": "cpu", "time": "2000-01-01T00:00:10Z", "fields": {"value": 20}},
|
||||
{"name": "cpu", "time": "2000-01-01T00:00:20Z", "fields": {"value": 30}},
|
||||
{"name": "cpu", "time": "2000-01-01T00:00:30Z", "fields": {"value": 100}}
|
||||
{"name": "cpu", "time": "2000-01-01T00:00:00Z", "tags": {"host": "server01"}, "fields": {"value": 30}},
|
||||
{"name": "cpu", "time": "2000-01-01T00:00:10Z", "tags": {"host": "server02"}, "fields": {"value": 20}},
|
||||
{"name": "cpu", "time": "2000-01-01T00:00:20Z", "tags": {"host": "server03"}, "fields": {"value": 30}},
|
||||
{"name": "cpu", "time": "2000-01-01T00:00:30Z", "tags": {"host": "server03"}, "fields": {"value": 100}}
|
||||
]}`,
|
||||
query: `SELECT distinct(value) FROM cpu`,
|
||||
queryDb: "%DB%",
|
||||
expected: `{"results":[{"series":[{"name":"cpu","columns":["time","distinct"],"values":[["1970-01-01T00:00:00Z",[20,30,100]]]}]}]}`,
|
||||
},
|
||||
{
|
||||
name: "distincts alt syntax",
|
||||
name: "distinct alt syntax",
|
||||
query: `SELECT distinct value FROM cpu`,
|
||||
queryDb: "%DB%",
|
||||
expected: `{"results":[{"series":[{"name":"cpu","columns":["time","distinct"],"values":[["1970-01-01T00:00:00Z",[20,30,100]]]}]}]}`,
|
||||
},
|
||||
{
|
||||
name: "distinct select tag",
|
||||
query: `SELECT distinct(host) FROM cpu`,
|
||||
queryDb: "%DB%",
|
||||
expected: `{"results":[{"error":"host isn't a field on measurement cpu; to query the unique values for a tag use SHOW TAG VALUES FROM cpu WITH KEY = \"host\""}]}`,
|
||||
},
|
||||
{
|
||||
name: "distinct alt select tag",
|
||||
query: `SELECT distinct host FROM cpu`,
|
||||
queryDb: "%DB%",
|
||||
expected: `{"results":[{"error":"host isn't a field on measurement cpu; to query the unique values for a tag use SHOW TAG VALUES FROM cpu WITH KEY = \"host\""}]}`,
|
||||
},
|
||||
{
|
||||
name: "count distinct",
|
||||
query: `SELECT count(distinct value) FROM cpu`,
|
||||
queryDb: "%DB%",
|
||||
expected: `{"results":[{"series":[{"name":"cpu","columns":["time","count"],"values":[["1970-01-01T00:00:00Z",3]]}]}]}`,
|
||||
},
|
||||
{
|
||||
name: "count distinct as call",
|
||||
query: `SELECT count(distinct(value)) FROM cpu`,
|
||||
queryDb: "%DB%",
|
||||
expected: `{"results":[{"series":[{"name":"cpu","columns":["time","count"],"values":[["1970-01-01T00:00:00Z",3]]}]}]}`,
|
||||
},
|
||||
{
|
||||
name: "count distinct select tag",
|
||||
query: `SELECT count(distinct host) FROM cpu`,
|
||||
queryDb: "%DB%",
|
||||
expected: `{"results":[{"error":"host isn't a field on measurement cpu; count(distinct) on tags isn't yet supported"}]}`,
|
||||
},
|
||||
{
|
||||
name: "count distinct as call select tag",
|
||||
query: `SELECT count(distinct(host)) FROM cpu`,
|
||||
queryDb: "%DB%",
|
||||
expected: `{"results":[{"error":"host isn't a field on measurement cpu; count(distinct) on tags isn't yet supported"}]}`,
|
||||
},
|
||||
{
|
||||
reset: true,
|
||||
name: "aggregations",
|
||||
|
|
|
@ -702,7 +702,7 @@ func (m *MapReduceJob) processRawResults(values []*rawQueryMapOutput) *Row {
|
|||
selectNames[0], selectNames[i] = selectNames[i], selectNames[0]
|
||||
}
|
||||
hasTime = true
|
||||
break
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
|
14
tx.go
14
tx.go
|
@ -374,6 +374,8 @@ func (l *LocalMapper) Begin(c *influxql.Call, startingTime int64, chunkSize int)
|
|||
l.chunkSize = chunkSize
|
||||
l.tmin = startingTime
|
||||
|
||||
var isCountDistinct bool
|
||||
|
||||
// determine if this is a raw data query with a single field, multiple fields, or an aggregate
|
||||
var fieldName string
|
||||
if c == nil { // its a raw data query
|
||||
|
@ -400,17 +402,27 @@ func (l *LocalMapper) Begin(c *influxql.Call, startingTime int64, chunkSize int)
|
|||
if c.Name != "count" {
|
||||
return fmt.Errorf("aggregate call didn't contain a field %s", c.String())
|
||||
}
|
||||
isCountDistinct = true
|
||||
fieldName = lit.Val
|
||||
default:
|
||||
return fmt.Errorf("aggregate call didn't contain a field %s", c.String())
|
||||
}
|
||||
|
||||
isCountDistinct = isCountDistinct || (c.Name == "count" && nested.Name == "distinct")
|
||||
}
|
||||
|
||||
// set up the field info if a specific field was set for this mapper
|
||||
if fieldName != "" {
|
||||
f := l.decoder.FieldByName(fieldName)
|
||||
if f == nil {
|
||||
return fmt.Errorf("%s isn't a field on measurement %s", fieldName, l.job.MeasurementName)
|
||||
switch {
|
||||
case c.Name == "distinct":
|
||||
return fmt.Errorf("%s isn't a field on measurement %s; to query the unique values for a tag use SHOW TAG VALUES FROM %s WITH KEY = %q", fieldName, l.job.MeasurementName, l.job.MeasurementName, fieldName)
|
||||
case isCountDistinct:
|
||||
return fmt.Errorf("%s isn't a field on measurement %s; count(distinct) on tags isn't yet supported", fieldName, l.job.MeasurementName)
|
||||
default:
|
||||
return fmt.Errorf("%s isn't a field on measurement %s", fieldName, l.job.MeasurementName)
|
||||
}
|
||||
}
|
||||
l.fieldID = f.ID
|
||||
l.fieldName = f.Name
|
||||
|
|
Loading…
Reference in New Issue