feat(query/influxql): expose default database and retention policy for transpiler

The influxql transpiler can now be configured with a default database
and retention policy.
pull/10616/head
Jonathan A. Sternberg 2018-06-11 11:21:39 -05:00
parent 4ef3573234
commit 2388d95949
4 changed files with 45 additions and 11 deletions

View File

@ -50,11 +50,12 @@ func (h *TranspilerQueryHandler) handlePostQuery(w http.ResponseWriter, r *http.
return
}
//TODO(nathanielc): Get database and rp information if needed.
// Create a new transpiler from the http request.
ce := influxqlCE
transpiler := ce.transpiler(r)
results, err := query.QueryWithTranspile(ctx, h.OrgID, queryStr, h.QueryService, ce.transpiler)
// Run the transpiler against the query service.
results, err := query.QueryWithTranspile(ctx, h.OrgID, queryStr, h.QueryService, transpiler)
if err != nil {
kerrors.EncodeHTTP(ctx, err, w)
return
@ -68,15 +69,21 @@ func (h *TranspilerQueryHandler) handlePostQuery(w http.ResponseWriter, r *http.
}
}
// crossExecute contains the components needed to execute a transpiled query and encode results
// crossExecute contains the components needed to execute a transpiled query and encode results.
type crossExecute struct {
transpiler query.Transpiler
transpiler func(req *http.Request) query.Transpiler
encoder query.MultiResultEncoder
contentType string
}
var influxqlCE = crossExecute{
transpiler: influxql.NewTranspiler(),
transpiler: func(req *http.Request) query.Transpiler {
config := influxql.Config{
DefaultDatabase: req.FormValue("db"),
DefaultRetentionPolicy: req.FormValue("rp"),
}
return influxql.NewTranspilerWithConfig(config)
},
encoder: influxql.NewMultiResultEncoder(),
contentType: "application/json",
}

7
query/influxql/config.go Normal file
View File

@ -0,0 +1,7 @@
package influxql
// Config modifies the behavior of the Transpiler.
type Config struct {
DefaultDatabase string
DefaultRetentionPolicy string
}

View File

@ -13,12 +13,20 @@ import (
)
// Transpiler converts InfluxQL queries into a query spec.
type Transpiler struct{}
type Transpiler struct {
Config *Config
}
func NewTranspiler() *Transpiler {
return new(Transpiler)
}
func NewTranspilerWithConfig(cfg Config) *Transpiler {
return &Transpiler{
Config: &cfg,
}
}
func (t *Transpiler) Transpile(ctx context.Context, txt string) (*query.Spec, error) {
// Parse the text of the query.
q, err := influxql.ParseQuery(txt)
@ -26,7 +34,7 @@ func (t *Transpiler) Transpile(ctx context.Context, txt string) (*query.Spec, er
return nil, err
}
transpiler := newTranspilerState()
transpiler := newTranspilerState(t.Config)
for i, s := range q.Statements {
stmt, ok := s.(*influxql.SelectStatement)
if !ok {
@ -42,17 +50,21 @@ func (t *Transpiler) Transpile(ctx context.Context, txt string) (*query.Spec, er
type transpilerState struct {
id int
stmt *influxql.SelectStatement
config Config
spec *query.Spec
nextID map[string]int
now time.Time
}
func newTranspilerState() *transpilerState {
func newTranspilerState(config *Config) *transpilerState {
state := &transpilerState{
spec: &query.Spec{},
nextID: make(map[string]int),
now: time.Now(),
}
if config != nil {
state.config = *config
}
return state
}
@ -101,11 +113,18 @@ func (t *transpilerState) mapType(ref *influxql.VarRef) influxql.DataType {
func (t *transpilerState) from(m *influxql.Measurement) (query.OperationID, error) {
db, rp := m.Database, m.RetentionPolicy
if db == "" {
if t.config.DefaultDatabase == "" {
return "", errors.New("database is required")
}
db = t.config.DefaultDatabase
}
if rp == "" {
if t.config.DefaultRetentionPolicy != "" {
rp = t.config.DefaultRetentionPolicy
} else {
rp = "autogen"
}
}
spec := &functions.FromOpSpec{
Bucket: fmt.Sprintf("%s/%s", db, rp),

View File

@ -8,6 +8,7 @@ import (
// Transpiler can convert a query from a source lanague into a query spec.
type Transpiler interface {
// Transpile will perform the transpilation.
Transpile(ctx context.Context, txt string) (*Spec, error)
}