本文整理汇总了Golang中github.com/influxdata/influxdb/influxql.NewParser函数的典型用法代码示例。如果您正苦于以下问题:Golang NewParser函数的具体用法?Golang NewParser怎么用?Golang NewParser使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了NewParser函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的Golang代码示例。
示例1: emptyTestServer
func emptyTestServer() *httptest.Server {
return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("X-Influxdb-Version", SERVER_VERSION)
switch r.URL.Path {
case "/query":
values := r.URL.Query()
parser := influxql.NewParser(bytes.NewBufferString(values.Get("q")))
q, err := parser.ParseQuery()
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
stmt := q.Statements[0]
switch stmt.(type) {
case *influxql.ShowDatabasesStatement:
io.WriteString(w, `{"results":[{"series":[{"name":"databases","columns":["name"],"values":[["db"]]}]}]}`)
case *influxql.ShowDiagnosticsStatement:
io.WriteString(w, `{"results":[{}]}`)
}
case "/write":
w.WriteHeader(http.StatusOK)
}
}))
}
开发者ID:seiflotfy,项目名称:influxdb,代码行数:26,代码来源:cli_test.go
示例2: MustParseQuery
// MustParseQuery parses an InfluxQL query. Panic on error.
func MustParseQuery(s string) *influxql.Query {
q, err := influxql.NewParser(strings.NewReader(s)).ParseQuery()
if err != nil {
panic(err.Error())
}
return q
}
开发者ID:rwarren,项目名称:influxdb,代码行数:8,代码来源:query_executor_test.go
示例3: BenchmarkMeasurement_SeriesIDForExp_NERegex
func BenchmarkMeasurement_SeriesIDForExp_NERegex(b *testing.B) {
m := tsdb.NewMeasurement("cpu")
for i := 0; i < 100000; i++ {
s := tsdb.NewSeries("cpu", models.Tags{models.Tag{
Key: []byte("host"),
Value: []byte(fmt.Sprintf("host%d", i))}})
s.ID = uint64(i)
m.AddSeries(s)
}
if exp, got := 100000, len(m.SeriesKeys()); exp != got {
b.Fatalf("series count mismatch: exp %v got %v", exp, got)
}
stmt, err := influxql.NewParser(strings.NewReader(`SELECT * FROM cpu WHERE host !~ /foo\d+/`)).ParseStatement()
if err != nil {
b.Fatalf("invalid statement: %s", err)
}
selectStmt := stmt.(*influxql.SelectStatement)
b.ResetTimer()
for i := 0; i < b.N; i++ {
ids := m.IDsForExpr(selectStmt.Condition.(*influxql.BinaryExpr))
if exp, got := 100000, len(ids); exp != got {
b.Fatalf("series count mismatch: exp %v got %v", exp, got)
}
}
}
开发者ID:li-ang,项目名称:influxdb,代码行数:31,代码来源:meta_test.go
示例4: BenchmarkQuery_String
func BenchmarkQuery_String(b *testing.B) {
p := influxql.NewParser(strings.NewReader(`SELECT foo AS zoo, a AS b FROM bar WHERE value > 10 AND q = 'hello'`))
q, _ := p.ParseStatement()
for i := 0; i < b.N; i++ {
_ = q.String()
}
}
开发者ID:sbouchex,项目名称:influxdb,代码行数:7,代码来源:ast_test.go
示例5: TestSelectStatement_IsSimpleDerivative
func TestSelectStatement_IsSimpleDerivative(t *testing.T) {
var tests = []struct {
stmt string
derivative bool
}{
// No derivatives
{
stmt: `SELECT value FROM cpu`,
derivative: false,
},
// Query derivative
{
stmt: `SELECT derivative(value) FROM cpu`,
derivative: true,
},
// Query derivative
{
stmt: `SELECT non_negative_derivative(value) FROM cpu`,
derivative: true,
},
// No GROUP BY time only
{
stmt: `SELECT mean(value) FROM cpu where time < now() GROUP BY time(5ms)`,
derivative: false,
},
// No GROUP BY derivatives, time only
{
stmt: `SELECT non_negative_derivative(mean(value)) FROM cpu where time < now() GROUP BY time(5ms)`,
derivative: false,
},
// Invalid derivative function name
{
stmt: `SELECT typoDerivative(value) FROM cpu where time < now()`,
derivative: false,
},
}
for i, tt := range tests {
// Parse statement.
t.Logf("index: %d, statement: %s", i, tt.stmt)
stmt, err := influxql.NewParser(strings.NewReader(tt.stmt)).ParseStatement()
if err != nil {
t.Fatalf("invalid statement: %q: %s", tt.stmt, err)
}
// Test derivative detection.
if d := stmt.(*influxql.SelectStatement).IsSimpleDerivative(); tt.derivative != d {
t.Errorf("%d. %q: unexpected derivative detection:\n\nexp=%v\n\ngot=%v\n\n", i, tt.stmt, tt.derivative, d)
continue
}
}
}
开发者ID:sbouchex,项目名称:influxdb,代码行数:57,代码来源:ast_test.go
示例6: TestSelectStatement_HasCountDistinct
func TestSelectStatement_HasCountDistinct(t *testing.T) {
var tests = []struct {
stmt string
count bool
}{
// No counts
{
stmt: `SELECT value FROM cpu`,
count: false,
},
// Query count
{
stmt: `SELECT count(value) FROM cpu`,
count: false,
},
// No GROUP BY time only
{
stmt: `SELECT count(distinct(value)) FROM cpu where time < now() GROUP BY time(5ms)`,
count: true,
},
// Query count
{
stmt: `SELECT typoCount(value) FROM cpu`,
count: false,
},
// No GROUP BY time only
{
stmt: `SELECT typoCount(distinct(value)) FROM cpu where time < now() GROUP BY time(5ms)`,
count: false,
},
}
for i, tt := range tests {
// Parse statement.
t.Logf("index: %d, statement: %s", i, tt.stmt)
stmt, err := influxql.NewParser(strings.NewReader(tt.stmt)).ParseStatement()
if err != nil {
t.Fatalf("invalid statement: %q: %s", tt.stmt, err)
}
// Test count detection.
if c := stmt.(*influxql.SelectStatement).HasCountDistinct(); tt.count != c {
t.Errorf("%d. %q: unexpected count detection:\n\nexp=%v\n\ngot=%v\n\n", i, tt.stmt, tt.count, c)
continue
}
}
}
开发者ID:seiflotfy,项目名称:influxdb,代码行数:51,代码来源:ast_test.go
示例7: TestSelectStatement_RewriteTimeFields
// Test SELECT statement time field rewrite.
func TestSelectStatement_RewriteTimeFields(t *testing.T) {
var tests = []struct {
s string
stmt influxql.Statement
}{
{
s: `SELECT time, field1 FROM cpu`,
stmt: &influxql.SelectStatement{
IsRawQuery: true,
Fields: []*influxql.Field{
{Expr: &influxql.VarRef{Val: "field1"}},
},
Sources: []influxql.Source{
&influxql.Measurement{Name: "cpu"},
},
},
},
{
s: `SELECT time AS timestamp, field1 FROM cpu`,
stmt: &influxql.SelectStatement{
IsRawQuery: true,
Fields: []*influxql.Field{
{Expr: &influxql.VarRef{Val: "field1"}},
},
Sources: []influxql.Source{
&influxql.Measurement{Name: "cpu"},
},
TimeAlias: "timestamp",
},
},
}
for i, tt := range tests {
// Parse statement.
stmt, err := influxql.NewParser(strings.NewReader(tt.s)).ParseStatement()
if err != nil {
t.Fatalf("invalid statement: %q: %s", tt.s, err)
}
// Rewrite statement.
stmt.(*influxql.SelectStatement).RewriteTimeFields()
if !reflect.DeepEqual(tt.stmt, stmt) {
t.Logf("\n# %s\nexp=%s\ngot=%s\n", tt.s, mustMarshalJSON(tt.stmt), mustMarshalJSON(stmt))
t.Logf("\nSQL exp=%s\nSQL got=%s\n", tt.stmt.String(), stmt.String())
t.Errorf("%d. %q\n\nstmt mismatch:\n\nexp=%#v\n\ngot=%#v\n\n", i, tt.s, tt.stmt, stmt)
}
}
}
开发者ID:sbouchex,项目名称:influxdb,代码行数:49,代码来源:ast_test.go
示例8: TestSelectStatement_GroupByInterval
// Ensure the SELECT statement can extract GROUP BY interval.
func TestSelectStatement_GroupByInterval(t *testing.T) {
q := "SELECT sum(value) from foo where time < now() GROUP BY time(10m)"
stmt, err := influxql.NewParser(strings.NewReader(q)).ParseStatement()
if err != nil {
t.Fatalf("invalid statement: %q: %s", stmt, err)
}
s := stmt.(*influxql.SelectStatement)
d, err := s.GroupByInterval()
if d != 10*time.Minute {
t.Fatalf("group by interval not equal:\nexp=%s\ngot=%s", 10*time.Minute, d)
}
if err != nil {
t.Fatalf("error parsing group by interval: %s", err.Error())
}
}
开发者ID:sbouchex,项目名称:influxdb,代码行数:17,代码来源:ast_test.go
示例9: emptyTestServer
func emptyTestServer() *httptest.Server {
return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("X-Influxdb-Version", SERVER_VERSION)
// Fake authorization entirely based on the username.
authorized := false
user, _, _ := r.BasicAuth()
switch user {
case "", "admin":
authorized = true
}
switch r.URL.Path {
case "/query":
values := r.URL.Query()
parser := influxql.NewParser(bytes.NewBufferString(values.Get("q")))
q, err := parser.ParseQuery()
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
stmt := q.Statements[0]
switch stmt.(type) {
case *influxql.ShowDatabasesStatement:
if authorized {
io.WriteString(w, `{"results":[{"series":[{"name":"databases","columns":["name"],"values":[["db"]]}]}]}`)
} else {
w.WriteHeader(http.StatusUnauthorized)
io.WriteString(w, fmt.Sprintf(`{"error":"error authorizing query: %s not authorized to execute statement 'SHOW DATABASES', requires admin privilege"}`, user))
}
case *influxql.ShowDiagnosticsStatement:
io.WriteString(w, `{"results":[{}]}`)
}
case "/write":
w.WriteHeader(http.StatusOK)
}
}))
}
开发者ID:ChenXiukun,项目名称:influxdb,代码行数:39,代码来源:cli_test.go
示例10: TestOnlyTimeExpr
// Ensure that we see if a where clause has only time limitations
func TestOnlyTimeExpr(t *testing.T) {
var tests = []struct {
stmt string
exp bool
}{
{
stmt: `SELECT value FROM myseries WHERE value > 1`,
exp: false,
},
{
stmt: `SELECT value FROM foo WHERE time >= '2000-01-01T00:00:05Z'`,
exp: true,
},
{
stmt: `SELECT value FROM foo WHERE time >= '2000-01-01T00:00:05Z' AND time < '2000-01-01T00:00:05Z'`,
exp: true,
},
{
stmt: `SELECT value FROM foo WHERE time >= '2000-01-01T00:00:05Z' AND asdf = 'bar'`,
exp: false,
},
{
stmt: `SELECT value FROM foo WHERE asdf = 'jkl' AND (time >= '2000-01-01T00:00:05Z' AND time < '2000-01-01T00:00:05Z')`,
exp: false,
},
}
for i, tt := range tests {
// Parse statement.
stmt, err := influxql.NewParser(strings.NewReader(tt.stmt)).ParseStatement()
if err != nil {
t.Fatalf("invalid statement: %q: %s", tt.stmt, err)
}
if influxql.OnlyTimeExpr(stmt.(*influxql.SelectStatement).Condition) != tt.exp {
t.Fatalf("%d. expected statement to return only time dimension to be %t: %s", i, tt.exp, tt.stmt)
}
}
}
开发者ID:sbouchex,项目名称:influxdb,代码行数:39,代码来源:ast_test.go
示例11: NewContinuousQuery
// NewContinuousQuery returns a ContinuousQuery object with a parsed influxql.CreateContinuousQueryStatement
func NewContinuousQuery(database string, cqi *meta.ContinuousQueryInfo) (*ContinuousQuery, error) {
stmt, err := influxql.NewParser(strings.NewReader(cqi.Query)).ParseStatement()
if err != nil {
return nil, err
}
q, ok := stmt.(*influxql.CreateContinuousQueryStatement)
if !ok || q.Source.Target == nil || q.Source.Target.Measurement == nil {
return nil, errors.New("query isn't a valid continuous query")
}
cquery := &ContinuousQuery{
Database: database,
Info: cqi,
Resample: ResampleOptions{
Every: q.ResampleEvery,
For: q.ResampleFor,
},
q: q.Source,
}
return cquery, nil
}
开发者ID:jsternberg,项目名称:influxdb,代码行数:24,代码来源:service.go
示例12: TestParseString
// Ensure that the String() value of a statement is parseable
func TestParseString(t *testing.T) {
var tests = []struct {
stmt string
}{
{
stmt: `SELECT "cpu load" FROM myseries`,
},
{
stmt: `SELECT "cpu load" FROM "my series"`,
},
{
stmt: `SELECT "cpu\"load" FROM myseries`,
},
{
stmt: `SELECT "cpu'load" FROM myseries`,
},
{
stmt: `SELECT "cpu load" FROM "my\"series"`,
},
{
stmt: `SELECT "field with spaces" FROM "\"ugly\" db"."\"ugly\" rp"."\"ugly\" measurement"`,
},
{
stmt: `SELECT * FROM myseries`,
},
{
stmt: `DROP DATABASE "!"`,
},
{
stmt: `DROP RETENTION POLICY "my rp" ON "a database"`,
},
{
stmt: `CREATE RETENTION POLICY "my rp" ON "a database" DURATION 1d REPLICATION 1`,
},
{
stmt: `ALTER RETENTION POLICY "my rp" ON "a database" DEFAULT`,
},
{
stmt: `SHOW RETENTION POLICIES ON "a database"`,
},
{
stmt: `SHOW TAG VALUES WITH KEY IN ("a long name", short)`,
},
{
stmt: `DROP CONTINUOUS QUERY "my query" ON "my database"`,
},
// See issues https://github.com/influxdata/influxdb/issues/1647
// and https://github.com/influxdata/influxdb/issues/4404
//{
// stmt: `DELETE FROM "my db"."my rp"."my measurement"`,
//},
{
stmt: `DROP SUBSCRIPTION "ugly \"subscription\" name" ON "\"my\" db"."\"my\" rp"`,
},
{
stmt: `CREATE SUBSCRIPTION "ugly \"subscription\" name" ON "\"my\" db"."\"my\" rp" DESTINATIONS ALL 'my host', 'my other host'`,
},
{
stmt: `SHOW MEASUREMENTS WITH MEASUREMENT =~ /foo/`,
},
{
stmt: `SHOW MEASUREMENTS WITH MEASUREMENT = "and/or"`,
},
{
stmt: `DROP USER "user with spaces"`,
},
{
stmt: `GRANT ALL PRIVILEGES ON "db with spaces" TO "user with spaces"`,
},
{
stmt: `GRANT ALL PRIVILEGES TO "user with spaces"`,
},
{
stmt: `SHOW GRANTS FOR "user with spaces"`,
},
{
stmt: `REVOKE ALL PRIVILEGES ON "db with spaces" FROM "user with spaces"`,
},
{
stmt: `REVOKE ALL PRIVILEGES FROM "user with spaces"`,
},
{
stmt: `CREATE DATABASE "db with spaces"`,
},
}
for _, tt := range tests {
// Parse statement.
stmt, err := influxql.NewParser(strings.NewReader(tt.stmt)).ParseStatement()
if err != nil {
t.Fatalf("invalid statement: %q: %s", tt.stmt, err)
}
stmtCopy, err := influxql.NewParser(strings.NewReader(stmt.String())).ParseStatement()
if err != nil {
t.Fatalf("failed to parse string: %v\norig: %v\ngot: %v", err, tt.stmt, stmt.String())
}
if !reflect.DeepEqual(stmt, stmtCopy) {
//.........这里部分代码省略.........
开发者ID:sbouchex,项目名称:influxdb,代码行数:101,代码来源:ast_test.go
示例13: TestSelectStatement_SetTimeRange
// Ensure the SELECT statement can have its start and end time set
func TestSelectStatement_SetTimeRange(t *testing.T) {
q := "SELECT sum(value) from foo where time < now() GROUP BY time(10m)"
stmt, err := influxql.NewParser(strings.NewReader(q)).ParseStatement()
if err != nil {
t.Fatalf("invalid statement: %q: %s", stmt, err)
}
s := stmt.(*influxql.SelectStatement)
start := time.Now().Add(-20 * time.Hour).Round(time.Second).UTC()
end := time.Now().Add(10 * time.Hour).Round(time.Second).UTC()
s.SetTimeRange(start, end)
min, max := MustTimeRange(s.Condition)
if min != start {
t.Fatalf("start time wasn't set properly.\n exp: %s\n got: %s", start, min)
}
// the end range is actually one nanosecond before the given one since end is exclusive
end = end.Add(-time.Nanosecond)
if max != end {
t.Fatalf("end time wasn't set properly.\n exp: %s\n got: %s", end, max)
}
// ensure we can set a time on a select that already has one set
start = time.Now().Add(-20 * time.Hour).Round(time.Second).UTC()
end = time.Now().Add(10 * time.Hour).Round(time.Second).UTC()
q = fmt.Sprintf("SELECT sum(value) from foo WHERE time >= %ds and time <= %ds GROUP BY time(10m)", start.Unix(), end.Unix())
stmt, err = influxql.NewParser(strings.NewReader(q)).ParseStatement()
if err != nil {
t.Fatalf("invalid statement: %q: %s", stmt, err)
}
s = stmt.(*influxql.SelectStatement)
min, max = MustTimeRange(s.Condition)
if start != min || end != max {
t.Fatalf("start and end times weren't equal:\n exp: %s\n got: %s\n exp: %s\n got:%s\n", start, min, end, max)
}
// update and ensure it saves it
start = time.Now().Add(-40 * time.Hour).Round(time.Second).UTC()
end = time.Now().Add(20 * time.Hour).Round(time.Second).UTC()
s.SetTimeRange(start, end)
min, max = MustTimeRange(s.Condition)
// TODO: right now the SetTimeRange can't override the start time if it's more recent than what they're trying to set it to.
// shouldn't matter for our purposes with continuous queries, but fix this later
if min != start {
t.Fatalf("start time wasn't set properly.\n exp: %s\n got: %s", start, min)
}
// the end range is actually one nanosecond before the given one since end is exclusive
end = end.Add(-time.Nanosecond)
if max != end {
t.Fatalf("end time wasn't set properly.\n exp: %s\n got: %s", end, max)
}
// ensure that when we set a time range other where clause conditions are still there
q = "SELECT sum(value) from foo WHERE foo = 'bar' and time < now() GROUP BY time(10m)"
stmt, err = influxql.NewParser(strings.NewReader(q)).ParseStatement()
if err != nil {
t.Fatalf("invalid statement: %q: %s", stmt, err)
}
s = stmt.(*influxql.SelectStatement)
// update and ensure it saves it
start = time.Now().Add(-40 * time.Hour).Round(time.Second).UTC()
end = time.Now().Add(20 * time.Hour).Round(time.Second).UTC()
s.SetTimeRange(start, end)
min, max = MustTimeRange(s.Condition)
if min != start {
t.Fatalf("start time wasn't set properly.\n exp: %s\n got: %s", start, min)
}
// the end range is actually one nanosecond before the given one since end is exclusive
end = end.Add(-time.Nanosecond)
if max != end {
t.Fatalf("end time wasn't set properly.\n exp: %s\n got: %s", end, max)
}
// ensure the where clause is there
hasWhere := false
influxql.WalkFunc(s.Condition, func(n influxql.Node) {
if ex, ok := n.(*influxql.BinaryExpr); ok {
if lhs, ok := ex.LHS.(*influxql.VarRef); ok {
if lhs.Val == "foo" {
if rhs, ok := ex.RHS.(*influxql.StringLiteral); ok {
if rhs.Val == "bar" {
hasWhere = true
}
}
}
}
}
})
if !hasWhere {
t.Fatal("set time range cleared out the where clause")
}
}
开发者ID:sbouchex,项目名称:influxdb,代码行数:99,代码来源:ast_test.go
示例14: serveQuery
// serveQuery parses an incoming query and, if valid, executes the query.
func (h *Handler) serveQuery(w http.ResponseWriter, r *http.Request, user *meta.UserInfo) {
h.statMap.Add(statQueryRequest, 1)
defer func(start time.Time) {
h.statMap.Add(statQueryRequestDuration, time.Since(start).Nanoseconds())
}(time.Now())
q := r.URL.Query()
pretty := q.Get("pretty") == "true"
qp := strings.TrimSpace(q.Get("q"))
if qp == "" {
httpError(w, `missing required parameter "q"`, pretty, http.StatusBadRequest)
return
}
epoch := strings.TrimSpace(q.Get("epoch"))
p := influxql.NewParser(strings.NewReader(qp))
db := q.Get("db")
// Parse query from query string.
query, err := p.ParseQuery()
if err != nil {
httpError(w, "error parsing query: "+err.Error(), pretty, http.StatusBadRequest)
return
}
// Sanitize statements with passwords.
for _, s := range query.Statements {
switch stmt := s.(type) {
case *influxql.CreateUserStatement:
sanitize(r, stmt.Password)
case *influxql.SetPasswordUserStatement:
sanitize(r, stmt.Password)
}
}
// Check authorization.
if h.requireAuthentication {
if err := h.QueryAuthorizer.AuthorizeQuery(user, query, db); err != nil {
if err, ok := err.(meta.ErrAuthorize); ok {
h.Logger.Printf("unauthorized request | user: %q | query: %q | database %q\n", err.User, err.Query.String(), err.Database)
}
httpError(w, "error authorizing query: "+err.Error(), pretty, http.StatusUnauthorized)
return
}
}
// Parse chunk size. Use default if not provided or unparsable.
chunked := (q.Get("chunked") == "true")
chunkSize := DefaultChunkSize
if chunked {
if n, err := strconv.ParseInt(q.Get("chunk_size"), 10, 64); err == nil {
chunkSize = int(n)
}
}
// Make sure if the client disconnects we signal the query to abort
closing := make(chan struct{})
if notifier, ok := w.(http.CloseNotifier); ok {
notify := notifier.CloseNotify()
go func() {
<-notify
close(closing)
}()
} else {
defer close(closing)
}
// Execute query.
w.Header().Add("content-type", "application/json")
results := h.QueryExecutor.ExecuteQuery(query, db, chunkSize, closing)
// if we're not chunking, this will be the in memory buffer for all results before sending to client
resp := Response{Results: make([]*influxql.Result, 0)}
// Status header is OK once this point is reached.
w.WriteHeader(http.StatusOK)
// pull all results from the channel
for r := range results {
// Ignore nil results.
if r == nil {
continue
}
// if requested, convert result timestamps to epoch
if epoch != "" {
convertToEpoch(r, epoch)
}
// Write out result immediately if chunked.
if chunked {
n, _ := w.Write(MarshalJSON(Response{
Results: []*influxql.Result{r},
}, pretty))
h.statMap.Add(statQueryRequestBytesTransmitted, int64(n))
w.(http.Flusher).Flush()
continue
//.........这里部分代码省略.........
开发者ID:daneroo,项目名称:go-ted1k,代码行数:101,代码来源:handler.go
示例15: TestSelectStatement_RewriteFields
// Test SELECT statement field rewrite.
func TestSelectStatement_RewriteFields(t *testing.T) {
var tests = []struct {
stmt string
rewrite string
}{
// No wildcards
{
stmt: `SELECT value FROM cpu`,
rewrite: `SELECT value FROM cpu`,
},
// Query wildcard
{
stmt: `SELECT * FROM cpu`,
rewrite: `SELECT host::tag, region::tag, value1::float, value2::integer FROM cpu`,
},
// Parser fundamentally prohibits multiple query sources
// Query wildcard with explicit
{
stmt: `SELECT *,value1 FROM cpu`,
rewrite: `SELECT host::tag, region::tag, value1::float, value2::integer, value1::float FROM cpu`,
},
// Query multiple wildcards
{
stmt: `SELECT *,* FROM cpu`,
rewrite: `SELECT host::tag, region::tag, value1::float, value2::integer, host::tag, region::tag, value1::float, value2::integer FROM cpu`,
},
// Query wildcards with group by
{
stmt: `SELECT * FROM cpu GROUP BY host`,
rewrite: `SELECT region::tag, value1::float, value2::integer FROM cpu GROUP BY host`,
},
// No GROUP BY wildcards
{
stmt: `SELECT value FROM cpu GROUP BY host`,
rewrite: `SELECT value FROM cpu GROUP BY host`,
},
// No GROUP BY wildcards, time only
{
stmt: `SELECT mean(value) FROM cpu where time < now() GROUP BY time(5ms)`,
rewrite: `SELECT mean(value) FROM cpu WHERE time < now() GROUP BY time(5ms)`,
},
// GROUP BY wildcard
{
stmt: `SELECT value FROM cpu GROUP BY *`,
rewrite: `SELECT value FROM cpu GROUP BY host, region`,
},
// GROUP BY wildcard with time
{
stmt: `SELECT mean(value) FROM cpu where time < now() GROUP BY *,time(1m)`,
rewrite: `SELECT mean(value) FROM cpu WHERE time < now() GROUP BY host, region, time(1m)`,
},
// GROUP BY wildcard with fill
{
stmt: `SELECT mean(value) FROM cpu where time < now() GROUP BY *,time(1m) fill(0)`,
rewrite: `SELECT mean(value) FROM cpu WHERE time < now() GROUP BY host, region, time(1m) fill(0)`,
},
// GROUP BY wildcard with explicit
{
stmt: `SELECT value FROM cpu GROUP BY *,host`,
rewrite: `SELECT value FROM cpu GROUP BY host, region, host`,
},
// GROUP BY multiple wildcards
{
stmt: `SELECT value FROM cpu GROUP BY *,*`,
rewrite: `SELECT value FROM cpu GROUP BY host, region, host, region`,
},
// Combo
{
stmt: `SELECT * FROM cpu GROUP BY *`,
rewrite: `SELECT value1::float, value2::integer FROM cpu GROUP BY host, region`,
},
}
for i, tt := range tests {
// Parse statement.
stmt, err := influxql.NewParser(strings.NewReader(tt.stmt)).ParseStatement()
if err != nil {
t.Fatalf("invalid statement: %q: %s", tt.stmt, err)
}
var ic IteratorCreator
ic.FieldDimensionsFn = func(sources influxql.Sources) (fields map[string]influxql.DataType, dimensions map[string]struct{}, err error) {
fields = map[string]influxql.DataType{"value1": influxql.Float, "value2": influxql.Integer}
dimensions = map[string]struct{}{"host": struct{}{}, "region": struct{}{}}
return
}
//.........这里部分代码省略.........
开发者ID:jipperinbham,项目名称:influxdb,代码行数:101,代码来源:ast_test.go
示例16: TestSelectStatement_Substatement
// Ensure the SELECT statement can extract substatements.
func TestSelectStatement_Substatement(t *testing.T) {
var tests = []struct {
stmt string
expr *influxql.VarRef
sub string
err string
}{
// 0. Single series
{
stmt: `SELECT value FROM myseries WHERE value > 1`,
expr: &influxql.VarRef{Val: "value"},
sub: `SELECT value FROM myseries WHERE value > 1`,
},
// 1. Simple join
{
stmt: `SELECT sum(aa.value) + sum(bb.value) FROM aa, bb`,
expr: &influxql.VarRef{Val: "aa.value"},
sub: `SELECT "aa.value" FROM aa`,
},
// 2. Simple merge
{
stmt: `SELECT sum(aa.value) + sum(bb.value) FROM aa, bb`,
expr: &influxql.VarRef{Val: "bb.value"},
sub: `SELECT "bb.value" FROM bb`,
},
// 3. Join with condition
{
stmt: `SELECT sum(aa.value) + sum(bb.value) FROM aa, bb WHERE aa.host = 'servera' AND bb.host = 'serverb'`,
expr: &influxql.VarRef{Val: "bb.value"},
sub: `SELECT "bb.value" FROM bb WHERE "bb.host" = 'serverb'`,
},
// 4. Join with complex condition
{
stmt: `SELECT sum(aa.value) + sum(bb.value) FROM aa, bb WHERE aa.host = 'servera' AND (bb.host = 'serverb' OR bb.host = 'serverc') AND 1 = 2`,
expr: &influxql.VarRef{Val: "bb.value"},
sub: `SELECT "bb.value" FROM bb WHERE ("bb.host" = 'serverb' OR "bb.host" = 'serverc') AND 1 = 2`,
},
// 5. 4 with different condition order
{
stmt: `SELECT sum(aa.value) + sum(bb.value) FROM aa, bb WHERE ((bb.host = 'serverb' OR bb.host = 'serverc') AND aa.host = 'servera') AND 1 = 2`,
expr: &influxql.VarRef{Val: "bb.value"},
sub: `SELECT "bb.value" FROM bb WHERE (("bb.host" = 'serverb' OR "bb.host" = 'serverc')) AND 1 = 2`,
},
}
for i, tt := range tests {
// Parse statement.
stmt, err := influxql.NewParser(strings.NewReader(tt.stmt)).ParseStatement()
if err != nil {
t.Fatalf("invalid statement: %q: %s", tt.stmt, err)
}
// Extract substatement.
sub, err := stmt.(*influxql.SelectStatement).Substatement(tt.expr)
if err != nil {
t.Errorf("%d. %q: unexpected error: %s", i, tt.stmt, err)
continue
}
if substr := sub.String(); tt.sub != substr {
t.Errorf("%d. %q: unexpected substatement:\n\nexp=%s\n\ngot=%s\n\n", i, tt.stmt, tt.sub, substr)
continue
}
}
}
开发者ID:jipperinbham,项目名称:influxdb,代码行数:70,代码来源:ast_test.go
示例17: TestSelectStatement_RewriteFields
//.........这里部分代码省略.........
// GROUP BY wildcard with fill
{
stmt: `SELECT mean(value) FROM cpu where time < now() GROUP BY *,time(1m) fill(0)`,
rewrite: `SELECT mean(value) FROM cpu WHERE time < now() GROUP BY host, region, time(1m) fill(0)`,
},
// GROUP BY wildcard with explicit
{
stmt: `SELECT value FROM cpu GROUP BY *,host`,
rewrite: `SELECT value FROM cpu GROUP BY host, region, host`,
},
// GROUP BY multiple wildcards
{
stmt: `SELECT value FROM cpu GROUP BY *,*`,
rewrite: `SELECT value FROM cpu GROUP BY host, region, host, region`,
},
// Combo
{
stmt: `SELECT * FROM cpu GROUP BY *`,
rewrite: `SELECT value1::float, value2::integer FROM cpu GROUP BY host, region`,
},
// Wildcard function with all fields.
{
stmt: `SELECT mean(*) FROM cpu`,
rewrite: `SELECT mean(value1::float) AS mean_value1, mean(value2::integer) AS mean_value2 FROM cpu`,
},
{
stmt: `SELECT distinct(*) FROM strings`,
rewrite: `SELECT distinct(string::string) AS distinct_string, distinct(value::float) AS distinct_value FROM strings`,
},
{
stmt: `SELECT distinct(*) FROM bools`,
rewrite: `SELECT distinct(bool::boolean) AS distinct_bool, distinct(value::float) AS distinct_value FROM bools`,
},
// Wildcard function with some fields excluded.
{
stmt: `SELECT mean(*) FROM strings`,
rewrite: `SELECT mean(value::float) AS mean_value FROM strings`,
},
{
stmt: `SELECT mean(*) FROM bools`,
rewrite: `SELECT mean(value::float) AS mean_value FROM bools`,
},
// Wildcard function with an alias.
{
stmt: `SELECT mean(*) AS alias FROM cpu`,
rewrite: `SELECT mean(value1::float) AS alias_value1, mean(value2::integer) AS alias_value2 FROM cpu`,
},
}
for i, tt := range tests {
// Parse statement.
stmt, err := influxql.NewParser(strings.NewReader(tt.stmt)).ParseStatement()
if err != nil {
t.Fatalf("invalid statement: %q: %s", tt.stmt, err)
}
var ic IteratorCreator
ic.FieldDimensionsFn = func(sources influxql.Sources) (fields map[string]influxql.DataType, dimensions map[string]struct{}, err error) {
source := sources[0].(*influxql.Measurement)
switch source.Name {
case "cpu":
fields = map[string]influxql.DataType{
"value1": influxql.Float,
"value2": influxql.Integer,
}
case "strings":
fields = map[string]influxql.DataType{
"value": influxql.Float,
"string": influxql.String,
}
case "bools":
fields = map[string]influxql.DataType{
"value": influxql.Float,
"bool": influxql.Boolean,
}
}
dimensions = map[string]struct{}{"host": struct{}{}, "region": struct{}{}}
return
}
// Rewrite statement.
rw, err := stmt.(*influxql.SelectStatement).RewriteFields(&ic)
if err != nil {
t.Errorf("%d. %q: error: %s", i, tt.stmt, err)
} else if rw == nil {
t.Errorf("%d. %q: unexpected nil statement", i, tt.stmt)
} else if rw := rw.String(); tt.rewrite != rw {
t.Errorf("%d. %q: unexpected rewrite:\n\nexp=%s\n\ngot=%s\n\n", i, tt.stmt, tt.rewrite, rw)
}
}
}
开发者ID:sbouchex,项目名称:influxdb,代码行数:101,代码来源:ast_test.go
示例18: TestSelectStatement_HasWildcard
func TestSelectStatement_HasWildcard(t *testing.T) {
var tests = []struct {
stmt string
wildcard bool
}{
// No wildcards
{
stmt: `SELECT value FROM cpu`,
wildcard: false,
},
// Query wildcard
{
stmt: `SELECT * FROM cpu`,
wildcard: true,
},
// No GROUP BY wildcards
{
stmt: `SELECT value FROM cpu GROUP BY host`,
wildcard: false,
},
// No GROUP BY wildcards, time only
{
stmt: `SELECT mean(value) FROM cpu where time < now() GROUP BY time(5ms)`,
wildcard: false,
},
// GROUP BY wildcard
{
stmt: `SELECT value FROM cpu GROUP BY *`,
wildcard: true,
},
// GROUP BY wildcard with time
{
stmt: `SELECT mean(value) FROM cpu where time < now() GROUP BY *,time(1m)`,
wildcard: true,
},
// GROUP BY wildcard with explicit
{
stmt: `SELECT value FROM cpu GROUP BY *,host`,
wildcard: true,
},
// GROUP BY multiple wildcards
{
stmt: `SELECT value FROM cpu GROUP BY *,*`,
wildcard: true,
},
// Combo
{
stmt: `SELECT * FROM cpu GROUP BY *`,
wildcard: true,
},
}
for i, tt := range tests {
// Parse statement.
stmt, err := influxql.NewParser(strings.NewReader(tt.stmt)).ParseStatement()
if err != nil {
t.Fatalf("invalid statement: %q: %s", tt.stmt, err)
}
// Test wildcard detection.
if w := stmt.(*influxql.SelectStatement).HasWildcard(); tt.wildcard != w {
t.Errorf("%d. %q: unexpected wildcard detection:\n\nexp=%v\n\ngot=%v\n\n", i, tt.stmt, tt.wildcard, w)
continue
}
}
}
开发者ID:sbouchex,项目名称:influxdb,代码行数:74,代码来源:ast_test.go
示例19: serveQuery
// serveQuery parses an incoming query and, if valid, executes the query.
func (h *Handler) serveQuery(w http.ResponseWriter, r *http.Request, user *meta.UserInfo) {
atomic.AddInt64(&h.stats.QueryRequests, 1)
defer func(start time.Time) {
atomic.AddInt64(&h.stats.QueryRequestDuration, time.Since(start).Nanoseconds())
}(time.Now())
pretty := r.FormValue("pretty") == "true"
nodeID, _ := strconv.ParseUint(r.FormValue("node_id"), 10, 64)
qp := strings.TrimSpace(r.FormValue("q"))
if qp == "" {
h.httpError(w, `missing required parameter "q"`, pretty, http.StatusBadRequest)
return
}
epoch := strings.TrimSpace(r.FormValue("epoch"))
p := influxql.NewParser(strings.NewReader(qp))
db := r.FormValue("db")
// Sanitize the request query params so it doesn't show up in the response logger.
// Do this before anything else so a parsing error doesn't leak passwords.
sanitize(r)
// Parse the parameters
rawParams := r.FormValue("params")
if rawParams != "" {
var params map[string]interface{}
decoder := json.NewDecoder(strings.NewReader(rawParams))
decoder.UseNumber()
if err := decoder.Decode(¶ms); err != nil {
h.httpError(w, "error parsing query parameters: "+err.Error(), pretty, http.StatusBadRequest)
return
}
// Convert json.Number into int64 and float64 values
for k, v := range params {
if v, ok := v.(json.Number); ok {
var err error
if strings.Contains(string(v), ".") {
params[k], err = v.Float64()
} else {
params[k], err = v.Int64()
}
if err != nil {
h.httpError(w, "error parsing json value: "+err.Error(), pretty, http.StatusBadRequest)
return
}
}
}
p.SetParams(params)
}
// Parse query from query string.
query, err := p.ParseQuery()
if err != nil {
h.httpError(w, "error parsing query: "+err.Error(), pretty, http.StatusBadRequest)
return
}
// Check authorization.
if h.Config.AuthEnabled {
if err := h.QueryAuthorizer.AuthorizeQuery(user, query, db); err != nil {
if err, ok := err.(meta.ErrAuthorize); ok {
h.Logger.Printf("Unauthorized request | user: %q | query: %q | database %q\n", err.User, err.Query.String(), err.Database)
}
h.httpError(w, "error authorizing query: "+err.Error(), pretty, http.StatusUnauthorized)
return
}
}
// Parse chunk size. Use default if not provided or unparsable.
chunked := (r.FormValue("chunked") == "true")
chunkSize := DefaultChunkSize
if chunked {
if n, err := strconv.ParseInt(r.FormValue("chunk_size"), 10, 64); err == nil && int(n) > 0 {
chunkSize = int(n)
}
}
// Make sure if the client disconnects we signal the query to abort
closing := make(chan struct{})
if notifier, ok := w.(http.CloseNotifier); ok {
// CloseNotify() is not guaranteed to send a notification when the query
// is closed. Use this channel to signal that the query is finished to
// prevent lingering goroutines that may be stuck.
done := make(chan struct{})
defer close(done)
notify := notifier.CloseNotify()
go func() {
// Wait for either the request to finish
// or for the client to disconnect
select {
case <-done:
case <-notify:
close(closing)
}
//.........这里部分代码省略.........
开发者ID:CrazyUncleJack,项目名称:influxdb,代码行数:101,代码来源:handler.go
示例20: serveQuery
// serveQuery parses an incoming query and, if valid, executes the query.
func (h *Handler) serveQuery(w http.ResponseWriter, r *http.Request, user *meta.UserInfo) {
atomic.AddInt64(&h.stats.QueryRequests, 1)
defer func(start time.Time) {
atomic.AddInt64(&h.stats.QueryRequestDuration, time.Since(start).Nanoseconds())
}(time.Now())
// Retrieve the underlying ResponseWriter or initialize our own.
rw, ok := w.(ResponseWriter)
if !ok {
rw = NewResponseWriter(w, r)
}
// Retrieve the node id the query should be executed on.
nodeID, _ := strconv.ParseUint(r.FormValue("node_id"), 10, 64)
var qr io.Reader
// Attempt to read the form value from the "q" form value.
if qp := strings.TrimSpace(r.FormValue("q")); qp != "" {
qr = strings.NewReader(qp)
} else if r.MultipartForm != nil && r.MultipartForm.File != nil {
// If we have a multipart/form-data, try to retrieve a file from 'q'.
if fhs := r.MultipartForm.File["q"]; len(fhs) > 0 {
f, err := fhs[0].Open()
if err != nil {
h.httpError(rw, err.Error(), http.StatusBadRequest)
return
}
defer f.Close()
qr = f
}
}
if qr == nil {
h.httpError(rw, `missing required parameter "q"`, http.StatusBadRequest)
return
}
epoch := strings.TrimSpace(r.FormValue("epoch"))
p := influxql.NewParser(qr)
db := r.FormValue("db")
// Sanitize the request query params so it doesn't show up in the response logger.
// Do this before anything else so a parsing error doesn't leak passwords.
sanitize(r)
// Parse the parameters
rawParams := r.FormValue("params")
if rawParams != "" {
var params map[string]interface{}
decoder := json.NewDecoder(strings.NewReader(rawParams))
decoder.UseNumber()
if err := decoder.Decode(¶ms); err != nil {
h.httpError(rw, "error parsing query parameters: "+err.Error(), http.StatusBadRequest)
return
}
// Convert json.Number into int64 and float64 values
for k, v := range params {
if v, ok := v.(json.Number); ok {
var err error
if strings.Contains(string(v), ".") {
params[k], err = v.Float64()
} else {
params[k], er
|
请发表评论