From 9a78d8a46616ff7cf57f36e336db00abb6197056 Mon Sep 17 00:00:00 2001 From: lxfeng1997 <824141436@qq.com> Date: Fri, 29 Nov 2024 16:16:08 +0800 Subject: [PATCH 1/2] only inserted fields --- pkg/datasource/sql/exec/at/insert_executor.go | 7 ++++-- .../builder/mysql_insert_undo_log_builder.go | 7 ++++-- .../mysql_multi_update_undo_log_builder.go | 22 +++++++++++++++++-- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/pkg/datasource/sql/exec/at/insert_executor.go b/pkg/datasource/sql/exec/at/insert_executor.go index a05da5062..d1c7b4cee 100644 --- a/pkg/datasource/sql/exec/at/insert_executor.go +++ b/pkg/datasource/sql/exec/at/insert_executor.go @@ -184,9 +184,12 @@ func (i *insertExecutor) buildAfterImageSQL(ctx context.Context) (string, []driv } // build check sql sb := strings.Builder{} - sb.WriteString("SELECT * FROM " + tableName) + suffix := strings.Builder{} + sb.WriteString("SELECT " + strings.Join(pkColumnNameList, ", ")) + suffix.WriteString(" FROM " + tableName) whereSQL := i.buildWhereConditionByPKs(pkColumnNameList, len(pkValuesMap[pkColumnNameList[0]]), "mysql", maxInSize) - sb.WriteString(" WHERE " + whereSQL + " ") + suffix.WriteString(" WHERE " + whereSQL + " ") + sb.WriteString(suffix.String()) return sb.String(), i.buildPKParams(pkRowImages, pkColumnNameList), nil } diff --git a/pkg/datasource/sql/undo/builder/mysql_insert_undo_log_builder.go b/pkg/datasource/sql/undo/builder/mysql_insert_undo_log_builder.go index c837579bd..6144e66b6 100644 --- a/pkg/datasource/sql/undo/builder/mysql_insert_undo_log_builder.go +++ b/pkg/datasource/sql/undo/builder/mysql_insert_undo_log_builder.go @@ -132,9 +132,12 @@ func (u *MySQLInsertUndoLogBuilder) buildAfterImageSQL(ctx context.Context, exec } // build check sql sb := strings.Builder{} - sb.WriteString("SELECT * FROM " + tableName) + suffix := strings.Builder{} + sb.WriteString("SELECT " + strings.Join(pkColumnNameList, ", ")) + suffix.WriteString(" FROM " + tableName) whereSQL := u.buildWhereConditionByPKs(pkColumnNameList, len(pkValuesMap[pkColumnNameList[0]]), "mysql", maxInSize) - sb.WriteString(" WHERE " + whereSQL + " ") + suffix.WriteString(" WHERE " + whereSQL + " ") + sb.WriteString(suffix.String()) return sb.String(), u.buildPKParams(pkRowImages, pkColumnNameList), nil } diff --git a/pkg/datasource/sql/undo/builder/mysql_multi_update_undo_log_builder.go b/pkg/datasource/sql/undo/builder/mysql_multi_update_undo_log_builder.go index 57b9f6ca5..0c15af393 100644 --- a/pkg/datasource/sql/undo/builder/mysql_multi_update_undo_log_builder.go +++ b/pkg/datasource/sql/undo/builder/mysql_multi_update_undo_log_builder.go @@ -138,8 +138,26 @@ func (u *MySQLMultiUpdateUndoLogBuilder) AfterImage(ctx context.Context, execCtx func (u *MySQLMultiUpdateUndoLogBuilder) buildAfterImageSQL(beforeImage *types.RecordImage, meta types.TableMeta) (string, []driver.Value) { sb := strings.Builder{} - // todo use ONLY_CARE_UPDATE_COLUMNS to judge select all columns or not - sb.WriteString("SELECT * FROM " + meta.TableName + " ") + var selectFieldsStr string + selectFields := make([]string, 0, len(meta.ColumnNames)) + var fieldsExits = make(map[string]struct{}) + if undo.UndoConfig.OnlyCareUpdateColumns { + for _, row := range beforeImage.Rows { + for _, column := range row.Columns { + if _, exist := fieldsExits[column.ColumnName]; exist { + continue + } + + fieldsExits[column.ColumnName] = struct{}{} + selectFields = append(selectFields, column.ColumnName) + } + } + selectFieldsStr = strings.Join(selectFields, ",") + } else { + selectFieldsStr = strings.Join(meta.ColumnNames, ",") + } + + sb.WriteString("SELECT " + selectFieldsStr + " FROM " + meta.TableName + " ") whereSQL := u.buildWhereConditionByPKs(meta.GetPrimaryKeyOnlyName(), len(beforeImage.Rows), "mysql", maxInSize) sb.WriteString(" " + whereSQL + " ") return sb.String(), u.buildPKParams(beforeImage.Rows, meta.GetPrimaryKeyOnlyName()) From 97a253bea35d5287f00cf5c07b44a7e8db93753c Mon Sep 17 00:00:00 2001 From: lxfeng1997 <824141436@qq.com> Date: Sun, 15 Dec 2024 15:05:39 +0800 Subject: [PATCH 2/2] It is suspected that it is not used, so restore the previous code --- pkg/datasource/sql/exec/at/base_executor.go | 43 +++++++++++++++++++ pkg/datasource/sql/exec/at/insert_executor.go | 9 +++- .../sql/exec/at/insert_executor_test.go | 4 +- .../builder/mysql_insert_undo_log_builder.go | 7 +-- .../mysql_multi_update_undo_log_builder.go | 22 +--------- 5 files changed, 56 insertions(+), 29 deletions(-) diff --git a/pkg/datasource/sql/exec/at/base_executor.go b/pkg/datasource/sql/exec/at/base_executor.go index 75f0cab56..05f440577 100644 --- a/pkg/datasource/sql/exec/at/base_executor.go +++ b/pkg/datasource/sql/exec/at/base_executor.go @@ -23,6 +23,7 @@ import ( "database/sql" "database/sql/driver" "fmt" + "seata.apache.org/seata-go/pkg/datasource/sql/undo" "strings" "github.com/arana-db/parser/ast" @@ -187,6 +188,48 @@ func (b *baseExecutor) buildRecordImages(rowsi driver.Rows, tableMetaData *types return &types.RecordImage{TableName: tableMetaData.TableName, Rows: rowImages, SQLType: sqlType}, nil } +func (b *baseExecutor) getNeedColumns(meta *types.TableMeta, columns []string, dbType types.DBType) []string { + var needUpdateColumns []string + if undo.UndoConfig.OnlyCareUpdateColumns && columns != nil && len(columns) > 0 { + needUpdateColumns = columns + if !b.containsPKByName(meta, columns) { + pkNames := meta.GetPrimaryKeyOnlyName() + if pkNames != nil && len(pkNames) > 0 { + for _, name := range pkNames { + needUpdateColumns = append(needUpdateColumns, name) + } + } + } + // todo If it contains onUpdate columns, add onUpdate columns + } else { + needUpdateColumns = meta.ColumnNames + } + + for i := range needUpdateColumns { + needUpdateColumns[i] = AddEscape(needUpdateColumns[i], dbType) + } + return needUpdateColumns +} + +func (b *baseExecutor) containsPKByName(meta *types.TableMeta, columns []string) bool { + pkColumnNameList := meta.GetPrimaryKeyOnlyName() + if len(pkColumnNameList) == 0 { + return false + } + + matchCounter := 0 + for _, column := range columns { + for _, pkName := range pkColumnNameList { + if strings.EqualFold(pkName, column) || + strings.EqualFold(pkName, strings.ToLower(column)) { + matchCounter++ + } + } + } + + return matchCounter == len(pkColumnNameList) +} + func getSqlNullValue(value interface{}) interface{} { if value == nil { return nil diff --git a/pkg/datasource/sql/exec/at/insert_executor.go b/pkg/datasource/sql/exec/at/insert_executor.go index d1c7b4cee..ae7bac71d 100644 --- a/pkg/datasource/sql/exec/at/insert_executor.go +++ b/pkg/datasource/sql/exec/at/insert_executor.go @@ -185,9 +185,14 @@ func (i *insertExecutor) buildAfterImageSQL(ctx context.Context) (string, []driv // build check sql sb := strings.Builder{} suffix := strings.Builder{} - sb.WriteString("SELECT " + strings.Join(pkColumnNameList, ", ")) + var insertColumns []string + + for _, column := range i.parserCtx.InsertStmt.Columns { + insertColumns = append(insertColumns, column.Name.O) + } + sb.WriteString("SELECT " + strings.Join(i.getNeedColumns(meta, insertColumns, types.DBTypeMySQL), ", ")) suffix.WriteString(" FROM " + tableName) - whereSQL := i.buildWhereConditionByPKs(pkColumnNameList, len(pkValuesMap[pkColumnNameList[0]]), "mysql", maxInSize) + whereSQL := i.buildWhereConditionByPKs(pkColumnNameList, rowSize, "mysql", maxInSize) suffix.WriteString(" WHERE " + whereSQL + " ") sb.WriteString(suffix.String()) return sb.String(), i.buildPKParams(pkRowImages, pkColumnNameList), nil diff --git a/pkg/datasource/sql/exec/at/insert_executor_test.go b/pkg/datasource/sql/exec/at/insert_executor_test.go index fa899df11..742249bc4 100644 --- a/pkg/datasource/sql/exec/at/insert_executor_test.go +++ b/pkg/datasource/sql/exec/at/insert_executor_test.go @@ -78,7 +78,7 @@ func TestBuildSelectSQLByInsert(t *testing.T) { }, }, - expectQuery: "SELECT * FROM user WHERE (`id`) IN ((?),(?)) ", + expectQuery: "SELECT id, name FROM user WHERE (`id`) IN ((?),(?)) ", expectQueryArgs: []driver.Value{int64(19), int64(21)}, }, { @@ -107,7 +107,7 @@ func TestBuildSelectSQLByInsert(t *testing.T) { }, }, }, - expectQuery: "SELECT * FROM user WHERE (`user_id`) IN ((?)) ", + expectQuery: "SELECT user_id, name FROM user WHERE (`user_id`) IN ((?)) ", expectQueryArgs: []driver.Value{int64(20)}, }, } diff --git a/pkg/datasource/sql/undo/builder/mysql_insert_undo_log_builder.go b/pkg/datasource/sql/undo/builder/mysql_insert_undo_log_builder.go index 6144e66b6..c837579bd 100644 --- a/pkg/datasource/sql/undo/builder/mysql_insert_undo_log_builder.go +++ b/pkg/datasource/sql/undo/builder/mysql_insert_undo_log_builder.go @@ -132,12 +132,9 @@ func (u *MySQLInsertUndoLogBuilder) buildAfterImageSQL(ctx context.Context, exec } // build check sql sb := strings.Builder{} - suffix := strings.Builder{} - sb.WriteString("SELECT " + strings.Join(pkColumnNameList, ", ")) - suffix.WriteString(" FROM " + tableName) + sb.WriteString("SELECT * FROM " + tableName) whereSQL := u.buildWhereConditionByPKs(pkColumnNameList, len(pkValuesMap[pkColumnNameList[0]]), "mysql", maxInSize) - suffix.WriteString(" WHERE " + whereSQL + " ") - sb.WriteString(suffix.String()) + sb.WriteString(" WHERE " + whereSQL + " ") return sb.String(), u.buildPKParams(pkRowImages, pkColumnNameList), nil } diff --git a/pkg/datasource/sql/undo/builder/mysql_multi_update_undo_log_builder.go b/pkg/datasource/sql/undo/builder/mysql_multi_update_undo_log_builder.go index 0c15af393..57b9f6ca5 100644 --- a/pkg/datasource/sql/undo/builder/mysql_multi_update_undo_log_builder.go +++ b/pkg/datasource/sql/undo/builder/mysql_multi_update_undo_log_builder.go @@ -138,26 +138,8 @@ func (u *MySQLMultiUpdateUndoLogBuilder) AfterImage(ctx context.Context, execCtx func (u *MySQLMultiUpdateUndoLogBuilder) buildAfterImageSQL(beforeImage *types.RecordImage, meta types.TableMeta) (string, []driver.Value) { sb := strings.Builder{} - var selectFieldsStr string - selectFields := make([]string, 0, len(meta.ColumnNames)) - var fieldsExits = make(map[string]struct{}) - if undo.UndoConfig.OnlyCareUpdateColumns { - for _, row := range beforeImage.Rows { - for _, column := range row.Columns { - if _, exist := fieldsExits[column.ColumnName]; exist { - continue - } - - fieldsExits[column.ColumnName] = struct{}{} - selectFields = append(selectFields, column.ColumnName) - } - } - selectFieldsStr = strings.Join(selectFields, ",") - } else { - selectFieldsStr = strings.Join(meta.ColumnNames, ",") - } - - sb.WriteString("SELECT " + selectFieldsStr + " FROM " + meta.TableName + " ") + // todo use ONLY_CARE_UPDATE_COLUMNS to judge select all columns or not + sb.WriteString("SELECT * FROM " + meta.TableName + " ") whereSQL := u.buildWhereConditionByPKs(meta.GetPrimaryKeyOnlyName(), len(beforeImage.Rows), "mysql", maxInSize) sb.WriteString(" " + whereSQL + " ") return sb.String(), u.buildPKParams(beforeImage.Rows, meta.GetPrimaryKeyOnlyName())