Skip to content

Commit 61f62df

Browse files
authored
Fix allow_duplicates edge case bug in append processor (#134319) (#134386)
1 parent 5d2c09c commit 61f62df

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
@@ -556,7 +556,7 @@ private void setFieldValue(String path, Object value, boolean append, boolean al
556556
Object object = map.getOrDefault(leafKey, NOT_FOUND); // getOrDefault is faster than containsKey + get
557557
if (object == NOT_FOUND) {
558558
List<Object> list = new ArrayList<>();
559-
appendValues(list, value);
559+
appendValues(list, value, allowDuplicates);
560560
map.put(leafKey, list);
561561
} else {
562562
Object list = appendValues(object, value, allowDuplicates);
@@ -606,23 +606,25 @@ private static Object appendValues(Object maybeList, Object value, boolean allow
606606
list.add(maybeList);
607607
}
608608
if (allowDuplicates) {
609-
appendValues(list, value);
609+
innerAppendValues(list, value);
610610
return list;
611611
} else {
612612
// if no values were appended due to duplication, return the original object so the ingest document remains unmodified
613-
return appendValuesWithoutDuplicates(list, value) ? list : maybeList;
613+
return innerAppendValuesWithoutDuplicates(list, value) ? list : maybeList;
614614
}
615615
}
616616

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

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

0 commit comments

Comments
 (0)