diff --git a/pkg/tsdb/mysql/mysql_snapshot_test.go b/pkg/tsdb/mysql/mysql_snapshot_test.go new file mode 100644 index 000000000000..d2ff94f889c6 --- /dev/null +++ b/pkg/tsdb/mysql/mysql_snapshot_test.go @@ -0,0 +1,214 @@ +package mysql + +import ( + "context" + "database/sql" + "encoding/json" + "fmt" + "os" + "path/filepath" + "regexp" + "strings" + "testing" + "time" + + "github.com/grafana/grafana-plugin-sdk-go/backend" + "github.com/grafana/grafana-plugin-sdk-go/experimental" + "github.com/stretchr/testify/require" + + "github.com/grafana/grafana/pkg/tsdb/sqleng" + + _ "github.com/go-sql-driver/mysql" +) + +var updateGoldenFiles = false + +// These tests require a real mysql database: +// - make devenv sources=potgres_tests +// - either set the env variable GRAFANA_TEST_DB = mysql +// - or set `forceRun := true` below +// +// The tests require a MySQL db named grafanadstest and a user/password grafanatest/grafanatest! +// Use the docker/blocks/mysql_tests/docker-compose.yaml to spin up a +// preconfigured MySQL server suitable for running these tests. +func TestIntegrationMySQLSnapshots(t *testing.T) { + // the logic in this function is copied from mysql_tests.go + shouldRunTest := func() bool { + if testing.Short() { + return false + } + + testDbName, present := os.LookupEnv("GRAFANA_TEST_DB") + + if present && testDbName == "mysql" { + return true + } + + return false + } + + if !shouldRunTest() { + t.Skip() + } + + sqlQueryCommentRe := regexp.MustCompile(`^-- (.+)\n`) + + readSqlFile := func(path string) (string, []string) { + // the file-path is not coming from the outside, + // it is hardcoded in this file. + //nolint:gosec + sqlBytes, err := os.ReadFile(path) + require.NoError(t, err) + + sql := string(sqlBytes) + + // first line of the file contains the sql query to run, commented out + match := sqlQueryCommentRe.FindStringSubmatch(sql) + require.Len(t, match, 2) + + rawSQL := strings.TrimSpace(match[1]) + + // mysql is unable to send multiple queries in a single `Query()`, + // so we split the queries. we split by an "empty new line" + sqls := strings.Split(sql, "\n\n") + + return rawSQL, sqls + } + + makeQuery := func(rawSQL string, format string) backend.QueryDataRequest { + queryData := map[string]string{ + "rawSql": rawSQL, + "format": format, + } + + queryBytes, err := json.Marshal(queryData) + require.NoError(t, err) + + return backend.QueryDataRequest{ + Queries: []backend.DataQuery{ + { + JSON: queryBytes, + RefID: "A", + TimeRange: backend.TimeRange{ + From: time.Date(2023, 12, 24, 14, 15, 22, 123456, time.UTC), + To: time.Date(2023, 12, 24, 14, 45, 13, 876543, time.UTC), + }, + }, + }, + } + } + + tt := []struct { + name string + format string + }{ + {format: "time_series", name: "simple"}, + {format: "time_series", name: "no_rows_long"}, + {format: "time_series", name: "no_rows_wide"}, + {format: "time_series", name: "7x_compat_metric_label"}, + {format: "time_series", name: "convert_to_float64"}, + {format: "time_series", name: "convert_to_float64_not"}, + {format: "time_series", name: "fill_null"}, + {format: "time_series", name: "fill_previous"}, + {format: "time_series", name: "fill_value"}, + {format: "time_series", name: "fill_value_wide"}, + {format: "table", name: "simple"}, + {format: "table", name: "no_rows"}, + {format: "table", name: "types_numeric"}, + {format: "table", name: "types_char"}, + {format: "table", name: "types_datetime"}, + {format: "table", name: "types_other"}, + {format: "table", name: "timestamp_convert_bigint"}, + {format: "table", name: "timestamp_convert_integer"}, + {format: "table", name: "timestamp_convert_float"}, + {format: "table", name: "timestamp_convert_double"}, + } + + for _, test := range tt { + require.True(t, test.format == "table" || test.format == "time_series") + t.Run(test.name, func(t *testing.T) { + origInterpolate := sqleng.Interpolate + t.Cleanup(func() { + sqleng.Interpolate = origInterpolate + }) + + sqleng.Interpolate = func(query backend.DataQuery, timeRange backend.TimeRange, timeInterval string, sql string) string { + return sql + } + + host := os.Getenv("MYSQL_HOST") + if host == "" { + host = "localhost" + } + port := os.Getenv("MYSQL_PORT") + if port == "" { + port = "3306" + } + cnnStr := fmt.Sprintf("grafana:password@tcp(%s:%s)/grafana_ds_tests?collation=utf8mb4_unicode_ci&sql_mode='ANSI_QUOTES'&parseTime=true&loc=UTC", host, port) + + dsInfo := sqleng.DataSourceInfo{ + JsonData: sqleng.JsonData{ + MaxOpenConns: 0, + MaxIdleConns: 2, + ConnMaxLifetime: 14400, + }, + } + + db, err := sql.Open("mysql", cnnStr) + + if err != nil { + t.Fatalf("Failed to init mysql db %v", err) + } + + db.SetMaxOpenConns(dsInfo.JsonData.MaxOpenConns) + db.SetMaxIdleConns(dsInfo.JsonData.MaxIdleConns) + db.SetConnMaxLifetime(time.Duration(dsInfo.JsonData.ConnMaxLifetime)) + + rowTransformer := mysqlQueryResultTransformer{} + + logger := backend.NewLoggerWith("logger", "mysql.test") + + config := sqleng.DataPluginConfiguration{ + DSInfo: dsInfo, + TimeColumnNames: []string{"time", "time_sec"}, + MetricColumnTypes: []string{"CHAR", "VARCHAR", "TINYTEXT", "TEXT", "MEDIUMTEXT", "LONGTEXT"}, + RowLimit: 1000000, + } + + handler, err := sqleng.NewQueryDataHandler("", db, config, &rowTransformer, newMysqlMacroEngine(logger, ""), logger) + + require.NoError(t, err) + + t.Cleanup((func() { + _, err := db.Exec("DROP TABLE IF EXISTS tbl") + require.NoError(t, err) + err = db.Close() + require.NoError(t, err) + })) + + require.NoError(t, err) + + sqlFilePath := filepath.Join("testdata", test.format, test.name+".sql") + goldenFileName := filepath.Join(test.format, test.name+".golden") + + rawSQL, sqls := readSqlFile(sqlFilePath) + + _, err = db.Exec("DROP TABLE IF EXISTS tbl") + require.NoError(t, err) + + for _, sql := range sqls { + _, err = db.Exec(sql) + require.NoError(t, err) + } + + query := makeQuery(rawSQL, test.format) + + result, err := handler.QueryData(context.Background(), &query) + require.Len(t, result.Responses, 1) + response, found := result.Responses["A"] + require.True(t, found) + require.NoError(t, err) + experimental.CheckGoldenJSONResponse(t, "testdata", goldenFileName, &response, updateGoldenFiles) + }) + } +} diff --git a/pkg/tsdb/mysql/testdata/table/no_rows.golden.jsonc b/pkg/tsdb/mysql/testdata/table/no_rows.golden.jsonc new file mode 100644 index 000000000000..2cc0ccc47b8b --- /dev/null +++ b/pkg/tsdb/mysql/testdata/table/no_rows.golden.jsonc @@ -0,0 +1,36 @@ +// 🌟 This was machine generated. Do not edit. 🌟 +// +// Frame[0] { +// "typeVersion": [ +// 0, +// 0 +// ], +// "executedQueryString": "SELECT * FROM tbl WHERE false" +// } +// Name: +// Dimensions: 0 Fields by 0 Rows +// + +// + +// +// +// 🌟 This was machine generated. Do not edit. 🌟 +{ + "status": 200, + "frames": [ + { + "schema": { + "meta": { + "typeVersion": [ + 0, + 0 + ], + "executedQueryString": "SELECT * FROM tbl WHERE false" + }, + "fields": [] + }, + "data": { + "values": [] + } + } + ] +} \ No newline at end of file diff --git a/pkg/tsdb/mysql/testdata/table/no_rows.sql b/pkg/tsdb/mysql/testdata/table/no_rows.sql new file mode 100644 index 000000000000..0a81eb4fa079 --- /dev/null +++ b/pkg/tsdb/mysql/testdata/table/no_rows.sql @@ -0,0 +1,12 @@ +-- SELECT * FROM tbl WHERE false +CREATE TABLE tbl ( + `time` timestamp NOT NULL, + v double precision, + c text +); + +INSERT INTO tbl (`time`, v, c) VALUES +('2023-12-24 14:30:03+00:00', 10, 'a'), +('2023-12-24 14:30:03+00:00', 110, 'b'), +('2023-12-24 14:31:03+00:00', 20, 'a'), +('2023-12-24 14:31:03+00:00', 120, 'b'); \ No newline at end of file diff --git a/pkg/tsdb/mysql/testdata/table/simple.golden.jsonc b/pkg/tsdb/mysql/testdata/table/simple.golden.jsonc new file mode 100644 index 000000000000..68803e3e77ee --- /dev/null +++ b/pkg/tsdb/mysql/testdata/table/simple.golden.jsonc @@ -0,0 +1,112 @@ +// 🌟 This was machine generated. Do not edit. 🌟 +// +// Frame[0] { +// "typeVersion": [ +// 0, +// 0 +// ], +// "executedQueryString": "SELECT * FROM tbl" +// } +// Name: +// Dimensions: 3 Fields by 10 Rows +// +-------------------------------+------------------+-----------------+ +// | Name: time | Name: v | Name: c | +// | Labels: | Labels: | Labels: | +// | Type: []*time.Time | Type: []*float64 | Type: []*string | +// +-------------------------------+------------------+-----------------+ +// | 2023-12-24 14:30:03 +0000 UTC | 10 | a | +// | 2023-12-24 14:30:03 +0000 UTC | 110 | b | +// | 2023-12-24 14:31:03 +0000 UTC | 20 | a | +// | 2023-12-24 14:31:03 +0000 UTC | 120 | b | +// | 2023-12-24 14:32:03 +0000 UTC | 30 | a | +// | 2023-12-24 14:32:03 +0000 UTC | 130 | b | +// | 2023-12-24 14:33:03 +0000 UTC | 40 | a | +// | 2023-12-24 14:33:03 +0000 UTC | 140 | b | +// | 2023-12-24 14:34:03 +0000 UTC | 50 | a | +// | 2023-12-24 14:34:03 +0000 UTC | 150 | b | +// +-------------------------------+------------------+-----------------+ +// +// +// 🌟 This was machine generated. Do not edit. 🌟 +{ + "status": 200, + "frames": [ + { + "schema": { + "meta": { + "typeVersion": [ + 0, + 0 + ], + "executedQueryString": "SELECT * FROM tbl" + }, + "fields": [ + { + "name": "time", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "name": "v", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + }, + { + "name": "c", + "type": "string", + "typeInfo": { + "frame": "string", + "nullable": true + } + } + ] + }, + "data": { + "values": [ + [ + 1703428203000, + 1703428203000, + 1703428263000, + 1703428263000, + 1703428323000, + 1703428323000, + 1703428383000, + 1703428383000, + 1703428443000, + 1703428443000 + ], + [ + 10, + 110, + 20, + 120, + 30, + 130, + 40, + 140, + 50, + 150 + ], + [ + "a", + "b", + "a", + "b", + "a", + "b", + "a", + "b", + "a", + "b" + ] + ] + } + } + ] +} \ No newline at end of file diff --git a/pkg/tsdb/mysql/testdata/table/simple.sql b/pkg/tsdb/mysql/testdata/table/simple.sql new file mode 100644 index 000000000000..38b5c33650d0 --- /dev/null +++ b/pkg/tsdb/mysql/testdata/table/simple.sql @@ -0,0 +1,18 @@ +-- SELECT * FROM tbl +CREATE TABLE tbl ( + `time` timestamp NOT NULL, + v double precision, + c text +); + +INSERT INTO tbl (`time`, v, c) VALUES +('2023-12-24 14:30:03+00:00', 10, 'a'), +('2023-12-24 14:30:03+00:00', 110, 'b'), +('2023-12-24 14:31:03+00:00', 20, 'a'), +('2023-12-24 14:31:03+00:00', 120, 'b'), +('2023-12-24 14:32:03+00:00', 30, 'a'), +('2023-12-24 14:32:03+00:00', 130, 'b'), +('2023-12-24 14:33:03+00:00', 40, 'a'), +('2023-12-24 14:33:03+00:00', 140, 'b'), +('2023-12-24 14:34:03+00:00', 50, 'a'), +('2023-12-24 14:34:03+00:00', 150, 'b'); \ No newline at end of file diff --git a/pkg/tsdb/mysql/testdata/table/timestamp_convert_bigint.golden.jsonc b/pkg/tsdb/mysql/testdata/table/timestamp_convert_bigint.golden.jsonc new file mode 100644 index 000000000000..81fe927d2010 --- /dev/null +++ b/pkg/tsdb/mysql/testdata/table/timestamp_convert_bigint.golden.jsonc @@ -0,0 +1,113 @@ +// 🌟 This was machine generated. Do not edit. 🌟 +// +// Frame[0] { +// "typeVersion": [ +// 0, +// 0 +// ], +// "executedQueryString": "SELECT * FROM tbl" +// } +// Name: +// Dimensions: 4 Fields by 4 Rows +// +--------------------------------------+-----------------------------------+---------------------+-----------------------------------+ +// | Name: reallyt | Name: time | Name: n | Name: timeend | +// | Labels: | Labels: | Labels: | Labels: | +// | Type: []*time.Time | Type: []*time.Time | Type: []*int64 | Type: []*time.Time | +// +--------------------------------------+-----------------------------------+---------------------+-----------------------------------+ +// | 2023-12-21 12:21:27 +0000 UTC | 2023-12-21 12:21:27 +0000 UTC | 1703161287 | 2023-12-21 12:21:52 +0000 UTC | +// | 2023-12-21 12:21:27.724 +0000 UTC | 2023-12-21 12:21:27.724 +0000 UTC | 1703161287724 | 2023-12-21 12:21:52.522 +0000 UTC | +// | 2023-12-21 12:21:27.724919 +0000 UTC | 2023-12-21 12:21:27.724 +0000 UTC | 1703161287724919000 | 2023-12-21 12:21:52.522 +0000 UTC | +// | null | null | null | null | +// +--------------------------------------+-----------------------------------+---------------------+-----------------------------------+ +// +// +// 🌟 This was machine generated. Do not edit. 🌟 +{ + "status": 200, + "frames": [ + { + "schema": { + "meta": { + "typeVersion": [ + 0, + 0 + ], + "executedQueryString": "SELECT * FROM tbl" + }, + "fields": [ + { + "name": "reallyt", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "name": "time", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "name": "n", + "type": "number", + "typeInfo": { + "frame": "int64", + "nullable": true + } + }, + { + "name": "timeend", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + } + ] + }, + "data": { + "values": [ + [ + 1703161287000, + 1703161287724, + 1703161287724, + null + ], + [ + 1703161287000, + 1703161287724, + 1703161287724, + null + ], + [ + 1703161287, + 1703161287724, + 1703161287724919000, + null + ], + [ + 1703161312000, + 1703161312522, + 1703161312522, + null + ] + ], + "nanos": [ + [ + 0, + 0, + 919000, + 0 + ], + null, + null, + null + ] + } + } + ] +} \ No newline at end of file diff --git a/pkg/tsdb/mysql/testdata/table/timestamp_convert_bigint.sql b/pkg/tsdb/mysql/testdata/table/timestamp_convert_bigint.sql new file mode 100644 index 000000000000..d432c6cdef8a --- /dev/null +++ b/pkg/tsdb/mysql/testdata/table/timestamp_convert_bigint.sql @@ -0,0 +1,15 @@ +-- SELECT * FROM tbl +-- the time-field and time-end field gets converted to time.Time +CREATE TABLE tbl ( + -- note, in the timestmap below we must say `NULL` otherwise mysql-below-8 inserts current timestamp + reallyt timestamp(6) NULL, -- reference real timestamp + "time" bigint, + n bigint, -- normal number, it should not get converted to a timestamp + timeend bigint +); + +INSERT INTO tbl (reallyt, "time", n, timeend) VALUES +('2023-12-21T12:21:27 UTC', 1703161287, 1703161287, 1703161312), +('2023-12-21T12:21:27.724 UTC', 1703161287724, 1703161287724, 1703161312522), +('2023-12-21T12:21:27.724919 UTC', 1703161287724919000, 1703161287724919000, 1703161312522186000), +(NULL, NULL, NULL, NULL); \ No newline at end of file diff --git a/pkg/tsdb/mysql/testdata/table/timestamp_convert_double.golden.jsonc b/pkg/tsdb/mysql/testdata/table/timestamp_convert_double.golden.jsonc new file mode 100644 index 000000000000..310adf7157d6 --- /dev/null +++ b/pkg/tsdb/mysql/testdata/table/timestamp_convert_double.golden.jsonc @@ -0,0 +1,113 @@ +// 🌟 This was machine generated. Do not edit. 🌟 +// +// Frame[0] { +// "typeVersion": [ +// 0, +// 0 +// ], +// "executedQueryString": "SELECT * FROM tbl" +// } +// Name: +// Dimensions: 4 Fields by 4 Rows +// +--------------------------------------+-----------------------------------+-----------------------+-----------------------------------+ +// | Name: reallyt | Name: time | Name: n | Name: timeend | +// | Labels: | Labels: | Labels: | Labels: | +// | Type: []*time.Time | Type: []*time.Time | Type: []*float64 | Type: []*time.Time | +// +--------------------------------------+-----------------------------------+-----------------------+-----------------------------------+ +// | 2023-12-21 12:21:27 +0000 UTC | 2023-12-21 12:21:27 +0000 UTC | 1.703161287e+09 | 2023-12-21 12:21:52 +0000 UTC | +// | 2023-12-21 12:21:27.724 +0000 UTC | 2023-12-21 12:21:27.724 +0000 UTC | 1.703161287724e+12 | 2023-12-21 12:21:52.522 +0000 UTC | +// | 2023-12-21 12:21:27.724919 +0000 UTC | 2023-12-21 12:21:27.724 +0000 UTC | 1.703161287724919e+18 | 2023-12-21 12:21:52.522 +0000 UTC | +// | null | null | null | null | +// +--------------------------------------+-----------------------------------+-----------------------+-----------------------------------+ +// +// +// 🌟 This was machine generated. Do not edit. 🌟 +{ + "status": 200, + "frames": [ + { + "schema": { + "meta": { + "typeVersion": [ + 0, + 0 + ], + "executedQueryString": "SELECT * FROM tbl" + }, + "fields": [ + { + "name": "reallyt", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "name": "time", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "name": "n", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + }, + { + "name": "timeend", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + } + ] + }, + "data": { + "values": [ + [ + 1703161287000, + 1703161287724, + 1703161287724, + null + ], + [ + 1703161287000, + 1703161287724, + 1703161287724, + null + ], + [ + 1703161287, + 1703161287724, + 1703161287724919000, + null + ], + [ + 1703161312000, + 1703161312522, + 1703161312522, + null + ] + ], + "nanos": [ + [ + 0, + 0, + 919000, + 0 + ], + null, + null, + null + ] + } + } + ] +} \ No newline at end of file diff --git a/pkg/tsdb/mysql/testdata/table/timestamp_convert_double.sql b/pkg/tsdb/mysql/testdata/table/timestamp_convert_double.sql new file mode 100644 index 000000000000..9b1c735a0770 --- /dev/null +++ b/pkg/tsdb/mysql/testdata/table/timestamp_convert_double.sql @@ -0,0 +1,15 @@ +-- SELECT * FROM tbl +-- the time-field and time-end field gets converted to time.Time +CREATE TABLE tbl ( + -- note, in the timestmap below we must say `NULL` otherwise mysql-below-8 inserts current timestamp + reallyt timestamp(6) NULL, -- reference real timestamp + "time" double precision, + n double precision, -- normal number, it should not get converted to a timestamp + timeend bigint +); + +INSERT INTO tbl (reallyt, "time", n, timeend) VALUES +('2023-12-21T12:21:27 UTC', 1703161287, 1703161287, 1703161312), +('2023-12-21T12:21:27.724 UTC', 1703161287724, 1703161287724, 1703161312522), +('2023-12-21T12:21:27.724919 UTC', 1703161287724919000, 1703161287724919000, 1703161312522186000), +(NULL, NULL, NULL, NULL); \ No newline at end of file diff --git a/pkg/tsdb/mysql/testdata/table/timestamp_convert_float.golden.jsonc b/pkg/tsdb/mysql/testdata/table/timestamp_convert_float.golden.jsonc new file mode 100644 index 000000000000..e6d1dfd23829 --- /dev/null +++ b/pkg/tsdb/mysql/testdata/table/timestamp_convert_float.golden.jsonc @@ -0,0 +1,113 @@ +// 🌟 This was machine generated. Do not edit. 🌟 +// +// Frame[0] { +// "typeVersion": [ +// 0, +// 0 +// ], +// "executedQueryString": "SELECT * FROM tbl" +// } +// Name: +// Dimensions: 4 Fields by 4 Rows +// +--------------------------------------+-----------------------------------+-----------------------+-----------------------------------+ +// | Name: reallyt | Name: time | Name: n | Name: timeend | +// | Labels: | Labels: | Labels: | Labels: | +// | Type: []*time.Time | Type: []*time.Time | Type: []*float64 | Type: []*time.Time | +// +--------------------------------------+-----------------------------------+-----------------------+-----------------------------------+ +// | 2023-12-21 12:22:24 +0000 UTC | 2023-12-21 12:22:24 +0000 UTC | 1.703161344e+09 | 2023-12-21 12:22:52 +0000 UTC | +// | 2023-12-21 12:20:33.408 +0000 UTC | 2023-12-21 12:20:33.408 +0000 UTC | 1.703161233408e+12 | 2023-12-21 12:21:52.522 +0000 UTC | +// | 2023-12-21 12:20:41.050022 +0000 UTC | 2023-12-21 12:20:41.05 +0000 UTC | 1.703161241050022e+18 | 2023-12-21 12:21:52.522 +0000 UTC | +// | null | null | null | null | +// +--------------------------------------+-----------------------------------+-----------------------+-----------------------------------+ +// +// +// 🌟 This was machine generated. Do not edit. 🌟 +{ + "status": 200, + "frames": [ + { + "schema": { + "meta": { + "typeVersion": [ + 0, + 0 + ], + "executedQueryString": "SELECT * FROM tbl" + }, + "fields": [ + { + "name": "reallyt", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "name": "time", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "name": "n", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + }, + { + "name": "timeend", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + } + ] + }, + "data": { + "values": [ + [ + 1703161344000, + 1703161233408, + 1703161241050, + null + ], + [ + 1703161344000, + 1703161233408, + 1703161241050, + null + ], + [ + 1703161344, + 1703161233408, + 1703161241050022000, + null + ], + [ + 1703161372000, + 1703161312522, + 1703161312522, + null + ] + ], + "nanos": [ + [ + 0, + 0, + 22000, + 0 + ], + null, + null, + null + ] + } + } + ] +} \ No newline at end of file diff --git a/pkg/tsdb/mysql/testdata/table/timestamp_convert_float.sql b/pkg/tsdb/mysql/testdata/table/timestamp_convert_float.sql new file mode 100644 index 000000000000..140b3e909e36 --- /dev/null +++ b/pkg/tsdb/mysql/testdata/table/timestamp_convert_float.sql @@ -0,0 +1,15 @@ +-- SELECT * FROM tbl +-- the time-field and time-end field gets converted to time.Time +CREATE TABLE tbl ( + -- note, in the timestmap below we must say `NULL` otherwise mysql-below-8 inserts current timestamp + reallyt timestamp(6) NULL, -- reference real timestamp + "time" real, + n real, -- normal number, it should not get converted to a timestamp + timeend bigint +); + +INSERT INTO tbl (reallyt, "time", n, timeend) VALUES +('2023-12-21T12:22:24', 1703161344, 1703161344, 1703161372), +('2023-12-21T12:20:33.408', 1703161233408, 1703161233408, 1703161312522), +('2023-12-21T12:20:41.050022', 1703161241050021888, 1703161241050021888, 1703161312522186000), +(NULL, NULL, NULL, NULL); \ No newline at end of file diff --git a/pkg/tsdb/mysql/testdata/table/timestamp_convert_integer.golden.jsonc b/pkg/tsdb/mysql/testdata/table/timestamp_convert_integer.golden.jsonc new file mode 100644 index 000000000000..9f0145041b04 --- /dev/null +++ b/pkg/tsdb/mysql/testdata/table/timestamp_convert_integer.golden.jsonc @@ -0,0 +1,92 @@ +// 🌟 This was machine generated. Do not edit. 🌟 +// +// Frame[0] { +// "typeVersion": [ +// 0, +// 0 +// ], +// "executedQueryString": "SELECT * FROM tbl" +// } +// Name: +// Dimensions: 4 Fields by 2 Rows +// +-------------------------------+-------------------------------+----------------+-------------------------------+ +// | Name: reallyt | Name: time | Name: n | Name: timeend | +// | Labels: | Labels: | Labels: | Labels: | +// | Type: []*time.Time | Type: []*time.Time | Type: []*int64 | Type: []*time.Time | +// +-------------------------------+-------------------------------+----------------+-------------------------------+ +// | 2023-12-21 12:21:27 +0000 UTC | 2023-12-21 12:21:27 +0000 UTC | 1703161287 | 2023-12-21 12:21:52 +0000 UTC | +// | null | null | null | null | +// +-------------------------------+-------------------------------+----------------+-------------------------------+ +// +// +// 🌟 This was machine generated. Do not edit. 🌟 +{ + "status": 200, + "frames": [ + { + "schema": { + "meta": { + "typeVersion": [ + 0, + 0 + ], + "executedQueryString": "SELECT * FROM tbl" + }, + "fields": [ + { + "name": "reallyt", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "name": "time", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "name": "n", + "type": "number", + "typeInfo": { + "frame": "int64", + "nullable": true + } + }, + { + "name": "timeend", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + } + ] + }, + "data": { + "values": [ + [ + 1703161287000, + null + ], + [ + 1703161287000, + null + ], + [ + 1703161287, + null + ], + [ + 1703161312000, + null + ] + ] + } + } + ] +} \ No newline at end of file diff --git a/pkg/tsdb/mysql/testdata/table/timestamp_convert_integer.sql b/pkg/tsdb/mysql/testdata/table/timestamp_convert_integer.sql new file mode 100644 index 000000000000..8d9a0d05d94a --- /dev/null +++ b/pkg/tsdb/mysql/testdata/table/timestamp_convert_integer.sql @@ -0,0 +1,13 @@ +-- SELECT * FROM tbl +-- the time-field and time-end field gets converted to time.Time +CREATE TABLE tbl ( + -- note, in the timestmap below we must say `NULL` otherwise mysql-below-8 inserts current timestamp + reallyt timestamp(6) NULL, -- reference real timestamp + "time" integer, -- 32bits, seconds-as-number is highest we can go, milliseconds-as-number does not fit + n integer, -- normal number, it should not get converted to a timestamp + timeend integer +); + +INSERT INTO tbl (reallyt, "time", n, timeend) VALUES +('2023-12-21T12:21:27 UTC', 1703161287, 1703161287, 1703161312), +(NULL, NULL, NULL, NULL); \ No newline at end of file diff --git a/pkg/tsdb/mysql/testdata/table/types_char.golden.jsonc b/pkg/tsdb/mysql/testdata/table/types_char.golden.jsonc new file mode 100644 index 000000000000..1f4c8147a05f --- /dev/null +++ b/pkg/tsdb/mysql/testdata/table/types_char.golden.jsonc @@ -0,0 +1,236 @@ +// 🌟 This was machine generated. Do not edit. 🌟 +// +// Frame[0] { +// "typeVersion": [ +// 0, +// 0 +// ], +// "executedQueryString": "SELECT * FROM tbl" +// } +// Name: +// Dimensions: 16 Fields by 2 Rows +// +-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+ +// | Name: vc | Name: vcnn | Name: c | Name: cnn | Name: tt | Name: ttnn | Name: t | Name: tnn | Name: mt | Name: mtnn | Name: lt | Name: ltnn | Name: e | Name: enn | Name: s | Name: snn | +// | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | +// | Type: []*string | Type: []*string | Type: []*string | Type: []*string | Type: []*string | Type: []*string | Type: []*string | Type: []*string | Type: []*string | Type: []*string | Type: []*string | Type: []*string | Type: []*string | Type: []*string | Type: []*string | Type: []*string | +// +-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+ +// | one | two | three | four | five | six | seven | eight | nine | ten | eleven | twelve | v1 | v2 | a,b | | +// | null | xtwo | null | xfour | null | xsix | null | xeight | null | xten | null | xtwelve | null | v1 | null | a,c | +// +-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+ +// +// +// 🌟 This was machine generated. Do not edit. 🌟 +{ + "status": 200, + "frames": [ + { + "schema": { + "meta": { + "typeVersion": [ + 0, + 0 + ], + "executedQueryString": "SELECT * FROM tbl" + }, + "fields": [ + { + "name": "vc", + "type": "string", + "typeInfo": { + "frame": "string", + "nullable": true + } + }, + { + "name": "vcnn", + "type": "string", + "typeInfo": { + "frame": "string", + "nullable": true + } + }, + { + "name": "c", + "type": "string", + "typeInfo": { + "frame": "string", + "nullable": true + } + }, + { + "name": "cnn", + "type": "string", + "typeInfo": { + "frame": "string", + "nullable": true + } + }, + { + "name": "tt", + "type": "string", + "typeInfo": { + "frame": "string", + "nullable": true + } + }, + { + "name": "ttnn", + "type": "string", + "typeInfo": { + "frame": "string", + "nullable": true + } + }, + { + "name": "t", + "type": "string", + "typeInfo": { + "frame": "string", + "nullable": true + } + }, + { + "name": "tnn", + "type": "string", + "typeInfo": { + "frame": "string", + "nullable": true + } + }, + { + "name": "mt", + "type": "string", + "typeInfo": { + "frame": "string", + "nullable": true + } + }, + { + "name": "mtnn", + "type": "string", + "typeInfo": { + "frame": "string", + "nullable": true + } + }, + { + "name": "lt", + "type": "string", + "typeInfo": { + "frame": "string", + "nullable": true + } + }, + { + "name": "ltnn", + "type": "string", + "typeInfo": { + "frame": "string", + "nullable": true + } + }, + { + "name": "e", + "type": "string", + "typeInfo": { + "frame": "string", + "nullable": true + } + }, + { + "name": "enn", + "type": "string", + "typeInfo": { + "frame": "string", + "nullable": true + } + }, + { + "name": "s", + "type": "string", + "typeInfo": { + "frame": "string", + "nullable": true + } + }, + { + "name": "snn", + "type": "string", + "typeInfo": { + "frame": "string", + "nullable": true + } + } + ] + }, + "data": { + "values": [ + [ + "one", + null + ], + [ + "two", + "xtwo" + ], + [ + "three", + null + ], + [ + "four", + "xfour" + ], + [ + "five", + null + ], + [ + "six", + "xsix" + ], + [ + "seven", + null + ], + [ + "eight", + "xeight" + ], + [ + "nine", + null + ], + [ + "ten", + "xten" + ], + [ + "eleven", + null + ], + [ + "twelve", + "xtwelve" + ], + [ + "v1", + null + ], + [ + "v2", + "v1" + ], + [ + "a,b", + null + ], + [ + "", + "a,c" + ] + ] + } + } + ] +} \ No newline at end of file diff --git a/pkg/tsdb/mysql/testdata/table/types_char.sql b/pkg/tsdb/mysql/testdata/table/types_char.sql new file mode 100644 index 000000000000..cc492a8d83b9 --- /dev/null +++ b/pkg/tsdb/mysql/testdata/table/types_char.sql @@ -0,0 +1,24 @@ +-- SELECT * FROM tbl +-- test all character-based mysql data types +CREATE TABLE tbl ( + vc varchar(10), + vcnn varchar(10) NOT NULL, + c char(10), + cnn char(10) NOT NULL, + tt tinytext, + ttnn tinytext NOT NULL, + t text, + tnn text NOT NULL, + mt mediumtext, + mtnn mediumtext NOT NULL, + lt longtext, + ltnn longtext NOT NULL, + e enum('v1', 'v2'), + enn enum('v1', 'v2') NOT NULL, + s set('a', 'b', 'c'), + snn set('a', 'b', 'c') NOT NULL +); + +INSERT INTO tbl (vc, vcnn, c, cnn, tt, ttnn, t, tnn, mt, mtnn, lt, ltnn, e, enn, s, snn) VALUES +('one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve', 'v1', 'v2', 'a,b', ''), +(NULL, 'xtwo', NULL, 'xfour', NULL, 'xsix', NULL, 'xeight' , NULL, 'xten', NULL, 'xtwelve', NULL, 'v1', NULL, 'a,c'); \ No newline at end of file diff --git a/pkg/tsdb/mysql/testdata/table/types_datetime.golden.jsonc b/pkg/tsdb/mysql/testdata/table/types_datetime.golden.jsonc new file mode 100644 index 000000000000..288010166bb8 --- /dev/null +++ b/pkg/tsdb/mysql/testdata/table/types_datetime.golden.jsonc @@ -0,0 +1,266 @@ +// 🌟 This was machine generated. Do not edit. 🌟 +// +// Frame[0] { +// "typeVersion": [ +// 0, +// 0 +// ], +// "executedQueryString": "SELECT * FROM tbl" +// } +// Name: +// Dimensions: 16 Fields by 2 Rows +// +-------------------------------+-------------------------------+--------------------------------------+--------------------------------------+-------------------------------+-------------------------------+--------------------------------------+--------------------------------------+-------------------------------+-------------------------------+-----------------+-----------------+-----------------+-----------------+----------------+----------------+ +// | Name: ts | Name: tsnn | Name: ts6 | Name: ts6nn | Name: dt | Name: dtnn | Name: dt6 | Name: dt6nn | Name: d | Name: dnn | Name: t | Name: tnn | Name: t6 | Name: t6nn | Name: y | Name: ynn | +// | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | +// | Type: []*time.Time | Type: []*time.Time | Type: []*time.Time | Type: []*time.Time | Type: []*time.Time | Type: []*time.Time | Type: []*time.Time | Type: []*time.Time | Type: []*time.Time | Type: []*time.Time | Type: []*string | Type: []*string | Type: []*string | Type: []*string | Type: []*int64 | Type: []*int64 | +// +-------------------------------+-------------------------------+--------------------------------------+--------------------------------------+-------------------------------+-------------------------------+--------------------------------------+--------------------------------------+-------------------------------+-------------------------------+-----------------+-----------------+-----------------+-----------------+----------------+----------------+ +// | 2023-11-15 05:06:07 +0000 UTC | 2023-11-15 05:06:08 +0000 UTC | 2021-07-22 13:22:33.654321 +0000 UTC | 2021-07-22 13:22:34.654321 +0000 UTC | 2023-11-15 06:06:07 +0000 UTC | 2023-11-15 06:06:08 +0000 UTC | 2021-07-22 14:22:33.654321 +0000 UTC | 2021-07-22 14:22:34.654321 +0000 UTC | 2023-12-20 00:00:00 +0000 UTC | 2023-12-21 00:00:00 +0000 UTC | 12:34:56 | 12:34:57 | 12:44:56.234567 | 12:44:57.234567 | 2022 | 2023 | +// | null | 2023-11-15 05:06:09 +0000 UTC | null | 2021-07-22 13:22:35.654321 +0000 UTC | null | 2023-11-16 05:06:09 +0000 UTC | null | 2021-07-23 13:22:35.654321 +0000 UTC | null | 2023-12-22 00:00:00 +0000 UTC | null | 12:34:58 | null | 12:44:58.234567 | null | 2024 | +// +-------------------------------+-------------------------------+--------------------------------------+--------------------------------------+-------------------------------+-------------------------------+--------------------------------------+--------------------------------------+-------------------------------+-------------------------------+-----------------+-----------------+-----------------+-----------------+----------------+----------------+ +// +// +// 🌟 This was machine generated. Do not edit. 🌟 +{ + "status": 200, + "frames": [ + { + "schema": { + "meta": { + "typeVersion": [ + 0, + 0 + ], + "executedQueryString": "SELECT * FROM tbl" + }, + "fields": [ + { + "name": "ts", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "name": "tsnn", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "name": "ts6", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "name": "ts6nn", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "name": "dt", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "name": "dtnn", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "name": "dt6", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "name": "dt6nn", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "name": "d", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "name": "dnn", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "name": "t", + "type": "string", + "typeInfo": { + "frame": "string", + "nullable": true + } + }, + { + "name": "tnn", + "type": "string", + "typeInfo": { + "frame": "string", + "nullable": true + } + }, + { + "name": "t6", + "type": "string", + "typeInfo": { + "frame": "string", + "nullable": true + } + }, + { + "name": "t6nn", + "type": "string", + "typeInfo": { + "frame": "string", + "nullable": true + } + }, + { + "name": "y", + "type": "number", + "typeInfo": { + "frame": "int64", + "nullable": true + } + }, + { + "name": "ynn", + "type": "number", + "typeInfo": { + "frame": "int64", + "nullable": true + } + } + ] + }, + "data": { + "values": [ + [ + 1700024767000, + null + ], + [ + 1700024768000, + 1700024769000 + ], + [ + 1626960153654, + null + ], + [ + 1626960154654, + 1626960155654 + ], + [ + 1700028367000, + null + ], + [ + 1700028368000, + 1700111169000 + ], + [ + 1626963753654, + null + ], + [ + 1626963754654, + 1627046555654 + ], + [ + 1703030400000, + null + ], + [ + 1703116800000, + 1703203200000 + ], + [ + "12:34:56", + null + ], + [ + "12:34:57", + "12:34:58" + ], + [ + "12:44:56.234567", + null + ], + [ + "12:44:57.234567", + "12:44:58.234567" + ], + [ + 2022, + null + ], + [ + 2023, + 2024 + ] + ], + "nanos": [ + null, + null, + [ + 321000, + 0 + ], + [ + 321000, + 321000 + ], + null, + null, + [ + 321000, + 0 + ], + [ + 321000, + 321000 + ], + null, + null, + null, + null, + null, + null, + null, + null + ] + } + } + ] +} \ No newline at end of file diff --git a/pkg/tsdb/mysql/testdata/table/types_datetime.sql b/pkg/tsdb/mysql/testdata/table/types_datetime.sql new file mode 100644 index 000000000000..89c921953833 --- /dev/null +++ b/pkg/tsdb/mysql/testdata/table/types_datetime.sql @@ -0,0 +1,56 @@ +-- SELECT * FROM tbl +-- test all date/time-based postgres data types +CREATE TABLE tbl ( + ts timestamp NULL, -- must say `NULL` for below mysql8, see (explicit_defaults_for_timestamp) + tsnn timestamp NOT NULL, + ts6 timestamp(6) NULL, -- must say `NULL` for below mysql8, see (explicit_defaults_for_timestamp) + ts6nn timestamp(6) NOT NULL, + dt datetime, + dtnn datetime NOT NULL, + dt6 datetime(6), + dt6nn datetime(6) NOT NULL, + d date, + dnn date NOT NULL, + t time, + tnn time NOT NULL, + t6 time(6), + t6nn time(6) NOT NULL, + y year, + ynn year NOT NULL +); + +INSERT INTO tbl (ts, tsnn, ts6, ts6nn, dt, dtnn, dt6, dt6nn, d, dnn, t, tnn, t6, t6nn, y, ynn) VALUES ( +'2023-11-15 05:06:07+00:00', +'2023-11-15 05:06:08+00:00', +'2021-07-22 13:22:33.654321+00:00', +'2021-07-22 13:22:34.654321+00:00', +'2023-11-15 06:06:07+00:00', +'2023-11-15 06:06:08+00:00', +'2021-07-22 14:22:33.654321+00:00', +'2021-07-22 14:22:34.654321+00:00', +'2023-12-20', +'2023-12-21', +'12:34:56', +'12:34:57', +'12:44:56.234567', +'12:44:57.234567', +'2022', +'2023' +), ( +NULL, +'2023-11-15 05:06:09+00:00', +NULL, +'2021-07-22 13:22:35.654321+00:00', +NULL, +'2023-11-16 05:06:09+00:00', +NULL, +'2021-07-23 13:22:35.654321+00:00', +NULL, +'2023-12-22', +NULL, +'12:34:58', +NULL, +'12:44:58.234567', +NULL, +'2024' +); \ No newline at end of file diff --git a/pkg/tsdb/mysql/testdata/table/types_numeric.golden.jsonc b/pkg/tsdb/mysql/testdata/table/types_numeric.golden.jsonc new file mode 100644 index 000000000000..0b4db9c7bf75 --- /dev/null +++ b/pkg/tsdb/mysql/testdata/table/types_numeric.golden.jsonc @@ -0,0 +1,235 @@ +// 🌟 This was machine generated. Do not edit. 🌟 +// +// Frame[0] { +// "typeVersion": [ +// 0, +// 0 +// ], +// "executedQueryString": "SELECT * FROM tbl" +// } +// Name: +// Dimensions: 16 Fields by 2 Rows +// +----------------+----------------+----------------+----------------+----------------+---------------+----------------+----------------+----------------+----------------+------------------+------------------+------------------+------------------+------------------+------------------+ +// | Name: i8 | Name: i8nn | Name: i16 | Name: i16nn | Name: i24 | Name: i24nn | Name: i32 | Name: i32nn | Name: i64 | Name: i64nn | Name: d | Name: dnn | Name: f32 | Name: f32nn | Name: f64 | Name: f64nn | +// | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | +// | Type: []*int64 | Type: []*int64 | Type: []*int64 | Type: []*int64 | Type: []*int64 | Type: []int32 | Type: []*int64 | Type: []*int64 | Type: []*int64 | Type: []*int64 | Type: []*float64 | Type: []*float64 | Type: []*float64 | Type: []*float64 | Type: []*float64 | Type: []*float64 | +// +----------------+----------------+----------------+----------------+----------------+---------------+----------------+----------------+----------------+----------------+------------------+------------------+------------------+------------------+------------------+------------------+ +// | -5 | -4 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 81.75 | 7065.25 | 30.75 | 14.625 | 21.5625 | 14.25 | +// | null | -44 | null | 22 | null | 44 | null | 66 | null | 88 | null | 169.75 | null | 77.125 | null | 215.8125 | +// +----------------+----------------+----------------+----------------+----------------+---------------+----------------+----------------+----------------+----------------+------------------+------------------+------------------+------------------+------------------+------------------+ +// +// +// 🌟 This was machine generated. Do not edit. 🌟 +{ + "status": 200, + "frames": [ + { + "schema": { + "meta": { + "typeVersion": [ + 0, + 0 + ], + "executedQueryString": "SELECT * FROM tbl" + }, + "fields": [ + { + "name": "i8", + "type": "number", + "typeInfo": { + "frame": "int64", + "nullable": true + } + }, + { + "name": "i8nn", + "type": "number", + "typeInfo": { + "frame": "int64", + "nullable": true + } + }, + { + "name": "i16", + "type": "number", + "typeInfo": { + "frame": "int64", + "nullable": true + } + }, + { + "name": "i16nn", + "type": "number", + "typeInfo": { + "frame": "int64", + "nullable": true + } + }, + { + "name": "i24", + "type": "number", + "typeInfo": { + "frame": "int64", + "nullable": true + } + }, + { + "name": "i24nn", + "type": "number", + "typeInfo": { + "frame": "int32" + } + }, + { + "name": "i32", + "type": "number", + "typeInfo": { + "frame": "int64", + "nullable": true + } + }, + { + "name": "i32nn", + "type": "number", + "typeInfo": { + "frame": "int64", + "nullable": true + } + }, + { + "name": "i64", + "type": "number", + "typeInfo": { + "frame": "int64", + "nullable": true + } + }, + { + "name": "i64nn", + "type": "number", + "typeInfo": { + "frame": "int64", + "nullable": true + } + }, + { + "name": "d", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + }, + { + "name": "dnn", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + }, + { + "name": "f32", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + }, + { + "name": "f32nn", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + }, + { + "name": "f64", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + }, + { + "name": "f64nn", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + } + ] + }, + "data": { + "values": [ + [ + -5, + null + ], + [ + -4, + -44 + ], + [ + 1, + null + ], + [ + 2, + 22 + ], + [ + 3, + null + ], + [ + 4, + 44 + ], + [ + 5, + null + ], + [ + 6, + 66 + ], + [ + 7, + null + ], + [ + 8, + 88 + ], + [ + 81.75, + null + ], + [ + 7065.25, + 169.75 + ], + [ + 30.75, + null + ], + [ + 14.625, + 77.125 + ], + [ + 21.5625, + null + ], + [ + 14.25, + 215.8125 + ] + ] + } + } + ] +} \ No newline at end of file diff --git a/pkg/tsdb/mysql/testdata/table/types_numeric.sql b/pkg/tsdb/mysql/testdata/table/types_numeric.sql new file mode 100644 index 000000000000..1574ef3d9267 --- /dev/null +++ b/pkg/tsdb/mysql/testdata/table/types_numeric.sql @@ -0,0 +1,24 @@ +-- SELECT * FROM tbl +-- test all numeric mysql data types +CREATE TABLE tbl ( + i8 tinyint, + i8nn tinyint NOT NULL, + i16 smallint, + i16nn smallint NOT NULL, + i24 mediumint, + i24nn mediumint NOT NULL, + i32 integer, + i32nn integer NOT NULL, + i64 bigint, + i64nn bigint NOT NULL, + d decimal(7, 2), + dnn decimal(7,2) NOT NULL, + f32 float, + f32nn float NOT NULL, + f64 double precision, + f64nn double precision NOT NULL +); + +INSERT INTO tbl (i8, i8nn, i16, i16nn, i24, i24nn, i32, i32nn, i64, i64nn, d, dnn, f32, f32nn, f64, f64nn) VALUES +(-5, -4, 1, 2, 3, 4, 5, 6, 7, 8, 81.75, 7065.25, 30.75, 14.625, 21.5625, 14.25), +(NULL, -44, NULL, 22, NULL, 44, NULL, 66, NULL, 88, NULL, 169.75, NULL, 77.125, NULL, 215.8125); \ No newline at end of file diff --git a/pkg/tsdb/mysql/testdata/table/types_other.golden.jsonc b/pkg/tsdb/mysql/testdata/table/types_other.golden.jsonc new file mode 100644 index 000000000000..413bf85bca8f Binary files /dev/null and b/pkg/tsdb/mysql/testdata/table/types_other.golden.jsonc differ diff --git a/pkg/tsdb/mysql/testdata/table/types_other.sql b/pkg/tsdb/mysql/testdata/table/types_other.sql new file mode 100644 index 000000000000..5f626828e6e9 --- /dev/null +++ b/pkg/tsdb/mysql/testdata/table/types_other.sql @@ -0,0 +1,40 @@ +-- SELECT * FROM tbl +-- test the less used mysql data types +CREATE TABLE tbl ( + tb tinyblob, + tbnn tinyblob NOT NULL, + b blob, + bnn blob NOT NULL, + mb mediumblob, + mbnn mediumblob NOT NULL, + lb longblob, + lbnn longblob NOT NULL, + bt bit(1), + btnn bit(1) NOT NULL +); + +INSERT INTO tbl (tb, tbnn, b, bnn, mb, mbnn, lb, lbnn, bt, btnn) VALUES +( + UNHEX('4141'), + UNHEX('4142'), + UNHEX('4143'), + UNHEX('4144'), + UNHEX('4145'), + UNHEX('4146'), + UNHEX('4147'), + UNHEX('4148'), + b'0', + b'1' +), +( + NULL, + UNHEX('4242'), + NULL, + UNHEX('4244'), + NULL, + UNHEX('4246'), + NULL, + UNHEX('4248'), + NULL, + b'0' +); \ No newline at end of file diff --git a/pkg/tsdb/mysql/testdata/time_series/7x_compat_metric_label.golden.jsonc b/pkg/tsdb/mysql/testdata/time_series/7x_compat_metric_label.golden.jsonc new file mode 100644 index 000000000000..4bbf17b84250 --- /dev/null +++ b/pkg/tsdb/mysql/testdata/time_series/7x_compat_metric_label.golden.jsonc @@ -0,0 +1,93 @@ +// 🌟 This was machine generated. Do not edit. 🌟 +// +// Frame[0] { +// "type": "timeseries-wide", +// "typeVersion": [ +// 0, +// 0 +// ], +// "executedQueryString": "SELECT * FROM tbl" +// } +// Name: +// Dimensions: 3 Fields by 5 Rows +// +-------------------------------+------------------+------------------+ +// | Name: Time | Name: a | Name: b | +// | Labels: | Labels: | Labels: | +// | Type: []time.Time | Type: []*float64 | Type: []*float64 | +// +-------------------------------+------------------+------------------+ +// | 2023-12-24 14:30:03 +0000 UTC | 10 | 110 | +// | 2023-12-24 14:31:03 +0000 UTC | 20 | 120 | +// | 2023-12-24 14:32:03 +0000 UTC | 30 | 130 | +// | 2023-12-24 14:33:03 +0000 UTC | 40 | 140 | +// | 2023-12-24 14:34:03 +0000 UTC | 50 | 150 | +// +-------------------------------+------------------+------------------+ +// +// +// 🌟 This was machine generated. Do not edit. 🌟 +{ + "status": 200, + "frames": [ + { + "schema": { + "meta": { + "type": "timeseries-wide", + "typeVersion": [ + 0, + 0 + ], + "executedQueryString": "SELECT * FROM tbl" + }, + "fields": [ + { + "name": "Time", + "type": "time", + "typeInfo": { + "frame": "time.Time" + } + }, + { + "name": "a", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + }, + { + "name": "b", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + } + ] + }, + "data": { + "values": [ + [ + 1703428203000, + 1703428263000, + 1703428323000, + 1703428383000, + 1703428443000 + ], + [ + 10, + 20, + 30, + 40, + 50 + ], + [ + 110, + 120, + 130, + 140, + 150 + ] + ] + } + } + ] +} \ No newline at end of file diff --git a/pkg/tsdb/mysql/testdata/time_series/7x_compat_metric_label.sql b/pkg/tsdb/mysql/testdata/time_series/7x_compat_metric_label.sql new file mode 100644 index 000000000000..f61cabe96d79 --- /dev/null +++ b/pkg/tsdb/mysql/testdata/time_series/7x_compat_metric_label.sql @@ -0,0 +1,19 @@ +-- SELECT * FROM tbl +-- there's special backward-compat code which handles a field named 'metric' +CREATE TABLE tbl ( + `time` timestamp NOT NULL, + v double precision, + metric text +); + +INSERT INTO tbl (`time`, v, metric) VALUES +('2023-12-24 14:30:03+00:00', 10, 'a'), +('2023-12-24 14:30:03+00:00', 110, 'b'), +('2023-12-24 14:31:03+00:00', 20, 'a'), +('2023-12-24 14:31:03+00:00', 120, 'b'), +('2023-12-24 14:32:03+00:00', 30, 'a'), +('2023-12-24 14:32:03+00:00', 130, 'b'), +('2023-12-24 14:33:03+00:00', 40, 'a'), +('2023-12-24 14:33:03+00:00', 140, 'b'), +('2023-12-24 14:34:03+00:00', 50, 'a'), +('2023-12-24 14:34:03+00:00', 150, 'b'); \ No newline at end of file diff --git a/pkg/tsdb/mysql/testdata/time_series/convert_to_float64.golden.jsonc b/pkg/tsdb/mysql/testdata/time_series/convert_to_float64.golden.jsonc new file mode 100644 index 000000000000..6229de42795c --- /dev/null +++ b/pkg/tsdb/mysql/testdata/time_series/convert_to_float64.golden.jsonc @@ -0,0 +1,267 @@ +// 🌟 This was machine generated. Do not edit. 🌟 +// +// Frame[0] { +// "type": "timeseries-wide", +// "typeVersion": [ +// 0, +// 0 +// ], +// "executedQueryString": "SELECT * FROM tbl" +// } +// Name: +// Dimensions: 15 Fields by 2 Rows +// +-------------------------------+------------------+------------------+------------------+------------------+------------------+------------------+------------------+------------------+------------------+------------------+------------------+------------------+------------------+------------------+ +// | Name: Time | Name: v1 | Name: v1nn | Name: v2 | Name: v2nn | Name: x1 | Name: x1nn | Name: x2 | Name: x2nn | Name: x3 | Name: x3nn | Name: x4 | Name: x4nn | Name: x5 | Name: x5nn | +// | Labels: | Labels: t=one | Labels: t=one | Labels: t=one | Labels: t=one | Labels: t=one | Labels: t=one | Labels: t=one | Labels: t=one | Labels: t=one | Labels: t=one | Labels: t=one | Labels: t=one | Labels: t=one | Labels: t=one | +// | Type: []time.Time | Type: []*float64 | Type: []*float64 | Type: []*float64 | Type: []*float64 | Type: []*float64 | Type: []*float64 | Type: []*float64 | Type: []*float64 | Type: []*float64 | Type: []*float64 | Type: []*float64 | Type: []*float64 | Type: []*float64 | Type: []*float64 | +// +-------------------------------+------------------+------------------+------------------+------------------+------------------+------------------+------------------+------------------+------------------+------------------+------------------+------------------+------------------+------------------+ +// | 2023-12-21 11:30:03 +0000 UTC | 3.78125 | 451.5625 | 52.25 | 511.312 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | +// | 2023-12-21 11:31:03 +0000 UTC | null | 464.375 | null | 346.125 | null | 127 | null | 204 | null | 206 | null | 208 | null | 210 | +// +-------------------------------+------------------+------------------+------------------+------------------+------------------+------------------+------------------+------------------+------------------+------------------+------------------+------------------+------------------+------------------+ +// +// +// 🌟 This was machine generated. Do not edit. 🌟 +{ + "status": 200, + "frames": [ + { + "schema": { + "meta": { + "type": "timeseries-wide", + "typeVersion": [ + 0, + 0 + ], + "executedQueryString": "SELECT * FROM tbl" + }, + "fields": [ + { + "name": "Time", + "type": "time", + "typeInfo": { + "frame": "time.Time" + } + }, + { + "name": "v1", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "t": "one" + } + }, + { + "name": "v1nn", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "t": "one" + } + }, + { + "name": "v2", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "t": "one" + } + }, + { + "name": "v2nn", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "t": "one" + } + }, + { + "name": "x1", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "t": "one" + } + }, + { + "name": "x1nn", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "t": "one" + } + }, + { + "name": "x2", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "t": "one" + } + }, + { + "name": "x2nn", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "t": "one" + } + }, + { + "name": "x3", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "t": "one" + } + }, + { + "name": "x3nn", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "t": "one" + } + }, + { + "name": "x4", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "t": "one" + } + }, + { + "name": "x4nn", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "t": "one" + } + }, + { + "name": "x5", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "t": "one" + } + }, + { + "name": "x5nn", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "t": "one" + } + } + ] + }, + "data": { + "values": [ + [ + 1703158203000, + 1703158263000 + ], + [ + 3.78125, + null + ], + [ + 451.5625, + 464.375 + ], + [ + 52.25, + null + ], + [ + 511.312, + 346.125 + ], + [ + 101, + null + ], + [ + 102, + 127 + ], + [ + 103, + null + ], + [ + 104, + 204 + ], + [ + 105, + null + ], + [ + 106, + 206 + ], + [ + 107, + null + ], + [ + 108, + 208 + ], + [ + 109, + null + ], + [ + 110, + 210 + ] + ] + } + } + ] +} \ No newline at end of file diff --git a/pkg/tsdb/mysql/testdata/time_series/convert_to_float64.sql b/pkg/tsdb/mysql/testdata/time_series/convert_to_float64.sql new file mode 100644 index 000000000000..c73e9e85fd61 --- /dev/null +++ b/pkg/tsdb/mysql/testdata/time_series/convert_to_float64.sql @@ -0,0 +1,33 @@ +-- SELECT * FROM tbl +-- in timeseries mode, most fields gets converted to float64 +CREATE TABLE tbl ( + "time" timestamp NOT NULL, + v1 double precision, + v1nn double precision NOT NULL, + v2 float, + v2nn float NOT NULL, + t text, + x1 tinyint, + x1nn tinyint NOT NULL, + x2 smallint, + x2nn smallint NOT NULL, + x3 mediumint, + x3nn mediumint NOT NULL, + x4 integer, + x4nn integer NOT NULL, + x5 bigint, + x5nn bigint NOT NULL +); + +INSERT INTO tbl ("time", +v1, v1nn, v2, v2nn, +t, +x1, x1nn, x2, x2nn, x3, x3nn, x4, x4nn, x5, x5nn) VALUES +('2023-12-21 11:30:03 UTC', +3.78125, 451.5625, 52.25, 511.3125, +'one', +101, 102, 103, 104, 105, 106, 107, 108, 109, 110), +('2023-12-21 11:31:03 UTC', +NULL, 464.375, NULL, 346.125, +'one', +NULL, 202, NULL, 204, NULL, 206, NULL, 208, NULL, 210); \ No newline at end of file diff --git a/pkg/tsdb/mysql/testdata/time_series/convert_to_float64_not.golden.jsonc b/pkg/tsdb/mysql/testdata/time_series/convert_to_float64_not.golden.jsonc new file mode 100644 index 000000000000..3cea08784fbc --- /dev/null +++ b/pkg/tsdb/mysql/testdata/time_series/convert_to_float64_not.golden.jsonc @@ -0,0 +1,113 @@ +// 🌟 This was machine generated. Do not edit. 🌟 +// +// Frame[0] { +// "type": "timeseries-wide", +// "typeVersion": [ +// 0, +// 0 +// ], +// "executedQueryString": "SELECT * FROM tbl" +// } +// Name: +// Dimensions: 3 Fields by 2 Rows +// +-------------------------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------+ +// | Name: Time | Name: v | Name: v | +// | Labels: | Labels: c1=, c1nn=bb, c2=, c2nn=dd, c3=, c3nn=ff, c4=, c4nn=hh, c5=, c5nn=jj, c6=, c6nn=ll, c7=, c7nn=v1 | Labels: c1=a, c1nn=b, c2=c, c2nn=d, c3=e, c3nn=f, c4=g, c4nn=h, c5=i, c5nn=j, c6=k, c6nn=l, c7=v1, c7nn=v2 | +// | Type: []time.Time | Type: []*float64 | Type: []*float64 | +// +-------------------------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------+ +// | 2023-12-21 11:30:03 +0000 UTC | null | 10.1 | +// | 2023-12-21 11:31:03 +0000 UTC | 20.1 | null | +// +-------------------------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------+ +// +// +// 🌟 This was machine generated. Do not edit. 🌟 +{ + "status": 200, + "frames": [ + { + "schema": { + "meta": { + "type": "timeseries-wide", + "typeVersion": [ + 0, + 0 + ], + "executedQueryString": "SELECT * FROM tbl" + }, + "fields": [ + { + "name": "Time", + "type": "time", + "typeInfo": { + "frame": "time.Time" + } + }, + { + "name": "v", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "c1": "", + "c1nn": "bb", + "c2": "", + "c2nn": "dd", + "c3": "", + "c3nn": "ff", + "c4": "", + "c4nn": "hh", + "c5": "", + "c5nn": "jj", + "c6": "", + "c6nn": "ll", + "c7": "", + "c7nn": "v1" + } + }, + { + "name": "v", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "c1": "a", + "c1nn": "b", + "c2": "c", + "c2nn": "d", + "c3": "e", + "c3nn": "f", + "c4": "g", + "c4nn": "h", + "c5": "i", + "c5nn": "j", + "c6": "k", + "c6nn": "l", + "c7": "v1", + "c7nn": "v2" + } + } + ] + }, + "data": { + "values": [ + [ + 1703158203000, + 1703158263000 + ], + [ + null, + 20.1 + ], + [ + 10.1, + null + ] + ] + } + } + ] +} \ No newline at end of file diff --git a/pkg/tsdb/mysql/testdata/time_series/convert_to_float64_not.sql b/pkg/tsdb/mysql/testdata/time_series/convert_to_float64_not.sql new file mode 100644 index 000000000000..32265521e7a4 --- /dev/null +++ b/pkg/tsdb/mysql/testdata/time_series/convert_to_float64_not.sql @@ -0,0 +1,30 @@ +-- SELECT * FROM tbl +-- in timeseries mode, most fields gets converted to float64, but text-fields should stay text +CREATE TABLE tbl ( + "time" timestamp NOT NULL, + v double precision NOT NULL, + c1 varchar(10), + c1nn varchar(10) NOT NULL, + c2 char(10), + c2nn char(10) NOT NULL, + c3 tinytext, + c3nn tinytext NOT NULL, + c4 text, + c4nn text NOT NULL, + c5 mediumtext, + c5nn mediumtext NOT NULL, + c6 longtext, + c6nn longtext NOT NULL, + c7 enum('v1', 'v2'), + c7nn enum('v1', 'v2') NOT NULL +); + +INSERT INTO tbl ("time", +v, +c1, c1nn, c2, c2nn, c3, c3nn, c4, c4nn, c5, c5nn, c6, c6nn, c7, c7nn) VALUES +('2023-12-21 11:30:03 UTC', +10.1, +'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'v1', 'v2'), +('2023-12-21 11:31:03 UTC', +20.1, +NULL, 'bb', NULL, 'dd', NULL, 'ff', NULL, 'hh', NULL, 'jj', NULL, 'll', NULL, 'v1'); \ No newline at end of file diff --git a/pkg/tsdb/mysql/testdata/time_series/fill_null.golden.jsonc b/pkg/tsdb/mysql/testdata/time_series/fill_null.golden.jsonc new file mode 100644 index 000000000000..e9e19ce2b01a --- /dev/null +++ b/pkg/tsdb/mysql/testdata/time_series/fill_null.golden.jsonc @@ -0,0 +1,107 @@ +// 🌟 This was machine generated. Do not edit. 🌟 +// +// Frame[0] { +// "type": "timeseries-wide", +// "typeVersion": [ +// 0, +// 0 +// ], +// "executedQueryString": "SELECT UNIX_TIMESTAMP(\"time\") DIV 300 * 300 AS \"time\",c,avg(v) AS \"v\" FROM tbl GROUP BY 1,2 ORDER BY 1,2" +// } +// Name: +// Dimensions: 3 Fields by 7 Rows +// +-------------------------------+------------------+------------------+ +// | Name: Time | Name: v | Name: v | +// | Labels: | Labels: c=a | Labels: c=b | +// | Type: []time.Time | Type: []*float64 | Type: []*float64 | +// +-------------------------------+------------------+------------------+ +// | 2023-12-24 14:15:00 +0000 UTC | null | null | +// | 2023-12-24 14:20:00 +0000 UTC | 15 | 115 | +// | 2023-12-24 14:25:00 +0000 UTC | null | null | +// | 2023-12-24 14:30:00 +0000 UTC | null | null | +// | 2023-12-24 14:35:00 +0000 UTC | 50 | 150 | +// | 2023-12-24 14:40:00 +0000 UTC | null | null | +// | 2023-12-24 14:45:00 +0000 UTC | null | null | +// +-------------------------------+------------------+------------------+ +// +// +// 🌟 This was machine generated. Do not edit. 🌟 +{ + "status": 200, + "frames": [ + { + "schema": { + "meta": { + "type": "timeseries-wide", + "typeVersion": [ + 0, + 0 + ], + "executedQueryString": "SELECT UNIX_TIMESTAMP(\"time\") DIV 300 * 300 AS \"time\",c,avg(v) AS \"v\" FROM tbl GROUP BY 1,2 ORDER BY 1,2" + }, + "fields": [ + { + "name": "Time", + "type": "time", + "typeInfo": { + "frame": "time.Time" + } + }, + { + "name": "v", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "c": "a" + } + }, + { + "name": "v", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "c": "b" + } + } + ] + }, + "data": { + "values": [ + [ + 1703427300000, + 1703427600000, + 1703427900000, + 1703428200000, + 1703428500000, + 1703428800000, + 1703429100000 + ], + [ + null, + 15, + null, + null, + 50, + null, + null + ], + [ + null, + 115, + null, + null, + 150, + null, + null + ] + ] + } + } + ] +} \ No newline at end of file diff --git a/pkg/tsdb/mysql/testdata/time_series/fill_null.sql b/pkg/tsdb/mysql/testdata/time_series/fill_null.sql new file mode 100644 index 000000000000..2a9bd0b54c4a --- /dev/null +++ b/pkg/tsdb/mysql/testdata/time_series/fill_null.sql @@ -0,0 +1,15 @@ +-- SELECT $__timeGroupAlias("time",5m,NULL),c,avg(v) AS "v" FROM tbl GROUP BY 1,2 ORDER BY 1,2 +-- tests fill-mode=null +CREATE TABLE tbl ( + `time` timestamp NOT NULL, + v double precision, + c text +); + +INSERT INTO tbl (`time`, v, c) VALUES +('2023-12-24 14:21:03+00:00', 10, 'a'), +('2023-12-24 14:21:03+00:00', 110, 'b'), +('2023-12-24 14:23:03+00:00', 20, 'a'), +('2023-12-24 14:23:03+00:00', 120, 'b'), +('2023-12-24 14:39:03+00:00', 50, 'a'), +('2023-12-24 14:39:03+00:00', 150, 'b'); \ No newline at end of file diff --git a/pkg/tsdb/mysql/testdata/time_series/fill_previous.golden.jsonc b/pkg/tsdb/mysql/testdata/time_series/fill_previous.golden.jsonc new file mode 100644 index 000000000000..743e9e0706e7 --- /dev/null +++ b/pkg/tsdb/mysql/testdata/time_series/fill_previous.golden.jsonc @@ -0,0 +1,107 @@ +// 🌟 This was machine generated. Do not edit. 🌟 +// +// Frame[0] { +// "type": "timeseries-wide", +// "typeVersion": [ +// 0, +// 0 +// ], +// "executedQueryString": "SELECT UNIX_TIMESTAMP(\"time\") DIV 300 * 300 AS \"time\",c,avg(v) AS \"v\" FROM tbl GROUP BY 1,2 ORDER BY 1,2" +// } +// Name: +// Dimensions: 3 Fields by 7 Rows +// +-------------------------------+------------------+------------------+ +// | Name: Time | Name: v | Name: v | +// | Labels: | Labels: c=a | Labels: c=b | +// | Type: []time.Time | Type: []*float64 | Type: []*float64 | +// +-------------------------------+------------------+------------------+ +// | 2023-12-24 14:15:00 +0000 UTC | null | null | +// | 2023-12-24 14:20:00 +0000 UTC | 15 | 115 | +// | 2023-12-24 14:25:00 +0000 UTC | 15 | 115 | +// | 2023-12-24 14:30:00 +0000 UTC | 15 | 115 | +// | 2023-12-24 14:35:00 +0000 UTC | 50 | 150 | +// | 2023-12-24 14:40:00 +0000 UTC | 50 | 150 | +// | 2023-12-24 14:45:00 +0000 UTC | 50 | 150 | +// +-------------------------------+------------------+------------------+ +// +// +// 🌟 This was machine generated. Do not edit. 🌟 +{ + "status": 200, + "frames": [ + { + "schema": { + "meta": { + "type": "timeseries-wide", + "typeVersion": [ + 0, + 0 + ], + "executedQueryString": "SELECT UNIX_TIMESTAMP(\"time\") DIV 300 * 300 AS \"time\",c,avg(v) AS \"v\" FROM tbl GROUP BY 1,2 ORDER BY 1,2" + }, + "fields": [ + { + "name": "Time", + "type": "time", + "typeInfo": { + "frame": "time.Time" + } + }, + { + "name": "v", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "c": "a" + } + }, + { + "name": "v", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "c": "b" + } + } + ] + }, + "data": { + "values": [ + [ + 1703427300000, + 1703427600000, + 1703427900000, + 1703428200000, + 1703428500000, + 1703428800000, + 1703429100000 + ], + [ + null, + 15, + 15, + 15, + 50, + 50, + 50 + ], + [ + null, + 115, + 115, + 115, + 150, + 150, + 150 + ] + ] + } + } + ] +} \ No newline at end of file diff --git a/pkg/tsdb/mysql/testdata/time_series/fill_previous.sql b/pkg/tsdb/mysql/testdata/time_series/fill_previous.sql new file mode 100644 index 000000000000..7f2d7b9870b6 --- /dev/null +++ b/pkg/tsdb/mysql/testdata/time_series/fill_previous.sql @@ -0,0 +1,15 @@ +-- SELECT $__timeGroupAlias("time",5m,previous),c,avg(v) AS "v" FROM tbl GROUP BY 1,2 ORDER BY 1,2 +-- tests fill-mode=previous +CREATE TABLE tbl ( + `time` timestamp NOT NULL, + v double precision, + c text +); + +INSERT INTO tbl (`time`, v, c) VALUES +('2023-12-24 14:21:03+00:00', 10, 'a'), +('2023-12-24 14:21:03+00:00', 110, 'b'), +('2023-12-24 14:23:03+00:00', 20, 'a'), +('2023-12-24 14:23:03+00:00', 120, 'b'), +('2023-12-24 14:39:03+00:00', 50, 'a'), +('2023-12-24 14:39:03+00:00', 150, 'b'); \ No newline at end of file diff --git a/pkg/tsdb/mysql/testdata/time_series/fill_value.golden.jsonc b/pkg/tsdb/mysql/testdata/time_series/fill_value.golden.jsonc new file mode 100644 index 000000000000..1c0b9889d692 --- /dev/null +++ b/pkg/tsdb/mysql/testdata/time_series/fill_value.golden.jsonc @@ -0,0 +1,107 @@ +// 🌟 This was machine generated. Do not edit. 🌟 +// +// Frame[0] { +// "type": "timeseries-wide", +// "typeVersion": [ +// 0, +// 0 +// ], +// "executedQueryString": "SELECT UNIX_TIMESTAMP(\"time\") DIV 300 * 300 AS \"time\",c,avg(v) AS \"v\" FROM tbl GROUP BY 1,2 ORDER BY 1,2" +// } +// Name: +// Dimensions: 3 Fields by 7 Rows +// +-------------------------------+------------------+------------------+ +// | Name: Time | Name: v | Name: v | +// | Labels: | Labels: c=a | Labels: c=b | +// | Type: []time.Time | Type: []*float64 | Type: []*float64 | +// +-------------------------------+------------------+------------------+ +// | 2023-12-24 14:15:00 +0000 UTC | 27 | 27 | +// | 2023-12-24 14:20:00 +0000 UTC | 15 | 115 | +// | 2023-12-24 14:25:00 +0000 UTC | 27 | 27 | +// | 2023-12-24 14:30:00 +0000 UTC | 27 | 27 | +// | 2023-12-24 14:35:00 +0000 UTC | 50 | 150 | +// | 2023-12-24 14:40:00 +0000 UTC | 27 | 27 | +// | 2023-12-24 14:45:00 +0000 UTC | 27 | 27 | +// +-------------------------------+------------------+------------------+ +// +// +// 🌟 This was machine generated. Do not edit. 🌟 +{ + "status": 200, + "frames": [ + { + "schema": { + "meta": { + "type": "timeseries-wide", + "typeVersion": [ + 0, + 0 + ], + "executedQueryString": "SELECT UNIX_TIMESTAMP(\"time\") DIV 300 * 300 AS \"time\",c,avg(v) AS \"v\" FROM tbl GROUP BY 1,2 ORDER BY 1,2" + }, + "fields": [ + { + "name": "Time", + "type": "time", + "typeInfo": { + "frame": "time.Time" + } + }, + { + "name": "v", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "c": "a" + } + }, + { + "name": "v", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "c": "b" + } + } + ] + }, + "data": { + "values": [ + [ + 1703427300000, + 1703427600000, + 1703427900000, + 1703428200000, + 1703428500000, + 1703428800000, + 1703429100000 + ], + [ + 27, + 15, + 27, + 27, + 50, + 27, + 27 + ], + [ + 27, + 115, + 27, + 27, + 150, + 27, + 27 + ] + ] + } + } + ] +} \ No newline at end of file diff --git a/pkg/tsdb/mysql/testdata/time_series/fill_value.sql b/pkg/tsdb/mysql/testdata/time_series/fill_value.sql new file mode 100644 index 000000000000..1b373c5e9945 --- /dev/null +++ b/pkg/tsdb/mysql/testdata/time_series/fill_value.sql @@ -0,0 +1,15 @@ +-- SELECT $__timeGroupAlias("time",5m,27),c,avg(v) AS "v" FROM tbl GROUP BY 1,2 ORDER BY 1,2 +-- tests fill-mode=value +CREATE TABLE tbl ( + `time` timestamp NOT NULL, + v double precision, + c text +); + +INSERT INTO tbl (`time`, v, c) VALUES +('2023-12-24 14:21:03+00:00', 10, 'a'), +('2023-12-24 14:21:03+00:00', 110, 'b'), +('2023-12-24 14:23:03+00:00', 20, 'a'), +('2023-12-24 14:23:03+00:00', 120, 'b'), +('2023-12-24 14:39:03+00:00', 50, 'a'), +('2023-12-24 14:39:03+00:00', 150, 'b'); \ No newline at end of file diff --git a/pkg/tsdb/mysql/testdata/time_series/fill_value_wide.golden.jsonc b/pkg/tsdb/mysql/testdata/time_series/fill_value_wide.golden.jsonc new file mode 100644 index 000000000000..a676314a6db8 --- /dev/null +++ b/pkg/tsdb/mysql/testdata/time_series/fill_value_wide.golden.jsonc @@ -0,0 +1,100 @@ +// 🌟 This was machine generated. Do not edit. 🌟 +// +// Frame[0] { +// "typeVersion": [ +// 0, +// 0 +// ], +// "executedQueryString": "SELECT UNIX_TIMESTAMP(\"time\") DIV 300 * 300 AS \"time\",avg(v1) AS \"v1\", avg(v2) AS \"v2\" FROM tbl GROUP BY 1 ORDER BY 1" +// } +// Name: +// Dimensions: 3 Fields by 7 Rows +// +-------------------------------+------------------+------------------+ +// | Name: Time | Name: v1 | Name: v2 | +// | Labels: | Labels: | Labels: | +// | Type: []*time.Time | Type: []*float64 | Type: []*float64 | +// +-------------------------------+------------------+------------------+ +// | 2023-12-24 14:15:00 +0000 UTC | 27 | 27 | +// | 2023-12-24 14:20:00 +0000 UTC | 15 | 115 | +// | 2023-12-24 14:25:00 +0000 UTC | 27 | 27 | +// | 2023-12-24 14:30:00 +0000 UTC | 27 | 27 | +// | 2023-12-24 14:35:00 +0000 UTC | 50 | 150 | +// | 2023-12-24 14:40:00 +0000 UTC | 27 | 27 | +// | 2023-12-24 14:45:00 +0000 UTC | 27 | 27 | +// +-------------------------------+------------------+------------------+ +// +// +// 🌟 This was machine generated. Do not edit. 🌟 +{ + "status": 200, + "frames": [ + { + "schema": { + "meta": { + "typeVersion": [ + 0, + 0 + ], + "executedQueryString": "SELECT UNIX_TIMESTAMP(\"time\") DIV 300 * 300 AS \"time\",avg(v1) AS \"v1\", avg(v2) AS \"v2\" FROM tbl GROUP BY 1 ORDER BY 1" + }, + "fields": [ + { + "name": "Time", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "name": "v1", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + }, + { + "name": "v2", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + } + ] + }, + "data": { + "values": [ + [ + 1703427300000, + 1703427600000, + 1703427900000, + 1703428200000, + 1703428500000, + 1703428800000, + 1703429100000 + ], + [ + 27, + 15, + 27, + 27, + 50, + 27, + 27 + ], + [ + 27, + 115, + 27, + 27, + 150, + 27, + 27 + ] + ] + } + } + ] +} \ No newline at end of file diff --git a/pkg/tsdb/mysql/testdata/time_series/fill_value_wide.sql b/pkg/tsdb/mysql/testdata/time_series/fill_value_wide.sql new file mode 100644 index 000000000000..22d6746b49b8 --- /dev/null +++ b/pkg/tsdb/mysql/testdata/time_series/fill_value_wide.sql @@ -0,0 +1,12 @@ +-- SELECT $__timeGroupAlias("time",5m,27),avg(v1) AS "v1", avg(v2) AS "v2" FROM tbl GROUP BY 1 ORDER BY 1 +-- tests fill-mode=value +CREATE TABLE tbl ( + "time" timestamp(6) NOT NULL, + v1 double precision, + v2 double precision +); + +INSERT INTO tbl ("time", v1, v2) VALUES +('2023-12-24 14:21:03 UTC', 10, 110), +('2023-12-24 14:23:03 UTC', 20, 120), +('2023-12-24 14:39:03 UTC', 50, 150); \ No newline at end of file diff --git a/pkg/tsdb/mysql/testdata/time_series/no_rows_long.golden.jsonc b/pkg/tsdb/mysql/testdata/time_series/no_rows_long.golden.jsonc new file mode 100644 index 000000000000..2cc0ccc47b8b --- /dev/null +++ b/pkg/tsdb/mysql/testdata/time_series/no_rows_long.golden.jsonc @@ -0,0 +1,36 @@ +// 🌟 This was machine generated. Do not edit. 🌟 +// +// Frame[0] { +// "typeVersion": [ +// 0, +// 0 +// ], +// "executedQueryString": "SELECT * FROM tbl WHERE false" +// } +// Name: +// Dimensions: 0 Fields by 0 Rows +// + +// + +// +// +// 🌟 This was machine generated. Do not edit. 🌟 +{ + "status": 200, + "frames": [ + { + "schema": { + "meta": { + "typeVersion": [ + 0, + 0 + ], + "executedQueryString": "SELECT * FROM tbl WHERE false" + }, + "fields": [] + }, + "data": { + "values": [] + } + } + ] +} \ No newline at end of file diff --git a/pkg/tsdb/mysql/testdata/time_series/no_rows_long.sql b/pkg/tsdb/mysql/testdata/time_series/no_rows_long.sql new file mode 100644 index 000000000000..0a81eb4fa079 --- /dev/null +++ b/pkg/tsdb/mysql/testdata/time_series/no_rows_long.sql @@ -0,0 +1,12 @@ +-- SELECT * FROM tbl WHERE false +CREATE TABLE tbl ( + `time` timestamp NOT NULL, + v double precision, + c text +); + +INSERT INTO tbl (`time`, v, c) VALUES +('2023-12-24 14:30:03+00:00', 10, 'a'), +('2023-12-24 14:30:03+00:00', 110, 'b'), +('2023-12-24 14:31:03+00:00', 20, 'a'), +('2023-12-24 14:31:03+00:00', 120, 'b'); \ No newline at end of file diff --git a/pkg/tsdb/mysql/testdata/time_series/no_rows_wide.golden.jsonc b/pkg/tsdb/mysql/testdata/time_series/no_rows_wide.golden.jsonc new file mode 100644 index 000000000000..2cc0ccc47b8b --- /dev/null +++ b/pkg/tsdb/mysql/testdata/time_series/no_rows_wide.golden.jsonc @@ -0,0 +1,36 @@ +// 🌟 This was machine generated. Do not edit. 🌟 +// +// Frame[0] { +// "typeVersion": [ +// 0, +// 0 +// ], +// "executedQueryString": "SELECT * FROM tbl WHERE false" +// } +// Name: +// Dimensions: 0 Fields by 0 Rows +// + +// + +// +// +// 🌟 This was machine generated. Do not edit. 🌟 +{ + "status": 200, + "frames": [ + { + "schema": { + "meta": { + "typeVersion": [ + 0, + 0 + ], + "executedQueryString": "SELECT * FROM tbl WHERE false" + }, + "fields": [] + }, + "data": { + "values": [] + } + } + ] +} \ No newline at end of file diff --git a/pkg/tsdb/mysql/testdata/time_series/no_rows_wide.sql b/pkg/tsdb/mysql/testdata/time_series/no_rows_wide.sql new file mode 100644 index 000000000000..25c16edda9cc --- /dev/null +++ b/pkg/tsdb/mysql/testdata/time_series/no_rows_wide.sql @@ -0,0 +1,10 @@ +-- SELECT * FROM tbl WHERE false +CREATE TABLE tbl ( + `time` timestamp NOT NULL, + v1 double precision, + v2 double precision +); + +INSERT INTO tbl (`time`, v1, v2) VALUES +('2023-12-24 14:30:03+00:00', 10, 110), +('2023-12-24 14:31:03+00:00', 20, 120); \ No newline at end of file diff --git a/pkg/tsdb/mysql/testdata/time_series/simple.golden.jsonc b/pkg/tsdb/mysql/testdata/time_series/simple.golden.jsonc new file mode 100644 index 000000000000..c8075f2b65b4 --- /dev/null +++ b/pkg/tsdb/mysql/testdata/time_series/simple.golden.jsonc @@ -0,0 +1,99 @@ +// 🌟 This was machine generated. Do not edit. 🌟 +// +// Frame[0] { +// "type": "timeseries-wide", +// "typeVersion": [ +// 0, +// 0 +// ], +// "executedQueryString": "SELECT * FROM tbl" +// } +// Name: +// Dimensions: 3 Fields by 5 Rows +// +-------------------------------+------------------+------------------+ +// | Name: Time | Name: v | Name: v | +// | Labels: | Labels: c=a | Labels: c=b | +// | Type: []time.Time | Type: []*float64 | Type: []*float64 | +// +-------------------------------+------------------+------------------+ +// | 2023-12-24 14:30:03 +0000 UTC | 10 | 110 | +// | 2023-12-24 14:31:03 +0000 UTC | 20 | 120 | +// | 2023-12-24 14:32:03 +0000 UTC | 30 | 130 | +// | 2023-12-24 14:33:03 +0000 UTC | 40 | 140 | +// | 2023-12-24 14:34:03 +0000 UTC | 50 | 150 | +// +-------------------------------+------------------+------------------+ +// +// +// 🌟 This was machine generated. Do not edit. 🌟 +{ + "status": 200, + "frames": [ + { + "schema": { + "meta": { + "type": "timeseries-wide", + "typeVersion": [ + 0, + 0 + ], + "executedQueryString": "SELECT * FROM tbl" + }, + "fields": [ + { + "name": "Time", + "type": "time", + "typeInfo": { + "frame": "time.Time" + } + }, + { + "name": "v", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "c": "a" + } + }, + { + "name": "v", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + }, + "labels": { + "c": "b" + } + } + ] + }, + "data": { + "values": [ + [ + 1703428203000, + 1703428263000, + 1703428323000, + 1703428383000, + 1703428443000 + ], + [ + 10, + 20, + 30, + 40, + 50 + ], + [ + 110, + 120, + 130, + 140, + 150 + ] + ] + } + } + ] +} \ No newline at end of file diff --git a/pkg/tsdb/mysql/testdata/time_series/simple.sql b/pkg/tsdb/mysql/testdata/time_series/simple.sql new file mode 100644 index 000000000000..38b5c33650d0 --- /dev/null +++ b/pkg/tsdb/mysql/testdata/time_series/simple.sql @@ -0,0 +1,18 @@ +-- SELECT * FROM tbl +CREATE TABLE tbl ( + `time` timestamp NOT NULL, + v double precision, + c text +); + +INSERT INTO tbl (`time`, v, c) VALUES +('2023-12-24 14:30:03+00:00', 10, 'a'), +('2023-12-24 14:30:03+00:00', 110, 'b'), +('2023-12-24 14:31:03+00:00', 20, 'a'), +('2023-12-24 14:31:03+00:00', 120, 'b'), +('2023-12-24 14:32:03+00:00', 30, 'a'), +('2023-12-24 14:32:03+00:00', 130, 'b'), +('2023-12-24 14:33:03+00:00', 40, 'a'), +('2023-12-24 14:33:03+00:00', 140, 'b'), +('2023-12-24 14:34:03+00:00', 50, 'a'), +('2023-12-24 14:34:03+00:00', 150, 'b'); \ No newline at end of file