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  }