From ced81e547b795b297a544407511557fe2408a3c6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dani=C3=ABl=20van=20Eeden?= <git@myname.nl>
Date: Sat, 26 Oct 2024 13:48:46 +0200
Subject: [PATCH] dump: Support newer mysqldump versions

Old mysqldump used `CHANGE MASTER TO ...` and newer versions use `CHANGE
REPLICATION SOURCE ...`.
---
 dump/parser.go      |  6 +++---
 dump/parser_test.go | 28 ++++++++++++++++++++++++++++
 2 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/dump/parser.go b/dump/parser.go
index dd39f8015..529e78bd9 100644
--- a/dump/parser.go
+++ b/dump/parser.go
@@ -29,7 +29,7 @@ var valuesExp *regexp.Regexp
 var gtidExp *regexp.Regexp
 
 func init() {
-	binlogExp = regexp.MustCompile(`^CHANGE MASTER TO MASTER_LOG_FILE='(.+)', MASTER_LOG_POS=(\d+);`)
+	binlogExp = regexp.MustCompile(`^CHANGE (MASTER|REPLICATION SOURCE) TO (MASTER_LOG_FILE|SOURCE_LOG_FILE)='(.+)', (MASTER_LOG_POS|SOURCE_LOG_POS)=(\d+);`)
 	useExp = regexp.MustCompile("^USE `(.+)`;")
 	valuesExp = regexp.MustCompile("^INSERT INTO `(.+?)` VALUES \\((.+)\\);$")
 	// The pattern will only match MySQL GTID, as you know SET GLOBAL gtid_slave_pos='0-1-4' is used for MariaDB.
@@ -71,8 +71,8 @@ func Parse(r io.Reader, h ParseHandler, parseBinlogPos bool) error {
 				}
 			}
 			if m := binlogExp.FindAllStringSubmatch(line, -1); len(m) == 1 {
-				name := m[0][1]
-				pos, err := strconv.ParseUint(m[0][2], 10, 64)
+				name := m[0][3]
+				pos, err := strconv.ParseUint(m[0][5], 10, 64)
 				if err != nil {
 					return errors.Errorf("parse binlog %v err, invalid number", line)
 				}
diff --git a/dump/parser_test.go b/dump/parser_test.go
index 3e5fc9ba0..c3dc2ddcc 100644
--- a/dump/parser_test.go
+++ b/dump/parser_test.go
@@ -8,6 +8,34 @@ import (
 	"github.com/stretchr/testify/require"
 )
 
+// This tests the binlogExp regexp that matches the line that mysqldump adds when called with --master-data or --source-data
+func TestBinlogExp(t *testing.T) {
+	stmts := []struct {
+		input string
+		file  string
+		pos   string
+	}{
+		{
+			// MySQL 9.1.0
+			`CHANGE REPLICATION SOURCE TO SOURCE_LOG_FILE='binlog.000002', SOURCE_LOG_POS=170923;`,
+			`binlog.000002`,
+			`170923`,
+		},
+		{
+			`CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.008995', MASTER_LOG_POS=102052485;`,
+			`mysql-bin.008995`,
+			`102052485`,
+		},
+	}
+
+	for _, stmt := range stmts {
+		m := binlogExp.FindAllStringSubmatch(stmt.input, -1)
+		require.NotNil(t, m)
+		require.Equal(t, stmt.file, m[0][3])
+		require.Equal(t, stmt.pos, m[0][5])
+	}
+}
+
 func TestParseGtidExp(t *testing.T) {
 	//	binlogExp := regexp.MustCompile("^CHANGE MASTER TO MASTER_LOG_FILE='(.+)', MASTER_LOG_POS=(\\d+);")
 	//	gtidExp := regexp.MustCompile("(\\w{8}(-\\w{4}){3}-\\w{12}:\\d+-\\d+)")