Repository: pingcap/tidb-binlog
Pull request #1103 (2021-12-22 11:13:33)

reparo: fix can't decode bit type data
<!--
Thank you for contributing to TiDB! Please read TiDB's [CONTRIBUTING](https://github.com/pingcap/tidb/blob/master/CONTRIBUTING.md) document **BEFORE** filing this PR.
-->

### What problem does this PR solve? <!--add issue link with summary if exists-->
close https://github.com/pingcap/tidb-binlog/issues/1096

### What is changed and how it works?
in https://github.com/pingcap/tidb-binlog/pull/655, drainer will write Uint64 datum for mysql bit type. align reparo's behaviour

### Check List <!--REMOVE the items that are not applicable-->

Tests <!-- At least one of them must be included. -->

 - Unit test
 - Integration test

Code changes


Side effects


Related changes

 - Need to cherry-pick to the release branch
 - Need to be included in the release note

ti-chi-bot: [REVIEW NOTIFICATION]

This pull request has not been approved.


To complete the [pull request process](https://book.prow.tidb.io/#/en/workflows/pr), please ask the reviewers in the [list](https://prow.tidb.io/tichi/repos/pingcap/tidb-binlog/pulls/1103/owners) to review by filling `/cc @reviewer` in the comment.
After your PR has acquired the required number of LGTMs, you can assign this pull request to the committer in the [list](https://prow.tidb.io/tichi/repos/pingcap/tidb-binlog/pulls/1103/owners) by filling  `/assign @committer` in the comment to help you merge this pull request.

The full list of commands accepted by this bot can be found [here](https://prow.tidb.io/command-help?repo=pingcap%2Ftidb-binlog).

<details>

Reviewer can indicate their review by submitting an approval review.
Reviewer can cancel approval by submitting a request changes review.
</details>

<!--Review Notification Identifier-->
lance6716: /run-all-tests
lance6716: /cc @lichunzhu 

I haven't run the integration test locally, not sure if it will pass 😂 
lance6716: /run-all-tests
lance6716: /cc @kennytm 
lance6716: /cc @glorv 
lichunzhu: /merge
ti-chi-bot: This pull request has been accepted and is ready to merge. <details>Commit hash: 263478c213d383eaf85dfd227ac2ba99623d0e53</details>

Patch:
diff --git a/reparo/syncer/util.go b/reparo/syncer/util.go
index e1847514..96ffe74f 100644
--- a/reparo/syncer/util.go
+++ b/reparo/syncer/util.go
@@ -46,7 +46,8 @@ func formatValue(value types.Datum, tp byte) types.Datum {
 	case mysql.TypeSet:
 		value = types.NewDatum(value.GetMysqlSet().Value)
 	case mysql.TypeBit:
-		value = types.NewDatum(value.GetMysqlBit())
+		// see drainer/translator/mysql.go formatData
+		value = types.NewDatum(value.GetUint64())
 	}
 
 	return value


Test patch:
diff --git a/reparo/syncer/util_test.go b/reparo/syncer/util_test.go
index b3cbc321..7cc19134 100644
--- a/reparo/syncer/util_test.go
+++ b/reparo/syncer/util_test.go
@@ -15,8 +15,7 @@ var _ = check.Suite(&testUtilSuite{})
 func (s *testUtilSuite) TestFormatValue(c *check.C) {
 	datetime, err := time.Parse("20060102150405", "20190415121212")
 	c.Assert(err, check.IsNil)
-	bitVal, err2 := types.NewBitLiteral("b'10010'")
-	c.Assert(err2, check.IsNil)
+	bitVal := uint64(12)
 
 	testCases := []struct {
 		value     interface{}
@@ -81,8 +80,8 @@ func (s *testUtilSuite) TestFormatValue(c *check.C) {
 		{
 			value:     bitVal,
 			tp:        mysql.TypeBit,
-			expectStr: "0x12",
-			expectVal: types.BinaryLiteral([]byte{0x12}),
+			expectStr: "12",
+			expectVal: uint64(12),
 		},
 	}
 
diff --git a/tests/dailytest/db.go b/tests/dailytest/db.go
index d13ac359..8c10e900 100644
--- a/tests/dailytest/db.go
+++ b/tests/dailytest/db.go
@@ -23,8 +23,9 @@ import (
 
 	"github.com/pingcap/errors"
 	"github.com/pingcap/log"
-	"github.com/pingcap/tidb-binlog/tests/util"
 	"github.com/pingcap/tidb/parser/mysql"
+
+	"github.com/pingcap/tidb-binlog/tests/util"
 )
 
 func intRangeValue(column *column, min int64, max int64) (int64, int64) {
@@ -221,6 +222,11 @@ func genColumnData(table *table, column *column) (string, error) {
 	isUnsigned := mysql.HasUnsignedFlag(tp.Flag)
 
 	switch tp.Tp {
+	case mysql.TypeBit:
+		if randInt(0, 1) == 0 {
+			return "b'0'", nil
+		}
+		return "b'1'", nil
 	case mysql.TypeTiny:
 		var data int64
 		if isUnique {
diff --git a/tests/reparo/binlog.go b/tests/reparo/binlog.go
index 7df0bc5a..3f6fb887 100644
--- a/tests/reparo/binlog.go
+++ b/tests/reparo/binlog.go
@@ -20,6 +20,7 @@ import (
 	_ "github.com/go-sql-driver/mysql"
 	"github.com/pingcap/errors"
 	"github.com/pingcap/log"
+
 	"github.com/pingcap/tidb-binlog/tests/dailytest"
 	"github.com/pingcap/tidb-binlog/tests/util"
 )
@@ -70,6 +71,14 @@ func main() {
 		c varchar(10) NOT NULL,
 		d time unique
 	);
+	`,
+		`
+	create table ntest2(
+		a int,
+		b double NOT NULL DEFAULT 2.0,
+		c varchar(10) NOT NULL,
+		d bit(20)
+	);
 	`}
 
 	dailytest.RunDailyTest(sourceDB, tableSQLs, cfg.WorkerCount, cfg.JobCount, cfg.Batch)