diff --git a/go/vt/vttablet/tabletserver/vstreamer/helper_event_test.go b/go/vt/vttablet/tabletserver/vstreamer/helper_event_test.go index ee67e482aa1..27b5fca91c8 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/helper_event_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/helper_event_test.go @@ -46,7 +46,6 @@ import ( "vitess.io/vitess/go/mysql/collations" "vitess.io/vitess/go/mysql/collations/colldata" "vitess.io/vitess/go/sqltypes" - "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/proto/query" "vitess.io/vitess/go/vt/schemadiff" "vitess.io/vitess/go/vt/sqlparser" @@ -67,6 +66,7 @@ const ( // This is the expected length of the only SET column using a binary collation // in the test schema. lengthSetBinary = 428 + lengthJSON = 4294967295 ) var ( @@ -547,8 +547,12 @@ func (ts *TestSpec) getFieldEvent(table *schemadiff.CreateTableEntity) *TestFiel tc.colType = fmt.Sprintf("%s(%s)", tc.dataTypeLowered, strings.Join(col.Type.EnumValues, ",")) ts.metadata[getMetadataKey(table.Name(), tc.name)] = col.Type.EnumValues tfe.enumSetStrings = true + case "json": + tc.colType = "json" + tc.len = lengthJSON + tc.collationID = collations.CollationBinaryID default: - log.Infof(fmt.Sprintf("unknown sqlTypeString %s", tc.dataTypeLowered)) + require.FailNowf(ts.t, "unknown sqlTypeString %s", tc.dataTypeLowered) } tfe.cols = append(tfe.cols, &tc) } @@ -591,11 +595,17 @@ func (ts *TestSpec) getRowEvent(table string, bv map[string]string, fe *TestFiel } val := []byte(bv[col.name]) l := int64(len(val)) - if col.dataTypeLowered == "binary" { + switch col.dataTypeLowered { + case "binary": for l < col.len { val = append(val, "\x00"...) l++ } + case "json": + sval := strings.Trim(string(val), "'") + sval = strings.ReplaceAll(sval, "\\", "") + val = []byte(sval) + l = int64(len(val)) } if slices.Equal(val, sqltypes.NullBytes) { l = -1 @@ -785,6 +795,8 @@ func getQueryType(strType string) query.Type { return query.Type_ENUM case "SET": return query.Type_SET + case "JSON": + return query.Type_JSON default: panic("unknown type " + strType) } diff --git a/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go b/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go index 8628aeeba70..d3e4d2730b6 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go @@ -1415,7 +1415,6 @@ func TestBuffering(t *testing.T) { // collation information, however, in the binlog_row_metadata in 8.0 but // not in 5.7. So in 5.7 our best effort uses varchar with its default // collation for text fields. -// todo: migrate to new framework func TestBestEffortNameInFieldEvent(t *testing.T) { bestEffortCollation := collations.ID(collations.CollationBinaryID) if strings.HasPrefix(testenv.MySQLVersion, "5.7") { @@ -1524,7 +1523,6 @@ func TestInternalTables(t *testing.T) { runCases(t, filter, testcases, position, nil) } -// todo: migrate to new framework func TestTypes(t *testing.T) { // Modeled after vttablet endtoend compatibility tests. execStatements(t, []string{ @@ -1648,50 +1646,28 @@ func TestTypes(t *testing.T) { runCases(t, nil, testcases, "", nil) } -// todo: migrate to new framework func TestJSON(t *testing.T) { - if err := env.Mysqld.ExecuteSuperQuery(context.Background(), "create table vitess_json(id int default 1, val json, primary key(id))"); err != nil { - // If it's a syntax error, MySQL is an older version. Skip this test. - if strings.Contains(err.Error(), "syntax") { - return - } - t.Fatal(err) + ts := &TestSpec{ + t: t, + ddls: []string{ + "create table vitess_json(id int default 1, val json, primary key(id))", + }, } - defer execStatement(t, "drop table vitess_json") - engine.se.Reload(context.Background()) + ts.Init() + defer ts.Close() + ts.tests = [][]*TestQuery{} + queries := []*TestQuery{} jsonValues := []string{"{}", "123456", `"vtTablet"`, `{"foo": "bar"}`, `["abc", 3.14, true]`} - - var inputs, outputs []string - var outputsArray [][]string - fieldAdded := false - var expect = func(in string) string { - return strings.ReplaceAll(in, "\"", "\\\"") - } + queries = append(queries, &TestQuery{"begin", nil}) for i, val := range jsonValues { - inputs = append(inputs, fmt.Sprintf("insert into vitess_json values(%d, %s)", i+1, encodeString(val))) - - outputs = []string{} - outputs = append(outputs, `begin`) - if !fieldAdded { - outputs = append(outputs, `type:FIELD field_event:{table_name:"vitess_json" fields:{name:"id" type:INT32 table:"vitess_json" org_table:"vitess_json" database:"vttest" org_name:"id" column_length:11 charset:63 column_type:"int(11)"} fields:{name:"val" type:JSON table:"vitess_json" org_table:"vitess_json" database:"vttest" org_name:"val" column_length:4294967295 charset:63 column_type:"json"}}`) - fieldAdded = true - } - out := expect(val) - - outputs = append(outputs, fmt.Sprintf(`type:ROW row_event:{table_name:"vitess_json" row_changes:{after:{lengths:1 lengths:%d values:"%d%s"}}}`, - len(val), i+1 /*id increments*/, out)) - outputs = append(outputs, `gtid`) - outputs = append(outputs, `commit`) - outputsArray = append(outputsArray, outputs) + queries = append(queries, &TestQuery{fmt.Sprintf("insert into vitess_json values(%d, %s)", i+1, encodeString(val)), nil}) } - testcases := []testcase{{ - input: inputs, - output: outputsArray, - }} - runCases(t, nil, testcases, "", nil) + queries = append(queries, &TestQuery{"commit", nil}) + + ts.tests = append(ts.tests, queries) + ts.Run() } -// todo: migrate to new framework func TestExternalTable(t *testing.T) { execStatements(t, []string{ "create database external", @@ -1718,7 +1694,6 @@ func TestExternalTable(t *testing.T) { runCases(t, nil, testcases, "", nil) } -// todo: migrate to new framework func TestJournal(t *testing.T) { execStatements(t, []string{ "create table if not exists _vt.resharding_journal(id int, db_name varchar(128), val blob, primary key(id))", @@ -1754,7 +1729,6 @@ func TestJournal(t *testing.T) { runCases(t, nil, testcases, "", nil) } -// todo: migrate to new framework // TestMinimalMode confirms that we don't support minimal binlog_row_image mode. func TestMinimalMode(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) @@ -1778,7 +1752,6 @@ func TestMinimalMode(t *testing.T) { require.Error(t, err, "minimal binlog_row_image is not supported by Vitess VReplication") } -// todo: migrate to new framework func TestStatementMode(t *testing.T) { execStatements(t, []string{ "create table stream1(id int, val varbinary(128), primary key(id))", @@ -1814,7 +1787,6 @@ func TestStatementMode(t *testing.T) { runCases(t, nil, testcases, "", nil) } -// todo: migrate to new framework func TestHeartbeat(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -1827,7 +1799,6 @@ func TestHeartbeat(t *testing.T) { cancel() } -// todo: migrate to new framework func TestNoFutureGTID(t *testing.T) { // Execute something to make sure we have ranges in GTIDs. execStatements(t, []string{