Skip to content

Commit d14cd21

Browse files
authored
[Bug][Transform-V2] Enable regex replacement by default for FieldRename (#10321)
1 parent 11ea6ec commit d14cd21

File tree

7 files changed

+178
-5
lines changed

7 files changed

+178
-5
lines changed

docs/en/transforms/field-rename.md

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ FieldRename transform plugin for rename field name.
1313
| convert_case | string | no | | The case conversion type. The options can be `UPPER`, `LOWER` |
1414
| prefix | string | no | | The prefix to be added to the field name |
1515
| suffix | string | no | | The suffix to be added to the field name |
16-
| replacements_with_regex | array | no | | The array of replacement rules with regex. The replacement rule is a map with `replace_from` and `replace_to` fields. |
16+
| replacements_with_regex | array | no | | The array of replacement rules. Each rule is a map with `replace_from`, `replace_to`, and optional `is_regex` (default `true`). When `is_regex=false`, `replace_from` is treated as an exact field name (full match). |
17+
| specific | array | no | | Specific rename rules. Each rule is a map with `field_name` and `target_name`. When matched, it will rename the field directly and skip other rename rules. |
1718

1819
## Examples
1920

@@ -73,6 +74,21 @@ sink {
7374
}
7475
```
7576

77+
### Rename specific fields
78+
79+
```
80+
transform {
81+
FieldRename {
82+
plugin_input = "input"
83+
plugin_output = "output"
84+
85+
specific = [
86+
{ field_name = "InvoiceNum", target_name = "invoice_num" }
87+
]
88+
}
89+
}
90+
```
91+
7692
### Convert field name to lowercase
7793

7894
```
@@ -129,4 +145,4 @@ sink {
129145
data_save_mode = "APPEND_DATA"
130146
}
131147
}
132-
```
148+
```

docs/zh/transforms/field-rename.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ FieldRename 用于批量重命名字段名。
1313
| convert_case | string || | 字母大小写转换类型,可选 `UPPER``LOWER` |
1414
| prefix | string || | 追加到字段名前的前缀 |
1515
| suffix | string || | 追加到字段名后的后缀 |
16-
| replacements_with_regex | array || | 正则替换规则数组,元素为包含 `replace_from``replace_to` 的映射,用于批量替换字段名 |
16+
| replacements_with_regex | array || | 替换规则数组,元素为包含 `replace_from``replace_to` 以及可选 `is_regex`(默认 `true`)的映射;当 `is_regex=false` 时,`replace_from` 按字段名精确匹配(全匹配) |
17+
| specific | array || | 指定字段重命名规则,元素为包含 `field_name``target_name` 的映射;命中后会直接重命名并跳过其他规则 |
1718

1819
## 示例
1920

@@ -73,6 +74,21 @@ sink {
7374
}
7475
```
7576

77+
### 指定字段重命名
78+
79+
```
80+
transform {
81+
FieldRename {
82+
plugin_input = "input"
83+
plugin_output = "output"
84+
85+
specific = [
86+
{ field_name = "InvoiceNum", target_name = "invoice_num" }
87+
]
88+
}
89+
}
90+
```
91+
7692
### 将字段名转为小写
7793

7894
```

seatunnel-e2e/seatunnel-transforms-v2-e2e/seatunnel-transforms-v2-e2e-part-2/src/test/java/org/apache/seatunnel/e2e/transform/TestRenameIT.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,11 @@ public void testRenameMultiTable(TestContainer container)
3434
container.executeJob("/table_field_rename_multi_table.conf");
3535
Assertions.assertEquals(0, execResult.getExitCode());
3636
}
37+
38+
@TestTemplate
39+
public void testFieldRenameRegexDefault(TestContainer container)
40+
throws IOException, InterruptedException {
41+
Container.ExecResult execResult = container.executeJob("/field_rename_regex_default.conf");
42+
Assertions.assertEquals(0, execResult.getExitCode());
43+
}
3744
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#
2+
# Licensed to the Apache Software Foundation (ASF) under one or more
3+
# contributor license agreements. See the NOTICE file distributed with
4+
# this work for additional information regarding copyright ownership.
5+
# The ASF licenses this file to You under the Apache License, Version 2.0
6+
# (the "License"); you may not use this file except in compliance with
7+
# the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
18+
env {
19+
parallelism = 1
20+
job.mode = "BATCH"
21+
}
22+
23+
source {
24+
FakeSource {
25+
plugin_output = "source1"
26+
27+
tables_configs = [
28+
{
29+
row.num = 1
30+
schema = {
31+
table = "test.regex"
32+
columns = [
33+
{
34+
name = "InvoiceNum"
35+
type = "bigint"
36+
},
37+
{
38+
name = "VendorID"
39+
type = "string"
40+
}
41+
]
42+
}
43+
}
44+
]
45+
}
46+
}
47+
48+
transform {
49+
FieldRename {
50+
plugin_input = "source1"
51+
plugin_output = "transform1"
52+
53+
convert_case = "LOWER"
54+
# intentionally omit is_regex to verify default behavior
55+
replacements_with_regex = [
56+
{
57+
replace_from = "(?<=[a-z0-9])(?=[A-Z])"
58+
replace_to = "_"
59+
}
60+
]
61+
}
62+
}
63+
64+
sink {
65+
Assert {
66+
plugin_input = "transform1"
67+
68+
rules =
69+
{
70+
tables_configs = [
71+
{
72+
table_path = "test.regex"
73+
row_rules = [
74+
{
75+
rule_type = MAX_ROW
76+
rule_value = 1
77+
},
78+
{
79+
rule_type = MIN_ROW
80+
rule_value = 1
81+
}
82+
],
83+
catalog_table_rule {
84+
table_path = "test.regex"
85+
column_rule = [
86+
{
87+
name = "invoice_num"
88+
type = "bigint"
89+
},
90+
{
91+
name = "vendor_id"
92+
type = "string"
93+
}
94+
]
95+
}
96+
}
97+
]
98+
}
99+
}
100+
}

seatunnel-transforms-v2/src/main/java/org/apache/seatunnel/transform/rename/FieldRenameConfig.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ public static class ReplacementsWithRegex implements Serializable {
114114
private String replaceTo;
115115

116116
@JsonAlias("is_regex")
117-
private Boolean isRegex;
117+
private Boolean isRegex = true;
118118
}
119119

120120
public static FieldRenameConfig of(ReadonlyConfig config) {

seatunnel-transforms-v2/src/main/java/org/apache/seatunnel/transform/rename/FieldRenameTransform.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ public String convertName(String name) {
143143
String replacement = replacementsWithRegex.getReplaceFrom();
144144
if (StringUtils.isNotEmpty(replacement)) {
145145
Map<Integer, Integer> matched = new LinkedHashMap<>();
146-
if (BooleanUtils.isNotTrue(isRegex)) {
146+
if (BooleanUtils.isFalse(isRegex)) {
147147
if (StringUtils.equals(replacement, name)) {
148148
matched.put(0, name.length());
149149
}

seatunnel-transforms-v2/src/test/java/org/apache/seatunnel/transform/rename/FieldRenameTransformTest.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,4 +240,38 @@ public void testRename() {
240240
Assertions.assertEquals("f5", outputChangeEvent.getColumn().getName());
241241
Assertions.assertEquals("f5", outputDropEvent.getColumn());
242242
}
243+
244+
@Test
245+
public void testRegexReplacementEnabledByDefault() {
246+
FieldRenameConfig.ReplacementsWithRegex rule =
247+
new FieldRenameConfig.ReplacementsWithRegex();
248+
rule.setReplaceFrom("(?<=[a-z0-9])(?=[A-Z])");
249+
rule.setReplaceTo("_");
250+
251+
FieldRenameConfig config =
252+
new FieldRenameConfig()
253+
.setConvertCase(ConvertCase.LOWER)
254+
.setReplacementsWithRegex(Collections.singletonList(rule));
255+
FieldRenameTransform transform = new FieldRenameTransform(config, DEFAULT_TABLE);
256+
257+
Assertions.assertEquals("invoice_num", transform.convertName("InvoiceNum"));
258+
Assertions.assertEquals("vendor_id", transform.convertName("VendorID"));
259+
}
260+
261+
@Test
262+
public void testRegexReplacementCanBeDisabled() {
263+
FieldRenameConfig.ReplacementsWithRegex rule =
264+
new FieldRenameConfig.ReplacementsWithRegex();
265+
rule.setReplaceFrom("(?<=[a-z0-9])(?=[A-Z])");
266+
rule.setReplaceTo("_");
267+
rule.setIsRegex(false);
268+
269+
FieldRenameConfig config =
270+
new FieldRenameConfig()
271+
.setConvertCase(ConvertCase.LOWER)
272+
.setReplacementsWithRegex(Collections.singletonList(rule));
273+
FieldRenameTransform transform = new FieldRenameTransform(config, DEFAULT_TABLE);
274+
275+
Assertions.assertEquals("invoicenum", transform.convertName("InvoiceNum"));
276+
}
243277
}

0 commit comments

Comments
 (0)