mirror of
https://github.com/grafana/grafana.git
synced 2025-07-29 23:32:30 +08:00
SQL Expressions: Add JSON support (#103157)
- Support bi-directional mapping of frame JSON fields and GMS (go-mysql-server) columns - Permit GMS json functions Co-authored-by: Kyle Brandt <kyle@grafana.com>
This commit is contained in:
@ -4,6 +4,7 @@ package sql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@ -205,6 +206,83 @@ func TestErrorsFromGoMySQLServerAreFlagged(t *testing.T) {
|
||||
require.Contains(t, err.Error(), "error in go-mysql-server")
|
||||
}
|
||||
|
||||
func TestFrameToSQLAndBack_JSONRoundtrip(t *testing.T) {
|
||||
expectedFrame := &data.Frame{
|
||||
RefID: "json_test",
|
||||
Name: "json_test",
|
||||
Fields: []*data.Field{
|
||||
data.NewField("id", nil, []int64{1, 2}),
|
||||
data.NewField("payload", nil, []json.RawMessage{
|
||||
json.RawMessage(`{"foo":1}`),
|
||||
json.RawMessage(`{"bar":"baz"}`),
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
db := DB{}
|
||||
|
||||
query := `SELECT * FROM json_test`
|
||||
|
||||
resultFrame, err := db.QueryFrames(context.Background(), "json_test", query, data.Frames{expectedFrame})
|
||||
require.NoError(t, err)
|
||||
|
||||
// Use custom compare options that ignore Name and RefID
|
||||
opts := append(
|
||||
data.FrameTestCompareOptions(),
|
||||
cmp.FilterPath(func(p cmp.Path) bool {
|
||||
return p.String() == "Name" || p.String() == "RefID"
|
||||
}, cmp.Ignore()),
|
||||
)
|
||||
|
||||
if diff := cmp.Diff(expectedFrame, resultFrame, opts...); diff != "" {
|
||||
require.FailNowf(t, "Frame mismatch (-want +got):\n%s", diff)
|
||||
}
|
||||
}
|
||||
|
||||
func TestQueryFrames_JSONFilter(t *testing.T) {
|
||||
input := &data.Frame{
|
||||
RefID: "A",
|
||||
Name: "A",
|
||||
Fields: []*data.Field{
|
||||
data.NewField("title", nil, []string{"Bug report", "Feature request"}),
|
||||
data.NewField("labels", nil, []json.RawMessage{
|
||||
json.RawMessage(`["type/bug", "priority/high"]`),
|
||||
json.RawMessage(`["type/feature", "priority/low"]`),
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
expected := &data.Frame{
|
||||
RefID: "B",
|
||||
Name: "B",
|
||||
Fields: []*data.Field{
|
||||
data.NewField("title", nil, []string{"Bug report"}),
|
||||
data.NewField("labels", nil, []json.RawMessage{
|
||||
json.RawMessage(`["type/bug", "priority/high"]`),
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
db := DB{}
|
||||
|
||||
query := `SELECT title, labels FROM A WHERE json_contains(labels, '"type/bug"')`
|
||||
|
||||
result, err := db.QueryFrames(context.Background(), "B", query, data.Frames{input})
|
||||
require.NoError(t, err)
|
||||
|
||||
// Use custom compare options that ignore Name and RefID
|
||||
opts := append(
|
||||
data.FrameTestCompareOptions(),
|
||||
cmp.FilterPath(func(p cmp.Path) bool {
|
||||
return p.String() == "Name" || p.String() == "RefID"
|
||||
}, cmp.Ignore()),
|
||||
)
|
||||
|
||||
if diff := cmp.Diff(expected, result, opts...); diff != "" {
|
||||
require.FailNowf(t, "Result mismatch (-want +got):\n%s", diff)
|
||||
}
|
||||
}
|
||||
|
||||
// p is a utility for pointers from constants
|
||||
func p[T any](v T) *T {
|
||||
return &v
|
||||
|
Reference in New Issue
Block a user