-
Notifications
You must be signed in to change notification settings - Fork 25.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SQL: Fix issue with field names containing "." #37364
Changes from 3 commits
35213d6
e75a4e8
266cd2b
b38aa31
7c17a51
eec5897
07fa7a8
00e5c09
c39978f
d8fdb93
818e48d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,7 @@ | |
package org.elasticsearch.xpack.sql.execution.search.extractor; | ||
|
||
import org.elasticsearch.common.Strings; | ||
import org.elasticsearch.common.collect.Tuple; | ||
import org.elasticsearch.common.document.DocumentField; | ||
import org.elasticsearch.common.io.stream.StreamInput; | ||
import org.elasticsearch.common.io.stream.StreamOutput; | ||
|
@@ -39,7 +40,7 @@ public class FieldHitExtractor implements HitExtractor { | |
*/ | ||
private static String[] sourcePath(String name, boolean useDocValue, String hitName) { | ||
return useDocValue ? Strings.EMPTY_ARRAY : Strings | ||
.tokenizeToStringArray(hitName == null ? name : name.substring(hitName.length() + 1), "."); | ||
.tokenizeToStringArray(hitName == null ? name : name.substring(hitName.length() + 1), "."); | ||
} | ||
|
||
private final String fieldName, hitName; | ||
|
@@ -144,19 +145,44 @@ Object extractFromSource(Map<String, Object> map) { | |
Object value = map; | ||
boolean first = true; | ||
// each node is a key inside the map | ||
for (String node : path) { | ||
for (int i = 0; i < path.length; i++) { | ||
String node = path[i]; | ||
if (value == null) { | ||
return null; | ||
} else if (first || value instanceof Map) { | ||
first = false; | ||
value = ((Map<String, Object>) value).get(node); | ||
map = ((Map<String, Object>) value); | ||
value = map.get(node); | ||
if (value == null) { // Try to extract field with dots (e.g.: "b.c") | ||
Tuple<Object, Integer> tuple = extractAsDottedField(map, i, node); | ||
value = tuple.v1(); | ||
if (value != null) { | ||
if (value instanceof Map) { | ||
i = tuple.v2(); | ||
} else { | ||
return unwrapMultiValue(value); | ||
} | ||
} | ||
} | ||
} else { | ||
throw new SqlIllegalArgumentException("Cannot extract value [{}] from source", fieldName); | ||
} | ||
} | ||
return unwrapMultiValue(value); | ||
} | ||
|
||
private Tuple<Object, Integer> extractAsDottedField(Map<String, Object> map, int idx, String node) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm thinking to remove this extracted code back to the body of Also the code might be a bit ugly but I wanted to avoid calling recursively a method (with every combination of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1. It looks like a small method and while it might be inlined the extra |
||
Object value = null; | ||
StringBuilder sb = new StringBuilder(node); | ||
int i = idx + 1; | ||
while (value == null && i < path.length) { | ||
sb.append(".").append(path[i]); | ||
value = map.get(sb.toString()); | ||
i++; | ||
} | ||
return new Tuple<>(value, i - 1); | ||
} | ||
|
||
@Override | ||
public String hitName() { | ||
return hitName; | ||
|
@@ -178,8 +204,8 @@ public boolean equals(Object obj) { | |
} | ||
FieldHitExtractor other = (FieldHitExtractor) obj; | ||
return fieldName.equals(other.fieldName) | ||
&& hitName.equals(other.hitName) | ||
&& useDocValue == other.useDocValue; | ||
&& hitName.equals(other.hitName) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again with the formatting... |
||
&& useDocValue == other.useDocValue; | ||
} | ||
|
||
@Override | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's definitely some formatting differences here.
Anyway, make sure you set your IDE to format only the lines that were modified as that prevents unnecessary changes like the above.