From 3fbc6bb0b49fd70c91cc440765ab4f231859559b Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Mon, 7 Jun 2021 15:11:28 +0300 Subject: [PATCH 01/21] Online DDL/VReplication suite: reject non utf8* charsets Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../fail-alter-charset-non-utf8}/alter | 0 .../fail-alter-charset-non-utf8}/create.sql | 0 .../expect_failure | 1 + .../fail-alter-charset-non-utf8/alter | 1 + .../fail-alter-charset-non-utf8/create.sql | 24 +++++++++++++++++++ .../expect_failure | 1 + go/vt/vttablet/onlineddl/vrepl.go | 3 +++ 7 files changed, 30 insertions(+) rename go/test/endtoend/onlineddl/vrepl_suite/{untestdata/alter-charset => testdata/fail-alter-charset-non-utf8}/alter (100%) rename go/test/endtoend/onlineddl/vrepl_suite/{untestdata/alter-charset => testdata/fail-alter-charset-non-utf8}/create.sql (100%) create mode 100644 go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/expect_failure create mode 100644 go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/alter create mode 100644 go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/create.sql create mode 100644 go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/expect_failure diff --git a/go/test/endtoend/onlineddl/vrepl_suite/untestdata/alter-charset/alter b/go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/alter similarity index 100% rename from go/test/endtoend/onlineddl/vrepl_suite/untestdata/alter-charset/alter rename to go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/alter diff --git a/go/test/endtoend/onlineddl/vrepl_suite/untestdata/alter-charset/create.sql b/go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/create.sql similarity index 100% rename from go/test/endtoend/onlineddl/vrepl_suite/untestdata/alter-charset/create.sql rename to go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/create.sql diff --git a/go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/expect_failure b/go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/expect_failure new file mode 100644 index 00000000000..925d0d81ded --- /dev/null +++ b/go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/expect_failure @@ -0,0 +1 @@ +Vitess does not support charset diff --git a/go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/alter b/go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/alter new file mode 100644 index 00000000000..b5ec82b1a8b --- /dev/null +++ b/go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/alter @@ -0,0 +1 @@ +MODIFY `t1` varchar(128) CHARACTER SET utf8mb4 NOT NULL, MODIFY `t2` varchar(128) CHARACTER SET latin2 NOT NULL, MODIFY `tutf8` varchar(128) CHARACTER SET latin1 NOT NULL diff --git a/go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/create.sql b/go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/create.sql new file mode 100644 index 00000000000..9db84563248 --- /dev/null +++ b/go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/create.sql @@ -0,0 +1,24 @@ +drop table if exists onlineddl_test; +create table onlineddl_test ( + id int auto_increment, + t1 varchar(128) charset latin1 collate latin1_swedish_ci, + t2 varchar(128) charset latin1 collate latin1_swedish_ci, + tutf8 varchar(128) charset utf8, + tutf8mb4 varchar(128) charset utf8mb4, + primary key(id) +) auto_increment=1; + +drop event if exists onlineddl_test; +delimiter ;; +create event onlineddl_test + on schedule every 1 second + starts current_timestamp + ends current_timestamp + interval 60 second + on completion not preserve + enable + do +begin + insert into onlineddl_test values (null, md5(rand()), md5(rand()), md5(rand()), md5(rand())); + insert into onlineddl_test values (null, 'átesting', 'átesting', 'átesting', 'átesting'); + insert into onlineddl_test values (null, 'testátest', 'testátest', 'testátest', '🍻😀'); +end ;; diff --git a/go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/expect_failure b/go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/expect_failure new file mode 100644 index 00000000000..925d0d81ded --- /dev/null +++ b/go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/expect_failure @@ -0,0 +1 @@ +Vitess does not support charset diff --git a/go/vt/vttablet/onlineddl/vrepl.go b/go/vt/vttablet/onlineddl/vrepl.go index e60130c89ab..bd4b976abcb 100644 --- a/go/vt/vttablet/onlineddl/vrepl.go +++ b/go/vt/vttablet/onlineddl/vrepl.go @@ -224,6 +224,9 @@ func (v *VRepl) applyColumnTypes(ctx context.Context, conn *dbconnpool.DBConnect column.BinaryOctetLength = columnOctetLength } if charset := row.AsString("CHARACTER_SET_NAME", ""); charset != "" { + if !strings.HasPrefix(charset, "utf8") { + return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Vitess does not support charset '%s'. Only utf8 and derivatives (like utf8mb4) are supported", charset) + } column.Charset = charset } } From f7962766e159f41a19b790829d382a3089285c26 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Thu, 10 Jun 2021 11:10:07 +0300 Subject: [PATCH 02/21] experiment: support online ddl convert from latin1 to utf8 Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/mysql/constants.go | 9 ++++ .../vrepl_suite/onlineddl_vrepl_suite_test.go | 2 +- go/vt/vttablet/onlineddl/vrepl.go | 34 +++++++++--- go/vt/vttablet/onlineddl/vrepl/types.go | 3 ++ .../vreplication/table_plan_builder.go | 53 +++++++++++++++++++ .../tabletmanager/vreplication/vcopier.go | 2 + .../tabletserver/vstreamer/planbuilder.go | 19 ++++++- .../tabletserver/vstreamer/rowstreamer.go | 10 +++- 8 files changed, 123 insertions(+), 9 deletions(-) diff --git a/go/mysql/constants.go b/go/mysql/constants.go index 68c94d9bff3..b2d4c86db1d 100644 --- a/go/mysql/constants.go +++ b/go/mysql/constants.go @@ -626,6 +626,15 @@ var CharacterSetMap = map[string]uint8{ "eucjpms": 97, } +// ReverseCharacterSetMap maps a charset integer code to charset name +var ReverseCharacterSetMap = map[uint8]string{} + +func init() { + for c, i := range CharacterSetMap { + ReverseCharacterSetMap[i] = c + } +} + // IsNum returns true if a MySQL type is a numeric value. // It is the same as IS_NUM defined in mysql.h. func IsNum(typ uint8) bool { diff --git a/go/test/endtoend/onlineddl/vrepl_suite/onlineddl_vrepl_suite_test.go b/go/test/endtoend/onlineddl/vrepl_suite/onlineddl_vrepl_suite_test.go index d96cfcfff22..68f71c8d683 100644 --- a/go/test/endtoend/onlineddl/vrepl_suite/onlineddl_vrepl_suite_test.go +++ b/go/test/endtoend/onlineddl/vrepl_suite/onlineddl_vrepl_suite_test.go @@ -60,7 +60,7 @@ var ( ) const ( - testDataPath = "testdata" + testDataPath = "tmptestdata" defaultSQLMode = "ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION" ) diff --git a/go/vt/vttablet/onlineddl/vrepl.go b/go/vt/vttablet/onlineddl/vrepl.go index bd4b976abcb..54aee9a9909 100644 --- a/go/vt/vttablet/onlineddl/vrepl.go +++ b/go/vt/vttablet/onlineddl/vrepl.go @@ -215,6 +215,9 @@ func (v *VRepl) applyColumnTypes(ctx context.Context, conn *dbconnpool.DBConnect if strings.Contains(columnType, "float") { column.Type = vrepl.FloatColumnType } + if strings.Contains(columnType, "int") { + column.Type = vrepl.IntegerColumnType + } if strings.HasPrefix(columnType, "enum") { column.Type = vrepl.EnumColumnType column.EnumValues = vrepl.ParseEnumValues(columnType) @@ -224,11 +227,15 @@ func (v *VRepl) applyColumnTypes(ctx context.Context, conn *dbconnpool.DBConnect column.BinaryOctetLength = columnOctetLength } if charset := row.AsString("CHARACTER_SET_NAME", ""); charset != "" { - if !strings.HasPrefix(charset, "utf8") { - return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Vitess does not support charset '%s'. Only utf8 and derivatives (like utf8mb4) are supported", charset) - } + // if !strings.HasPrefix(charset, "utf8") { + // return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Vitess does not support charset '%s'. Only utf8 and derivatives (like utf8mb4) are supported", charset) + // } column.Charset = charset } + if collation := row.AsString("COLLATION_NAME", ""); collation != "" { + column.Type = vrepl.StringColumnType + column.Collation = collation + } } } return nil @@ -386,9 +393,24 @@ func (v *VRepl) generateFilterQuery(ctx context.Context) error { } switch col.Type { case vrepl.JSONColumnType: - sb.WriteString("convert(") - sb.WriteString(escapeName(name)) - sb.WriteString(" using utf8mb4)") + sb.WriteString(fmt.Sprintf("convert(%s using utf8mb4)", escapeName(name))) + case vrepl.StringColumnType: + targetCol := v.targetSharedColumns.GetColumn(targetName) + if targetCol == nil { + return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "Cannot find target column %s", targetName) + } + if col.Collation != targetCol.Collation { + fmt.Printf("============ collcation change: %s => %s\n", col.Collation, targetCol.Collation) + if strings.HasPrefix(targetCol.Charset, "utf8") { + // sb.WriteString(fmt.Sprintf("cast(%s as binary)", escapeName(name))) + sb.WriteString(fmt.Sprintf("convert(convert(convert(%s USING %s) USING binary) USING %s)", escapeName(name), col.Charset, targetCol.Charset)) + // sb.WriteString(fmt.Sprintf("convert(%s USING %s) COLLATE %s", escapeName(name), targetCol.Charset, targetCol.Collation)) + } else { + sb.WriteString(fmt.Sprintf("convert(%s, char character set %s) COLLATE %s", escapeName(name), targetCol.Charset, targetCol.Collation)) + } + } else { + sb.WriteString(escapeName(name)) + } default: sb.WriteString(escapeName(name)) } diff --git a/go/vt/vttablet/onlineddl/vrepl/types.go b/go/vt/vttablet/onlineddl/vrepl/types.go index f4ff965a381..665906434cd 100644 --- a/go/vt/vttablet/onlineddl/vrepl/types.go +++ b/go/vt/vttablet/onlineddl/vrepl/types.go @@ -41,6 +41,8 @@ const ( JSONColumnType FloatColumnType BinaryColumnType + StringColumnType + IntegerColumnType ) // Column represents a table column @@ -48,6 +50,7 @@ type Column struct { Name string IsUnsigned bool Charset string + Collation string Type ColumnType EnumValues string EnumToTextConversion bool diff --git a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go index 66c57ca09d0..0b929989185 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go +++ b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go @@ -186,6 +186,7 @@ func MatchTable(tableName string, filter *binlogdatapb.Filter) (*binlogdatapb.Ru func buildTablePlan(tableName, filter string, pkInfoMap map[string][]*PrimaryKeyInfo, lastpk *sqltypes.Result, stats *binlogplayer.Stats) (*TablePlan, error) { query := filter // generate equivalent select statement if filter is empty or a keyrange. + fmt.Printf("============ filter: %v\n", filter) switch { case filter == "": buf := sqlparser.NewTrackedBuffer(nil) @@ -237,6 +238,9 @@ func buildTablePlan(tableName, filter string, pkInfoMap map[string][]*PrimaryKey stats: stats, } + for _, s := range sel.SelectExprs { + fmt.Printf("============ SelectExpr: %v\n", sqlparser.String(s)) + } if err := tpb.analyzeExprs(sel.SelectExprs); err != nil { return nil, err } @@ -268,7 +272,9 @@ func buildTablePlan(tableName, filter string, pkInfoMap map[string][]*PrimaryKey }, }) } + fmt.Printf("============ sendSelect.SelectExprs [3]: %v\n", sqlparser.String(tpb.sendSelect.SelectExprs)) sendRule.Filter = sqlparser.String(tpb.sendSelect) + fmt.Printf("============ sendRule.Filter: %v\n", sendRule.Filter) tablePlan := tpb.generate() tablePlan.SendRule = sendRule @@ -338,6 +344,7 @@ func analyzeSelectFrom(query string) (sel *sqlparser.Select, from string, err er func (tpb *tablePlanBuilder) analyzeExprs(selExprs sqlparser.SelectExprs) error { for _, selExpr := range selExprs { cexpr, err := tpb.analyzeExpr(selExpr) + fmt.Printf("============ selExpr: %v, cexpr.expr: %v\n", sqlparser.String(selExpr), sqlparser.String(cexpr.expr)) if err != nil { return err } @@ -364,6 +371,52 @@ func (tpb *tablePlanBuilder) analyzeExpr(selExpr sqlparser.SelectExpr) (*colExpr colName: as, references: make(map[string]bool), } + if expr, ok := aliased.Expr.(*sqlparser.ConvertUsingExpr); ok { + fmt.Printf("============ ConvertUsingExpr: %v\n", sqlparser.String(expr)) + selExpr := &sqlparser.ConvertUsingExpr{ + Type: "binary", + Expr: &sqlparser.ColName{Name: as}, + } + fmt.Printf("============ ConvertUsingExpr generated: %v\n", sqlparser.String(selExpr)) + cexpr.expr = expr + cexpr.operation = opExpr + tpb.sendSelect.SelectExprs = append(tpb.sendSelect.SelectExprs, &sqlparser.AliasedExpr{Expr: selExpr, As: as}) + return cexpr, nil + } + if expr, ok := aliased.Expr.(*sqlparser.ConvertExpr); ok { + // convertAsBinary := fmt.Sprintf("convert(%s, binary) as %s", sqlparser.String(as), sqlparser.String(as)) + // fmt.Printf("============ convertAsBinary: %v\n", convertAsBinary) + // convertAsBinaryExpr, err := sqlparser.Parse(convertAsBinary) + // fmt.Printf("============ convertAsBinaryExpr, err: %v, %v\n", convertAsBinaryExpr, err) + // if err != nil { + // return nil, err + // } + // expr, ok := convertAsBinaryExpr.(*sqlparser.ConvertExpr) + fmt.Printf("============ ConvertExpr: %v\n", sqlparser.String(expr)) + fmt.Printf("============ ConvertExpr.Type: %v\n", expr.Type) + fmt.Printf("============ ConvertExpr.Type.Type: %v\n", expr.Type.Type) + fmt.Printf("============ ConvertExpr.Type.Charset: %v\n", expr.Type.Charset) + fmt.Printf("============ ConvertExpr.Expr: %v\n", expr.Expr) + // expr.Type:= + // type ConvertType struct { + // Type string + // Length *Literal + // Scale *Literal + // Operator ConvertTypeOperator + // Charset string + // } + // expr.Type = &sqlparser.ConvertType{Type: "binary"} + // expr.Expr = as + selExpr := &sqlparser.ConvertExpr{ + Type: &sqlparser.ConvertType{Type: "binary"}, + Expr: &sqlparser.ColName{Name: as}, + } + fmt.Printf("============ ConvertExpr generated: %v\n", sqlparser.String(selExpr)) + cexpr.expr = expr + cexpr.operation = opExpr + tpb.sendSelect.SelectExprs = append(tpb.sendSelect.SelectExprs, &sqlparser.AliasedExpr{Expr: selExpr, As: as}) + return cexpr, nil + } if expr, ok := aliased.Expr.(*sqlparser.FuncExpr); ok { if expr.Distinct { return nil, fmt.Errorf("unexpected: %v", sqlparser.String(expr)) diff --git a/go/vt/vttablet/tabletmanager/vreplication/vcopier.go b/go/vt/vttablet/tabletmanager/vreplication/vcopier.go index a16cb1ba528..3cef585455e 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vcopier.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vcopier.go @@ -200,6 +200,7 @@ func (vc *vcopier) copyTable(ctx context.Context, tableName string, copyState ma log.Infof("Copying table %s, lastpk: %v", tableName, copyState[tableName]) + fmt.Printf("============ buildReplicatorPlan( ivc.vr.source.Filter: %v\n", vc.vr.source.Filter) plan, err := buildReplicatorPlan(vc.vr.source.Filter, vc.vr.pkInfoMap, nil, vc.vr.stats) if err != nil { return err @@ -222,6 +223,7 @@ func (vc *vcopier) copyTable(ctx context.Context, tableName string, copyState ma var updateCopyState *sqlparser.ParsedQuery var bv map[string]*querypb.BindVariable var sqlbuffer bytes2.Buffer + fmt.Printf("============ VStreamRows( initialPlan.SendRule.Filter: %v\n", initialPlan.SendRule.Filter) err = vc.vr.sourceVStreamer.VStreamRows(ctx, initialPlan.SendRule.Filter, lastpkpb, func(rows *binlogdatapb.VStreamRowsResponse) error { for { select { diff --git a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go index eed93df1106..80dd00b8102 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go +++ b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go @@ -48,6 +48,8 @@ type Plan struct { // in the stream. ColExprs []ColExpr + convertToBinary map[string]bool + // Filters is the list of filters to be applied to the columns // of the table. Filters []Filter @@ -323,12 +325,14 @@ func buildTablePlan(ti *Table, vschema *localVSchema, query string) (*Plan, erro } plan := &Plan{ - Table: ti, + Table: ti, + convertToBinary: map[string]bool{}, } if err := plan.analyzeWhere(vschema, sel.Where); err != nil { log.Errorf("%s", err.Error()) return nil, err } + fmt.Printf("========= buildTablePlan.analyzeExprs: sel.SelectExprs: %v, %v\n", len(sel.SelectExprs), sqlparser.String(sel.SelectExprs)) if err := plan.analyzeExprs(vschema, sel.SelectExprs); err != nil { log.Errorf("%s", err.Error()) return nil, err @@ -456,6 +460,7 @@ func (plan *Plan) analyzeExprs(vschema *localVSchema, selExprs sqlparser.SelectE } func (plan *Plan) analyzeExpr(vschema *localVSchema, selExpr sqlparser.SelectExpr) (cExpr ColExpr, err error) { + fmt.Printf("========= Plan: analyzeExpr selExpr s: %v\n", sqlparser.String(selExpr)) aliased, ok := selExpr.(*sqlparser.AliasedExpr) if !ok { return ColExpr{}, fmt.Errorf("unsupported: %v", sqlparser.String(selExpr)) @@ -520,6 +525,18 @@ func (plan *Plan) analyzeExpr(vschema *localVSchema, selExpr sqlparser.SelectExp ColNum: -1, FixedValue: sqltypes.NewInt64(num), }, nil + case *sqlparser.ConvertExpr, *sqlparser.ConvertUsingExpr: + colnum, err := findColumn(plan.Table, aliased.As) + fmt.Printf("========= findColumn2: %v, %v \n", colnum, err) + if err != nil { + return ColExpr{}, err + } + field := plan.Table.Fields[colnum] + plan.convertToBinary[field.Name] = true + return ColExpr{ + ColNum: colnum, + Field: field, + }, nil default: log.Infof("Unsupported expression: %v", inner) return ColExpr{}, fmt.Errorf("unsupported: %v", sqlparser.String(aliased.Expr)) diff --git a/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go b/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go index b605bd8ad80..89c0c3190fa 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go +++ b/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go @@ -113,6 +113,7 @@ func (rs *rowStreamer) Stream() error { func (rs *rowStreamer) buildPlan() error { // This pre-parsing is required to extract the table name // and create its metadata. + fmt.Printf("========= analyzeSelect: %v\n", rs.query) _, fromTable, err := analyzeSelect(rs.query) if err != nil { return err @@ -139,6 +140,7 @@ func (rs *rowStreamer) buildPlan() error { return err } rs.sendQuery, err = rs.buildSelect() + fmt.Printf("================= rs.sendQuery: %v\n", rs.sendQuery) if err != nil { return err } @@ -169,7 +171,13 @@ func (rs *rowStreamer) buildSelect() (string, error) { buf.Myprintf("select ") prefix := "" for _, col := range rs.plan.Table.Fields { - buf.Myprintf("%s%v", prefix, sqlparser.NewColIdent(col.Name)) + if rs.plan.convertToBinary[col.Name] { + // fmt.Printf("========== WOOHOO! convertToBinary for %v\n", col.Name) + buf.Myprintf("%sconvert(convert(%v using binary) using utf8)", prefix, sqlparser.NewColIdent(col.Name)) + // buf.Myprintf("%s%v", prefix, sqlparser.NewColIdent(col.Name)) + } else { + buf.Myprintf("%s%v", prefix, sqlparser.NewColIdent(col.Name)) + } prefix = ", " } buf.Myprintf(" from %v", sqlparser.NewTableIdent(rs.plan.Table.Name)) From 1013d7939eef921dd4c85ac07c59d6f35d40f92c Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Thu, 10 Jun 2021 12:36:54 +0300 Subject: [PATCH 03/21] temporary test data Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../__expect_failure | 1 + .../fail-alter-charset-non-utf8/alter | 1 + .../fail-alter-charset-non-utf8/create.sql | 24 +++++++++++++++++++ 3 files changed, 26 insertions(+) create mode 100644 go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/__expect_failure create mode 100644 go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/alter create mode 100644 go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/create.sql diff --git a/go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/__expect_failure b/go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/__expect_failure new file mode 100644 index 00000000000..925d0d81ded --- /dev/null +++ b/go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/__expect_failure @@ -0,0 +1 @@ +Vitess does not support charset diff --git a/go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/alter b/go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/alter new file mode 100644 index 00000000000..b5ec82b1a8b --- /dev/null +++ b/go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/alter @@ -0,0 +1 @@ +MODIFY `t1` varchar(128) CHARACTER SET utf8mb4 NOT NULL, MODIFY `t2` varchar(128) CHARACTER SET latin2 NOT NULL, MODIFY `tutf8` varchar(128) CHARACTER SET latin1 NOT NULL diff --git a/go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/create.sql b/go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/create.sql new file mode 100644 index 00000000000..9db84563248 --- /dev/null +++ b/go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/create.sql @@ -0,0 +1,24 @@ +drop table if exists onlineddl_test; +create table onlineddl_test ( + id int auto_increment, + t1 varchar(128) charset latin1 collate latin1_swedish_ci, + t2 varchar(128) charset latin1 collate latin1_swedish_ci, + tutf8 varchar(128) charset utf8, + tutf8mb4 varchar(128) charset utf8mb4, + primary key(id) +) auto_increment=1; + +drop event if exists onlineddl_test; +delimiter ;; +create event onlineddl_test + on schedule every 1 second + starts current_timestamp + ends current_timestamp + interval 60 second + on completion not preserve + enable + do +begin + insert into onlineddl_test values (null, md5(rand()), md5(rand()), md5(rand()), md5(rand())); + insert into onlineddl_test values (null, 'átesting', 'átesting', 'átesting', 'átesting'); + insert into onlineddl_test values (null, 'testátest', 'testátest', 'testátest', '🍻😀'); +end ;; From 88d509ead786cb5b6b969810a49a9ecb2d0e9aeb Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Sun, 13 Jun 2021 12:17:22 +0300 Subject: [PATCH 04/21] only convert using utf8, no binary Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/vttablet/onlineddl/vrepl.go | 2 +- go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/go/vt/vttablet/onlineddl/vrepl.go b/go/vt/vttablet/onlineddl/vrepl.go index 54aee9a9909..ecbf42aec96 100644 --- a/go/vt/vttablet/onlineddl/vrepl.go +++ b/go/vt/vttablet/onlineddl/vrepl.go @@ -403,7 +403,7 @@ func (v *VRepl) generateFilterQuery(ctx context.Context) error { fmt.Printf("============ collcation change: %s => %s\n", col.Collation, targetCol.Collation) if strings.HasPrefix(targetCol.Charset, "utf8") { // sb.WriteString(fmt.Sprintf("cast(%s as binary)", escapeName(name))) - sb.WriteString(fmt.Sprintf("convert(convert(convert(%s USING %s) USING binary) USING %s)", escapeName(name), col.Charset, targetCol.Charset)) + sb.WriteString(fmt.Sprintf("convert(%s USING %s)", escapeName(name), targetCol.Charset)) // sb.WriteString(fmt.Sprintf("convert(%s USING %s) COLLATE %s", escapeName(name), targetCol.Charset, targetCol.Collation)) } else { sb.WriteString(fmt.Sprintf("convert(%s, char character set %s) COLLATE %s", escapeName(name), targetCol.Charset, targetCol.Collation)) diff --git a/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go b/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go index 89c0c3190fa..f7be38644e2 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go +++ b/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go @@ -173,7 +173,8 @@ func (rs *rowStreamer) buildSelect() (string, error) { for _, col := range rs.plan.Table.Fields { if rs.plan.convertToBinary[col.Name] { // fmt.Printf("========== WOOHOO! convertToBinary for %v\n", col.Name) - buf.Myprintf("%sconvert(convert(%v using binary) using utf8)", prefix, sqlparser.NewColIdent(col.Name)) + // buf.Myprintf("%sconvert(convert(%v using binary) using utf8)", prefix, sqlparser.NewColIdent(col.Name)) + buf.Myprintf("%sconvert(%v using utf8)", prefix, sqlparser.NewColIdent(col.Name)) // buf.Myprintf("%s%v", prefix, sqlparser.NewColIdent(col.Name)) } else { buf.Myprintf("%s%v", prefix, sqlparser.NewColIdent(col.Name)) From 21b59edca61b614ae7744dd883fca6b40344e61f Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Sun, 13 Jun 2021 17:24:44 +0300 Subject: [PATCH 05/21] working. Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/mysql/constants.go | 34 +- .../alter-charset-non-utf8-80}/alter | 0 .../alter-charset-non-utf8-80}/create.sql | 13 +- .../alter-charset-non-utf8-80/ignore_versions | 1 + .../alter-charset-non-utf8}/alter | 0 .../alter-charset-non-utf8}/create.sql | 9 +- .../alter-charset-non-utf8/ignore_versions | 1 + .../__expect_failure | 1 - go/vt/proto/binlogdata/binlogdata.pb.go | 938 ++++++++++-------- .../proto/binlogdata/binlogdata_vtproto.pb.go | 348 +++++++ go/vt/vttablet/onlineddl/vrepl.go | 78 +- .../vreplication/replicator_plan.go | 61 +- .../vreplication/table_plan_builder.go | 16 +- .../tabletserver/vstreamer/rowstreamer.go | 2 +- 14 files changed, 1036 insertions(+), 466 deletions(-) rename go/test/endtoend/onlineddl/vrepl_suite/{tmptestdata/fail-alter-charset-non-utf8 => testdata/alter-charset-non-utf8-80}/alter (100%) rename go/test/endtoend/onlineddl/vrepl_suite/{untestdata/alter-charset-all-dml => testdata/alter-charset-non-utf8-80}/create.sql (50%) create mode 100644 go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8-80/ignore_versions rename go/test/endtoend/onlineddl/vrepl_suite/{untestdata/alter-charset-all-dml => testdata/alter-charset-non-utf8}/alter (100%) rename go/test/endtoend/onlineddl/vrepl_suite/{tmptestdata/fail-alter-charset-non-utf8 => testdata/alter-charset-non-utf8}/create.sql (57%) create mode 100644 go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8/ignore_versions delete mode 100644 go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/__expect_failure diff --git a/go/mysql/constants.go b/go/mysql/constants.go index b2d4c86db1d..726ec00b76e 100644 --- a/go/mysql/constants.go +++ b/go/mysql/constants.go @@ -16,7 +16,13 @@ limitations under the License. package mysql -import "strings" +import ( + "strings" + + "golang.org/x/text/encoding" + "golang.org/x/text/encoding/charmap" + "golang.org/x/text/encoding/simplifiedchinese" +) const ( // MaxPacketSize is the maximum payload length of a packet @@ -626,6 +632,32 @@ var CharacterSetMap = map[string]uint8{ "eucjpms": 97, } +// CharacterSetEncoding maps a charset name to a golang encoder. +// golang does not support encoders for all MySQL charsets. +// A charset not in this map is unsupported. +// A trivial encoding (e.g. utf8) has a `nil` encoder +var CharacterSetEncoding = map[string]encoding.Encoding{ + "cp850": charmap.CodePage850, + "koi8r": charmap.KOI8R, + "latin1": charmap.Windows1252, + "latin2": charmap.ISO8859_2, + "ascii": nil, + "hebrew": charmap.ISO8859_8, + "greek": charmap.ISO8859_7, + "cp1250": charmap.Windows1250, + "gbk": simplifiedchinese.GBK, + "latin5": charmap.ISO8859_9, + "utf8": nil, + "cp866": charmap.CodePage866, + "cp852": charmap.CodePage852, + "latin7": charmap.ISO8859_13, + "utf8mb4": nil, + "cp1251": charmap.Windows1251, + "cp1256": charmap.Windows1256, + "cp1257": charmap.Windows1257, + "binary": nil, +} + // ReverseCharacterSetMap maps a charset integer code to charset name var ReverseCharacterSetMap = map[uint8]string{} diff --git a/go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/alter b/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8-80/alter similarity index 100% rename from go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/alter rename to go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8-80/alter diff --git a/go/test/endtoend/onlineddl/vrepl_suite/untestdata/alter-charset-all-dml/create.sql b/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8-80/create.sql similarity index 50% rename from go/test/endtoend/onlineddl/vrepl_suite/untestdata/alter-charset-all-dml/create.sql rename to go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8-80/create.sql index c55c793ee1d..6f97756291b 100644 --- a/go/test/endtoend/onlineddl/vrepl_suite/untestdata/alter-charset-all-dml/create.sql +++ b/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8-80/create.sql @@ -5,10 +5,14 @@ create table onlineddl_test ( t2 varchar(128) charset latin1 collate latin1_swedish_ci, tutf8 varchar(128) charset utf8, tutf8mb4 varchar(128) charset utf8mb4, - random_value varchar(128) charset ascii, + tlatin1 varchar(128) charset latin1 collate latin1_swedish_ci, primary key(id) ) auto_increment=1; +insert into onlineddl_test values (null, md5(rand()), md5(rand()), md5(rand()), md5(rand()), md5(rand())); +insert into onlineddl_test values (null, 'átesting', 'átesting', 'átesting', 'átesting', 'átesting'); +insert into onlineddl_test values (null, 'testátest', 'testátest', 'testátest', '🍻😀', 'átesting'); + drop event if exists onlineddl_test; delimiter ;; create event onlineddl_test @@ -20,9 +24,6 @@ create event onlineddl_test do begin insert into onlineddl_test values (null, md5(rand()), md5(rand()), md5(rand()), md5(rand()), md5(rand())); - insert into onlineddl_test values (null, 'átesting', 'átesting', 'átesting', 'átesting', md5(rand())); - insert into onlineddl_test values (null, 'átesting_del', 'átesting', 'átesting', 'átesting', md5(rand())); - insert into onlineddl_test values (null, 'testátest', 'testátest', 'testátest', '🍻😀', md5(rand())); - update onlineddl_test set t1='átesting2' where t1='átesting' order by id desc limit 1; - delete from onlineddl_test where t1='átesting_del' order by id desc limit 1; + insert into onlineddl_test values (null, 'átesting-binlog', 'átesting-binlog', 'átesting-binlog', 'átesting-binlog', 'átesting-binlog'); + insert into onlineddl_test values (null, 'testátest-binlog', 'testátest-binlog', 'testátest-binlog', '🍻😀', 'átesting-binlog'); end ;; diff --git a/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8-80/ignore_versions b/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8-80/ignore_versions new file mode 100644 index 00000000000..0790a1e68fd --- /dev/null +++ b/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8-80/ignore_versions @@ -0,0 +1 @@ +(5.5|5.6|5.7) diff --git a/go/test/endtoend/onlineddl/vrepl_suite/untestdata/alter-charset-all-dml/alter b/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8/alter similarity index 100% rename from go/test/endtoend/onlineddl/vrepl_suite/untestdata/alter-charset-all-dml/alter rename to go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8/alter diff --git a/go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/create.sql b/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8/create.sql similarity index 57% rename from go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/create.sql rename to go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8/create.sql index 9db84563248..d0d19253449 100644 --- a/go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/create.sql +++ b/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8/create.sql @@ -5,9 +5,13 @@ create table onlineddl_test ( t2 varchar(128) charset latin1 collate latin1_swedish_ci, tutf8 varchar(128) charset utf8, tutf8mb4 varchar(128) charset utf8mb4, + tlatin1 varchar(128) charset latin1 collate latin1_swedish_ci, primary key(id) ) auto_increment=1; +insert into onlineddl_test values (null, md5(rand()), md5(rand()), md5(rand()), md5(rand()), md5(rand())); +insert into onlineddl_test values (null, 'átesting', 'átesting', 'átesting', 'átesting', 'átesting'); + drop event if exists onlineddl_test; delimiter ;; create event onlineddl_test @@ -18,7 +22,6 @@ create event onlineddl_test enable do begin - insert into onlineddl_test values (null, md5(rand()), md5(rand()), md5(rand()), md5(rand())); - insert into onlineddl_test values (null, 'átesting', 'átesting', 'átesting', 'átesting'); - insert into onlineddl_test values (null, 'testátest', 'testátest', 'testátest', '🍻😀'); + insert into onlineddl_test values (null, md5(rand()), md5(rand()), md5(rand()), md5(rand()), md5(rand())); + insert into onlineddl_test values (null, 'átesting-binlog', 'átesting-binlog', 'átesting-binlog', 'átesting-binlog', 'átesting-binlog'); end ;; diff --git a/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8/ignore_versions b/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8/ignore_versions new file mode 100644 index 00000000000..b6de5f8d9f5 --- /dev/null +++ b/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8/ignore_versions @@ -0,0 +1 @@ +(5.5|5.6) diff --git a/go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/__expect_failure b/go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/__expect_failure deleted file mode 100644 index 925d0d81ded..00000000000 --- a/go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/__expect_failure +++ /dev/null @@ -1 +0,0 @@ -Vitess does not support charset diff --git a/go/vt/proto/binlogdata/binlogdata.pb.go b/go/vt/proto/binlogdata/binlogdata.pb.go index af9c9f9580c..4f58f679bd1 100644 --- a/go/vt/proto/binlogdata/binlogdata.pb.go +++ b/go/vt/proto/binlogdata/binlogdata.pb.go @@ -366,7 +366,7 @@ func (x Filter_FieldEventMode) Number() protoreflect.EnumNumber { // Deprecated: Use Filter_FieldEventMode.Descriptor instead. func (Filter_FieldEventMode) EnumDescriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{7, 0} + return file_binlogdata_proto_rawDescGZIP(), []int{8, 0} } // Charset is the per-statement charset info from a QUERY_EVENT binlog entry. @@ -725,6 +725,64 @@ func (x *StreamTablesResponse) GetBinlogTransaction() *BinlogTransaction { return nil } +// CharsetConversion represent a conversion of text from one charset to another +type CharsetConversion struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // FromCharset is the charset name from which we convert the text (e.g. latin1) + FromCharset string `protobuf:"bytes,1,opt,name=from_charset,json=fromCharset,proto3" json:"from_charset,omitempty"` + // ToCharset is the charset name to which we convert the text (e.g. utf8mb4) + ToCharset string `protobuf:"bytes,2,opt,name=to_charset,json=toCharset,proto3" json:"to_charset,omitempty"` +} + +func (x *CharsetConversion) Reset() { + *x = CharsetConversion{} + if protoimpl.UnsafeEnabled { + mi := &file_binlogdata_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CharsetConversion) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CharsetConversion) ProtoMessage() {} + +func (x *CharsetConversion) ProtoReflect() protoreflect.Message { + mi := &file_binlogdata_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CharsetConversion.ProtoReflect.Descriptor instead. +func (*CharsetConversion) Descriptor() ([]byte, []int) { + return file_binlogdata_proto_rawDescGZIP(), []int{6} +} + +func (x *CharsetConversion) GetFromCharset() string { + if x != nil { + return x.FromCharset + } + return "" +} + +func (x *CharsetConversion) GetToCharset() string { + if x != nil { + return x.ToCharset + } + return "" +} + // Rule represents one rule in a Filter. type Rule struct { state protoimpl.MessageState @@ -751,13 +809,14 @@ type Rule struct { // "exclude" value, which will cause the matched tables // to be excluded. // TODO(sougou): support this on vstreamer side also. - Filter string `protobuf:"bytes,2,opt,name=filter,proto3" json:"filter,omitempty"` + Filter string `protobuf:"bytes,2,opt,name=filter,proto3" json:"filter,omitempty"` + ConvertCharset map[string]*CharsetConversion `protobuf:"bytes,3,rep,name=convert_charset,json=convertCharset,proto3" json:"convert_charset,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } func (x *Rule) Reset() { *x = Rule{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[6] + mi := &file_binlogdata_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -770,7 +829,7 @@ func (x *Rule) String() string { func (*Rule) ProtoMessage() {} func (x *Rule) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[6] + mi := &file_binlogdata_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -783,7 +842,7 @@ func (x *Rule) ProtoReflect() protoreflect.Message { // Deprecated: Use Rule.ProtoReflect.Descriptor instead. func (*Rule) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{6} + return file_binlogdata_proto_rawDescGZIP(), []int{7} } func (x *Rule) GetMatch() string { @@ -800,6 +859,13 @@ func (x *Rule) GetFilter() string { return "" } +func (x *Rule) GetConvertCharset() map[string]*CharsetConversion { + if x != nil { + return x.ConvertCharset + } + return nil +} + // Filter represents a list of ordered rules. The first // match wins. type Filter struct { @@ -822,7 +888,7 @@ type Filter struct { func (x *Filter) Reset() { *x = Filter{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[7] + mi := &file_binlogdata_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -835,7 +901,7 @@ func (x *Filter) String() string { func (*Filter) ProtoMessage() {} func (x *Filter) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[7] + mi := &file_binlogdata_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -848,7 +914,7 @@ func (x *Filter) ProtoReflect() protoreflect.Message { // Deprecated: Use Filter.ProtoReflect.Descriptor instead. func (*Filter) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{7} + return file_binlogdata_proto_rawDescGZIP(), []int{8} } func (x *Filter) GetRules() []*Rule { @@ -902,7 +968,7 @@ type BinlogSource struct { func (x *BinlogSource) Reset() { *x = BinlogSource{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[8] + mi := &file_binlogdata_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -915,7 +981,7 @@ func (x *BinlogSource) String() string { func (*BinlogSource) ProtoMessage() {} func (x *BinlogSource) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[8] + mi := &file_binlogdata_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -928,7 +994,7 @@ func (x *BinlogSource) ProtoReflect() protoreflect.Message { // Deprecated: Use BinlogSource.ProtoReflect.Descriptor instead. func (*BinlogSource) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{8} + return file_binlogdata_proto_rawDescGZIP(), []int{9} } func (x *BinlogSource) GetKeyspace() string { @@ -1017,7 +1083,7 @@ type RowChange struct { func (x *RowChange) Reset() { *x = RowChange{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[9] + mi := &file_binlogdata_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1030,7 +1096,7 @@ func (x *RowChange) String() string { func (*RowChange) ProtoMessage() {} func (x *RowChange) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[9] + mi := &file_binlogdata_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1043,7 +1109,7 @@ func (x *RowChange) ProtoReflect() protoreflect.Message { // Deprecated: Use RowChange.ProtoReflect.Descriptor instead. func (*RowChange) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{9} + return file_binlogdata_proto_rawDescGZIP(), []int{10} } func (x *RowChange) GetBefore() *query.Row { @@ -1073,7 +1139,7 @@ type RowEvent struct { func (x *RowEvent) Reset() { *x = RowEvent{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[10] + mi := &file_binlogdata_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1086,7 +1152,7 @@ func (x *RowEvent) String() string { func (*RowEvent) ProtoMessage() {} func (x *RowEvent) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[10] + mi := &file_binlogdata_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1099,7 +1165,7 @@ func (x *RowEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use RowEvent.ProtoReflect.Descriptor instead. func (*RowEvent) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{10} + return file_binlogdata_proto_rawDescGZIP(), []int{11} } func (x *RowEvent) GetTableName() string { @@ -1129,7 +1195,7 @@ type FieldEvent struct { func (x *FieldEvent) Reset() { *x = FieldEvent{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[11] + mi := &file_binlogdata_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1142,7 +1208,7 @@ func (x *FieldEvent) String() string { func (*FieldEvent) ProtoMessage() {} func (x *FieldEvent) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[11] + mi := &file_binlogdata_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1155,7 +1221,7 @@ func (x *FieldEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use FieldEvent.ProtoReflect.Descriptor instead. func (*FieldEvent) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{11} + return file_binlogdata_proto_rawDescGZIP(), []int{12} } func (x *FieldEvent) GetTableName() string { @@ -1191,7 +1257,7 @@ type ShardGtid struct { func (x *ShardGtid) Reset() { *x = ShardGtid{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[12] + mi := &file_binlogdata_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1204,7 +1270,7 @@ func (x *ShardGtid) String() string { func (*ShardGtid) ProtoMessage() {} func (x *ShardGtid) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[12] + mi := &file_binlogdata_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1217,7 +1283,7 @@ func (x *ShardGtid) ProtoReflect() protoreflect.Message { // Deprecated: Use ShardGtid.ProtoReflect.Descriptor instead. func (*ShardGtid) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{12} + return file_binlogdata_proto_rawDescGZIP(), []int{13} } func (x *ShardGtid) GetKeyspace() string { @@ -1260,7 +1326,7 @@ type VGtid struct { func (x *VGtid) Reset() { *x = VGtid{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[13] + mi := &file_binlogdata_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1273,7 +1339,7 @@ func (x *VGtid) String() string { func (*VGtid) ProtoMessage() {} func (x *VGtid) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[13] + mi := &file_binlogdata_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1286,7 +1352,7 @@ func (x *VGtid) ProtoReflect() protoreflect.Message { // Deprecated: Use VGtid.ProtoReflect.Descriptor instead. func (*VGtid) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{13} + return file_binlogdata_proto_rawDescGZIP(), []int{14} } func (x *VGtid) GetShardGtids() []*ShardGtid { @@ -1309,7 +1375,7 @@ type KeyspaceShard struct { func (x *KeyspaceShard) Reset() { *x = KeyspaceShard{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[14] + mi := &file_binlogdata_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1322,7 +1388,7 @@ func (x *KeyspaceShard) String() string { func (*KeyspaceShard) ProtoMessage() {} func (x *KeyspaceShard) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[14] + mi := &file_binlogdata_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1335,7 +1401,7 @@ func (x *KeyspaceShard) ProtoReflect() protoreflect.Message { // Deprecated: Use KeyspaceShard.ProtoReflect.Descriptor instead. func (*KeyspaceShard) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{14} + return file_binlogdata_proto_rawDescGZIP(), []int{15} } func (x *KeyspaceShard) GetKeyspace() string { @@ -1387,7 +1453,7 @@ type Journal struct { func (x *Journal) Reset() { *x = Journal{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[15] + mi := &file_binlogdata_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1400,7 +1466,7 @@ func (x *Journal) String() string { func (*Journal) ProtoMessage() {} func (x *Journal) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[15] + mi := &file_binlogdata_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1413,7 +1479,7 @@ func (x *Journal) ProtoReflect() protoreflect.Message { // Deprecated: Use Journal.ProtoReflect.Descriptor instead. func (*Journal) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{15} + return file_binlogdata_proto_rawDescGZIP(), []int{16} } func (x *Journal) GetId() int64 { @@ -1507,7 +1573,7 @@ type VEvent struct { func (x *VEvent) Reset() { *x = VEvent{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[16] + mi := &file_binlogdata_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1520,7 +1586,7 @@ func (x *VEvent) String() string { func (*VEvent) ProtoMessage() {} func (x *VEvent) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[16] + mi := &file_binlogdata_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1533,7 +1599,7 @@ func (x *VEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use VEvent.ProtoReflect.Descriptor instead. func (*VEvent) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{16} + return file_binlogdata_proto_rawDescGZIP(), []int{17} } func (x *VEvent) GetType() VEventType { @@ -1626,7 +1692,7 @@ type MinimalTable struct { func (x *MinimalTable) Reset() { *x = MinimalTable{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[17] + mi := &file_binlogdata_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1639,7 +1705,7 @@ func (x *MinimalTable) String() string { func (*MinimalTable) ProtoMessage() {} func (x *MinimalTable) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[17] + mi := &file_binlogdata_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1652,7 +1718,7 @@ func (x *MinimalTable) ProtoReflect() protoreflect.Message { // Deprecated: Use MinimalTable.ProtoReflect.Descriptor instead. func (*MinimalTable) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{17} + return file_binlogdata_proto_rawDescGZIP(), []int{18} } func (x *MinimalTable) GetName() string { @@ -1687,7 +1753,7 @@ type MinimalSchema struct { func (x *MinimalSchema) Reset() { *x = MinimalSchema{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[18] + mi := &file_binlogdata_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1700,7 +1766,7 @@ func (x *MinimalSchema) String() string { func (*MinimalSchema) ProtoMessage() {} func (x *MinimalSchema) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[18] + mi := &file_binlogdata_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1713,7 +1779,7 @@ func (x *MinimalSchema) ProtoReflect() protoreflect.Message { // Deprecated: Use MinimalSchema.ProtoReflect.Descriptor instead. func (*MinimalSchema) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{18} + return file_binlogdata_proto_rawDescGZIP(), []int{19} } func (x *MinimalSchema) GetTables() []*MinimalTable { @@ -1740,7 +1806,7 @@ type VStreamRequest struct { func (x *VStreamRequest) Reset() { *x = VStreamRequest{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[19] + mi := &file_binlogdata_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1753,7 +1819,7 @@ func (x *VStreamRequest) String() string { func (*VStreamRequest) ProtoMessage() {} func (x *VStreamRequest) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[19] + mi := &file_binlogdata_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1766,7 +1832,7 @@ func (x *VStreamRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use VStreamRequest.ProtoReflect.Descriptor instead. func (*VStreamRequest) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{19} + return file_binlogdata_proto_rawDescGZIP(), []int{20} } func (x *VStreamRequest) GetEffectiveCallerId() *vtrpc.CallerID { @@ -1823,7 +1889,7 @@ type VStreamResponse struct { func (x *VStreamResponse) Reset() { *x = VStreamResponse{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[20] + mi := &file_binlogdata_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1836,7 +1902,7 @@ func (x *VStreamResponse) String() string { func (*VStreamResponse) ProtoMessage() {} func (x *VStreamResponse) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[20] + mi := &file_binlogdata_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1849,7 +1915,7 @@ func (x *VStreamResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use VStreamResponse.ProtoReflect.Descriptor instead. func (*VStreamResponse) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{20} + return file_binlogdata_proto_rawDescGZIP(), []int{21} } func (x *VStreamResponse) GetEvents() []*VEvent { @@ -1875,7 +1941,7 @@ type VStreamRowsRequest struct { func (x *VStreamRowsRequest) Reset() { *x = VStreamRowsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[21] + mi := &file_binlogdata_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1888,7 +1954,7 @@ func (x *VStreamRowsRequest) String() string { func (*VStreamRowsRequest) ProtoMessage() {} func (x *VStreamRowsRequest) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[21] + mi := &file_binlogdata_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1901,7 +1967,7 @@ func (x *VStreamRowsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use VStreamRowsRequest.ProtoReflect.Descriptor instead. func (*VStreamRowsRequest) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{21} + return file_binlogdata_proto_rawDescGZIP(), []int{22} } func (x *VStreamRowsRequest) GetEffectiveCallerId() *vtrpc.CallerID { @@ -1955,7 +2021,7 @@ type VStreamRowsResponse struct { func (x *VStreamRowsResponse) Reset() { *x = VStreamRowsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[22] + mi := &file_binlogdata_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1968,7 +2034,7 @@ func (x *VStreamRowsResponse) String() string { func (*VStreamRowsResponse) ProtoMessage() {} func (x *VStreamRowsResponse) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[22] + mi := &file_binlogdata_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1981,7 +2047,7 @@ func (x *VStreamRowsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use VStreamRowsResponse.ProtoReflect.Descriptor instead. func (*VStreamRowsResponse) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{22} + return file_binlogdata_proto_rawDescGZIP(), []int{23} } func (x *VStreamRowsResponse) GetFields() []*query.Field { @@ -2031,7 +2097,7 @@ type LastPKEvent struct { func (x *LastPKEvent) Reset() { *x = LastPKEvent{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[23] + mi := &file_binlogdata_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2044,7 +2110,7 @@ func (x *LastPKEvent) String() string { func (*LastPKEvent) ProtoMessage() {} func (x *LastPKEvent) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[23] + mi := &file_binlogdata_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2057,7 +2123,7 @@ func (x *LastPKEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use LastPKEvent.ProtoReflect.Descriptor instead. func (*LastPKEvent) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{23} + return file_binlogdata_proto_rawDescGZIP(), []int{24} } func (x *LastPKEvent) GetTableLastPK() *TableLastPK { @@ -2086,7 +2152,7 @@ type TableLastPK struct { func (x *TableLastPK) Reset() { *x = TableLastPK{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[24] + mi := &file_binlogdata_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2099,7 +2165,7 @@ func (x *TableLastPK) String() string { func (*TableLastPK) ProtoMessage() {} func (x *TableLastPK) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[24] + mi := &file_binlogdata_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2112,7 +2178,7 @@ func (x *TableLastPK) ProtoReflect() protoreflect.Message { // Deprecated: Use TableLastPK.ProtoReflect.Descriptor instead. func (*TableLastPK) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{24} + return file_binlogdata_proto_rawDescGZIP(), []int{25} } func (x *TableLastPK) GetTableName() string { @@ -2146,7 +2212,7 @@ type VStreamResultsRequest struct { func (x *VStreamResultsRequest) Reset() { *x = VStreamResultsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[25] + mi := &file_binlogdata_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2159,7 +2225,7 @@ func (x *VStreamResultsRequest) String() string { func (*VStreamResultsRequest) ProtoMessage() {} func (x *VStreamResultsRequest) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[25] + mi := &file_binlogdata_proto_msgTypes[26] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2172,7 +2238,7 @@ func (x *VStreamResultsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use VStreamResultsRequest.ProtoReflect.Descriptor instead. func (*VStreamResultsRequest) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{25} + return file_binlogdata_proto_rawDescGZIP(), []int{26} } func (x *VStreamResultsRequest) GetEffectiveCallerId() *vtrpc.CallerID { @@ -2218,7 +2284,7 @@ type VStreamResultsResponse struct { func (x *VStreamResultsResponse) Reset() { *x = VStreamResultsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[26] + mi := &file_binlogdata_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2231,7 +2297,7 @@ func (x *VStreamResultsResponse) String() string { func (*VStreamResultsResponse) ProtoMessage() {} func (x *VStreamResultsResponse) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[26] + mi := &file_binlogdata_proto_msgTypes[27] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2244,7 +2310,7 @@ func (x *VStreamResultsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use VStreamResultsResponse.ProtoReflect.Descriptor instead. func (*VStreamResultsResponse) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{26} + return file_binlogdata_proto_rawDescGZIP(), []int{27} } func (x *VStreamResultsResponse) GetFields() []*query.Field { @@ -2284,7 +2350,7 @@ type BinlogTransaction_Statement struct { func (x *BinlogTransaction_Statement) Reset() { *x = BinlogTransaction_Statement{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[27] + mi := &file_binlogdata_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2297,7 +2363,7 @@ func (x *BinlogTransaction_Statement) String() string { func (*BinlogTransaction_Statement) ProtoMessage() {} func (x *BinlogTransaction_Statement) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[27] + mi := &file_binlogdata_proto_msgTypes[28] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2406,252 +2472,268 @@ var file_binlogdata_proto_rawDesc = []byte{ 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x42, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x11, 0x62, 0x69, 0x6e, 0x6c, - 0x6f, 0x67, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x34, 0x0a, - 0x04, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x66, - 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, 0x6c, - 0x74, 0x65, 0x72, 0x22, 0xb3, 0x01, 0x0a, 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x26, - 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, - 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x75, 0x6c, 0x65, 0x52, - 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x49, 0x0a, 0x0e, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x21, - 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x69, 0x6c, 0x74, - 0x65, 0x72, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x64, - 0x65, 0x52, 0x0e, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x64, - 0x65, 0x22, 0x36, 0x0a, 0x0e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, - 0x6f, 0x64, 0x65, 0x12, 0x13, 0x0a, 0x0f, 0x45, 0x52, 0x52, 0x5f, 0x4f, 0x4e, 0x5f, 0x4d, 0x49, - 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x42, 0x45, 0x53, 0x54, - 0x5f, 0x45, 0x46, 0x46, 0x4f, 0x52, 0x54, 0x10, 0x01, 0x22, 0x96, 0x03, 0x0a, 0x0c, 0x42, 0x69, - 0x6e, 0x6c, 0x6f, 0x67, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x35, 0x0a, 0x0b, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, - 0x79, 0x70, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x52, - 0x61, 0x6e, 0x67, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x05, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x06, - 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x62, - 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, - 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x2e, 0x0a, 0x06, 0x6f, 0x6e, 0x5f, 0x64, - 0x64, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, - 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4f, 0x6e, 0x44, 0x44, 0x4c, 0x41, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x05, 0x6f, 0x6e, 0x44, 0x64, 0x6c, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x74, 0x65, - 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0d, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x4d, 0x79, 0x73, 0x71, 0x6c, 0x12, - 0x26, 0x0a, 0x0f, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x6f, - 0x70, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x70, 0x41, 0x66, - 0x74, 0x65, 0x72, 0x43, 0x6f, 0x70, 0x79, 0x12, 0x29, 0x0a, 0x10, 0x65, 0x78, 0x74, 0x65, 0x72, - 0x6e, 0x61, 0x6c, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0f, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x6c, 0x75, 0x73, 0x74, - 0x65, 0x72, 0x22, 0x51, 0x0a, 0x09, 0x52, 0x6f, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, - 0x22, 0x0a, 0x06, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x0a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x06, 0x62, 0x65, 0x66, - 0x6f, 0x72, 0x65, 0x12, 0x20, 0x0a, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x05, - 0x61, 0x66, 0x74, 0x65, 0x72, 0x22, 0x61, 0x0a, 0x08, 0x52, 0x6f, 0x77, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, - 0x12, 0x36, 0x0a, 0x0b, 0x72, 0x6f, 0x77, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x52, 0x6f, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x0a, 0x72, 0x6f, - 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x22, 0x51, 0x0a, 0x0a, 0x46, 0x69, 0x65, 0x6c, - 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, - 0x65, 0x6c, 0x64, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x22, 0x88, 0x01, 0x0a, 0x09, - 0x53, 0x68, 0x61, 0x72, 0x64, 0x47, 0x74, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x67, - 0x74, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x67, 0x74, 0x69, 0x64, 0x12, - 0x35, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x70, 0x5f, 0x6b, 0x73, 0x18, 0x04, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x52, 0x08, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x50, 0x4b, 0x73, 0x22, 0x3f, 0x0a, 0x05, 0x56, 0x47, 0x74, 0x69, 0x64, 0x12, - 0x36, 0x0a, 0x0b, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x67, 0x74, 0x69, 0x64, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x47, 0x74, 0x69, 0x64, 0x52, 0x0a, 0x73, 0x68, 0x61, - 0x72, 0x64, 0x47, 0x74, 0x69, 0x64, 0x73, 0x22, 0x41, 0x0a, 0x0d, 0x4b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x22, 0xbc, 0x02, 0x0a, 0x07, 0x4a, - 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x40, 0x0a, 0x0e, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, - 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x69, 0x67, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0d, 0x6d, 0x69, 0x67, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, - 0x12, 0x25, 0x0a, 0x0e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x50, - 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x36, 0x0a, 0x0b, 0x73, 0x68, 0x61, 0x72, 0x64, - 0x5f, 0x67, 0x74, 0x69, 0x64, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x62, - 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x47, - 0x74, 0x69, 0x64, 0x52, 0x0a, 0x73, 0x68, 0x61, 0x72, 0x64, 0x47, 0x74, 0x69, 0x64, 0x73, 0x12, - 0x3d, 0x0a, 0x0c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x18, - 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, - 0x52, 0x0c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x29, - 0x0a, 0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, - 0x77, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x22, 0xbb, 0x03, 0x0a, 0x06, 0x56, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x56, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, - 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x12, - 0x0a, 0x04, 0x67, 0x74, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x67, 0x74, - 0x69, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, - 0x12, 0x31, 0x0a, 0x09, 0x72, 0x6f, 0x77, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x52, 0x6f, 0x77, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x08, 0x72, 0x6f, 0x77, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x12, 0x37, 0x0a, 0x0b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x65, 0x76, 0x65, - 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, - 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x52, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x27, 0x0a, 0x05, - 0x76, 0x67, 0x74, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x62, 0x69, - 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x47, 0x74, 0x69, 0x64, 0x52, 0x05, - 0x76, 0x67, 0x74, 0x69, 0x64, 0x12, 0x2d, 0x0a, 0x07, 0x6a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, - 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x52, 0x07, 0x6a, 0x6f, 0x75, - 0x72, 0x6e, 0x61, 0x6c, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x6d, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x64, 0x6d, 0x6c, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, - 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x63, 0x75, - 0x72, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x3c, 0x0a, 0x0e, 0x6c, 0x61, 0x73, - 0x74, 0x5f, 0x70, 0x5f, 0x6b, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x15, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x17, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, - 0x61, 0x73, 0x74, 0x50, 0x4b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x0b, 0x6c, 0x61, 0x73, 0x74, - 0x50, 0x4b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x68, 0x0a, 0x0c, 0x4d, 0x69, 0x6e, 0x69, 0x6d, - 0x61, 0x6c, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x06, 0x66, - 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, 0x75, - 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, - 0x73, 0x12, 0x1e, 0x0a, 0x0b, 0x70, 0x5f, 0x6b, 0x5f, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, - 0x18, 0x03, 0x20, 0x03, 0x28, 0x03, 0x52, 0x09, 0x70, 0x4b, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, - 0x73, 0x22, 0x41, 0x0a, 0x0d, 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x53, 0x63, 0x68, 0x65, - 0x6d, 0x61, 0x12, 0x30, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x06, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x73, 0x22, 0xc7, 0x02, 0x0a, 0x0e, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, - 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, - 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, - 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, - 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, - 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, - 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, - 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, - 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x2a, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x3e, - 0x0a, 0x0f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x5f, 0x6b, - 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, - 0x52, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x73, 0x22, 0x3d, - 0x0a, 0x0f, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x12, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x85, 0x02, - 0x0a, 0x12, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, - 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, - 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, - 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, - 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, - 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, - 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, - 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, - 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, - 0x67, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2a, 0x0a, 0x06, 0x6c, 0x61, 0x73, - 0x74, 0x70, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, - 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x6c, - 0x61, 0x73, 0x74, 0x70, 0x6b, 0x22, 0xbd, 0x01, 0x0a, 0x13, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x52, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, - 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, - 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x06, 0x66, 0x69, 0x65, - 0x6c, 0x64, 0x73, 0x12, 0x28, 0x0a, 0x08, 0x70, 0x6b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, - 0x65, 0x6c, 0x64, 0x52, 0x08, 0x70, 0x6b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x12, 0x0a, - 0x04, 0x67, 0x74, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x67, 0x74, 0x69, - 0x64, 0x12, 0x1e, 0x0a, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x0a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x04, 0x72, 0x6f, 0x77, - 0x73, 0x12, 0x22, 0x0a, 0x06, 0x6c, 0x61, 0x73, 0x74, 0x70, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x06, 0x6c, - 0x61, 0x73, 0x74, 0x70, 0x6b, 0x22, 0x69, 0x0a, 0x0b, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x12, 0x3c, 0x0a, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6c, 0x61, - 0x73, 0x74, 0x5f, 0x70, 0x5f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x62, - 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x4c, - 0x61, 0x73, 0x74, 0x50, 0x4b, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, - 0x50, 0x4b, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, - 0x22, 0x58, 0x0a, 0x0b, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x12, + 0x6f, 0x67, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x55, 0x0a, + 0x11, 0x43, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x63, 0x68, 0x61, 0x72, 0x73, + 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x66, 0x72, 0x6f, 0x6d, 0x43, 0x68, + 0x61, 0x72, 0x73, 0x65, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x5f, 0x63, 0x68, 0x61, 0x72, + 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x6f, 0x43, 0x68, 0x61, + 0x72, 0x73, 0x65, 0x74, 0x22, 0xe5, 0x01, 0x0a, 0x04, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x14, 0x0a, + 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x61, + 0x74, 0x63, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x4d, 0x0a, 0x0f, 0x63, + 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x5f, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x18, 0x03, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x52, 0x75, 0x6c, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x43, 0x68, + 0x61, 0x72, 0x73, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x76, + 0x65, 0x72, 0x74, 0x43, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x1a, 0x60, 0x0a, 0x13, 0x43, 0x6f, + 0x6e, 0x76, 0x65, 0x72, 0x74, 0x43, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x12, 0x33, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x43, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xb3, 0x01, 0x0a, + 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x26, 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x12, + 0x49, 0x0a, 0x0e, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x64, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x2e, 0x46, 0x69, 0x65, 0x6c, + 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x0e, 0x66, 0x69, 0x65, 0x6c, + 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x22, 0x36, 0x0a, 0x0e, 0x46, 0x69, + 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x13, 0x0a, 0x0f, + 0x45, 0x52, 0x52, 0x5f, 0x4f, 0x4e, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, + 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x42, 0x45, 0x53, 0x54, 0x5f, 0x45, 0x46, 0x46, 0x4f, 0x52, 0x54, + 0x10, 0x01, 0x22, 0x96, 0x03, 0x0a, 0x0c, 0x42, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x53, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, + 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x35, 0x0a, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, + 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, + 0x52, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x2f, 0x0a, 0x09, + 0x6b, 0x65, 0x79, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x12, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x61, + 0x6e, 0x67, 0x65, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x16, 0x0a, + 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x12, 0x2e, 0x0a, 0x06, 0x6f, 0x6e, 0x5f, 0x64, 0x64, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x17, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4f, + 0x6e, 0x44, 0x44, 0x4c, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x6f, 0x6e, 0x44, 0x64, + 0x6c, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x6d, 0x79, + 0x73, 0x71, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x78, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x6c, 0x4d, 0x79, 0x73, 0x71, 0x6c, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x74, 0x6f, 0x70, + 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x70, 0x41, 0x66, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x70, 0x79, + 0x12, 0x29, 0x0a, 0x10, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x63, 0x6c, 0x75, + 0x73, 0x74, 0x65, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x65, 0x78, 0x74, 0x65, + 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x22, 0x51, 0x0a, 0x09, 0x52, + 0x6f, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x22, 0x0a, 0x06, 0x62, 0x65, 0x66, 0x6f, + 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, + 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x06, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x12, 0x20, 0x0a, 0x05, + 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, + 0x65, 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x22, 0x61, + 0x0a, 0x08, 0x52, 0x6f, 0x77, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x36, 0x0a, 0x0b, 0x72, 0x6f, 0x77, + 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, + 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x6f, 0x77, 0x43, + 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x0a, 0x72, 0x6f, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x73, 0x22, 0x51, 0x0a, 0x0a, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2a, - 0x0a, 0x06, 0x6c, 0x61, 0x73, 0x74, 0x70, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, - 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x52, 0x06, 0x6c, 0x61, 0x73, 0x74, 0x70, 0x6b, 0x22, 0xdc, 0x01, 0x0a, 0x15, 0x56, - 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, - 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, - 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, - 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, - 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, - 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, - 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, - 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, - 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, - 0x67, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x22, 0x72, 0x0a, 0x16, 0x56, 0x53, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, - 0x64, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x67, 0x74, 0x69, - 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x67, 0x74, 0x69, 0x64, 0x12, 0x1e, 0x0a, - 0x04, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, - 0x65, 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x2a, 0x3e, 0x0a, - 0x0b, 0x4f, 0x6e, 0x44, 0x44, 0x4c, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0a, 0x0a, 0x06, - 0x49, 0x47, 0x4e, 0x4f, 0x52, 0x45, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x54, 0x4f, 0x50, - 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x45, 0x58, 0x45, 0x43, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, - 0x45, 0x58, 0x45, 0x43, 0x5f, 0x49, 0x47, 0x4e, 0x4f, 0x52, 0x45, 0x10, 0x03, 0x2a, 0xf9, 0x01, - 0x0a, 0x0a, 0x56, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, - 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x47, 0x54, 0x49, - 0x44, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x10, 0x02, 0x12, 0x0a, - 0x0a, 0x06, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, 0x10, 0x03, 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x4f, - 0x4c, 0x4c, 0x42, 0x41, 0x43, 0x4b, 0x10, 0x04, 0x12, 0x07, 0x0a, 0x03, 0x44, 0x44, 0x4c, 0x10, - 0x05, 0x12, 0x0a, 0x0a, 0x06, 0x49, 0x4e, 0x53, 0x45, 0x52, 0x54, 0x10, 0x06, 0x12, 0x0b, 0x0a, - 0x07, 0x52, 0x45, 0x50, 0x4c, 0x41, 0x43, 0x45, 0x10, 0x07, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x50, - 0x44, 0x41, 0x54, 0x45, 0x10, 0x08, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, - 0x10, 0x09, 0x12, 0x07, 0x0a, 0x03, 0x53, 0x45, 0x54, 0x10, 0x0a, 0x12, 0x09, 0x0a, 0x05, 0x4f, - 0x54, 0x48, 0x45, 0x52, 0x10, 0x0b, 0x12, 0x07, 0x0a, 0x03, 0x52, 0x4f, 0x57, 0x10, 0x0c, 0x12, - 0x09, 0x0a, 0x05, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x10, 0x0d, 0x12, 0x0d, 0x0a, 0x09, 0x48, 0x45, - 0x41, 0x52, 0x54, 0x42, 0x45, 0x41, 0x54, 0x10, 0x0e, 0x12, 0x09, 0x0a, 0x05, 0x56, 0x47, 0x54, - 0x49, 0x44, 0x10, 0x0f, 0x12, 0x0b, 0x0a, 0x07, 0x4a, 0x4f, 0x55, 0x52, 0x4e, 0x41, 0x4c, 0x10, - 0x10, 0x12, 0x0b, 0x0a, 0x07, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x11, 0x12, 0x0a, - 0x0a, 0x06, 0x4c, 0x41, 0x53, 0x54, 0x50, 0x4b, 0x10, 0x12, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x41, - 0x56, 0x45, 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x10, 0x13, 0x2a, 0x27, 0x0a, 0x0d, 0x4d, 0x69, 0x67, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x54, 0x41, - 0x42, 0x4c, 0x45, 0x53, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x48, 0x41, 0x52, 0x44, 0x53, - 0x10, 0x01, 0x42, 0x29, 0x5a, 0x27, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6f, 0x2f, - 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x74, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2f, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x24, + 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, + 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x06, 0x66, 0x69, + 0x65, 0x6c, 0x64, 0x73, 0x22, 0x88, 0x01, 0x0a, 0x09, 0x53, 0x68, 0x61, 0x72, 0x64, 0x47, 0x74, + 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, + 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, + 0x68, 0x61, 0x72, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x67, 0x74, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x67, 0x74, 0x69, 0x64, 0x12, 0x35, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x5f, 0x70, 0x5f, 0x6b, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x62, + 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x4c, + 0x61, 0x73, 0x74, 0x50, 0x4b, 0x52, 0x08, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x50, 0x4b, 0x73, 0x22, + 0x3f, 0x0a, 0x05, 0x56, 0x47, 0x74, 0x69, 0x64, 0x12, 0x36, 0x0a, 0x0b, 0x73, 0x68, 0x61, 0x72, + 0x64, 0x5f, 0x67, 0x74, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, + 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, + 0x47, 0x74, 0x69, 0x64, 0x52, 0x0a, 0x73, 0x68, 0x61, 0x72, 0x64, 0x47, 0x74, 0x69, 0x64, 0x73, + 0x22, 0x41, 0x0a, 0x0d, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, + 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, + 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, + 0x61, 0x72, 0x64, 0x22, 0xbc, 0x02, 0x0a, 0x07, 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x12, + 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, + 0x40, 0x0a, 0x0e, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, + 0x70, 0x65, 0x52, 0x0d, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x36, 0x0a, 0x0b, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x67, 0x74, 0x69, 0x64, 0x73, 0x18, + 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x47, 0x74, 0x69, 0x64, 0x52, 0x0a, 0x73, 0x68, + 0x61, 0x72, 0x64, 0x47, 0x74, 0x69, 0x64, 0x73, 0x12, 0x3d, 0x0a, 0x0c, 0x70, 0x61, 0x72, 0x74, + 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, + 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x0c, 0x70, 0x61, 0x72, 0x74, 0x69, + 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x0f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, + 0x77, 0x73, 0x22, 0xbb, 0x03, 0x0a, 0x06, 0x56, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2a, 0x0a, + 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x62, 0x69, + 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x67, 0x74, 0x69, 0x64, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x67, 0x74, 0x69, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x31, 0x0a, 0x09, 0x72, 0x6f, 0x77, + 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x62, + 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x6f, 0x77, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x52, 0x08, 0x72, 0x6f, 0x77, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x37, 0x0a, 0x0b, + 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x16, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, + 0x69, 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x27, 0x0a, 0x05, 0x76, 0x67, 0x74, 0x69, 0x64, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x56, 0x47, 0x74, 0x69, 0x64, 0x52, 0x05, 0x76, 0x67, 0x74, 0x69, 0x64, 0x12, 0x2d, + 0x0a, 0x07, 0x6a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x13, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4a, 0x6f, 0x75, + 0x72, 0x6e, 0x61, 0x6c, 0x52, 0x07, 0x6a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x12, 0x10, 0x0a, + 0x03, 0x64, 0x6d, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x6d, 0x6c, 0x12, + 0x21, 0x0a, 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, + 0x14, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x69, + 0x6d, 0x65, 0x12, 0x3c, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x5f, 0x6b, 0x5f, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x62, 0x69, 0x6e, + 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x52, 0x0b, 0x6c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x22, 0x68, 0x0a, 0x0c, 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, + 0x6c, 0x64, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x1e, 0x0a, 0x0b, 0x70, 0x5f, + 0x6b, 0x5f, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x03, 0x52, + 0x09, 0x70, 0x4b, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x22, 0x41, 0x0a, 0x0d, 0x4d, 0x69, + 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x30, 0x0a, 0x06, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x62, 0x69, + 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x61, 0x6c, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x22, 0xc7, 0x02, + 0x0a, 0x0e, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, + 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, + 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, + 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, + 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, + 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, + 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, + 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, + 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, + 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, + 0x1a, 0x0a, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x0a, 0x06, 0x66, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x62, 0x69, + 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, + 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x3e, 0x0a, 0x0f, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x5f, 0x6b, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x17, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x52, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x73, 0x22, 0x3d, 0x0a, 0x0f, 0x56, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x65, 0x76, + 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x62, 0x69, 0x6e, + 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x85, 0x02, 0x0a, 0x12, 0x56, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x52, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, + 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, + 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, + 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, + 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, + 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, + 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, + 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, + 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, + 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, + 0x72, 0x79, 0x12, 0x2a, 0x0a, 0x06, 0x6c, 0x61, 0x73, 0x74, 0x70, 0x6b, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x6c, 0x61, 0x73, 0x74, 0x70, 0x6b, 0x22, 0xbd, + 0x01, 0x0a, 0x13, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x6f, 0x77, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, + 0x69, 0x65, 0x6c, 0x64, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x28, 0x0a, 0x08, + 0x70, 0x6b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, + 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x08, 0x70, 0x6b, + 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x67, 0x74, 0x69, 0x64, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x67, 0x74, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x04, 0x72, 0x6f, + 0x77, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, + 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x12, 0x22, 0x0a, 0x06, 0x6c, 0x61, + 0x73, 0x74, 0x70, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, 0x65, + 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x06, 0x6c, 0x61, 0x73, 0x74, 0x70, 0x6b, 0x22, 0x69, + 0x0a, 0x0b, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x3c, 0x0a, + 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x5f, 0x6b, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x52, 0x0b, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x12, 0x1c, 0x0a, 0x09, 0x63, + 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, + 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x22, 0x58, 0x0a, 0x0b, 0x54, 0x61, 0x62, + 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x6c, 0x61, 0x73, 0x74, 0x70, + 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x6c, 0x61, 0x73, + 0x74, 0x70, 0x6b, 0x22, 0xdc, 0x01, 0x0a, 0x15, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, + 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, + 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, + 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, + 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, + 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, + 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, + 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, + 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, + 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, + 0x72, 0x79, 0x22, 0x72, 0x0a, 0x16, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x06, + 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, + 0x64, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x67, 0x74, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x67, 0x74, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x04, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, + 0x52, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x2a, 0x3e, 0x0a, 0x0b, 0x4f, 0x6e, 0x44, 0x44, 0x4c, 0x41, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0a, 0x0a, 0x06, 0x49, 0x47, 0x4e, 0x4f, 0x52, 0x45, 0x10, + 0x00, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x54, 0x4f, 0x50, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x45, + 0x58, 0x45, 0x43, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x45, 0x58, 0x45, 0x43, 0x5f, 0x49, 0x47, + 0x4e, 0x4f, 0x52, 0x45, 0x10, 0x03, 0x2a, 0xf9, 0x01, 0x0a, 0x0a, 0x56, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, + 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x47, 0x54, 0x49, 0x44, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, + 0x42, 0x45, 0x47, 0x49, 0x4e, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x4f, 0x4d, 0x4d, 0x49, + 0x54, 0x10, 0x03, 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x4f, 0x4c, 0x4c, 0x42, 0x41, 0x43, 0x4b, 0x10, + 0x04, 0x12, 0x07, 0x0a, 0x03, 0x44, 0x44, 0x4c, 0x10, 0x05, 0x12, 0x0a, 0x0a, 0x06, 0x49, 0x4e, + 0x53, 0x45, 0x52, 0x54, 0x10, 0x06, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x45, 0x50, 0x4c, 0x41, 0x43, + 0x45, 0x10, 0x07, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x10, 0x08, 0x12, + 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x09, 0x12, 0x07, 0x0a, 0x03, 0x53, + 0x45, 0x54, 0x10, 0x0a, 0x12, 0x09, 0x0a, 0x05, 0x4f, 0x54, 0x48, 0x45, 0x52, 0x10, 0x0b, 0x12, + 0x07, 0x0a, 0x03, 0x52, 0x4f, 0x57, 0x10, 0x0c, 0x12, 0x09, 0x0a, 0x05, 0x46, 0x49, 0x45, 0x4c, + 0x44, 0x10, 0x0d, 0x12, 0x0d, 0x0a, 0x09, 0x48, 0x45, 0x41, 0x52, 0x54, 0x42, 0x45, 0x41, 0x54, + 0x10, 0x0e, 0x12, 0x09, 0x0a, 0x05, 0x56, 0x47, 0x54, 0x49, 0x44, 0x10, 0x0f, 0x12, 0x0b, 0x0a, + 0x07, 0x4a, 0x4f, 0x55, 0x52, 0x4e, 0x41, 0x4c, 0x10, 0x10, 0x12, 0x0b, 0x0a, 0x07, 0x56, 0x45, + 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x11, 0x12, 0x0a, 0x0a, 0x06, 0x4c, 0x41, 0x53, 0x54, 0x50, + 0x4b, 0x10, 0x12, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x41, 0x56, 0x45, 0x50, 0x4f, 0x49, 0x4e, 0x54, + 0x10, 0x13, 0x2a, 0x27, 0x0a, 0x0d, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x53, 0x10, 0x00, 0x12, + 0x0a, 0x0a, 0x06, 0x53, 0x48, 0x41, 0x52, 0x44, 0x53, 0x10, 0x01, 0x42, 0x29, 0x5a, 0x27, 0x76, + 0x69, 0x74, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2f, + 0x67, 0x6f, 0x2f, 0x76, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x62, 0x69, 0x6e, 0x6c, + 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2667,7 +2749,7 @@ func file_binlogdata_proto_rawDescGZIP() []byte { } var file_binlogdata_proto_enumTypes = make([]protoimpl.EnumInfo, 5) -var file_binlogdata_proto_msgTypes = make([]protoimpl.MessageInfo, 28) +var file_binlogdata_proto_msgTypes = make([]protoimpl.MessageInfo, 30) var file_binlogdata_proto_goTypes = []interface{}{ (OnDDLAction)(0), // 0: binlogdata.OnDDLAction (VEventType)(0), // 1: binlogdata.VEventType @@ -2680,97 +2762,101 @@ var file_binlogdata_proto_goTypes = []interface{}{ (*StreamKeyRangeResponse)(nil), // 8: binlogdata.StreamKeyRangeResponse (*StreamTablesRequest)(nil), // 9: binlogdata.StreamTablesRequest (*StreamTablesResponse)(nil), // 10: binlogdata.StreamTablesResponse - (*Rule)(nil), // 11: binlogdata.Rule - (*Filter)(nil), // 12: binlogdata.Filter - (*BinlogSource)(nil), // 13: binlogdata.BinlogSource - (*RowChange)(nil), // 14: binlogdata.RowChange - (*RowEvent)(nil), // 15: binlogdata.RowEvent - (*FieldEvent)(nil), // 16: binlogdata.FieldEvent - (*ShardGtid)(nil), // 17: binlogdata.ShardGtid - (*VGtid)(nil), // 18: binlogdata.VGtid - (*KeyspaceShard)(nil), // 19: binlogdata.KeyspaceShard - (*Journal)(nil), // 20: binlogdata.Journal - (*VEvent)(nil), // 21: binlogdata.VEvent - (*MinimalTable)(nil), // 22: binlogdata.MinimalTable - (*MinimalSchema)(nil), // 23: binlogdata.MinimalSchema - (*VStreamRequest)(nil), // 24: binlogdata.VStreamRequest - (*VStreamResponse)(nil), // 25: binlogdata.VStreamResponse - (*VStreamRowsRequest)(nil), // 26: binlogdata.VStreamRowsRequest - (*VStreamRowsResponse)(nil), // 27: binlogdata.VStreamRowsResponse - (*LastPKEvent)(nil), // 28: binlogdata.LastPKEvent - (*TableLastPK)(nil), // 29: binlogdata.TableLastPK - (*VStreamResultsRequest)(nil), // 30: binlogdata.VStreamResultsRequest - (*VStreamResultsResponse)(nil), // 31: binlogdata.VStreamResultsResponse - (*BinlogTransaction_Statement)(nil), // 32: binlogdata.BinlogTransaction.Statement - (*query.EventToken)(nil), // 33: query.EventToken - (*topodata.KeyRange)(nil), // 34: topodata.KeyRange - (topodata.TabletType)(0), // 35: topodata.TabletType - (*query.Row)(nil), // 36: query.Row - (*query.Field)(nil), // 37: query.Field - (*vtrpc.CallerID)(nil), // 38: vtrpc.CallerID - (*query.VTGateCallerID)(nil), // 39: query.VTGateCallerID - (*query.Target)(nil), // 40: query.Target - (*query.QueryResult)(nil), // 41: query.QueryResult + (*CharsetConversion)(nil), // 11: binlogdata.CharsetConversion + (*Rule)(nil), // 12: binlogdata.Rule + (*Filter)(nil), // 13: binlogdata.Filter + (*BinlogSource)(nil), // 14: binlogdata.BinlogSource + (*RowChange)(nil), // 15: binlogdata.RowChange + (*RowEvent)(nil), // 16: binlogdata.RowEvent + (*FieldEvent)(nil), // 17: binlogdata.FieldEvent + (*ShardGtid)(nil), // 18: binlogdata.ShardGtid + (*VGtid)(nil), // 19: binlogdata.VGtid + (*KeyspaceShard)(nil), // 20: binlogdata.KeyspaceShard + (*Journal)(nil), // 21: binlogdata.Journal + (*VEvent)(nil), // 22: binlogdata.VEvent + (*MinimalTable)(nil), // 23: binlogdata.MinimalTable + (*MinimalSchema)(nil), // 24: binlogdata.MinimalSchema + (*VStreamRequest)(nil), // 25: binlogdata.VStreamRequest + (*VStreamResponse)(nil), // 26: binlogdata.VStreamResponse + (*VStreamRowsRequest)(nil), // 27: binlogdata.VStreamRowsRequest + (*VStreamRowsResponse)(nil), // 28: binlogdata.VStreamRowsResponse + (*LastPKEvent)(nil), // 29: binlogdata.LastPKEvent + (*TableLastPK)(nil), // 30: binlogdata.TableLastPK + (*VStreamResultsRequest)(nil), // 31: binlogdata.VStreamResultsRequest + (*VStreamResultsResponse)(nil), // 32: binlogdata.VStreamResultsResponse + (*BinlogTransaction_Statement)(nil), // 33: binlogdata.BinlogTransaction.Statement + nil, // 34: binlogdata.Rule.ConvertCharsetEntry + (*query.EventToken)(nil), // 35: query.EventToken + (*topodata.KeyRange)(nil), // 36: topodata.KeyRange + (topodata.TabletType)(0), // 37: topodata.TabletType + (*query.Row)(nil), // 38: query.Row + (*query.Field)(nil), // 39: query.Field + (*vtrpc.CallerID)(nil), // 40: vtrpc.CallerID + (*query.VTGateCallerID)(nil), // 41: query.VTGateCallerID + (*query.Target)(nil), // 42: query.Target + (*query.QueryResult)(nil), // 43: query.QueryResult } var file_binlogdata_proto_depIdxs = []int32{ - 32, // 0: binlogdata.BinlogTransaction.statements:type_name -> binlogdata.BinlogTransaction.Statement - 33, // 1: binlogdata.BinlogTransaction.event_token:type_name -> query.EventToken - 34, // 2: binlogdata.StreamKeyRangeRequest.key_range:type_name -> topodata.KeyRange + 33, // 0: binlogdata.BinlogTransaction.statements:type_name -> binlogdata.BinlogTransaction.Statement + 35, // 1: binlogdata.BinlogTransaction.event_token:type_name -> query.EventToken + 36, // 2: binlogdata.StreamKeyRangeRequest.key_range:type_name -> topodata.KeyRange 5, // 3: binlogdata.StreamKeyRangeRequest.charset:type_name -> binlogdata.Charset 6, // 4: binlogdata.StreamKeyRangeResponse.binlog_transaction:type_name -> binlogdata.BinlogTransaction 5, // 5: binlogdata.StreamTablesRequest.charset:type_name -> binlogdata.Charset 6, // 6: binlogdata.StreamTablesResponse.binlog_transaction:type_name -> binlogdata.BinlogTransaction - 11, // 7: binlogdata.Filter.rules:type_name -> binlogdata.Rule - 4, // 8: binlogdata.Filter.fieldEventMode:type_name -> binlogdata.Filter.FieldEventMode - 35, // 9: binlogdata.BinlogSource.tablet_type:type_name -> topodata.TabletType - 34, // 10: binlogdata.BinlogSource.key_range:type_name -> topodata.KeyRange - 12, // 11: binlogdata.BinlogSource.filter:type_name -> binlogdata.Filter - 0, // 12: binlogdata.BinlogSource.on_ddl:type_name -> binlogdata.OnDDLAction - 36, // 13: binlogdata.RowChange.before:type_name -> query.Row - 36, // 14: binlogdata.RowChange.after:type_name -> query.Row - 14, // 15: binlogdata.RowEvent.row_changes:type_name -> binlogdata.RowChange - 37, // 16: binlogdata.FieldEvent.fields:type_name -> query.Field - 29, // 17: binlogdata.ShardGtid.table_p_ks:type_name -> binlogdata.TableLastPK - 17, // 18: binlogdata.VGtid.shard_gtids:type_name -> binlogdata.ShardGtid - 2, // 19: binlogdata.Journal.migration_type:type_name -> binlogdata.MigrationType - 17, // 20: binlogdata.Journal.shard_gtids:type_name -> binlogdata.ShardGtid - 19, // 21: binlogdata.Journal.participants:type_name -> binlogdata.KeyspaceShard - 1, // 22: binlogdata.VEvent.type:type_name -> binlogdata.VEventType - 15, // 23: binlogdata.VEvent.row_event:type_name -> binlogdata.RowEvent - 16, // 24: binlogdata.VEvent.field_event:type_name -> binlogdata.FieldEvent - 18, // 25: binlogdata.VEvent.vgtid:type_name -> binlogdata.VGtid - 20, // 26: binlogdata.VEvent.journal:type_name -> binlogdata.Journal - 28, // 27: binlogdata.VEvent.last_p_k_event:type_name -> binlogdata.LastPKEvent - 37, // 28: binlogdata.MinimalTable.fields:type_name -> query.Field - 22, // 29: binlogdata.MinimalSchema.tables:type_name -> binlogdata.MinimalTable - 38, // 30: binlogdata.VStreamRequest.effective_caller_id:type_name -> vtrpc.CallerID - 39, // 31: binlogdata.VStreamRequest.immediate_caller_id:type_name -> query.VTGateCallerID - 40, // 32: binlogdata.VStreamRequest.target:type_name -> query.Target - 12, // 33: binlogdata.VStreamRequest.filter:type_name -> binlogdata.Filter - 29, // 34: binlogdata.VStreamRequest.table_last_p_ks:type_name -> binlogdata.TableLastPK - 21, // 35: binlogdata.VStreamResponse.events:type_name -> binlogdata.VEvent - 38, // 36: binlogdata.VStreamRowsRequest.effective_caller_id:type_name -> vtrpc.CallerID - 39, // 37: binlogdata.VStreamRowsRequest.immediate_caller_id:type_name -> query.VTGateCallerID - 40, // 38: binlogdata.VStreamRowsRequest.target:type_name -> query.Target - 41, // 39: binlogdata.VStreamRowsRequest.lastpk:type_name -> query.QueryResult - 37, // 40: binlogdata.VStreamRowsResponse.fields:type_name -> query.Field - 37, // 41: binlogdata.VStreamRowsResponse.pkfields:type_name -> query.Field - 36, // 42: binlogdata.VStreamRowsResponse.rows:type_name -> query.Row - 36, // 43: binlogdata.VStreamRowsResponse.lastpk:type_name -> query.Row - 29, // 44: binlogdata.LastPKEvent.table_last_p_k:type_name -> binlogdata.TableLastPK - 41, // 45: binlogdata.TableLastPK.lastpk:type_name -> query.QueryResult - 38, // 46: binlogdata.VStreamResultsRequest.effective_caller_id:type_name -> vtrpc.CallerID - 39, // 47: binlogdata.VStreamResultsRequest.immediate_caller_id:type_name -> query.VTGateCallerID - 40, // 48: binlogdata.VStreamResultsRequest.target:type_name -> query.Target - 37, // 49: binlogdata.VStreamResultsResponse.fields:type_name -> query.Field - 36, // 50: binlogdata.VStreamResultsResponse.rows:type_name -> query.Row - 3, // 51: binlogdata.BinlogTransaction.Statement.category:type_name -> binlogdata.BinlogTransaction.Statement.Category - 5, // 52: binlogdata.BinlogTransaction.Statement.charset:type_name -> binlogdata.Charset - 53, // [53:53] is the sub-list for method output_type - 53, // [53:53] is the sub-list for method input_type - 53, // [53:53] is the sub-list for extension type_name - 53, // [53:53] is the sub-list for extension extendee - 0, // [0:53] is the sub-list for field type_name + 34, // 7: binlogdata.Rule.convert_charset:type_name -> binlogdata.Rule.ConvertCharsetEntry + 12, // 8: binlogdata.Filter.rules:type_name -> binlogdata.Rule + 4, // 9: binlogdata.Filter.fieldEventMode:type_name -> binlogdata.Filter.FieldEventMode + 37, // 10: binlogdata.BinlogSource.tablet_type:type_name -> topodata.TabletType + 36, // 11: binlogdata.BinlogSource.key_range:type_name -> topodata.KeyRange + 13, // 12: binlogdata.BinlogSource.filter:type_name -> binlogdata.Filter + 0, // 13: binlogdata.BinlogSource.on_ddl:type_name -> binlogdata.OnDDLAction + 38, // 14: binlogdata.RowChange.before:type_name -> query.Row + 38, // 15: binlogdata.RowChange.after:type_name -> query.Row + 15, // 16: binlogdata.RowEvent.row_changes:type_name -> binlogdata.RowChange + 39, // 17: binlogdata.FieldEvent.fields:type_name -> query.Field + 30, // 18: binlogdata.ShardGtid.table_p_ks:type_name -> binlogdata.TableLastPK + 18, // 19: binlogdata.VGtid.shard_gtids:type_name -> binlogdata.ShardGtid + 2, // 20: binlogdata.Journal.migration_type:type_name -> binlogdata.MigrationType + 18, // 21: binlogdata.Journal.shard_gtids:type_name -> binlogdata.ShardGtid + 20, // 22: binlogdata.Journal.participants:type_name -> binlogdata.KeyspaceShard + 1, // 23: binlogdata.VEvent.type:type_name -> binlogdata.VEventType + 16, // 24: binlogdata.VEvent.row_event:type_name -> binlogdata.RowEvent + 17, // 25: binlogdata.VEvent.field_event:type_name -> binlogdata.FieldEvent + 19, // 26: binlogdata.VEvent.vgtid:type_name -> binlogdata.VGtid + 21, // 27: binlogdata.VEvent.journal:type_name -> binlogdata.Journal + 29, // 28: binlogdata.VEvent.last_p_k_event:type_name -> binlogdata.LastPKEvent + 39, // 29: binlogdata.MinimalTable.fields:type_name -> query.Field + 23, // 30: binlogdata.MinimalSchema.tables:type_name -> binlogdata.MinimalTable + 40, // 31: binlogdata.VStreamRequest.effective_caller_id:type_name -> vtrpc.CallerID + 41, // 32: binlogdata.VStreamRequest.immediate_caller_id:type_name -> query.VTGateCallerID + 42, // 33: binlogdata.VStreamRequest.target:type_name -> query.Target + 13, // 34: binlogdata.VStreamRequest.filter:type_name -> binlogdata.Filter + 30, // 35: binlogdata.VStreamRequest.table_last_p_ks:type_name -> binlogdata.TableLastPK + 22, // 36: binlogdata.VStreamResponse.events:type_name -> binlogdata.VEvent + 40, // 37: binlogdata.VStreamRowsRequest.effective_caller_id:type_name -> vtrpc.CallerID + 41, // 38: binlogdata.VStreamRowsRequest.immediate_caller_id:type_name -> query.VTGateCallerID + 42, // 39: binlogdata.VStreamRowsRequest.target:type_name -> query.Target + 43, // 40: binlogdata.VStreamRowsRequest.lastpk:type_name -> query.QueryResult + 39, // 41: binlogdata.VStreamRowsResponse.fields:type_name -> query.Field + 39, // 42: binlogdata.VStreamRowsResponse.pkfields:type_name -> query.Field + 38, // 43: binlogdata.VStreamRowsResponse.rows:type_name -> query.Row + 38, // 44: binlogdata.VStreamRowsResponse.lastpk:type_name -> query.Row + 30, // 45: binlogdata.LastPKEvent.table_last_p_k:type_name -> binlogdata.TableLastPK + 43, // 46: binlogdata.TableLastPK.lastpk:type_name -> query.QueryResult + 40, // 47: binlogdata.VStreamResultsRequest.effective_caller_id:type_name -> vtrpc.CallerID + 41, // 48: binlogdata.VStreamResultsRequest.immediate_caller_id:type_name -> query.VTGateCallerID + 42, // 49: binlogdata.VStreamResultsRequest.target:type_name -> query.Target + 39, // 50: binlogdata.VStreamResultsResponse.fields:type_name -> query.Field + 38, // 51: binlogdata.VStreamResultsResponse.rows:type_name -> query.Row + 3, // 52: binlogdata.BinlogTransaction.Statement.category:type_name -> binlogdata.BinlogTransaction.Statement.Category + 5, // 53: binlogdata.BinlogTransaction.Statement.charset:type_name -> binlogdata.Charset + 11, // 54: binlogdata.Rule.ConvertCharsetEntry.value:type_name -> binlogdata.CharsetConversion + 55, // [55:55] is the sub-list for method output_type + 55, // [55:55] is the sub-list for method input_type + 55, // [55:55] is the sub-list for extension type_name + 55, // [55:55] is the sub-list for extension extendee + 0, // [0:55] is the sub-list for field type_name } func init() { file_binlogdata_proto_init() } @@ -2852,7 +2938,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Rule); i { + switch v := v.(*CharsetConversion); i { case 0: return &v.state case 1: @@ -2864,7 +2950,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Filter); i { + switch v := v.(*Rule); i { case 0: return &v.state case 1: @@ -2876,7 +2962,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BinlogSource); i { + switch v := v.(*Filter); i { case 0: return &v.state case 1: @@ -2888,7 +2974,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RowChange); i { + switch v := v.(*BinlogSource); i { case 0: return &v.state case 1: @@ -2900,7 +2986,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RowEvent); i { + switch v := v.(*RowChange); i { case 0: return &v.state case 1: @@ -2912,7 +2998,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FieldEvent); i { + switch v := v.(*RowEvent); i { case 0: return &v.state case 1: @@ -2924,7 +3010,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ShardGtid); i { + switch v := v.(*FieldEvent); i { case 0: return &v.state case 1: @@ -2936,7 +3022,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VGtid); i { + switch v := v.(*ShardGtid); i { case 0: return &v.state case 1: @@ -2948,7 +3034,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*KeyspaceShard); i { + switch v := v.(*VGtid); i { case 0: return &v.state case 1: @@ -2960,7 +3046,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Journal); i { + switch v := v.(*KeyspaceShard); i { case 0: return &v.state case 1: @@ -2972,7 +3058,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VEvent); i { + switch v := v.(*Journal); i { case 0: return &v.state case 1: @@ -2984,7 +3070,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MinimalTable); i { + switch v := v.(*VEvent); i { case 0: return &v.state case 1: @@ -2996,7 +3082,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MinimalSchema); i { + switch v := v.(*MinimalTable); i { case 0: return &v.state case 1: @@ -3008,7 +3094,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VStreamRequest); i { + switch v := v.(*MinimalSchema); i { case 0: return &v.state case 1: @@ -3020,7 +3106,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VStreamResponse); i { + switch v := v.(*VStreamRequest); i { case 0: return &v.state case 1: @@ -3032,7 +3118,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VStreamRowsRequest); i { + switch v := v.(*VStreamResponse); i { case 0: return &v.state case 1: @@ -3044,7 +3130,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VStreamRowsResponse); i { + switch v := v.(*VStreamRowsRequest); i { case 0: return &v.state case 1: @@ -3056,7 +3142,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*LastPKEvent); i { + switch v := v.(*VStreamRowsResponse); i { case 0: return &v.state case 1: @@ -3068,7 +3154,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TableLastPK); i { + switch v := v.(*LastPKEvent); i { case 0: return &v.state case 1: @@ -3080,7 +3166,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VStreamResultsRequest); i { + switch v := v.(*TableLastPK); i { case 0: return &v.state case 1: @@ -3092,7 +3178,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VStreamResultsResponse); i { + switch v := v.(*VStreamResultsRequest); i { case 0: return &v.state case 1: @@ -3104,6 +3190,18 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*VStreamResultsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_binlogdata_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*BinlogTransaction_Statement); i { case 0: return &v.state @@ -3122,7 +3220,7 @@ func file_binlogdata_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_binlogdata_proto_rawDesc, NumEnums: 5, - NumMessages: 28, + NumMessages: 30, NumExtensions: 0, NumServices: 0, }, diff --git a/go/vt/proto/binlogdata/binlogdata_vtproto.pb.go b/go/vt/proto/binlogdata/binlogdata_vtproto.pb.go index 194ce30aaf9..acf8fd4269a 100644 --- a/go/vt/proto/binlogdata/binlogdata_vtproto.pb.go +++ b/go/vt/proto/binlogdata/binlogdata_vtproto.pb.go @@ -401,6 +401,53 @@ func (m *StreamTablesResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) return len(dAtA) - i, nil } +func (m *CharsetConversion) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *CharsetConversion) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *CharsetConversion) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.ToCharset) > 0 { + i -= len(m.ToCharset) + copy(dAtA[i:], m.ToCharset) + i = encodeVarint(dAtA, i, uint64(len(m.ToCharset))) + i-- + dAtA[i] = 0x12 + } + if len(m.FromCharset) > 0 { + i -= len(m.FromCharset) + copy(dAtA[i:], m.FromCharset) + i = encodeVarint(dAtA, i, uint64(len(m.FromCharset))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *Rule) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil @@ -431,6 +478,30 @@ func (m *Rule) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if len(m.ConvertCharset) > 0 { + for k := range m.ConvertCharset { + v := m.ConvertCharset[k] + baseI := i + { + size, err := v.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarint(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + i -= len(k) + copy(dAtA[i:], k) + i = encodeVarint(dAtA, i, uint64(len(k))) + i-- + dAtA[i] = 0xa + i = encodeVarint(dAtA, i, uint64(baseI-i)) + i-- + dAtA[i] = 0x1a + } + } if len(m.Filter) > 0 { i -= len(m.Filter) copy(dAtA[i:], m.Filter) @@ -2062,6 +2133,26 @@ func (m *StreamTablesResponse) SizeVT() (n int) { return n } +func (m *CharsetConversion) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.FromCharset) + if l > 0 { + n += 1 + l + sov(uint64(l)) + } + l = len(m.ToCharset) + if l > 0 { + n += 1 + l + sov(uint64(l)) + } + if m.unknownFields != nil { + n += len(m.unknownFields) + } + return n +} + func (m *Rule) SizeVT() (n int) { if m == nil { return 0 @@ -2076,6 +2167,19 @@ func (m *Rule) SizeVT() (n int) { if l > 0 { n += 1 + l + sov(uint64(l)) } + if len(m.ConvertCharset) > 0 { + for k, v := range m.ConvertCharset { + _ = k + _ = v + l = 0 + if v != nil { + l = v.SizeVT() + } + l += 1 + sov(uint64(l)) + mapEntrySize := 1 + len(k) + sov(uint64(len(k))) + l + n += mapEntrySize + 1 + sov(uint64(mapEntrySize)) + } + } if m.unknownFields != nil { n += len(m.unknownFields) } @@ -3508,6 +3612,121 @@ func (m *StreamTablesResponse) UnmarshalVT(dAtA []byte) error { } return nil } +func (m *CharsetConversion) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: CharsetConversion: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CharsetConversion: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FromCharset", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.FromCharset = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ToCharset", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ToCharset = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *Rule) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -3601,6 +3820,135 @@ func (m *Rule) UnmarshalVT(dAtA []byte) error { } m.Filter = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ConvertCharset", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ConvertCharset == nil { + m.ConvertCharset = make(map[string]*CharsetConversion) + } + var mapkey string + var mapvalue *CharsetConversion + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLength + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLength + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var mapmsglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + mapmsglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if mapmsglen < 0 { + return ErrInvalidLength + } + postmsgIndex := iNdEx + mapmsglen + if postmsgIndex < 0 { + return ErrInvalidLength + } + if postmsgIndex > l { + return io.ErrUnexpectedEOF + } + mapvalue = &CharsetConversion{} + if err := mapvalue.UnmarshalVT(dAtA[iNdEx:postmsgIndex]); err != nil { + return err + } + iNdEx = postmsgIndex + } else { + iNdEx = entryPreIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.ConvertCharset[mapkey] = mapvalue + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skip(dAtA[iNdEx:]) diff --git a/go/vt/vttablet/onlineddl/vrepl.go b/go/vt/vttablet/onlineddl/vrepl.go index ecbf42aec96..7cefafbf4ea 100644 --- a/go/vt/vttablet/onlineddl/vrepl.go +++ b/go/vt/vttablet/onlineddl/vrepl.go @@ -30,6 +30,7 @@ import ( "strconv" "strings" + "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/binlog/binlogplayer" "vitess.io/vitess/go/vt/dbconnpool" @@ -76,19 +77,22 @@ type VRepl struct { bls *binlogdatapb.BinlogSource parser *vrepl.AlterTableParser + + convertCharset map[string](*binlogdatapb.CharsetConversion) } // NewVRepl creates a VReplication handler for Online DDL func NewVRepl(workflow, keyspace, shard, dbName, sourceTable, targetTable, alterOptions string) *VRepl { return &VRepl{ - workflow: workflow, - keyspace: keyspace, - shard: shard, - dbName: dbName, - sourceTable: sourceTable, - targetTable: targetTable, - alterOptions: alterOptions, - parser: vrepl.NewAlterTableParser(), + workflow: workflow, + keyspace: keyspace, + shard: shard, + dbName: dbName, + sourceTable: sourceTable, + targetTable: targetTable, + alterOptions: alterOptions, + parser: vrepl.NewAlterTableParser(), + convertCharset: map[string](*binlogdatapb.CharsetConversion){}, } } @@ -384,14 +388,14 @@ func (v *VRepl) generateFilterQuery(ctx context.Context) error { } var sb strings.Builder sb.WriteString("select ") - for i, col := range v.sourceSharedColumns.Columns() { - name := col.Name + for i, sourceCol := range v.sourceSharedColumns.Columns() { + name := sourceCol.Name targetName := v.sharedColumnsMap[name] if i > 0 { sb.WriteString(", ") } - switch col.Type { + switch sourceCol.Type { case vrepl.JSONColumnType: sb.WriteString(fmt.Sprintf("convert(%s using utf8mb4)", escapeName(name))) case vrepl.StringColumnType: @@ -399,15 +403,52 @@ func (v *VRepl) generateFilterQuery(ctx context.Context) error { if targetCol == nil { return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "Cannot find target column %s", targetName) } - if col.Collation != targetCol.Collation { - fmt.Printf("============ collcation change: %s => %s\n", col.Collation, targetCol.Collation) - if strings.HasPrefix(targetCol.Charset, "utf8") { + if true || sourceCol.Collation != targetCol.Collation { + // sourceEncoding, ok := mysql.CharacterSetEncoding[sourceCol.Charset] + // if !ok { + // return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Character set %s not supported for column %s", sourceCol.Charset, sourceCol.Name) + // } + fromEncoding, ok := mysql.CharacterSetEncoding[sourceCol.Charset] + if !ok { + return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Character set %s not supported for column %s", sourceCol.Charset, sourceCol.Name) + } + toEncoding, ok := mysql.CharacterSetEncoding[targetCol.Charset] + if !ok { + return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Character set %s not supported for column %s", targetCol.Charset, targetCol.Name) + } + if fromEncoding != nil || toEncoding != nil { + // encoding can be nil for trivial charsets, like utf8, ascii, binary, etc. + v.convertCharset[targetName] = &binlogdatapb.CharsetConversion{ + FromCharset: sourceCol.Charset, + ToCharset: targetCol.Charset, + } + fmt.Printf("============ v.convertCharset[targetName]: %v, %v\n", targetName, v.convertCharset[targetName]) + } + fmt.Printf("============ collcation change: %s => %s\n", sourceCol.Collation, targetCol.Collation) + if strings.HasPrefix(sourceCol.Charset, "utf8") { + // sb.WriteString(escapeName(name)) + sb.WriteString(fmt.Sprintf("convert(%s USING utf8mb4)", escapeName(name))) + } else { // sb.WriteString(fmt.Sprintf("cast(%s as binary)", escapeName(name))) - sb.WriteString(fmt.Sprintf("convert(%s USING %s)", escapeName(name), targetCol.Charset)) + sb.WriteString(fmt.Sprintf("convert(%s USING utf8mb4)", escapeName(name))) + // sb.WriteString(fmt.Sprintf("convert(%s USING %s)", escapeName(name), targetCol.Charset)) // sb.WriteString(fmt.Sprintf("convert(%s USING %s) COLLATE %s", escapeName(name), targetCol.Charset, targetCol.Collation)) - } else { - sb.WriteString(fmt.Sprintf("convert(%s, char character set %s) COLLATE %s", escapeName(name), targetCol.Charset, targetCol.Collation)) } + // if strings.HasPrefix(targetCol.Charset, "utf8") { + // // sb.WriteString(fmt.Sprintf("cast(%s as binary)", escapeName(name))) + // sb.WriteString(fmt.Sprintf("convert(convert(%s USING binary) USING %s)", escapeName(name), targetCol.Charset)) + // // sb.WriteString(fmt.Sprintf("convert(%s USING %s)", escapeName(name), targetCol.Charset)) + // // sb.WriteString(fmt.Sprintf("convert(%s USING %s) COLLATE %s", escapeName(name), targetCol.Charset, targetCol.Collation)) + // } else if strings.HasPrefix(sourceCol.Charset, "utf8") { + // // sb.WriteString(fmt.Sprintf("cast(%s as binary)", escapeName(name))) + // sb.WriteString(fmt.Sprintf("convert(%s USING %s)", escapeName(name), targetCol.Charset)) + // // sb.WriteString(fmt.Sprintf("convert(%s USING %s)", escapeName(name), targetCol.Charset)) + // // sb.WriteString(fmt.Sprintf("convert(%s USING %s) COLLATE %s", escapeName(name), targetCol.Charset, targetCol.Collation)) + // } else { + // // sb.WriteString(fmt.Sprintf("convert(%s USING %s)", escapeName(name), targetCol.Charset)) + // sb.WriteString(fmt.Sprintf("convert(%s USING %s) COLLATE %s", escapeName(name), targetCol.Charset, targetCol.Collation)) + // // sb.WriteString(fmt.Sprintf("convert(convert(%s USING binary) USING %s) COLLATE %s", escapeName(name), targetCol.Charset, targetCol.Collation)) + // } } else { sb.WriteString(escapeName(name)) } @@ -435,6 +476,9 @@ func (v *VRepl) analyzeBinlogSource(ctx context.Context) { Match: v.targetTable, Filter: v.filterQuery, } + if len(v.convertCharset) > 0 { + rule.ConvertCharset = v.convertCharset + } bls.Filter.Rules = append(bls.Filter.Rules, rule) v.bls = bls } diff --git a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go index 9558533decd..92352495f47 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go +++ b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go @@ -25,15 +25,15 @@ import ( "google.golang.org/protobuf/proto" "vitess.io/vitess/go/bytes2" - - "vitess.io/vitess/go/vt/binlog/binlogplayer" - "vitess.io/vitess/go/vt/vtgate/evalengine" - + "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/sqltypes" - "vitess.io/vitess/go/vt/sqlparser" - + "vitess.io/vitess/go/vt/binlog/binlogplayer" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" querypb "vitess.io/vitess/go/vt/proto/query" + vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" + "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/vt/vtgate/evalengine" ) // ReplicatorPlan is the execution plan for the replicator. It contains @@ -194,9 +194,10 @@ type TablePlan struct { Fields []*querypb.Field // PKReferences is used to check if an event changed // a primary key column (row move). - PKReferences []string - Stats *binlogplayer.Stats - FieldsToSkip map[string]bool + PKReferences []string + Stats *binlogplayer.Stats + FieldsToSkip map[string]bool + ConvertCharset map[string](*binlogdatapb.CharsetConversion) } // MarshalJSON performs a custom JSON Marshalling. @@ -303,7 +304,47 @@ func (tp *TablePlan) applyChange(rowChange *binlogdatapb.RowChange, executor fun after = true vals := sqltypes.MakeRowTrusted(tp.Fields, rowChange.After) for i, field := range tp.Fields { - bindvars["a_"+field.Name] = sqltypes.ValueBindVariable(vals[i]) + bindVal := func() (err error) { + if conversion, ok := tp.ConvertCharset[field.Name]; ok { + valString := vals[i].ToString() + fmt.Printf("=========== ConvertCharset[field.Name]: %v, %v \n", field.Name, conversion) + fmt.Printf("=========== s0: %v \n", valString) + + fromEncoding, encodingOK := mysql.CharacterSetEncoding[conversion.FromCharset] + if !encodingOK { + return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Character set %s not supported for column %s", conversion.FromCharset, field.Name) + } + if fromEncoding != nil { + fmt.Printf("=========== ConvertCharset fromEncoding: %v, %v \n", field.Name, fromEncoding) + valString, err = fromEncoding.NewDecoder().String(valString) + if err != nil { + return err + } + fmt.Printf("=========== s1: %v \n", valString) + } + + // // There is a request to encode given charset + // toEncoding, encodingOK := mysql.CharacterSetEncoding[conversion.ToCharset] + // if !encodingOK { + // return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Character set %s not supported for column %s", conversion.ToCharset, field.Name) + // } + // if toEncoding != nil { + // fmt.Printf("=========== ConvertCharset toEncoding: %v, %v \n", field.Name, toEncoding) + // valString, err = toEncoding.NewEncoder().String(valString) + // if err != nil { + // return err + // } + // fmt.Printf("=========== s2: %v \n", valString) + // } + bindvars["a_"+field.Name] = sqltypes.StringBindVariable(valString) + return nil + } + bindvars["a_"+field.Name] = sqltypes.ValueBindVariable(vals[i]) + return nil + } + if err := bindVal(); err != nil { + return nil, err + } } } switch { diff --git a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go index 3108c4a0a2a..529d1028ac5 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go +++ b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go @@ -144,7 +144,7 @@ func buildReplicatorPlan(filter *binlogdatapb.Filter, colInfoMap map[string][]*C if rule == nil { continue } - tablePlan, err := buildTablePlan(tableName, rule.Filter, colInfoMap, lastpk, stats) + tablePlan, err := buildTablePlan(tableName, rule.Filter, colInfoMap, lastpk, rule.ConvertCharset, stats) if err != nil { return nil, err } @@ -183,7 +183,7 @@ func MatchTable(tableName string, filter *binlogdatapb.Filter) (*binlogdatapb.Ru return nil, nil } -func buildTablePlan(tableName, filter string, colInfoMap map[string][]*ColumnInfo, lastpk *sqltypes.Result, stats *binlogplayer.Stats) (*TablePlan, error) { +func buildTablePlan(tableName, filter string, colInfoMap map[string][]*ColumnInfo, lastpk *sqltypes.Result, convertCharset map[string](*binlogdatapb.CharsetConversion), stats *binlogplayer.Stats) (*TablePlan, error) { query := filter // generate equivalent select statement if filter is empty or a keyrange. fmt.Printf("============ filter: %v\n", filter) @@ -218,10 +218,11 @@ func buildTablePlan(tableName, filter string, colInfoMap map[string][]*ColumnInf } sendRule.Filter = query tablePlan := &TablePlan{ - TargetName: tableName, - SendRule: sendRule, - Lastpk: lastpk, - Stats: stats, + TargetName: tableName, + SendRule: sendRule, + Lastpk: lastpk, + Stats: stats, + ConvertCharset: convertCharset, } return tablePlan, nil } @@ -278,6 +279,7 @@ func buildTablePlan(tableName, filter string, colInfoMap map[string][]*ColumnInf tablePlan := tpb.generate() tablePlan.SendRule = sendRule + tablePlan.ConvertCharset = convertCharset return tablePlan, nil } @@ -382,7 +384,7 @@ func (tpb *tablePlanBuilder) analyzeExpr(selExpr sqlparser.SelectExpr) (*colExpr if expr, ok := aliased.Expr.(*sqlparser.ConvertUsingExpr); ok { fmt.Printf("============ ConvertUsingExpr: %v\n", sqlparser.String(expr)) selExpr := &sqlparser.ConvertUsingExpr{ - Type: "binary", + Type: "utf8mb4", Expr: &sqlparser.ColName{Name: as}, } fmt.Printf("============ ConvertUsingExpr generated: %v\n", sqlparser.String(selExpr)) diff --git a/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go b/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go index f7be38644e2..e934fb51ac6 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go +++ b/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go @@ -174,7 +174,7 @@ func (rs *rowStreamer) buildSelect() (string, error) { if rs.plan.convertToBinary[col.Name] { // fmt.Printf("========== WOOHOO! convertToBinary for %v\n", col.Name) // buf.Myprintf("%sconvert(convert(%v using binary) using utf8)", prefix, sqlparser.NewColIdent(col.Name)) - buf.Myprintf("%sconvert(%v using utf8)", prefix, sqlparser.NewColIdent(col.Name)) + buf.Myprintf("%sconvert(%v using utf8mb4)", prefix, sqlparser.NewColIdent(col.Name)) // buf.Myprintf("%s%v", prefix, sqlparser.NewColIdent(col.Name)) } else { buf.Myprintf("%s%v", prefix, sqlparser.NewColIdent(col.Name)) From abd0f269bae8900cdd8d8b324e170ec80b692b70 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Sun, 13 Jun 2021 17:35:45 +0300 Subject: [PATCH 06/21] testdata path Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../vrepl_suite/onlineddl_vrepl_suite_test.go | 2 +- .../fail-alter-charset-non-utf8/alter | 1 - .../fail-alter-charset-non-utf8/create.sql | 24 ------------------- .../expect_failure | 1 - 4 files changed, 1 insertion(+), 27 deletions(-) delete mode 100644 go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/alter delete mode 100644 go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/create.sql delete mode 100644 go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/expect_failure diff --git a/go/test/endtoend/onlineddl/vrepl_suite/onlineddl_vrepl_suite_test.go b/go/test/endtoend/onlineddl/vrepl_suite/onlineddl_vrepl_suite_test.go index 68f71c8d683..d96cfcfff22 100644 --- a/go/test/endtoend/onlineddl/vrepl_suite/onlineddl_vrepl_suite_test.go +++ b/go/test/endtoend/onlineddl/vrepl_suite/onlineddl_vrepl_suite_test.go @@ -60,7 +60,7 @@ var ( ) const ( - testDataPath = "tmptestdata" + testDataPath = "testdata" defaultSQLMode = "ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION" ) diff --git a/go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/alter b/go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/alter deleted file mode 100644 index b5ec82b1a8b..00000000000 --- a/go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/alter +++ /dev/null @@ -1 +0,0 @@ -MODIFY `t1` varchar(128) CHARACTER SET utf8mb4 NOT NULL, MODIFY `t2` varchar(128) CHARACTER SET latin2 NOT NULL, MODIFY `tutf8` varchar(128) CHARACTER SET latin1 NOT NULL diff --git a/go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/create.sql b/go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/create.sql deleted file mode 100644 index 9db84563248..00000000000 --- a/go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/create.sql +++ /dev/null @@ -1,24 +0,0 @@ -drop table if exists onlineddl_test; -create table onlineddl_test ( - id int auto_increment, - t1 varchar(128) charset latin1 collate latin1_swedish_ci, - t2 varchar(128) charset latin1 collate latin1_swedish_ci, - tutf8 varchar(128) charset utf8, - tutf8mb4 varchar(128) charset utf8mb4, - primary key(id) -) auto_increment=1; - -drop event if exists onlineddl_test; -delimiter ;; -create event onlineddl_test - on schedule every 1 second - starts current_timestamp - ends current_timestamp + interval 60 second - on completion not preserve - enable - do -begin - insert into onlineddl_test values (null, md5(rand()), md5(rand()), md5(rand()), md5(rand())); - insert into onlineddl_test values (null, 'átesting', 'átesting', 'átesting', 'átesting'); - insert into onlineddl_test values (null, 'testátest', 'testátest', 'testátest', '🍻😀'); -end ;; diff --git a/go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/expect_failure b/go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/expect_failure deleted file mode 100644 index 925d0d81ded..00000000000 --- a/go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/expect_failure +++ /dev/null @@ -1 +0,0 @@ -Vitess does not support charset From 90488dea2466907137a554a9e33238c545d8aafe Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Sun, 13 Jun 2021 17:36:03 +0300 Subject: [PATCH 07/21] proto change Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- proto/binlogdata.proto | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/proto/binlogdata.proto b/proto/binlogdata.proto index 777affe1766..220ef41c5df 100644 --- a/proto/binlogdata.proto +++ b/proto/binlogdata.proto @@ -115,6 +115,14 @@ message StreamTablesResponse { BinlogTransaction binlog_transaction = 1; } +// CharsetConversion represent a conversion of text from one charset to another +message CharsetConversion { + // FromCharset is the charset name from which we convert the text (e.g. latin1) + string from_charset = 1; + // ToCharset is the charset name to which we convert the text (e.g. utf8mb4) + string to_charset = 2; +} + // Rule represents one rule in a Filter. message Rule { // Match can be a table name or a regular expression. @@ -138,6 +146,8 @@ message Rule { // to be excluded. // TODO(sougou): support this on vstreamer side also. string filter = 2; + + map convert_charset = 3; } // Filter represents a list of ordered rules. The first From 95a3d11e09a2aaceb44778fc832750cd8db17075 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Sun, 13 Jun 2021 17:44:22 +0300 Subject: [PATCH 08/21] removed test from untestdata Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../fail-alter-charset-non-utf8/alter | 1 - .../fail-alter-charset-non-utf8/create.sql | 24 ------------------- .../expect_failure | 1 - 3 files changed, 26 deletions(-) delete mode 100644 go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/alter delete mode 100644 go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/create.sql delete mode 100644 go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/expect_failure diff --git a/go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/alter b/go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/alter deleted file mode 100644 index b5ec82b1a8b..00000000000 --- a/go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/alter +++ /dev/null @@ -1 +0,0 @@ -MODIFY `t1` varchar(128) CHARACTER SET utf8mb4 NOT NULL, MODIFY `t2` varchar(128) CHARACTER SET latin2 NOT NULL, MODIFY `tutf8` varchar(128) CHARACTER SET latin1 NOT NULL diff --git a/go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/create.sql b/go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/create.sql deleted file mode 100644 index 9db84563248..00000000000 --- a/go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/create.sql +++ /dev/null @@ -1,24 +0,0 @@ -drop table if exists onlineddl_test; -create table onlineddl_test ( - id int auto_increment, - t1 varchar(128) charset latin1 collate latin1_swedish_ci, - t2 varchar(128) charset latin1 collate latin1_swedish_ci, - tutf8 varchar(128) charset utf8, - tutf8mb4 varchar(128) charset utf8mb4, - primary key(id) -) auto_increment=1; - -drop event if exists onlineddl_test; -delimiter ;; -create event onlineddl_test - on schedule every 1 second - starts current_timestamp - ends current_timestamp + interval 60 second - on completion not preserve - enable - do -begin - insert into onlineddl_test values (null, md5(rand()), md5(rand()), md5(rand()), md5(rand())); - insert into onlineddl_test values (null, 'átesting', 'átesting', 'átesting', 'átesting'); - insert into onlineddl_test values (null, 'testátest', 'testátest', 'testátest', '🍻😀'); -end ;; diff --git a/go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/expect_failure b/go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/expect_failure deleted file mode 100644 index 925d0d81ded..00000000000 --- a/go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/expect_failure +++ /dev/null @@ -1 +0,0 @@ -Vitess does not support charset From e46c122ba17a0d8d56e2cda9bb3072ca64dcc802 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Sun, 13 Jun 2021 18:35:56 +0300 Subject: [PATCH 09/21] don't convert NULL strings Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../vttablet/tabletmanager/vreplication/replicator_plan.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go index 92352495f47..3e9eb11f814 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go +++ b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go @@ -304,9 +304,10 @@ func (tp *TablePlan) applyChange(rowChange *binlogdatapb.RowChange, executor fun after = true vals := sqltypes.MakeRowTrusted(tp.Fields, rowChange.After) for i, field := range tp.Fields { + val := &vals[i] bindVal := func() (err error) { - if conversion, ok := tp.ConvertCharset[field.Name]; ok { - valString := vals[i].ToString() + if conversion, ok := tp.ConvertCharset[field.Name]; ok && !val.IsNull() { + valString := val.ToString() fmt.Printf("=========== ConvertCharset[field.Name]: %v, %v \n", field.Name, conversion) fmt.Printf("=========== s0: %v \n", valString) @@ -339,7 +340,7 @@ func (tp *TablePlan) applyChange(rowChange *binlogdatapb.RowChange, executor fun bindvars["a_"+field.Name] = sqltypes.StringBindVariable(valString) return nil } - bindvars["a_"+field.Name] = sqltypes.ValueBindVariable(vals[i]) + bindvars["a_"+field.Name] = sqltypes.ValueBindVariable(*val) return nil } if err := bindVal(); err != nil { From ac75428d40d23b103d0e213d8444e178e61ab29e Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Mon, 14 Jun 2021 08:29:18 +0300 Subject: [PATCH 10/21] lazy initialization of convertUsingUTF8Columns Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../tabletserver/vstreamer/planbuilder.go | 25 ++++++++++++++++--- .../tabletserver/vstreamer/rowstreamer.go | 2 +- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go index b4cc346b5f8..29ee3e01d20 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go +++ b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go @@ -48,7 +48,7 @@ type Plan struct { // in the stream. ColExprs []ColExpr - convertToBinary map[string]bool + convertUsingUTF8Columns map[string]bool // Filters is the list of filters to be applied to the columns // of the table. @@ -401,8 +401,7 @@ func buildTablePlan(ti *Table, vschema *localVSchema, query string) (*Plan, erro } plan := &Plan{ - Table: ti, - convertToBinary: map[string]bool{}, + Table: ti, } if err := plan.analyzeWhere(vschema, sel.Where); err != nil { log.Errorf("%s", err.Error()) @@ -444,6 +443,24 @@ func analyzeSelect(query string) (sel *sqlparser.Select, fromTable sqlparser.Tab return sel, fromTable, nil } +// isConvertColumnUsingUTF8 returns 'true' when given column needs to be converted as UTF8 +// while read from source table +func (plan *Plan) isConvertColumnUsingUTF8(columnName string) bool { + if plan.convertUsingUTF8Columns == nil { + return false + } + return plan.convertUsingUTF8Columns[columnName] +} + +// setConvertColumnUsingUTF8 marks given column as needs to be converted as UTF8 +// while read from source table +func (plan *Plan) setConvertColumnUsingUTF8(columnName string) { + if plan.convertUsingUTF8Columns == nil { + plan.convertUsingUTF8Columns = map[string]bool{} + } + plan.convertUsingUTF8Columns[columnName] = true +} + func (plan *Plan) analyzeWhere(vschema *localVSchema, where *sqlparser.Where) error { if where == nil { return nil @@ -612,7 +629,7 @@ func (plan *Plan) analyzeExpr(vschema *localVSchema, selExpr sqlparser.SelectExp return ColExpr{}, err } field := plan.Table.Fields[colnum] - plan.convertToBinary[field.Name] = true + plan.setConvertColumnUsingUTF8(field.Name) return ColExpr{ ColNum: colnum, Field: field, diff --git a/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go b/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go index e934fb51ac6..2afbf181b92 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go +++ b/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go @@ -171,7 +171,7 @@ func (rs *rowStreamer) buildSelect() (string, error) { buf.Myprintf("select ") prefix := "" for _, col := range rs.plan.Table.Fields { - if rs.plan.convertToBinary[col.Name] { + if rs.plan.isConvertColumnUsingUTF8(col.Name) { // fmt.Printf("========== WOOHOO! convertToBinary for %v\n", col.Name) // buf.Myprintf("%sconvert(convert(%v using binary) using utf8)", prefix, sqlparser.NewColIdent(col.Name)) buf.Myprintf("%sconvert(%v using utf8mb4)", prefix, sqlparser.NewColIdent(col.Name)) From a921f2cacda30844a1f0534f8ecab66a3b746070 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Mon, 14 Jun 2021 08:55:05 +0300 Subject: [PATCH 11/21] test for NULL values Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../vrepl_suite/testdata/alter-charset-non-utf8-80/create.sql | 1 + .../vrepl_suite/testdata/alter-charset-non-utf8/create.sql | 1 + 2 files changed, 2 insertions(+) diff --git a/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8-80/create.sql b/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8-80/create.sql index 6f97756291b..26bae0cc966 100644 --- a/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8-80/create.sql +++ b/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8-80/create.sql @@ -26,4 +26,5 @@ begin insert into onlineddl_test values (null, md5(rand()), md5(rand()), md5(rand()), md5(rand()), md5(rand())); insert into onlineddl_test values (null, 'átesting-binlog', 'átesting-binlog', 'átesting-binlog', 'átesting-binlog', 'átesting-binlog'); insert into onlineddl_test values (null, 'testátest-binlog', 'testátest-binlog', 'testátest-binlog', '🍻😀', 'átesting-binlog'); + insert into onlineddl_test values (null, 'átesting-bnull', 'átesting-bnull', 'átesting-bnull', null, null); end ;; diff --git a/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8/create.sql b/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8/create.sql index d0d19253449..72df20e51ad 100644 --- a/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8/create.sql +++ b/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8/create.sql @@ -24,4 +24,5 @@ create event onlineddl_test begin insert into onlineddl_test values (null, md5(rand()), md5(rand()), md5(rand()), md5(rand()), md5(rand())); insert into onlineddl_test values (null, 'átesting-binlog', 'átesting-binlog', 'átesting-binlog', 'átesting-binlog', 'átesting-binlog'); + insert into onlineddl_test values (null, 'átesting-bnull', 'átesting-bnull', 'átesting-bnull', null, null); end ;; From 594d2b99c9b0afb4ba49b725f70482d74d67df6a Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Mon, 14 Jun 2021 08:55:32 +0300 Subject: [PATCH 12/21] strip comments; more to go Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/vttablet/onlineddl/vrepl.go | 34 +------------------------------ 1 file changed, 1 insertion(+), 33 deletions(-) diff --git a/go/vt/vttablet/onlineddl/vrepl.go b/go/vt/vttablet/onlineddl/vrepl.go index 7cefafbf4ea..2a75a2180bc 100644 --- a/go/vt/vttablet/onlineddl/vrepl.go +++ b/go/vt/vttablet/onlineddl/vrepl.go @@ -231,9 +231,6 @@ func (v *VRepl) applyColumnTypes(ctx context.Context, conn *dbconnpool.DBConnect column.BinaryOctetLength = columnOctetLength } if charset := row.AsString("CHARACTER_SET_NAME", ""); charset != "" { - // if !strings.HasPrefix(charset, "utf8") { - // return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Vitess does not support charset '%s'. Only utf8 and derivatives (like utf8mb4) are supported", charset) - // } column.Charset = charset } if collation := row.AsString("COLLATION_NAME", ""); collation != "" { @@ -404,10 +401,6 @@ func (v *VRepl) generateFilterQuery(ctx context.Context) error { return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "Cannot find target column %s", targetName) } if true || sourceCol.Collation != targetCol.Collation { - // sourceEncoding, ok := mysql.CharacterSetEncoding[sourceCol.Charset] - // if !ok { - // return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Character set %s not supported for column %s", sourceCol.Charset, sourceCol.Name) - // } fromEncoding, ok := mysql.CharacterSetEncoding[sourceCol.Charset] if !ok { return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Character set %s not supported for column %s", sourceCol.Charset, sourceCol.Name) @@ -422,33 +415,8 @@ func (v *VRepl) generateFilterQuery(ctx context.Context) error { FromCharset: sourceCol.Charset, ToCharset: targetCol.Charset, } - fmt.Printf("============ v.convertCharset[targetName]: %v, %v\n", targetName, v.convertCharset[targetName]) } - fmt.Printf("============ collcation change: %s => %s\n", sourceCol.Collation, targetCol.Collation) - if strings.HasPrefix(sourceCol.Charset, "utf8") { - // sb.WriteString(escapeName(name)) - sb.WriteString(fmt.Sprintf("convert(%s USING utf8mb4)", escapeName(name))) - } else { - // sb.WriteString(fmt.Sprintf("cast(%s as binary)", escapeName(name))) - sb.WriteString(fmt.Sprintf("convert(%s USING utf8mb4)", escapeName(name))) - // sb.WriteString(fmt.Sprintf("convert(%s USING %s)", escapeName(name), targetCol.Charset)) - // sb.WriteString(fmt.Sprintf("convert(%s USING %s) COLLATE %s", escapeName(name), targetCol.Charset, targetCol.Collation)) - } - // if strings.HasPrefix(targetCol.Charset, "utf8") { - // // sb.WriteString(fmt.Sprintf("cast(%s as binary)", escapeName(name))) - // sb.WriteString(fmt.Sprintf("convert(convert(%s USING binary) USING %s)", escapeName(name), targetCol.Charset)) - // // sb.WriteString(fmt.Sprintf("convert(%s USING %s)", escapeName(name), targetCol.Charset)) - // // sb.WriteString(fmt.Sprintf("convert(%s USING %s) COLLATE %s", escapeName(name), targetCol.Charset, targetCol.Collation)) - // } else if strings.HasPrefix(sourceCol.Charset, "utf8") { - // // sb.WriteString(fmt.Sprintf("cast(%s as binary)", escapeName(name))) - // sb.WriteString(fmt.Sprintf("convert(%s USING %s)", escapeName(name), targetCol.Charset)) - // // sb.WriteString(fmt.Sprintf("convert(%s USING %s)", escapeName(name), targetCol.Charset)) - // // sb.WriteString(fmt.Sprintf("convert(%s USING %s) COLLATE %s", escapeName(name), targetCol.Charset, targetCol.Collation)) - // } else { - // // sb.WriteString(fmt.Sprintf("convert(%s USING %s)", escapeName(name), targetCol.Charset)) - // sb.WriteString(fmt.Sprintf("convert(%s USING %s) COLLATE %s", escapeName(name), targetCol.Charset, targetCol.Collation)) - // // sb.WriteString(fmt.Sprintf("convert(convert(%s USING binary) USING %s) COLLATE %s", escapeName(name), targetCol.Charset, targetCol.Collation)) - // } + sb.WriteString(fmt.Sprintf("convert(%s USING utf8mb4)", escapeName(name))) } else { sb.WriteString(escapeName(name)) } From 2da4b7eaf03d17625da80ff5ff7db0739789c964 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Mon, 14 Jun 2021 08:56:04 +0300 Subject: [PATCH 13/21] strip comments; more to go Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go | 1 - 1 file changed, 1 deletion(-) diff --git a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go index 529d1028ac5..9e6c589741a 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go +++ b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go @@ -354,7 +354,6 @@ func analyzeSelectFrom(query string) (sel *sqlparser.Select, from string, err er func (tpb *tablePlanBuilder) analyzeExprs(selExprs sqlparser.SelectExprs) error { for _, selExpr := range selExprs { cexpr, err := tpb.analyzeExpr(selExpr) - fmt.Printf("============ selExpr: %v, cexpr.expr: %v\n", sqlparser.String(selExpr), sqlparser.String(cexpr.expr)) if err != nil { return err } From 0c669938fe7b17e6a49e77262d2c864169699896 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Mon, 14 Jun 2021 08:59:07 +0300 Subject: [PATCH 14/21] refactor, simplify Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/vttablet/onlineddl/vrepl.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/go/vt/vttablet/onlineddl/vrepl.go b/go/vt/vttablet/onlineddl/vrepl.go index 2a75a2180bc..f2e3595d78d 100644 --- a/go/vt/vttablet/onlineddl/vrepl.go +++ b/go/vt/vttablet/onlineddl/vrepl.go @@ -400,7 +400,9 @@ func (v *VRepl) generateFilterQuery(ctx context.Context) error { if targetCol == nil { return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "Cannot find target column %s", targetName) } - if true || sourceCol.Collation != targetCol.Collation { + { + // Check source and target charset/encoding. If needed, create + // a binlogdatapb.CharsetConversion entry (later written to vreplication) fromEncoding, ok := mysql.CharacterSetEncoding[sourceCol.Charset] if !ok { return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Character set %s not supported for column %s", sourceCol.Charset, sourceCol.Name) @@ -416,10 +418,9 @@ func (v *VRepl) generateFilterQuery(ctx context.Context) error { ToCharset: targetCol.Charset, } } - sb.WriteString(fmt.Sprintf("convert(%s USING utf8mb4)", escapeName(name))) - } else { - sb.WriteString(escapeName(name)) } + // We will always read strings as utf8mb4. + sb.WriteString(fmt.Sprintf("convert(%s USING utf8mb4)", escapeName(name))) default: sb.WriteString(escapeName(name)) } From a4e1114ae739a71f540797c935dfb51cde7894a0 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Mon, 14 Jun 2021 09:21:17 +0300 Subject: [PATCH 15/21] refactor: extract bindFiledVar function Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../vreplication/replicator_plan.go | 69 ++++++++----------- 1 file changed, 30 insertions(+), 39 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go index 3e9eb11f814..75125dcb349 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go +++ b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go @@ -289,6 +289,33 @@ func (tp *TablePlan) isOutsidePKRange(bindvars map[string]*querypb.BindVariable, return false } +// bindFieldVal returns a bind variable based on given field and value. +// Most values will just bind directly. But some values may need manipulation: +// - text values with charset conversion +// - enum values converted to text via Online DDL +// - ...any other future possible values +func (tp *TablePlan) bindFieldVal(field *querypb.Field, val *sqltypes.Value) (*querypb.BindVariable, error) { + if conversion, ok := tp.ConvertCharset[field.Name]; ok && !val.IsNull() { + // Non-null string value, for which we have a charset conversion instruction + valString := val.ToString() + fromEncoding, encodingOK := mysql.CharacterSetEncoding[conversion.FromCharset] + if !encodingOK { + return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Character set %s not supported for column %s", conversion.FromCharset, field.Name) + } + if fromEncoding != nil { + // As reminder, encoding can be nil for trivial charsets, like utf8 or ascii. + // encoding will be non-nil for charsets like latin1, gbk, etc. + var err error + valString, err = fromEncoding.NewDecoder().String(valString) + if err != nil { + return nil, err + } + } + return sqltypes.StringBindVariable(valString), nil + } + return sqltypes.ValueBindVariable(*val), nil +} + func (tp *TablePlan) applyChange(rowChange *binlogdatapb.RowChange, executor func(string) (*sqltypes.Result, error)) (*sqltypes.Result, error) { // MakeRowTrusted is needed here because Proto3ToResult is not convenient. var before, after bool @@ -305,47 +332,11 @@ func (tp *TablePlan) applyChange(rowChange *binlogdatapb.RowChange, executor fun vals := sqltypes.MakeRowTrusted(tp.Fields, rowChange.After) for i, field := range tp.Fields { val := &vals[i] - bindVal := func() (err error) { - if conversion, ok := tp.ConvertCharset[field.Name]; ok && !val.IsNull() { - valString := val.ToString() - fmt.Printf("=========== ConvertCharset[field.Name]: %v, %v \n", field.Name, conversion) - fmt.Printf("=========== s0: %v \n", valString) - - fromEncoding, encodingOK := mysql.CharacterSetEncoding[conversion.FromCharset] - if !encodingOK { - return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Character set %s not supported for column %s", conversion.FromCharset, field.Name) - } - if fromEncoding != nil { - fmt.Printf("=========== ConvertCharset fromEncoding: %v, %v \n", field.Name, fromEncoding) - valString, err = fromEncoding.NewDecoder().String(valString) - if err != nil { - return err - } - fmt.Printf("=========== s1: %v \n", valString) - } - - // // There is a request to encode given charset - // toEncoding, encodingOK := mysql.CharacterSetEncoding[conversion.ToCharset] - // if !encodingOK { - // return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Character set %s not supported for column %s", conversion.ToCharset, field.Name) - // } - // if toEncoding != nil { - // fmt.Printf("=========== ConvertCharset toEncoding: %v, %v \n", field.Name, toEncoding) - // valString, err = toEncoding.NewEncoder().String(valString) - // if err != nil { - // return err - // } - // fmt.Printf("=========== s2: %v \n", valString) - // } - bindvars["a_"+field.Name] = sqltypes.StringBindVariable(valString) - return nil - } - bindvars["a_"+field.Name] = sqltypes.ValueBindVariable(*val) - return nil - } - if err := bindVal(); err != nil { + bindVar, err := tp.bindFieldVal(field, val) + if err != nil { return nil, err } + bindvars["a_"+field.Name] = bindVar } } switch { From 9d392930832936c724745ae7689718472aa4b20e Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Mon, 14 Jun 2021 09:21:36 +0300 Subject: [PATCH 16/21] remove comments Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../vttablet/tabletmanager/vreplication/table_plan_builder.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go index 9e6c589741a..7122e3e1557 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go +++ b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go @@ -186,7 +186,6 @@ func MatchTable(tableName string, filter *binlogdatapb.Filter) (*binlogdatapb.Ru func buildTablePlan(tableName, filter string, colInfoMap map[string][]*ColumnInfo, lastpk *sqltypes.Result, convertCharset map[string](*binlogdatapb.CharsetConversion), stats *binlogplayer.Stats) (*TablePlan, error) { query := filter // generate equivalent select statement if filter is empty or a keyrange. - fmt.Printf("============ filter: %v\n", filter) switch { case filter == "": buf := sqlparser.NewTrackedBuffer(nil) @@ -239,9 +238,6 @@ func buildTablePlan(tableName, filter string, colInfoMap map[string][]*ColumnInf stats: stats, } - for _, s := range sel.SelectExprs { - fmt.Printf("============ SelectExpr: %v\n", sqlparser.String(s)) - } if err := tpb.analyzeExprs(sel.SelectExprs); err != nil { return nil, err } From 7a2ba41f5ccc761c193fc5a3ac7587d7e2f9f471 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Mon, 14 Jun 2021 09:25:50 +0300 Subject: [PATCH 17/21] remvoe comments Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../vreplication/table_plan_builder.go | 28 ------------------- .../tabletmanager/vreplication/vcopier.go | 2 -- .../tabletserver/vstreamer/planbuilder.go | 3 -- .../tabletserver/vstreamer/rowstreamer.go | 5 ---- 4 files changed, 38 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go index 7122e3e1557..01d2d214b64 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go +++ b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go @@ -269,9 +269,7 @@ func buildTablePlan(tableName, filter string, colInfoMap map[string][]*ColumnInf }, }) } - fmt.Printf("============ sendSelect.SelectExprs [3]: %v\n", sqlparser.String(tpb.sendSelect.SelectExprs)) sendRule.Filter = sqlparser.String(tpb.sendSelect) - fmt.Printf("============ sendRule.Filter: %v\n", sendRule.Filter) tablePlan := tpb.generate() tablePlan.SendRule = sendRule @@ -377,46 +375,20 @@ func (tpb *tablePlanBuilder) analyzeExpr(selExpr sqlparser.SelectExpr) (*colExpr references: make(map[string]bool), } if expr, ok := aliased.Expr.(*sqlparser.ConvertUsingExpr); ok { - fmt.Printf("============ ConvertUsingExpr: %v\n", sqlparser.String(expr)) selExpr := &sqlparser.ConvertUsingExpr{ Type: "utf8mb4", Expr: &sqlparser.ColName{Name: as}, } - fmt.Printf("============ ConvertUsingExpr generated: %v\n", sqlparser.String(selExpr)) cexpr.expr = expr cexpr.operation = opExpr tpb.sendSelect.SelectExprs = append(tpb.sendSelect.SelectExprs, &sqlparser.AliasedExpr{Expr: selExpr, As: as}) return cexpr, nil } if expr, ok := aliased.Expr.(*sqlparser.ConvertExpr); ok { - // convertAsBinary := fmt.Sprintf("convert(%s, binary) as %s", sqlparser.String(as), sqlparser.String(as)) - // fmt.Printf("============ convertAsBinary: %v\n", convertAsBinary) - // convertAsBinaryExpr, err := sqlparser.Parse(convertAsBinary) - // fmt.Printf("============ convertAsBinaryExpr, err: %v, %v\n", convertAsBinaryExpr, err) - // if err != nil { - // return nil, err - // } - // expr, ok := convertAsBinaryExpr.(*sqlparser.ConvertExpr) - fmt.Printf("============ ConvertExpr: %v\n", sqlparser.String(expr)) - fmt.Printf("============ ConvertExpr.Type: %v\n", expr.Type) - fmt.Printf("============ ConvertExpr.Type.Type: %v\n", expr.Type.Type) - fmt.Printf("============ ConvertExpr.Type.Charset: %v\n", expr.Type.Charset) - fmt.Printf("============ ConvertExpr.Expr: %v\n", expr.Expr) - // expr.Type:= - // type ConvertType struct { - // Type string - // Length *Literal - // Scale *Literal - // Operator ConvertTypeOperator - // Charset string - // } - // expr.Type = &sqlparser.ConvertType{Type: "binary"} - // expr.Expr = as selExpr := &sqlparser.ConvertExpr{ Type: &sqlparser.ConvertType{Type: "binary"}, Expr: &sqlparser.ColName{Name: as}, } - fmt.Printf("============ ConvertExpr generated: %v\n", sqlparser.String(selExpr)) cexpr.expr = expr cexpr.operation = opExpr tpb.sendSelect.SelectExprs = append(tpb.sendSelect.SelectExprs, &sqlparser.AliasedExpr{Expr: selExpr, As: as}) diff --git a/go/vt/vttablet/tabletmanager/vreplication/vcopier.go b/go/vt/vttablet/tabletmanager/vreplication/vcopier.go index 25ca3e90cf1..6472d0b79e5 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vcopier.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vcopier.go @@ -200,7 +200,6 @@ func (vc *vcopier) copyTable(ctx context.Context, tableName string, copyState ma log.Infof("Copying table %s, lastpk: %v", tableName, copyState[tableName]) - fmt.Printf("============ buildReplicatorPlan( ivc.vr.source.Filter: %v\n", vc.vr.source.Filter) plan, err := buildReplicatorPlan(vc.vr.source.Filter, vc.vr.colInfoMap, nil, vc.vr.stats) if err != nil { return err @@ -223,7 +222,6 @@ func (vc *vcopier) copyTable(ctx context.Context, tableName string, copyState ma var updateCopyState *sqlparser.ParsedQuery var bv map[string]*querypb.BindVariable var sqlbuffer bytes2.Buffer - fmt.Printf("============ VStreamRows( initialPlan.SendRule.Filter: %v\n", initialPlan.SendRule.Filter) err = vc.vr.sourceVStreamer.VStreamRows(ctx, initialPlan.SendRule.Filter, lastpkpb, func(rows *binlogdatapb.VStreamRowsResponse) error { for { select { diff --git a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go index 29ee3e01d20..5149c3d36ab 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go +++ b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go @@ -407,7 +407,6 @@ func buildTablePlan(ti *Table, vschema *localVSchema, query string) (*Plan, erro log.Errorf("%s", err.Error()) return nil, err } - fmt.Printf("========= buildTablePlan.analyzeExprs: sel.SelectExprs: %v, %v\n", len(sel.SelectExprs), sqlparser.String(sel.SelectExprs)) if err := plan.analyzeExprs(vschema, sel.SelectExprs); err != nil { log.Errorf("%s", err.Error()) return nil, err @@ -557,7 +556,6 @@ func (plan *Plan) analyzeExprs(vschema *localVSchema, selExprs sqlparser.SelectE } func (plan *Plan) analyzeExpr(vschema *localVSchema, selExpr sqlparser.SelectExpr) (cExpr ColExpr, err error) { - fmt.Printf("========= Plan: analyzeExpr selExpr s: %v\n", sqlparser.String(selExpr)) aliased, ok := selExpr.(*sqlparser.AliasedExpr) if !ok { return ColExpr{}, fmt.Errorf("unsupported: %v", sqlparser.String(selExpr)) @@ -624,7 +622,6 @@ func (plan *Plan) analyzeExpr(vschema *localVSchema, selExpr sqlparser.SelectExp }, nil case *sqlparser.ConvertExpr, *sqlparser.ConvertUsingExpr: colnum, err := findColumn(plan.Table, aliased.As) - fmt.Printf("========= findColumn2: %v, %v \n", colnum, err) if err != nil { return ColExpr{}, err } diff --git a/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go b/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go index 2afbf181b92..d1e5aaec9f6 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go +++ b/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go @@ -113,7 +113,6 @@ func (rs *rowStreamer) Stream() error { func (rs *rowStreamer) buildPlan() error { // This pre-parsing is required to extract the table name // and create its metadata. - fmt.Printf("========= analyzeSelect: %v\n", rs.query) _, fromTable, err := analyzeSelect(rs.query) if err != nil { return err @@ -140,7 +139,6 @@ func (rs *rowStreamer) buildPlan() error { return err } rs.sendQuery, err = rs.buildSelect() - fmt.Printf("================= rs.sendQuery: %v\n", rs.sendQuery) if err != nil { return err } @@ -172,10 +170,7 @@ func (rs *rowStreamer) buildSelect() (string, error) { prefix := "" for _, col := range rs.plan.Table.Fields { if rs.plan.isConvertColumnUsingUTF8(col.Name) { - // fmt.Printf("========== WOOHOO! convertToBinary for %v\n", col.Name) - // buf.Myprintf("%sconvert(convert(%v using binary) using utf8)", prefix, sqlparser.NewColIdent(col.Name)) buf.Myprintf("%sconvert(%v using utf8mb4)", prefix, sqlparser.NewColIdent(col.Name)) - // buf.Myprintf("%s%v", prefix, sqlparser.NewColIdent(col.Name)) } else { buf.Myprintf("%s%v", prefix, sqlparser.NewColIdent(col.Name)) } From 4ec59590184995d2d5f5054267e2a1c47227f47c Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Mon, 14 Jun 2021 09:38:49 +0300 Subject: [PATCH 18/21] vrepl.IntegerColumnType is for a different PR Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/vttablet/onlineddl/vrepl.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/go/vt/vttablet/onlineddl/vrepl.go b/go/vt/vttablet/onlineddl/vrepl.go index f2e3595d78d..d935a9da1e5 100644 --- a/go/vt/vttablet/onlineddl/vrepl.go +++ b/go/vt/vttablet/onlineddl/vrepl.go @@ -219,9 +219,6 @@ func (v *VRepl) applyColumnTypes(ctx context.Context, conn *dbconnpool.DBConnect if strings.Contains(columnType, "float") { column.Type = vrepl.FloatColumnType } - if strings.Contains(columnType, "int") { - column.Type = vrepl.IntegerColumnType - } if strings.HasPrefix(columnType, "enum") { column.Type = vrepl.EnumColumnType column.EnumValues = vrepl.ParseEnumValues(columnType) @@ -420,7 +417,7 @@ func (v *VRepl) generateFilterQuery(ctx context.Context) error { } } // We will always read strings as utf8mb4. - sb.WriteString(fmt.Sprintf("convert(%s USING utf8mb4)", escapeName(name))) + sb.WriteString(fmt.Sprintf("convert(%s using utf8mb4)", escapeName(name))) default: sb.WriteString(escapeName(name)) } From 60eb70dc7739c4a873c74210eea92b952658153b Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Mon, 14 Jun 2021 09:40:03 +0300 Subject: [PATCH 19/21] ConvertUsingExpr is the only hint vreplication/plan sends to vstreamer/plan ; ConvertExpr not needed Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../tabletmanager/vreplication/table_plan_builder.go | 10 ---------- go/vt/vttablet/tabletserver/vstreamer/planbuilder.go | 2 +- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go index 01d2d214b64..734f119be60 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go +++ b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go @@ -384,16 +384,6 @@ func (tpb *tablePlanBuilder) analyzeExpr(selExpr sqlparser.SelectExpr) (*colExpr tpb.sendSelect.SelectExprs = append(tpb.sendSelect.SelectExprs, &sqlparser.AliasedExpr{Expr: selExpr, As: as}) return cexpr, nil } - if expr, ok := aliased.Expr.(*sqlparser.ConvertExpr); ok { - selExpr := &sqlparser.ConvertExpr{ - Type: &sqlparser.ConvertType{Type: "binary"}, - Expr: &sqlparser.ColName{Name: as}, - } - cexpr.expr = expr - cexpr.operation = opExpr - tpb.sendSelect.SelectExprs = append(tpb.sendSelect.SelectExprs, &sqlparser.AliasedExpr{Expr: selExpr, As: as}) - return cexpr, nil - } if expr, ok := aliased.Expr.(*sqlparser.FuncExpr); ok { if expr.Distinct { return nil, fmt.Errorf("unexpected: %v", sqlparser.String(expr)) diff --git a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go index 5149c3d36ab..8eabce49642 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go +++ b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go @@ -620,7 +620,7 @@ func (plan *Plan) analyzeExpr(vschema *localVSchema, selExpr sqlparser.SelectExp ColNum: -1, FixedValue: sqltypes.NewInt64(num), }, nil - case *sqlparser.ConvertExpr, *sqlparser.ConvertUsingExpr: + case *sqlparser.ConvertUsingExpr: colnum, err := findColumn(plan.Table, aliased.As) if err != nil { return ColExpr{}, err From 8043874a8bbd9a791aeadcf71ee31c5640426ebf Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Mon, 14 Jun 2021 10:14:16 +0300 Subject: [PATCH 20/21] adding test: convert-utf8mb4 Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../vrepl_suite/{untestdata => testdata}/convert-utf8mb4/alter | 0 .../{untestdata => testdata}/convert-utf8mb4/create.sql | 3 --- 2 files changed, 3 deletions(-) rename go/test/endtoend/onlineddl/vrepl_suite/{untestdata => testdata}/convert-utf8mb4/alter (100%) rename go/test/endtoend/onlineddl/vrepl_suite/{untestdata => testdata}/convert-utf8mb4/create.sql (94%) diff --git a/go/test/endtoend/onlineddl/vrepl_suite/untestdata/convert-utf8mb4/alter b/go/test/endtoend/onlineddl/vrepl_suite/testdata/convert-utf8mb4/alter similarity index 100% rename from go/test/endtoend/onlineddl/vrepl_suite/untestdata/convert-utf8mb4/alter rename to go/test/endtoend/onlineddl/vrepl_suite/testdata/convert-utf8mb4/alter diff --git a/go/test/endtoend/onlineddl/vrepl_suite/untestdata/convert-utf8mb4/create.sql b/go/test/endtoend/onlineddl/vrepl_suite/testdata/convert-utf8mb4/create.sql similarity index 94% rename from go/test/endtoend/onlineddl/vrepl_suite/untestdata/convert-utf8mb4/create.sql rename to go/test/endtoend/onlineddl/vrepl_suite/testdata/convert-utf8mb4/create.sql index a2a662fe23c..54963d7ff17 100644 --- a/go/test/endtoend/onlineddl/vrepl_suite/untestdata/convert-utf8mb4/create.sql +++ b/go/test/endtoend/onlineddl/vrepl_suite/testdata/convert-utf8mb4/create.sql @@ -7,9 +7,6 @@ create table onlineddl_test ( primary key(id) ) auto_increment=1; -insert into onlineddl_test values (null, 'átesting'); - - insert into onlineddl_test values (null, 'Hello world, Καλημέρα κόσμε, コンニチハ', 'átesting0', 'initial'); drop event if exists onlineddl_test; From dfd826e935c331ae70b009c27b77990c2bfcc209 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Tue, 15 Jun 2021 09:18:51 +0300 Subject: [PATCH 21/21] fix text/enum override Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/vttablet/onlineddl/vrepl.go | 21 +++++++++++---------- go/vt/vttablet/onlineddl/vrepl/types.go | 7 +++++++ 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/go/vt/vttablet/onlineddl/vrepl.go b/go/vt/vttablet/onlineddl/vrepl.go index 6f03fcd57f5..60c0d2f0157 100644 --- a/go/vt/vttablet/onlineddl/vrepl.go +++ b/go/vt/vttablet/onlineddl/vrepl.go @@ -221,37 +221,38 @@ func (v *VRepl) applyColumnTypes(ctx context.Context, conn *dbconnpool.DBConnect continue } + column.Type = vrepl.UnknownColumnType if strings.Contains(columnType, "unsigned") { column.IsUnsigned = true } if strings.Contains(columnType, "mediumint") { - column.Type = vrepl.MediumIntColumnType + column.SetTypeIfUnknown(vrepl.MediumIntColumnType) } if strings.Contains(columnType, "timestamp") { - column.Type = vrepl.TimestampColumnType + column.SetTypeIfUnknown(vrepl.TimestampColumnType) } if strings.Contains(columnType, "datetime") { - column.Type = vrepl.DateTimeColumnType + column.SetTypeIfUnknown(vrepl.DateTimeColumnType) } if strings.Contains(columnType, "json") { - column.Type = vrepl.JSONColumnType + column.SetTypeIfUnknown(vrepl.JSONColumnType) } if strings.Contains(columnType, "float") { - column.Type = vrepl.FloatColumnType + column.SetTypeIfUnknown(vrepl.FloatColumnType) } if strings.HasPrefix(columnType, "enum") { - column.Type = vrepl.EnumColumnType + column.SetTypeIfUnknown(vrepl.EnumColumnType) column.EnumValues = schema.ParseEnumValues(columnType) } if strings.HasPrefix(columnType, "binary") { - column.Type = vrepl.BinaryColumnType + column.SetTypeIfUnknown(vrepl.BinaryColumnType) column.BinaryOctetLength = columnOctetLength } if charset := row.AsString("CHARACTER_SET_NAME", ""); charset != "" { column.Charset = charset } if collation := row.AsString("COLLATION_NAME", ""); collation != "" { - column.Type = vrepl.StringColumnType + column.SetTypeIfUnknown(vrepl.StringColumnType) column.Collation = collation } } @@ -425,6 +426,8 @@ func (v *VRepl) generateFilterQuery(ctx context.Context) error { sb.WriteString(", ") } switch { + case sourceCol.EnumToTextConversion: + sb.WriteString(fmt.Sprintf("CONCAT(%s)", escapeName(name))) case sourceCol.Type == vrepl.JSONColumnType: sb.WriteString(fmt.Sprintf("convert(%s using utf8mb4)", escapeName(name))) case sourceCol.Type == vrepl.StringColumnType: @@ -453,8 +456,6 @@ func (v *VRepl) generateFilterQuery(ctx context.Context) error { } // We will always read strings as utf8mb4. sb.WriteString(fmt.Sprintf("convert(%s using utf8mb4)", escapeName(name))) - case sourceCol.EnumToTextConversion: - sb.WriteString(fmt.Sprintf("CONCAT(%s)", escapeName(name))) default: sb.WriteString(escapeName(name)) } diff --git a/go/vt/vttablet/onlineddl/vrepl/types.go b/go/vt/vttablet/onlineddl/vrepl/types.go index ca2c830af0a..204388169e6 100644 --- a/go/vt/vttablet/onlineddl/vrepl/types.go +++ b/go/vt/vttablet/onlineddl/vrepl/types.go @@ -60,6 +60,13 @@ type Column struct { BinaryOctetLength uint64 } +// SetTypeIfUnknown will set a new column type only if the current type is unknown, otherwise silently skip +func (c *Column) SetTypeIfUnknown(t ColumnType) { + if c.Type == UnknownColumnType { + c.Type = t + } +} + // NewColumns creates a new column array from non empty names func NewColumns(names []string) []Column { result := []Column{}