Skip to content
Open
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
58 changes: 47 additions & 11 deletions events-processor/utils/string.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/json"
"fmt"
"strings"
"unicode"
)

type StringArray []string
Expand Down Expand Up @@ -52,22 +53,57 @@ func parsePostgresArray(s string) []string {
return []string{}
}

// Remove curly braces
s = strings.TrimPrefix(s, "{")
s = strings.TrimSuffix(s, "}")
if !strings.HasPrefix(s, "{") || !strings.HasSuffix(s, "}") {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

For inputs without braces this changes behavior compared to the old code.

Old code would return two elements for hello,world but new logic would return one element.

Can you please explain if this was made on purpose?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Side note: I guess we're lacking tests for such cases.

return []string{strings.Trim(s, "\"")}
}

s = strings.TrimSuffix(strings.TrimPrefix(s, "{"), "}")
result := make([]string, 0)
var current strings.Builder
inQuotes := false
escaped := false
quoted := false
tokenStarted := false

// Split by comma and clean up quotes
parts := strings.Split(s, ",")
result := make([]string, 0, len(parts))
appendValue := func() {
value := current.String()
if !quoted {
value = strings.TrimSpace(value)
}
if quoted || value != "" {
result = append(result, value)
}
current.Reset()
quoted = false
tokenStarted = false
}

for _, part := range parts {
part = strings.TrimSpace(part)
part = strings.Trim(part, "\"")
if part != "" {
result = append(result, part)
for _, char := range s {
switch {
case escaped:
current.WriteRune(char)
escaped = false
tokenStarted = true
case char == '\\' && inQuotes:
escaped = true
case char == '"':
inQuotes = !inQuotes
quoted = true
tokenStarted = true
case char == ',' && !inQuotes:
appendValue()
case !inQuotes && quoted && unicode.IsSpace(char):
continue
case !inQuotes && !tokenStarted && unicode.IsSpace(char):
continue
default:
current.WriteRune(char)
tokenStarted = true
}
}

appendValue()

return result
}

Expand Down
12 changes: 12 additions & 0 deletions events-processor/utils/string_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,18 @@ func TestStringArray_Scan(t *testing.T) {
expected: StringArray{"plain string"},
wantErr: false,
},
{
name: "postgres array with quoted comma",
input: `{"value,1","value2"}`,
expected: StringArray{"value,1", "value2"},
wantErr: false,
},
{
name: "postgres array with empty string",
input: `{"","value2"}`,
expected: StringArray{"", "value2"},
wantErr: false,
},
}

for _, tt := range tests {
Expand Down