github.com/cockroachdb/cockroachdb-parser@v0.23.3-0.20240213214944-911057d40c9a/pkg/sql/sem/tree/treecmp/comparison_operator.go (about)

     1  // Copyright 2022 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package treecmp
    12  
    13  import (
    14  	"fmt"
    15  
    16  	"github.com/cockroachdb/errors"
    17  )
    18  
    19  // ComparisonOperator represents a binary operator which returns a bool.
    20  type ComparisonOperator struct {
    21  	Symbol ComparisonOperatorSymbol
    22  	// IsExplicitOperator is true if OPERATOR(symbol) is used.
    23  	IsExplicitOperator bool
    24  }
    25  
    26  // MakeComparisonOperator creates a ComparisonOperator given a symbol.
    27  func MakeComparisonOperator(symbol ComparisonOperatorSymbol) ComparisonOperator {
    28  	return ComparisonOperator{Symbol: symbol}
    29  }
    30  
    31  func (o ComparisonOperator) String() string {
    32  	if o.IsExplicitOperator {
    33  		return fmt.Sprintf("OPERATOR(%s)", o.Symbol.String())
    34  	}
    35  	return o.Symbol.String()
    36  }
    37  
    38  // Operator implements tree.Operator.
    39  func (ComparisonOperator) Operator() {}
    40  
    41  // ComparisonOperatorSymbol represents a comparison operator symbol.
    42  type ComparisonOperatorSymbol int
    43  
    44  // ComparisonExpr.Operator
    45  const (
    46  	EQ ComparisonOperatorSymbol = iota
    47  	LT
    48  	GT
    49  	LE
    50  	GE
    51  	NE
    52  	In
    53  	NotIn
    54  	Like
    55  	NotLike
    56  	ILike
    57  	NotILike
    58  	SimilarTo
    59  	NotSimilarTo
    60  	RegMatch
    61  	NotRegMatch
    62  	RegIMatch
    63  	NotRegIMatch
    64  	IsDistinctFrom
    65  	IsNotDistinctFrom
    66  	Contains
    67  	ContainedBy
    68  	JSONExists
    69  	JSONSomeExists
    70  	JSONAllExists
    71  	Overlaps
    72  	TSMatches
    73  
    74  	// The following operators will always be used with an associated SubOperator.
    75  	// If Go had algebraic data types they would be defined in a self-contained
    76  	// manner like:
    77  	//
    78  	// Any(ComparisonOperator)
    79  	// Some(ComparisonOperator)
    80  	// ...
    81  	//
    82  	// where the internal ComparisonOperator qualifies the behavior of the primary
    83  	// operator. Instead, a secondary ComparisonOperator is optionally included in
    84  	// ComparisonExpr for the cases where these operators are the primary op.
    85  	//
    86  	// ComparisonOperator.HasSubOperator returns true for ops in this group.
    87  	Any
    88  	Some
    89  	All
    90  
    91  	NumComparisonOperatorSymbols
    92  )
    93  
    94  var _ = NumComparisonOperatorSymbols
    95  
    96  var comparisonOpName = [...]string{
    97  	EQ:           "=",
    98  	LT:           "<",
    99  	GT:           ">",
   100  	LE:           "<=",
   101  	GE:           ">=",
   102  	NE:           "!=",
   103  	In:           "IN",
   104  	NotIn:        "NOT IN",
   105  	Like:         "LIKE",
   106  	NotLike:      "NOT LIKE",
   107  	ILike:        "ILIKE",
   108  	NotILike:     "NOT ILIKE",
   109  	SimilarTo:    "SIMILAR TO",
   110  	NotSimilarTo: "NOT SIMILAR TO",
   111  	// TODO(otan): come up with a better name than RegMatch, as it also covers GeoContains.
   112  	RegMatch:          "~",
   113  	NotRegMatch:       "!~",
   114  	RegIMatch:         "~*",
   115  	NotRegIMatch:      "!~*",
   116  	IsDistinctFrom:    "IS DISTINCT FROM",
   117  	IsNotDistinctFrom: "IS NOT DISTINCT FROM",
   118  	Contains:          "@>",
   119  	ContainedBy:       "<@",
   120  	JSONExists:        "?",
   121  	JSONSomeExists:    "?|",
   122  	JSONAllExists:     "?&",
   123  	Overlaps:          "&&",
   124  	TSMatches:         "@@",
   125  	Any:               "ANY",
   126  	Some:              "SOME",
   127  	All:               "ALL",
   128  }
   129  
   130  func (i ComparisonOperatorSymbol) String() string {
   131  	if i < 0 || i > ComparisonOperatorSymbol(len(comparisonOpName)-1) {
   132  		return fmt.Sprintf("ComparisonOp(%d)", i)
   133  	}
   134  	return comparisonOpName[i]
   135  }
   136  
   137  // HasSubOperator returns if the ComparisonOperator is used with a sub-operator.
   138  func (i ComparisonOperatorSymbol) HasSubOperator() bool {
   139  	switch i {
   140  	case Any:
   141  	case Some:
   142  	case All:
   143  	default:
   144  		return false
   145  	}
   146  	return true
   147  }
   148  
   149  // ComparisonOpName returns the name of op.
   150  func ComparisonOpName(op ComparisonOperatorSymbol) string {
   151  	if int(op) >= len(comparisonOpName) || comparisonOpName[op] == "" {
   152  		panic(errors.AssertionFailedf("missing name for operator %q", op.String()))
   153  	}
   154  	return comparisonOpName[op]
   155  }