Skip to content

fix: tags with commas#862

Open
karel-rehor wants to merge 22 commits intohotfix/v6.10.1from
fix/tags-with-commas
Open

fix: tags with commas#862
karel-rehor wants to merge 22 commits intohotfix/v6.10.1from
fix/tags-with-commas

Conversation

@karel-rehor
Copy link
Contributor

@karel-rehor karel-rehor commented Mar 19, 2026

Closes #

Proposed Changes

Rewrite InfluxQLQueryAPIImpl.parseTags() to handle escaped commas and other reserved characters.

Checklist

  • CHANGELOG.md updated
  • Rebased/mergeable
  • A test has been added if appropriate
  • mvn test completes successfully
  • Commit messages are conventional
  • Sign CLA (if not already signed)

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the InfluxQL CSV parsing logic to correctly handle tagsets containing escaped commas (and other escaped reserved characters) in the tags column, and adds test coverage for these cases.

Changes:

  • Rewrote InfluxQLQueryApiImpl.parseTags() to parse tagsets character-by-character instead of splitting on , and =.
  • Added a new unit test covering multiple escaped-comma / escaped-reserved-character tag scenarios.
  • Minor formatting adjustment to the CSVParser construction.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
client/src/main/java/com/influxdb/client/internal/InfluxQLQueryApiImpl.java Replaces naive tag splitting with an escape-aware parser for tag key/value extraction.
client/src/test/java/com/influxdb/client/internal/InfluxQLQueryApiImplTest.java Adds coverage for escaped commas/reserved characters in tags returned from InfluxQL CSV responses.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

@karel-rehor karel-rehor requested a review from Copilot March 19, 2026 15:56
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates InfluxQL CSV result parsing to correctly handle tagsets that contain escaped commas (and other escaped reserved characters), preventing incorrect tag splitting when reserved characters appear in tag keys/values.

Changes:

  • Rewrote InfluxQLQueryApiImpl.parseTags() to parse tagsets character-by-character with escape awareness.
  • Added a focused regression test covering tagsets with escaped commas/spaces/equals in both keys and values.
  • Minor formatting adjustment to the CSVParser construction for readability.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
client/src/main/java/com/influxdb/client/internal/InfluxQLQueryApiImpl.java Replaces naive split()-based tag parsing with an escape-aware parser.
client/src/test/java/com/influxdb/client/internal/InfluxQLQueryApiImplTest.java Adds coverage for tag parsing when commas (and other reserved chars) are escaped in tagsets.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

@karel-rehor karel-rehor requested a review from Copilot March 19, 2026 16:21
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes InfluxQL CSV tagset parsing so tag key/value pairs containing escaped commas (and other escaped reserved characters) are correctly split into Series.getTags() without breaking on escaped delimiters.

Changes:

  • Rewrote InfluxQLQueryApiImpl.parseTags() to parse tagsets with an escape-aware state machine (instead of naive split).
  • Added a dedicated regression test covering escaped commas/spaces/equals in both tag keys and values (plus a “legacy broken tags” case).
  • Minor formatting adjustment to the CSVParser construction for readability.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
client/src/main/java/com/influxdb/client/internal/InfluxQLQueryApiImpl.java Implements escape-aware tag parsing to avoid incorrect splitting on escaped commas/equals/spaces.
client/src/test/java/com/influxdb/client/internal/InfluxQLQueryApiImplTest.java Adds regression coverage for multiple escaped-tag patterns and validates parsed tags/columns/value extraction behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Copy link
Contributor

@alespour alespour left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Parser is safe and robust. GTG with CHANGELOG entry and if checks pass.

I tried edge cases tests (see bellow, for your consideration whether to add or not), they pass OK.

diff --git a/client/src/test/java/com/influxdb/client/internal/InfluxQLQueryApiImplTest.java b/client/src/test/java/com/influxdb/client/internal/InfluxQLQueryApiImplTest.java
index ca587ab7c0..9cc8fbe05a 100644
--- a/client/src/test/java/com/influxdb/client/internal/InfluxQLQueryApiImplTest.java
+++ b/client/src/test/java/com/influxdb/client/internal/InfluxQLQueryApiImplTest.java
@@ -63,6 +63,38 @@ class InfluxQLQueryApiImplTest {
                return map;
        }
 
+       private static void assertParsedTags(
+               @Nonnull final String rawTags,
+               @Nonnull final Map<String, String> expectedTags
+       ) throws IOException {
+
+               StringReader reader = new StringReader(
+                       "name,tags,time,value\n" +
+                               "m,\"" + rawTags + "\",1,1\n"
+               );
+               InfluxQLQueryResult result = InfluxQLQueryApiImpl.readInfluxQLResult(reader, NO_CANCELLING, null);
+
+               Assertions.assertThat(result.getResults()).hasSize(1);
+               Assertions.assertThat(result.getResults().get(0).getSeries()).hasSize(1);
+               Assertions.assertThat(result.getResults().get(0).getSeries().get(0).getTags()).isEqualTo(expectedTags);
+       }
+
+       @Test
+       void readInfluxQLResultWithMalformedAndBoundaryTagCases() throws IOException {
+               assertParsedTags("", mapOf());
+               assertParsedTags("host=", mapOf("host", ""));
+               assertParsedTags("host=a,host=b", mapOf("host", "b"));
+               assertParsedTags("host=a,broken", mapOf("host", "a"));
+               assertParsedTags("=a,host=b", mapOf("host", "b"));
+               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());
+       }
+
        @Test
        void readInfluxQLResultWithTagCommas() throws IOException {
                InfluxQLQueryResult.Series.ValueExtractor extractValue = (columnName, rawValue, resultIndex, seriesName) -> {

@karel-rehor karel-rehor requested a review from alespour March 23, 2026 13:56
assertParsedTags("host=a,broken", mapOf("host", "a"));
assertParsedTags("=a,host=b", mapOf("host", "b"));
assertParsedTags("host=a,", mapOf("host", "a"));
assertParsedTags(",host=a", mapOf(",host", "a"));
Copy link
Contributor

@alespour alespour Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adds another edge case

Suggested change
assertParsedTags(",host=a", mapOf(",host", "a"));
assertParsedTags("host=a\\,b", mapOf("host", "a\\,b"));
assertParsedTags(",host=a", mapOf(",host", "a"));

}

if (firstEscaped) {
firstEscaped = false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what Codex suggests to fix changes introduced in 7fe6761:

High: Possible tag corruption for single-escaped delimiters in parser state machine.
At InfluxQLQueryApiImpl.java:226, when firstEscaped is true, the next non-\ character is skipped entirely (continue), not preserved.
This means inputs like host=a,b (single backslash before comma) become a\b (comma dropped), so tags are parsed incorrectly even though the exception is avoided.

Suggested change
firstEscaped = false;
if (inValue) {
currentValue.append(c);
} else {
currentKey.append(c);
}
firstEscaped = false;

.addTag("host", "A")
.addTag("region", "west")
.addTag("location", "vancouver\\,\\ BC")
.addTag("model\\,\\ uid","droid\\,\\ C3PO")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codex finding: Medium: New IT test does not reflect normal client write usage for comma-containing tags.
In ITInfluxQLQueryApi.java:108 and ITInfluxQLQueryApi.java:109, tags are written already escaped ("vancouver\,\ BC", "model\,\ uid").
With Point.addTag(...), callers typically pass raw values ("vancouver, BC"), and escaping is handled during line-protocol serialization. This test can pass while missing real-world parser cases.

Such raw values could be added to match more real-world cases, imho.

@codecov-commenter
Copy link

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 92.00000% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.38%. Comparing base (70bd52e) to head (5951261).

Files with missing lines Patch % Lines
...influxdb/client/internal/InfluxQLQueryApiImpl.java 92.00% 2 Missing and 2 partials ⚠️
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.
Additional details and impacted files
@@                 Coverage Diff                  @@
##             hotfix/v6.10.1     #862      +/-   ##
====================================================
+ Coverage             88.36%   88.38%   +0.01%     
  Complexity              777      777              
====================================================
  Files                   172      172              
  Lines                  7022     7067      +45     
  Branches                382      393      +11     
====================================================
+ Hits                   6205     6246      +41     
- Misses                  698      700       +2     
- Partials                119      121       +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Contributor

@bednar bednar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All versions in pom.xml should be: 6.10.1-SNAPSHOT and all tags should be HEAD.

<developerConnection>scm:git:git@github.com:influxdata/influxdb-client-java.git</developerConnection>
<url>https://github.com/influxdata/influxdb-client-java/tree/master</url>
<tag>v6.10.0</tag>
<tag>v6.10.1</tag>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here should be: <tag>HEAD</tag>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet