diff --git a/CHANGELOG.md b/CHANGELOG.md index 685d330..3bba06a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ## 0.13.0 [unreleased] +1. [#111](https://github.com/InfluxCommunity/influxdb3-go/pull/111): Support tabs in tag values. + ### Features 1. [#108](https://github.com/InfluxCommunity/influxdb3-go/pull/108): Allow Request.GetBody to be set when writing gzipped data to make calls more resilient. diff --git a/influxdb3/client_e2e_test.go b/influxdb3/client_e2e_test.go index 4b71724..d581e10 100644 --- a/influxdb3/client_e2e_test.go +++ b/influxdb3/client_e2e_test.go @@ -345,6 +345,8 @@ func TestEscapedStringValues(t *testing.T) { map[string]string{ "tag1": "new\nline and space", "tag2": "escaped\\nline and space", + "tag3": "escaped\nline and\ttab", + "tag4": "preescaped\\nline and\\ttab", }, map[string]interface{}{ "fVal": 41.3, @@ -359,5 +361,7 @@ func TestEscapedStringValues(t *testing.T) { assert.EqualValues(t, "greetings\\nearthlings", qit.Value()["sVal"]) assert.EqualValues(t, "new\\nline and space", qit.Value()["tag1"]) assert.EqualValues(t, "escaped\\nline and space", qit.Value()["tag2"]) + assert.EqualValues(t, "escaped\\nline and\\ttab", qit.Value()["tag3"]) + assert.EqualValues(t, "preescaped\\nline and\\ttab", qit.Value()["tag4"]) } } diff --git a/influxdb3/point.go b/influxdb3/point.go index 9dbae70..ce3e9b1 100644 --- a/influxdb3/point.go +++ b/influxdb3/point.go @@ -248,6 +248,14 @@ func (p *Point) MarshalBinaryWithDefaultTags(precision lineprotocol.Precision, d enc.SetPrecision(precision) enc.StartLine(p.Values.MeasurementName) + // N.B. Some customers have requested support for newline and tab chars in tag values (EAR 5476) + // Though this is outside the lineprotocol specification, it was supported in + // previous GO client versions. + replacer := strings.NewReplacer( + "\n", "\\n", + "\t", "\\t", + ) + // sort Tags tagKeys := make([]string, 0, len(p.Values.Tags)+len(defaultTags)) for k := range p.Values.Tags { @@ -269,13 +277,11 @@ func (p *Point) MarshalBinaryWithDefaultTags(precision lineprotocol.Precision, d } lastKey = tagKey - // N.B. Some customers have requested support for newline chars in tag values (EAR 5476) - // Though this is outside the lineprotocol specification, it was supported in - // previous GO client versions. + // N.B. Some customers have requested support for newline and tab chars in tag values (EAR 5476) if value, ok := p.Values.Tags[tagKey]; ok { - enc.AddTag(tagKey, strings.ReplaceAll(value, "\n", "\\n")) + enc.AddTag(tagKey, replacer.Replace(value)) } else { - enc.AddTag(tagKey, strings.ReplaceAll(defaultTags[tagKey], "\n", "\\n")) + enc.AddTag(tagKey, replacer.Replace(defaultTags[tagKey])) } } diff --git a/influxdb3/point_test.go b/influxdb3/point_test.go index 1e055ab..c6dd183 100644 --- a/influxdb3/point_test.go +++ b/influxdb3/point_test.go @@ -178,12 +178,14 @@ func TestPointDefaultTags(t *testing.T) { assert.EqualValues(t, `test,tag1=a,tag2=b,tag3=f float64=80.1234567 60000000070`+"\n", string(line)) } -func TestPointWithNewlineTags(t *testing.T) { +func TestPointWithEscapedTags(t *testing.T) { p := NewPoint("test", map[string]string{ "tag1": "new\nline and space", "tag2": "escaped\\nline and space", "ambiTag": "ambiguous\ntag", + "tabTag1": "drink\tTab", + "tabTag2": "Tab\\tulator", }, map[string]interface{}{ "fVal": 41.3, @@ -198,16 +200,16 @@ func TestPointWithNewlineTags(t *testing.T) { line, err := p.MarshalBinary(lineprotocol.Nanosecond) require.NoError(t, err) assert.EqualValues(t, - "test,ambiTag=ambiguous\\ntag,tag1=new\\nline\\ and\\ space,tag2=escaped\\nline\\ and\\ space "+ - "fVal=41.3 60000000070\n", + "test,ambiTag=ambiguous\\ntag,tabTag1=drink\\tTab,tabTag2=Tab\\tulator,"+ + "tag1=new\\nline\\ and\\ space,tag2=escaped\\nline\\ and\\ space fVal=41.3 60000000070\n", string(line)) line, err = p.MarshalBinaryWithDefaultTags(lineprotocol.Nanosecond, defaultTags) require.NoError(t, err) assert.EqualValues(t, - "test,ambiTag=ambiguous\\ntag,defTag1=default\\nline\\ and\\ space,defTag2=escaped"+ - "\\ndefault\\ line\\ and\\ space,tag1=new\\nline\\ and\\ space,tag2=escaped\\nline\\ and\\ space "+ - "fVal=41.3 60000000070\n", + "test,ambiTag=ambiguous\\ntag,defTag1=default\\nline\\ and\\ space,"+ + "defTag2=escaped\\ndefault\\ line\\ and\\ space,tabTag1=drink\\tTab,tabTag2=Tab\\tulator,"+ + "tag1=new\\nline\\ and\\ space,tag2=escaped\\nline\\ and\\ space fVal=41.3 60000000070\n", string(line)) pInvalid := NewPoint("test", map[string]string{