@@ -1234,46 +1234,68 @@ func (this *Applier) ApplyDMLEventQueries(dmlEvents [](*binlog.BinlogDMLEvent))
12341234 if _ , err := tx .Exec (sessionQuery ); err != nil {
12351235 return rollback (err )
12361236 }
1237- rowDeltas := make ([]int64 , 0 , len (dmlEvents ))
1238- multiArgs := []driver.NamedValue {}
1239- var multiQueryBuilder strings.Builder
1237+
1238+ buildResults := make ([]* dmlBuildResult , 0 , len (dmlEvents ))
12401239 for _ , dmlEvent := range dmlEvents {
12411240 for _ , buildResult := range this .buildDMLEventQuery (dmlEvent ) {
12421241 if buildResult .err != nil {
12431242 return rollback (buildResult .err )
12441243 }
1245- for _ , arg := range buildResult .args {
1246- multiArgs = append (multiArgs , driver.NamedValue {Value : driver .Value (arg )})
1247- }
1248- rowDeltas = append (rowDeltas , buildResult .rowsDelta )
1249- multiQueryBuilder .WriteString (buildResult .query )
1250- multiQueryBuilder .WriteString (";\n " )
1244+
1245+ buildResults = append (buildResults , buildResult )
12511246 }
12521247 }
12531248
1254- //this.migrationContext.Log.Infof("Executing query: %s, args: %+v", multiQueryBuilder.String(), multiArgs)
12551249 execErr := conn .Raw (func (driverConn any ) error {
12561250 ex , ok := driverConn .(driver.ExecerContext )
12571251 if ! ok {
12581252 return fmt .Errorf ("could not cast driverConn to ExecerContext" )
12591253 }
1254+
1255+ nvc , ok := driverConn .(driver.NamedValueChecker )
1256+ if ! ok {
1257+ return fmt .Errorf ("could not cast driverConn to NamedValueChecker" )
1258+ }
1259+
1260+ var multiArgs []driver.NamedValue
1261+ multiQueryBuilder := strings.Builder {}
1262+ var rowDeltas []int64
1263+
1264+ for _ , buildResult := range buildResults {
1265+ for _ , arg := range buildResult .args {
1266+ nv := driver.NamedValue {Value : driver .Value (arg )}
1267+ nvc .CheckNamedValue (& nv )
1268+ multiArgs = append (multiArgs , nv )
1269+ }
1270+
1271+ multiQueryBuilder .WriteString (buildResult .query )
1272+ multiQueryBuilder .WriteString (";\n " )
1273+
1274+ rowDeltas = append (rowDeltas , buildResult .rowsDelta )
1275+ }
1276+
1277+ // this.migrationContext.Log.Infof("Executing query: %s, args: %+v", multiQueryBuilder.String(), multiArgs)
12601278 res , err := ex .ExecContext (ctx , multiQueryBuilder .String (), multiArgs )
12611279 if err != nil {
12621280 err = fmt .Errorf ("%w; query=%s; args=%+v" , err , multiQueryBuilder .String (), multiArgs )
12631281 this .migrationContext .Log .Errorf ("Error exec: %+v" , err )
12641282 return err
12651283 }
1284+
12661285 mysqlRes , ok := res .(drivermysql.Result )
12671286 if ! ok {
12681287 return fmt .Errorf ("Could not cast %+v to mysql.Result" , res )
12691288 }
1289+
12701290 // each DML is either a single insert (delta +1), update (delta +0) or delete (delta -1).
12711291 // multiplying by the rows actually affected (either 0 or 1) will give an accurate row delta for this DML event
12721292 for i , rowsAffected := range mysqlRes .AllRowsAffected () {
12731293 totalDelta += rowDeltas [i ] * rowsAffected
12741294 }
1295+
12751296 return nil
12761297 })
1298+
12771299 if execErr != nil {
12781300 return rollback (execErr )
12791301 }
0 commit comments