Update SHOW FIELD KEYS to return the field type with the field key

Fixes #3451.
pull/6592/head
Jonathan A. Sternberg 2016-05-10 13:16:55 -04:00
parent 9b86bfea2a
commit 733a17d9e9
5 changed files with 84 additions and 13 deletions

View File

@ -1,3 +1,9 @@
## v1.0.0 [unreleased]
### Features
- [#3541](https://github.com/influxdata/influxdb/issues/3451): Update SHOW FIELD KEYS to return the field type with the field key.
## v0.13.0 [unreleased]
### Release Notes

View File

@ -5568,19 +5568,19 @@ func TestServer_Query_ShowFieldKeys(t *testing.T) {
&Query{
name: `show field keys`,
command: `SHOW FIELD KEYS`,
exp: `{"results":[{"series":[{"name":"cpu","columns":["fieldKey"],"values":[["field1"],["field2"],["field3"]]},{"name":"disk","columns":["fieldKey"],"values":[["field8"],["field9"]]},{"name":"gpu","columns":["fieldKey"],"values":[["field4"],["field5"],["field6"],["field7"]]}]}]}`,
exp: `{"results":[{"series":[{"name":"cpu","columns":["fieldKey","fieldType"],"values":[["field1","float"],["field2","float"],["field3","float"]]},{"name":"disk","columns":["fieldKey","fieldType"],"values":[["field8","float"],["field9","float"]]},{"name":"gpu","columns":["fieldKey","fieldType"],"values":[["field4","float"],["field5","float"],["field6","float"],["field7","float"]]}]}]}`,
params: url.Values{"db": []string{"db0"}},
},
&Query{
name: `show field keys from measurement`,
command: `SHOW FIELD KEYS FROM cpu`,
exp: `{"results":[{"series":[{"name":"cpu","columns":["fieldKey"],"values":[["field1"],["field2"],["field3"]]}]}]}`,
exp: `{"results":[{"series":[{"name":"cpu","columns":["fieldKey","fieldType"],"values":[["field1","float"],["field2","float"],["field3","float"]]}]}]}`,
params: url.Values{"db": []string{"db0"}},
},
&Query{
name: `show field keys measurement with regex`,
command: `SHOW FIELD KEYS FROM /[cg]pu/`,
exp: `{"results":[{"series":[{"name":"cpu","columns":["fieldKey"],"values":[["field1"],["field2"],["field3"]]},{"name":"gpu","columns":["fieldKey"],"values":[["field4"],["field5"],["field6"],["field7"]]}]}]}`,
exp: `{"results":[{"series":[{"name":"cpu","columns":["fieldKey","fieldType"],"values":[["field1","float"],["field2","float"],["field3","float"]]},{"name":"gpu","columns":["fieldKey","fieldType"],"values":[["field4","float"],["field5","float"],["field6","float"],["field7","float"]]}]}]}`,
params: url.Values{"db": []string{"db0"}},
},
}...)

View File

@ -24,6 +24,7 @@ func rewriteShowFieldKeysStatement(stmt *ShowFieldKeysStatement) (Statement, err
return &SelectStatement{
Fields: Fields([]*Field{
{Expr: &VarRef{Val: "fieldKey"}},
{Expr: &VarRef{Val: "fieldType"}},
}),
Sources: rewriteSources(stmt.Sources, "_fieldKeys"),
Condition: rewriteSourcesCondition(stmt.Sources, nil),

View File

@ -13,23 +13,23 @@ func TestRewriteStatement(t *testing.T) {
}{
{
stmt: `SHOW FIELD KEYS`,
s: `SELECT fieldKey FROM _fieldKeys`,
s: `SELECT fieldKey, fieldType FROM _fieldKeys`,
},
{
stmt: `SHOW FIELD KEYS FROM cpu`,
s: `SELECT fieldKey FROM _fieldKeys WHERE _name = 'cpu'`,
s: `SELECT fieldKey, fieldType FROM _fieldKeys WHERE _name = 'cpu'`,
},
{
stmt: `SHOW FIELD KEYS FROM /c.*/`,
s: `SELECT fieldKey FROM _fieldKeys WHERE _name =~ /c.*/`,
s: `SELECT fieldKey, fieldType FROM _fieldKeys WHERE _name =~ /c.*/`,
},
{
stmt: `SHOW FIELD KEYS FROM mydb.myrp2.cpu`,
s: `SELECT fieldKey FROM mydb.myrp2._fieldKeys WHERE _name = 'cpu'`,
s: `SELECT fieldKey, fieldType FROM mydb.myrp2._fieldKeys WHERE _name = 'cpu'`,
},
{
stmt: `SHOW FIELD KEYS FROM mydb.myrp2./c.*/`,
s: `SELECT fieldKey FROM mydb.myrp2._fieldKeys WHERE _name =~ /c.*/`,
s: `SELECT fieldKey, fieldType FROM mydb.myrp2._fieldKeys WHERE _name =~ /c.*/`,
},
{
stmt: `SHOW MEASUREMENTS`,

View File

@ -944,12 +944,76 @@ func (ic *shardIteratorCreator) ExpandSources(sources influxql.Sources) (influxq
}
func NewFieldKeysIterator(sh *Shard, opt influxql.IteratorOptions) (influxql.Iterator, error) {
fn := func(m *Measurement) []string {
keys := m.FieldNames()
sort.Strings(keys)
return keys
itr := &fieldKeysIterator{sh: sh}
// Retrieve measurements from shard. Filter if condition specified.
if opt.Condition == nil {
itr.mms = sh.index.Measurements()
} else {
mms, _, err := sh.index.measurementsByExpr(opt.Condition)
if err != nil {
return nil, err
}
itr.mms = mms
}
// Sort measurements by name.
sort.Sort(itr.mms)
return itr, nil
}
// fieldKeysIterator iterates over measurements and gets field keys from each measurement.
type fieldKeysIterator struct {
sh *Shard
mms Measurements // remaining measurements
buf struct {
mm *Measurement // current measurement
fields []*Field // current measurement's fields
}
}
// Stats returns stats about the points processed.
func (itr *fieldKeysIterator) Stats() influxql.IteratorStats { return influxql.IteratorStats{} }
// Close closes the iterator.
func (itr *fieldKeysIterator) Close() error { return nil }
// Next emits the next tag key name.
func (itr *fieldKeysIterator) Next() (*influxql.FloatPoint, error) {
for {
// If there are no more keys then move to the next measurements.
if len(itr.buf.fields) == 0 {
if len(itr.mms) == 0 {
return nil, nil
}
itr.buf.mm = itr.mms[0]
keys := itr.buf.mm.FieldNames()
if len(keys) > 0 {
// Sort the keys in alphabetical order.
sort.Strings(keys)
// Retrieve the field for each key.
mf := itr.sh.engine.MeasurementFields(itr.buf.mm.Name)
itr.buf.fields = make([]*Field, len(keys))
for i, name := range keys {
itr.buf.fields[i] = mf.Field(name)
}
}
itr.mms = itr.mms[1:]
continue
}
// Return next key.
field := itr.buf.fields[0]
p := &influxql.FloatPoint{
Name: itr.buf.mm.Name,
Aux: []interface{}{field.Name, field.Type.String()},
}
itr.buf.fields = itr.buf.fields[1:]
return p, nil
}
return newMeasurementKeysIterator(sh, fn, opt)
}
// MeasurementIterator represents a string iterator that emits all measurement names in a shard.