Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
## 6.10.2 [2026-03-27]

### Bug Fixes

1. [#864](https://github.com/influxdata/influxdb-client-java/pull/864): Correct tags parsing.
- Previous hot fix 6.10.1 used incorrect escapes in testing tag keys and values.
- This fix...
- Uses correctly escaped keys and values
- Updates the tags parser in InfluxQLQueryAPI to handle them correctly

## 6.10.1 [2026-03-25]

### Bug Fixes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,6 @@ private static Map<String, String> parseTags(@Nonnull final String value) {
StringBuilder currentValue = new StringBuilder();
boolean inValue = false;
boolean escaped = false;
boolean firstEscaped = false;

for (int i = 0; i < value.length(); i++) {
char c = value.charAt(i);
Expand All @@ -208,24 +207,9 @@ private static Map<String, String> parseTags(@Nonnull final String value) {

if (c == '\\') {
// start escape sequence
// preserve escape character
if (firstEscaped) {
// don't preserve escape character
escaped = true;
firstEscaped = false;
continue;
}
if (inValue) {
currentValue.append(c);
} else {
currentKey.append(c);
}
firstEscaped = true;
continue;
}

if (firstEscaped) {
firstEscaped = false;
continue;
}

if (!inValue && c == '=') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,15 +105,15 @@ void testQueryWithTagsWithEscapedChars() {
.addField("free", 10)
.addTag("host", "A")
.addTag("region", "west")
.addTag("location", "vancouver\\,\\ BC")
.addTag("model\\,\\ uid","droid\\,\\ C3PO")
.addTag("location", "vancouver, BC")
.addTag("model, uid","droid, C3PO")
);

Map<String,String> expectedTags = new HashMap<>();
expectedTags.put("host", "A");
expectedTags.put("region", "west");
expectedTags.put("location", "vancouver\\,\\ BC");
expectedTags.put("model\\,\\ uid","droid\\,\\ C3PO");
expectedTags.put("location", "vancouver, BC");
expectedTags.put("model, uid","droid, C3PO");

InfluxQLQueryResult result = influxQLQueryApi.query(
new InfluxQLQuery("SELECT * FROM \"specialTags\" GROUP BY *", DATABASE_NAME));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,10 @@ void readInfluxQLResultWithMalformedAndBoundaryTagCases() throws IOException {
assertParsedTags("host=a,", mapOf("host", "a"));
assertParsedTags(",host=a", mapOf(",host", "a"));
assertParsedTags("a=1,,b=2", mapOf("a", "1", ",b", "2"));
assertParsedTags("a=foo\\", mapOf("a", "foo\\"));
assertParsedTags("k\\\\==v\\\\=1", mapOf("k\\=", "v\\=1"));
assertParsedTags("k\\\\,x=v\\\\,y,b=2", mapOf("k\\,x", "v\\,y", "b", "2"));
assertParsedTags("k\\\\=x", mapOf());
assertParsedTags("a=foo\\", mapOf("a", "foo"));
assertParsedTags("k\\==v\\=1", mapOf("k=", "v=1"));
assertParsedTags("k\\,x=v\\,y,b=2", mapOf("k,x", "v,y", "b", "2"));
assertParsedTags("k\\=x", mapOf());
}

@Test
Expand All @@ -112,14 +112,14 @@ void readInfluxQLResultWithTagCommas() throws IOException {
List<String> testTags = Arrays.asList(
"location=Cheb_CZ", //simpleTag
"region=us-east-1,host=server1", // standardTags * 2
"location=Cheb\\\\,\\\\ CZ", // simpleTag with value comma and space
"location=Cheb\\,\\ CZ", // simpleTag with value comma and space
"location=Cheb_CZ,branch=Munchen_DE", // multiple tags with underscore
"location=Cheb\\\\,\\\\ CZ,branch=Munchen\\\\,\\\\ DE", // multiple tags with comma and space
"model\\\\,\\\\ uin=C3PO", // tag with comma space in key
"model\\\\,\\\\ uin=Droid\\\\,\\\\ C3PO", // tag with comma space in key and value
"model\\\\,\\\\ uin=Droid\\\\,\\\\ C3PO,location=Cheb\\\\,\\\\ CZ,branch=Munchen\\\\,\\\\ DE", // comma space in key and val
"silly\\\\,\\\\=long\\\\,tag=a\\\\,b\\\\\\\\\\,\\\\ c\\\\,\\\\ d", // multi commas in k and v plus escaped reserved chars
"region=us\\\\,\\\\ east-1,host\\\\,\\\\ name=ser\\\\,\\\\ ver1" // legacy broken tags
"location=Cheb\\,\\ CZ,branch=Munchen\\,\\ DE", // multiple tags with comma and space
"model\\,\\ uin=C3PO", // tag with comma space in key
"model\\,\\ uin=Droid\\,\\ C3PO", // tag with comma space in key and value
"model\\,\\ uin=Droid\\,\\ C3PO,location=Cheb\\,\\ CZ,branch=Munchen\\,\\ DE", // comma space in key and val
"silly\\,\\=long\\,tag=a\\,b\\\\\\,\\ c\\,\\ d", // multi commas in k and v plus escaped reserved chars
"region=us\\,\\ east-1,host\\,\\ name=ser\\,\\ ver1" // legacy broken tags
);

Map<String,Map<String,String>> expectedTagsMap = Stream.of(
Expand All @@ -134,7 +134,7 @@ void readInfluxQLResultWithTagCommas() throws IOException {
)),
// 3. simpleTag with value comma and space
new AbstractMap.SimpleImmutableEntry<>(testTags.get(2),
mapOf("location", "Cheb\\,\\ CZ")),
mapOf("location", "Cheb, CZ")),
// 4. multiple tags with underscore
new AbstractMap.SimpleImmutableEntry<>(testTags.get(3),
mapOf(
Expand All @@ -144,32 +144,32 @@ void readInfluxQLResultWithTagCommas() throws IOException {
// 5. multiple tags with comma and space
new AbstractMap.SimpleImmutableEntry<>(testTags.get(4),
mapOf(
"location", "Cheb\\,\\ CZ",
"branch", "Munchen\\,\\ DE"
"location", "Cheb, CZ",
"branch", "Munchen, DE"
)),
// 6. tag with comma and space in key
new AbstractMap.SimpleImmutableEntry<>(testTags.get(5),
mapOf("model\\,\\ uin", "C3PO")),
mapOf("model, uin", "C3PO")),
// 7. tag with comma and space in key and value
new AbstractMap.SimpleImmutableEntry<>(testTags.get(6),
mapOf("model\\,\\ uin", "Droid\\,\\ C3PO")),
mapOf("model, uin", "Droid, C3PO")),
// 8. comma space in key and val with multiple tags
new AbstractMap.SimpleImmutableEntry<>(testTags.get(7),
mapOf(
"model\\,\\ uin", "Droid\\,\\ C3PO",
"location", "Cheb\\,\\ CZ",
"branch", "Munchen\\,\\ DE"
"model, uin", "Droid, C3PO",
"location", "Cheb, CZ",
"branch", "Munchen, DE"
)),
// 9. multiple commas in key and value
new AbstractMap.SimpleImmutableEntry<>(testTags.get(8),
mapOf(
"silly\\,\\=long\\,tag", "a\\,b\\\\\\,\\ c\\,\\ d"
"silly,=long,tag", "a,b\\, c, d"
)),
// legacy broken tags
new AbstractMap.SimpleImmutableEntry<>(testTags.get(9),
mapOf(
"region", "us\\,\\ east-1",
"host\\,\\ name", "ser\\,\\ ver1"
"region", "us, east-1",
"host, name", "ser, ver1"
))
).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

Expand Down