diff --git a/internal/app/push/cli.go b/internal/app/push/cli.go index 5fa345e4..a22d1564 100755 --- a/internal/app/push/cli.go +++ b/internal/app/push/cli.go @@ -312,7 +312,7 @@ func (c idToPushConverter) getTable(name string, autoTruncate bool) push.Table { columns := []push.Column{} for _, col := range table.Columns { - columns = append(columns, push.NewColumn(col.Name, col.Export, col.Import, col.DBInfo.Length, col.DBInfo.ByteBased, autoTruncate)) + columns = append(columns, push.NewColumn(col.Name, col.Export, col.Import, col.DBInfo.Length, col.DBInfo.ByteBased, autoTruncate, col.DBInfo.Preserve)) } return push.NewTable(table.Name, table.Keys, push.NewColumnList(columns)) diff --git a/internal/infra/push/datadestination_oracle.go b/internal/infra/push/datadestination_oracle.go index 59815727..f6e184f7 100644 --- a/internal/infra/push/datadestination_oracle.go +++ b/internal/infra/push/datadestination_oracle.go @@ -148,9 +148,13 @@ func (d OracleDialect) UpdateStatement(tableName string, selectValues []ValueDes headers = append(headers, column) - sql.WriteString(column.name) - sql.WriteString("=") - sql.WriteString(d.Placeholder(index + 1)) + if column.column.Preserve() == "null" { + sql.WriteString(fmt.Sprintf("%s = CASE WHEN %s IS NOT NULL THEN %s ELSE %s END", column.name, column.name, d.Placeholder(index+1), column.name)) + } else { + sql.WriteString(column.name) + sql.WriteString("=") + sql.WriteString(d.Placeholder(index + 1)) + } if index+1 < len(selectValues) { sql.WriteString(", ") } diff --git a/internal/infra/table/storage_yaml.go b/internal/infra/table/storage_yaml.go index 68f226b7..14be1074 100755 --- a/internal/infra/table/storage_yaml.go +++ b/internal/infra/table/storage_yaml.go @@ -57,6 +57,7 @@ type YAMLDBInfo struct { Size int64 `yaml:"size,omitempty"` Precision int64 `yaml:"precision,omitempty"` ByteBased bool `yaml:"bytes,omitempty"` + Preserve string `yaml:"preserve,omitempty"` } // YAMLStorage provides storage in a local YAML file diff --git a/pkg/push/model.go b/pkg/push/model.go index b1fc7d10..22f90494 100755 --- a/pkg/push/model.go +++ b/pkg/push/model.go @@ -48,6 +48,7 @@ type Column interface { Length() int64 LengthInBytes() bool Truncate() bool + Preserve() string } // Plan describe how to push data diff --git a/pkg/push/model_table.go b/pkg/push/model_table.go index 551d2b38..d0f976c9 100755 --- a/pkg/push/model_table.go +++ b/pkg/push/model_table.go @@ -96,11 +96,12 @@ type column struct { lgth int64 inbytes bool truncate bool + preserve string } // NewColumn initialize a new Column object -func NewColumn(name string, exp string, imp string, lgth int64, inbytes bool, truncate bool) Column { - return column{name, exp, imp, lgth, inbytes, truncate} +func NewColumn(name string, exp string, imp string, lgth int64, inbytes bool, truncate bool, preserve string) Column { + return column{name, exp, imp, lgth, inbytes, truncate, preserve} } func (c column) Name() string { return c.name } @@ -109,6 +110,7 @@ func (c column) Import() string { return c.imp } func (c column) Length() int64 { return c.lgth } func (c column) LengthInBytes() bool { return c.inbytes } func (c column) Truncate() bool { return c.truncate } +func (c column) Preserve() string { return c.preserve } type ImportedRow struct { jsonline.Row diff --git a/pkg/table/model.go b/pkg/table/model.go index a7dbe2e4..3e09ab73 100755 --- a/pkg/table/model.go +++ b/pkg/table/model.go @@ -24,6 +24,7 @@ type DBInfo struct { Size int64 Precision int64 ByteBased bool + Preserve string } // Column holds the name of a column.