go.temporal.io/server@v1.23.0/common/searchattribute/defs.go (about) 1 // The MIT License 2 // 3 // Copyright (c) 2020 Temporal Technologies Inc. All rights reserved. 4 // 5 // Copyright (c) 2020 Uber Technologies, Inc. 6 // 7 // Permission is hereby granted, free of charge, to any person obtaining a copy 8 // of this software and associated documentation files (the "Software"), to deal 9 // in the Software without restriction, including without limitation the rights 10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 // copies of the Software, and to permit persons to whom the Software is 12 // furnished to do so, subject to the following conditions: 13 // 14 // The above copyright notice and this permission notice shall be included in 15 // all copies or substantial portions of the Software. 16 // 17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 // THE SOFTWARE. 24 25 package searchattribute 26 27 import ( 28 "fmt" 29 "strings" 30 31 enumspb "go.temporal.io/api/enums/v1" 32 persistencespb "go.temporal.io/server/api/persistence/v1" 33 ) 34 35 const ( 36 NamespaceID = "NamespaceId" 37 WorkflowID = "WorkflowId" 38 RunID = "RunId" 39 WorkflowType = "WorkflowType" 40 StartTime = "StartTime" 41 ExecutionTime = "ExecutionTime" 42 CloseTime = "CloseTime" 43 ExecutionStatus = "ExecutionStatus" 44 TaskQueue = "TaskQueue" 45 HistoryLength = "HistoryLength" 46 ExecutionDuration = "ExecutionDuration" 47 StateTransitionCount = "StateTransitionCount" 48 TemporalChangeVersion = "TemporalChangeVersion" 49 BinaryChecksums = "BinaryChecksums" 50 BuildIds = "BuildIds" 51 BatcherNamespace = "BatcherNamespace" 52 BatcherUser = "BatcherUser" 53 HistorySizeBytes = "HistorySizeBytes" 54 ParentWorkflowID = "ParentWorkflowId" 55 ParentRunID = "ParentRunId" 56 57 TemporalNamespaceDivision = "TemporalNamespaceDivision" 58 59 // These fields are not in Elasticsearch mappings definition and therefore are not indexed. 60 MemoEncoding = "MemoEncoding" 61 Memo = "Memo" 62 VisibilityTaskKey = "VisibilityTaskKey" 63 64 // Added to workflows started by a schedule. 65 TemporalScheduledStartTime = "TemporalScheduledStartTime" 66 TemporalScheduledById = "TemporalScheduledById" 67 68 // Used by scheduler workflow. 69 TemporalSchedulePaused = "TemporalSchedulePaused" 70 71 ReservedPrefix = "Temporal" 72 73 // Query clause that mentions TemporalNamespaceDivision to disable special handling of that 74 // search attribute in visibility. 75 matchAnyNamespaceDivision = TemporalNamespaceDivision + ` IS NULL OR ` + TemporalNamespaceDivision + ` IS NOT NULL` 76 ) 77 78 var ( 79 // system are internal search attributes which are passed and stored as separate fields. 80 system = map[string]enumspb.IndexedValueType{ 81 WorkflowID: enumspb.INDEXED_VALUE_TYPE_KEYWORD, 82 RunID: enumspb.INDEXED_VALUE_TYPE_KEYWORD, 83 WorkflowType: enumspb.INDEXED_VALUE_TYPE_KEYWORD, 84 StartTime: enumspb.INDEXED_VALUE_TYPE_DATETIME, 85 ExecutionTime: enumspb.INDEXED_VALUE_TYPE_DATETIME, 86 CloseTime: enumspb.INDEXED_VALUE_TYPE_DATETIME, 87 ExecutionStatus: enumspb.INDEXED_VALUE_TYPE_KEYWORD, 88 TaskQueue: enumspb.INDEXED_VALUE_TYPE_KEYWORD, 89 HistoryLength: enumspb.INDEXED_VALUE_TYPE_INT, 90 ExecutionDuration: enumspb.INDEXED_VALUE_TYPE_INT, 91 StateTransitionCount: enumspb.INDEXED_VALUE_TYPE_INT, 92 HistorySizeBytes: enumspb.INDEXED_VALUE_TYPE_INT, 93 ParentWorkflowID: enumspb.INDEXED_VALUE_TYPE_KEYWORD, 94 ParentRunID: enumspb.INDEXED_VALUE_TYPE_KEYWORD, 95 } 96 97 // predefined are internal search attributes which are passed and stored in SearchAttributes object together with custom search attributes. 98 predefined = map[string]enumspb.IndexedValueType{ 99 TemporalChangeVersion: enumspb.INDEXED_VALUE_TYPE_KEYWORD_LIST, 100 BinaryChecksums: enumspb.INDEXED_VALUE_TYPE_KEYWORD_LIST, 101 BuildIds: enumspb.INDEXED_VALUE_TYPE_KEYWORD_LIST, 102 BatcherNamespace: enumspb.INDEXED_VALUE_TYPE_KEYWORD, 103 BatcherUser: enumspb.INDEXED_VALUE_TYPE_KEYWORD, 104 TemporalScheduledStartTime: enumspb.INDEXED_VALUE_TYPE_DATETIME, 105 TemporalScheduledById: enumspb.INDEXED_VALUE_TYPE_KEYWORD, 106 TemporalSchedulePaused: enumspb.INDEXED_VALUE_TYPE_BOOL, 107 TemporalNamespaceDivision: enumspb.INDEXED_VALUE_TYPE_KEYWORD, 108 } 109 110 // reserved are internal field names that can't be used as search attribute names. 111 reserved = map[string]struct{}{ 112 NamespaceID: {}, 113 MemoEncoding: {}, 114 Memo: {}, 115 // Used in the Elasticsearch bulk processor, not needed in SQL databases. 116 VisibilityTaskKey: {}, 117 } 118 119 sqlDbSystemNameToColName = map[string]string{ 120 NamespaceID: "namespace_id", 121 WorkflowID: "workflow_id", 122 RunID: "run_id", 123 WorkflowType: "workflow_type_name", 124 StartTime: "start_time", 125 ExecutionTime: "execution_time", 126 CloseTime: "close_time", 127 ExecutionStatus: "status", 128 TaskQueue: "task_queue", 129 HistoryLength: "history_length", 130 HistorySizeBytes: "history_size_bytes", 131 ExecutionDuration: "execution_duration", 132 StateTransitionCount: "state_transition_count", 133 Memo: "memo", 134 MemoEncoding: "encoding", 135 ParentWorkflowID: "parent_workflow_id", 136 ParentRunID: "parent_run_id", 137 } 138 139 sqlDbCustomSearchAttributes = map[string]enumspb.IndexedValueType{ 140 "Bool01": enumspb.INDEXED_VALUE_TYPE_BOOL, 141 "Bool02": enumspb.INDEXED_VALUE_TYPE_BOOL, 142 "Bool03": enumspb.INDEXED_VALUE_TYPE_BOOL, 143 "Datetime01": enumspb.INDEXED_VALUE_TYPE_DATETIME, 144 "Datetime02": enumspb.INDEXED_VALUE_TYPE_DATETIME, 145 "Datetime03": enumspb.INDEXED_VALUE_TYPE_DATETIME, 146 "Double01": enumspb.INDEXED_VALUE_TYPE_DOUBLE, 147 "Double02": enumspb.INDEXED_VALUE_TYPE_DOUBLE, 148 "Double03": enumspb.INDEXED_VALUE_TYPE_DOUBLE, 149 "Int01": enumspb.INDEXED_VALUE_TYPE_INT, 150 "Int02": enumspb.INDEXED_VALUE_TYPE_INT, 151 "Int03": enumspb.INDEXED_VALUE_TYPE_INT, 152 "Keyword01": enumspb.INDEXED_VALUE_TYPE_KEYWORD, 153 "Keyword02": enumspb.INDEXED_VALUE_TYPE_KEYWORD, 154 "Keyword03": enumspb.INDEXED_VALUE_TYPE_KEYWORD, 155 "Keyword04": enumspb.INDEXED_VALUE_TYPE_KEYWORD, 156 "Keyword05": enumspb.INDEXED_VALUE_TYPE_KEYWORD, 157 "Keyword06": enumspb.INDEXED_VALUE_TYPE_KEYWORD, 158 "Keyword07": enumspb.INDEXED_VALUE_TYPE_KEYWORD, 159 "Keyword08": enumspb.INDEXED_VALUE_TYPE_KEYWORD, 160 "Keyword09": enumspb.INDEXED_VALUE_TYPE_KEYWORD, 161 "Keyword10": enumspb.INDEXED_VALUE_TYPE_KEYWORD, 162 "Text01": enumspb.INDEXED_VALUE_TYPE_TEXT, 163 "Text02": enumspb.INDEXED_VALUE_TYPE_TEXT, 164 "Text03": enumspb.INDEXED_VALUE_TYPE_TEXT, 165 "KeywordList01": enumspb.INDEXED_VALUE_TYPE_KEYWORD_LIST, 166 "KeywordList02": enumspb.INDEXED_VALUE_TYPE_KEYWORD_LIST, 167 "KeywordList03": enumspb.INDEXED_VALUE_TYPE_KEYWORD_LIST, 168 } 169 ) 170 171 // IsSystem returns true if name is system search attribute 172 func IsSystem(name string) bool { 173 _, ok := system[name] 174 return ok 175 } 176 177 // IsReserved returns true if name is system reserved and can't be used as custom search attribute name. 178 func IsReserved(name string) bool { 179 if _, ok := system[name]; ok { 180 return true 181 } 182 if _, ok := predefined[name]; ok { 183 return true 184 } 185 if _, ok := reserved[name]; ok { 186 return true 187 } 188 return strings.HasPrefix(name, ReservedPrefix) 189 } 190 191 // IsMappable returns true if name can have be mapped tho the alias. 192 func IsMappable(name string) bool { 193 if _, ok := system[name]; ok { 194 return false 195 } 196 if _, ok := predefined[name]; ok { 197 return false 198 } 199 return true 200 } 201 202 // GetSqlDbColName maps system and reserved search attributes to column names for SQL tables. 203 // If the input is not a system or reserved search attribute, then it returns the input. 204 func GetSqlDbColName(name string) string { 205 if fieldName, ok := sqlDbSystemNameToColName[name]; ok { 206 return fieldName 207 } 208 return name 209 } 210 211 func GetSqlDbIndexSearchAttributes() *persistencespb.IndexSearchAttributes { 212 return &persistencespb.IndexSearchAttributes{ 213 CustomSearchAttributes: sqlDbCustomSearchAttributes, 214 } 215 } 216 217 // QueryWithAnyNamespaceDivision returns a modified workflow visibility query that disables 218 // special handling of namespace division and so matches workflows in all namespace divisions. 219 // Normally a query that didn't explicitly mention TemporalNamespaceDivision would be limited 220 // to the default (empty string) namespace division. 221 func QueryWithAnyNamespaceDivision(query string) string { 222 if strings.TrimSpace(query) == "" { 223 return matchAnyNamespaceDivision 224 } 225 return fmt.Sprintf(`(%s) AND (%s)`, query, matchAnyNamespaceDivision) 226 }