Skip to content

Commit ca96643

Browse files
authored
Fix allow_duplicates edge case bug in append processor (#134319) (#134387)
1 parent e60d312 commit ca96643

File tree

3 files changed

+122
-5
lines changed

3 files changed

+122
-5
lines changed

docs/changelog/134319.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 134319
2+
summary: Fix `allow_duplicates` edge case bug in append processor
3+
area: Ingest Node
4+
type: bug
5+
issues: []
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
---
2+
setup:
3+
- do:
4+
ingest.put_pipeline:
5+
id: "test-pipeline-1"
6+
body: >
7+
{
8+
"processors": [
9+
{
10+
"append": {
11+
"if": "ctx?.templating == true",
12+
"field": "dest",
13+
"value": ["{{three}}", "{{three}}", "{{three}}"],
14+
"allow_duplicates": false
15+
}
16+
},
17+
{
18+
"foreach": {
19+
"description": "templating results in strings, so convert them if necessary",
20+
"field": "dest",
21+
"processor": {
22+
"convert": {
23+
"field": "_ingest._value",
24+
"type": "long"
25+
}
26+
}
27+
}
28+
},
29+
{
30+
"remove": {
31+
"description": "we only care about the dest, so remove everything else",
32+
"keep": ["dest"]
33+
}
34+
}
35+
]
36+
}
37+
- do:
38+
indices.create:
39+
index: "test-some-index"
40+
41+
---
42+
teardown:
43+
- do:
44+
indices.delete:
45+
index: "test-some-index"
46+
ignore_unavailable: true
47+
- do:
48+
ingest.delete_pipeline:
49+
id: "test-pipeline-1"
50+
ignore: 404
51+
52+
---
53+
"allow_duplicates (false) removes duplicates with a present array and templating":
54+
- do:
55+
index:
56+
index: test-some-index
57+
id: 1
58+
pipeline: test-pipeline-1
59+
body: >
60+
{
61+
"templating": true,
62+
"three": 3,
63+
"dest": ["3"],
64+
"note": "blargh, duplicate removal is based on strings, because of templating"
65+
}
66+
67+
- do:
68+
get:
69+
index: test-some-index
70+
id: "1"
71+
- match: { _source.dest: [3] }
72+
73+
---
74+
"allow_duplicates (false) removes duplicates with an empty array and templating":
75+
- do:
76+
index:
77+
index: test-some-index
78+
id: 1
79+
pipeline: test-pipeline-1
80+
body: >
81+
{
82+
"templating": true,
83+
"three": 3,
84+
"dest": []
85+
}
86+
87+
- do:
88+
get:
89+
index: test-some-index
90+
id: "1"
91+
- match: { _source.dest: [3] }
92+
93+
---
94+
"allow_duplicates (false) removes duplicates with a missing array and templating":
95+
- do:
96+
index:
97+
index: test-some-index
98+
id: 1
99+
pipeline: test-pipeline-1
100+
body: >
101+
{
102+
"templating": true,
103+
"three": 3
104+
}
105+
106+
- do:
107+
get:
108+
index: test-some-index
109+
id: "1"
110+
- match: { _source.dest: [3] }

server/src/main/java/org/elasticsearch/ingest/IngestDocument.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -555,7 +555,7 @@ private void setFieldValue(String path, Object value, boolean append, boolean al
555555
Object object = map.getOrDefault(leafKey, NOT_FOUND); // getOrDefault is faster than containsKey + get
556556
if (object == NOT_FOUND) {
557557
List<Object> list = new ArrayList<>();
558-
appendValues(list, value);
558+
appendValues(list, value, allowDuplicates);
559559
map.put(leafKey, list);
560560
} else {
561561
Object list = appendValues(object, value, allowDuplicates);
@@ -605,23 +605,25 @@ private static Object appendValues(Object maybeList, Object value, boolean allow
605605
list.add(maybeList);
606606
}
607607
if (allowDuplicates) {
608-
appendValues(list, value);
608+
innerAppendValues(list, value);
609609
return list;
610610
} else {
611611
// if no values were appended due to duplication, return the original object so the ingest document remains unmodified
612-
return appendValuesWithoutDuplicates(list, value) ? list : maybeList;
612+
return innerAppendValuesWithoutDuplicates(list, value) ? list : maybeList;
613613
}
614614
}
615615

616-
private static void appendValues(List<Object> list, Object value) {
616+
// helper method for use in appendValues above, please do not call this directly except from that method
617+
private static void innerAppendValues(List<Object> list, Object value) {
617618
if (value instanceof List<?> l) {
618619
list.addAll(l);
619620
} else {
620621
list.add(value);
621622
}
622623
}
623624

624-
private static boolean appendValuesWithoutDuplicates(List<Object> list, Object value) {
625+
// helper method for use in appendValues above, please do not call this directly except from that method
626+
private static boolean innerAppendValuesWithoutDuplicates(List<Object> list, Object value) {
625627
boolean valuesWereAppended = false;
626628
if (value instanceof List<?> valueList) {
627629
for (Object val : valueList) {

0 commit comments

Comments
 (0)