(ctx context.Context, tCtx base.TransformContext, statementInfoList []statementInfo, databaseName string, tablePrefix string)
| 615 | } |
| 616 | |
| 617 | func generateSQLForMixedDML(ctx context.Context, tCtx base.TransformContext, statementInfoList []statementInfo, databaseName string, tablePrefix string) ([]base.BackupStatement, error) { |
| 618 | var result []base.BackupStatement |
| 619 | offsetLength := 1 |
| 620 | if len(statementInfoList) > 1 { |
| 621 | offsetLength = base.GetOffsetLength(statementInfoList[len(statementInfoList)-1].offset) |
| 622 | } |
| 623 | |
| 624 | for _, statementInfo := range statementInfoList { |
| 625 | table := statementInfo.table |
| 626 | targetTable := fmt.Sprintf("%s_%0*d_%s", tablePrefix, offsetLength, statementInfo.offset, table.Table) |
| 627 | targetTable, _ = common.TruncateString(targetTable, maxTableNameLength) |
| 628 | // If enforce_gtid_consistency = true, we cannot run CREATE TABLE .. AS SELECT. |
| 629 | // So we create the table first and then run INSERT INTO .. SELECT. |
| 630 | var buf strings.Builder |
| 631 | if _, err := fmt.Fprintf(&buf, "CREATE TABLE `%s`.`%s` LIKE `%s`.`%s`;\n", databaseName, targetTable, table.Database, table.Table); err != nil { |
| 632 | return nil, errors.Wrap(err, "failed to write create table statement") |
| 633 | } |
| 634 | generatedColumns, normalColumns, err := classifyColumns(ctx, tCtx.GetDatabaseMetadataFunc, tCtx.ListDatabaseNamesFunc, tCtx.IsCaseSensitive, tCtx.InstanceID, table) |
| 635 | if err != nil { |
| 636 | return nil, errors.Wrap(err, "failed to classify columns") |
| 637 | } |
| 638 | tableNameOrAlias := table.Table |
| 639 | if len(table.Alias) > 0 { |
| 640 | tableNameOrAlias = table.Alias |
| 641 | } |
| 642 | if len(generatedColumns) == 0 { |
| 643 | if _, err := fmt.Fprintf(&buf, "INSERT INTO `%s`.`%s` ", databaseName, targetTable); err != nil { |
| 644 | return nil, errors.Wrap(err, "failed to write insert into statement") |
| 645 | } |
| 646 | if err := writeCTEPrefix(&buf, statementInfo.node, statementInfo.fullSQL); err != nil { |
| 647 | return nil, errors.Wrap(err, "failed to write cte") |
| 648 | } |
| 649 | if _, err := fmt.Fprintf(&buf, "SELECT `%s`.* FROM ", tableNameOrAlias); err != nil { |
| 650 | return nil, errors.Wrap(err, "failed to write select statement") |
| 651 | } |
| 652 | } else { |
| 653 | if _, err := fmt.Fprintf(&buf, "INSERT INTO `%s`.`%s` (", databaseName, targetTable); err != nil { |
| 654 | return nil, errors.Wrap(err, "failed to write insert into statement") |
| 655 | } |
| 656 | for i, column := range normalColumns { |
| 657 | if i > 0 { |
| 658 | if err := buf.WriteByte(','); err != nil { |
| 659 | return nil, errors.Wrap(err, "failed to write comma") |
| 660 | } |
| 661 | } |
| 662 | if _, err := fmt.Fprintf(&buf, "`%s`", column); err != nil { |
| 663 | return nil, errors.Wrap(err, "failed to write column") |
| 664 | } |
| 665 | } |
| 666 | if _, err := buf.WriteString(") "); err != nil { |
| 667 | return nil, errors.Wrap(err, "failed to write select") |
| 668 | } |
| 669 | if err := writeCTEPrefix(&buf, statementInfo.node, statementInfo.fullSQL); err != nil { |
| 670 | return nil, errors.Wrap(err, "failed to write cte") |
| 671 | } |
| 672 | if _, err := buf.WriteString("SELECT "); err != nil { |
| 673 | return nil, errors.Wrap(err, "failed to write select") |
| 674 | } |
no test coverage detected