diff --git a/common/persistence/pinotVisibilityTripleManager.go b/common/persistence/pinotVisibilityTripleManager.go index 4f536081c4d..749cf89ebce 100644 --- a/common/persistence/pinotVisibilityTripleManager.go +++ b/common/persistence/pinotVisibilityTripleManager.go @@ -24,6 +24,7 @@ import ( "context" "fmt" "math/rand" + "strings" "github.com/uber/cadence/common" "github.com/uber/cadence/common/dynamicconfig" @@ -341,7 +342,14 @@ func (v *pinotVisibilityTripleManager) logUserQueryParameters(userParam userPara tag.WorkflowType(userParam.workflowType), tag.WorkflowID(userParam.workflowID), tag.WorkflowCloseStatus(userParam.closeStatus), - tag.VisibilityQuery(userParam.customQuery)) + tag.VisibilityQuery(filterAttrPrefix(userParam.customQuery))) +} + +// This is for only logUserQueryParameters (for Pinot Response comparator) usage. +// Be careful because there's a low possibility that there'll be false positive cases (shown in unit tests) +func filterAttrPrefix(str string) string { + str = strings.Replace(str, "`Attr.", "", -1) + return strings.Replace(str, "`", "", -1) } func (v *pinotVisibilityTripleManager) ListOpenWorkflowExecutions( diff --git a/common/persistence/pinotVisibilityTripleManager_test.go b/common/persistence/pinotVisibilityTripleManager_test.go new file mode 100644 index 00000000000..016a04ec405 --- /dev/null +++ b/common/persistence/pinotVisibilityTripleManager_test.go @@ -0,0 +1,62 @@ +// The MIT License (MIT) + +// Copyright (c) 2017-2020 Uber Technologies Inc. + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +package persistence + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestFilterAttrPrefix(t *testing.T) { + tests := map[string]struct { + expectedInput string + expectedOutput string + }{ + "Case1: empty input": { + expectedInput: "", + expectedOutput: "", + }, + "Case2: filtered input": { + expectedInput: "`Attr.CustomIntField` = 12", + expectedOutput: "CustomIntField = 12", + }, + "Case3: complex input": { + expectedInput: "WorkflowID = 'test-wf' and (`Attr.CustomIntField` = 12 or `Attr.CustomStringField` = 'a-b-c' and WorkflowType = 'wf-type')", + expectedOutput: "WorkflowID = 'test-wf' and (CustomIntField = 12 or CustomStringField = 'a-b-c' and WorkflowType = 'wf-type')", + }, + "Case4: false positive case": { + expectedInput: "`Attr.CustomStringField` = '`Attr.ABCtesting'", + expectedOutput: "CustomStringField = 'ABCtesting'", // this is supposed to be CustomStringField = '`Attr.ABCtesting' + }, + } + + for name, test := range tests { + t.Run(name, func(t *testing.T) { + assert.NotPanics(t, func() { + actualOutput := filterAttrPrefix(test.expectedInput) + assert.Equal(t, test.expectedOutput, actualOutput) + }) + }) + } +}