diff --git a/common/persistence/visibility/store/sql/visibility_store.go b/common/persistence/visibility/store/sql/visibility_store.go index 65da372f15..a2681e0963 100644 --- a/common/persistence/visibility/store/sql/visibility_store.go +++ b/common/persistence/visibility/store/sql/visibility_store.go @@ -24,6 +24,7 @@ import ( "go.temporal.io/server/common/persistence/visibility/store/query" "go.temporal.io/server/common/resolver" "go.temporal.io/server/common/searchattribute" + "go.temporal.io/server/common/searchattribute/sadefs" ) type ( @@ -859,19 +860,25 @@ func (s *VisibilityStore) encodeRowSearchAttributes( } combinedTypeMap := store.CombineTypeMaps(saTypeMap, chasmMapper) + registeredSearchAttributes := sqlplugin.VisibilitySearchAttributes{} // Fix SQLite keyword list handling (convert string to []string for keyword lists) for name, value := range rowSearchAttributes { tp, err := combinedTypeMap.GetType(name) if err != nil { + // Silently ignore ErrInvalidName for unregistered chasm search attributes + if sadefs.IsChasmSearchAttribute(name) && errors.Is(err, searchattribute.ErrInvalidName) { + continue + } return nil, err } + registeredSearchAttributes[name] = value if tp == enumspb.INDEXED_VALUE_TYPE_KEYWORD_LIST { switch v := value.(type) { case []string: // no-op case string: - rowSearchAttributes[name] = []string{v} + registeredSearchAttributes[name] = []string{v} default: return nil, serviceerror.NewInternal( fmt.Sprintf("Unexpected data type for keyword list: %T (expected list of strings)", v), @@ -881,7 +888,7 @@ func (s *VisibilityStore) encodeRowSearchAttributes( } // Encode all search attributes together - encodedSAs, err := searchattribute.Encode(rowSearchAttributes, &combinedTypeMap) + encodedSAs, err := searchattribute.Encode(registeredSearchAttributes, &combinedTypeMap) if err != nil { return nil, err } diff --git a/tests/chasm_test.go b/tests/chasm_test.go index ccb1e4ba1e..56f62fa4d6 100644 --- a/tests/chasm_test.go +++ b/tests/chasm_test.go @@ -9,6 +9,8 @@ import ( "github.com/stretchr/testify/suite" "go.temporal.io/api/serviceerror" + workflowpb "go.temporal.io/api/workflow/v1" + "go.temporal.io/api/workflowservice/v1" "go.temporal.io/server/chasm" "go.temporal.io/server/chasm/lib/tests" "go.temporal.io/server/chasm/lib/tests/gen/testspb/v1" @@ -433,4 +435,66 @@ func (s *ChasmTestSuite) TestCountExecutions_GroupBy() { s.Contains(err.Error(), "GROUP BY") } +func (s *ChasmTestSuite) TestListWorkflowExecutions() { + tv := testvars.New(s.T()) + ctx, cancel := context.WithTimeout(s.chasmContext, chasmTestTimeout) + defer cancel() + + storeID := tv.Any().String() + createResp, err := tests.NewPayloadStoreHandler( + ctx, + tests.NewPayloadStoreRequest{ + NamespaceID: s.NamespaceID(), + StoreID: storeID, + }, + ) + s.NoError(err) + + _, err = tests.AddPayloadHandler( + ctx, + tests.AddPayloadRequest{ + NamespaceID: s.NamespaceID(), + StoreID: storeID, + PayloadKey: "test-key", + Payload: payload.EncodeString("test-value"), + }, + ) + s.NoError(err) + + visQuery := sadefs.QueryWithAnyNamespaceDivision( + fmt.Sprintf("WorkflowId = '%s'", storeID), + ) + + var execInfo *workflowpb.WorkflowExecutionInfo + s.Eventually( + func() bool { + listResp, err := s.FrontendClient().ListWorkflowExecutions(testcore.NewContext(), &workflowservice.ListWorkflowExecutionsRequest{ + Namespace: s.Namespace().String(), + PageSize: 10, + Query: visQuery, + }) + s.NoError(err) + if len(listResp.Executions) != 1 { + return false + } + execInfo = listResp.Executions[0] + return true + }, + testcore.WaitForESToSettle, + 100*time.Millisecond, + ) + + s.Equal(storeID, execInfo.Execution.WorkflowId) + s.Equal(createResp.RunID, execInfo.Execution.RunId) + + s.NotNil(execInfo.SearchAttributes) + _, hasScheduledByID := execInfo.SearchAttributes.IndexedFields[sadefs.TemporalScheduledById] + s.True(hasScheduledByID) + + _, hasTotalCount := execInfo.SearchAttributes.IndexedFields["TemporalInt01"] + s.False(hasTotalCount, "CHASM search attribute TemporalInt01 should not be exposed") + _, hasTotalSize := execInfo.SearchAttributes.IndexedFields["TemporalInt02"] + s.False(hasTotalSize, "CHASM search attribute TemporalInt02 should not be exposed") +} + // TODO: More tests here...