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

     1  // Copyright 2020 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 volatility
    12  
    13  import "github.com/cockroachdb/errors"
    14  
    15  // V indicates whether the result of a function is dependent *only*
    16  // on the values of its explicit arguments, or can change due to outside factors
    17  // (such as parameter variables or table contents).
    18  //
    19  // The values are ordered with smaller values being strictly more restrictive
    20  // than larger values.
    21  //
    22  // NOTE: functions having side-effects, such as setval(),
    23  // must be labeled volatile to ensure they will not get optimized away,
    24  // even if the actual return value is not changeable.
    25  type V int8
    26  
    27  const (
    28  	// Leakproof means that the operator cannot modify the database, the
    29  	// transaction state, or any other state. It cannot depend on configuration
    30  	// settings and is guaranteed to return the same results given the same
    31  	// arguments in any context. In addition, no information about the arguments
    32  	// is conveyed except via the return value. Any function that might throw an
    33  	// error depending on the values of its arguments is not leakproof.
    34  	//
    35  	// USE THIS WITH CAUTION! The optimizer might call operators that are leak
    36  	// proof on inputs that they wouldn't normally be called on (e.g. pulling
    37  	// expressions out of a CASE). In the future, they may even run on rows that
    38  	// the user doesn't have permission to access.
    39  	//
    40  	// Note: Leakproof is strictly stronger than Immutable. In
    41  	// principle it could be possible to have leakproof stable or volatile
    42  	// functions (perhaps now()); but this is not useful in practice as very few
    43  	// operators are marked leakproof.
    44  	// Examples: integer comparison.
    45  	Leakproof V = 1 + iota
    46  	// Immutable means that the operator cannot modify the database, the
    47  	// transaction state, or any other state. It cannot depend on configuration
    48  	// settings and is guaranteed to return the same results given the same
    49  	// arguments in any context. ImmutableCopy operators can be constant folded.
    50  	// Examples: log, from_json.
    51  	Immutable
    52  	// Stable means that the operator cannot modify the database or the
    53  	// transaction state and is guaranteed to return the same results given the
    54  	// same arguments whenever it is evaluated within the same statement. Multiple
    55  	// calls to a stable operator can be optimized to a single call.
    56  	// Examples: current_timestamp, current_date.
    57  	Stable
    58  	// Volatile means that the operator can do anything, including
    59  	// modifying database state.
    60  	// Examples: random, crdb_internal.force_error, nextval.
    61  	Volatile
    62  )
    63  
    64  // String returns the byte representation of Volatility as a string.
    65  func (v V) String() string {
    66  	switch v {
    67  	case Leakproof:
    68  		return "leakproof"
    69  	case Immutable:
    70  		return "immutable"
    71  	case Stable:
    72  		return "stable"
    73  	case Volatile:
    74  		return "volatile"
    75  	default:
    76  		return "invalid"
    77  	}
    78  }
    79  
    80  // TitleString returns the byte representation of Volatility as a title-cased
    81  // string.
    82  func (v V) TitleString() string {
    83  	switch v {
    84  	case Leakproof:
    85  		return "Leakproof"
    86  	case Immutable:
    87  		return "Immutable"
    88  	case Stable:
    89  		return "Stable"
    90  	case Volatile:
    91  		return "Volatile"
    92  	default:
    93  		return "Invalid"
    94  	}
    95  }
    96  
    97  // ToPostgres returns the postgres "provolatile" string ("i" or "s" or "v") and
    98  // the "proleakproof" flag.
    99  func (v V) ToPostgres() (provolatile string, proleakproof bool) {
   100  	switch v {
   101  	case Leakproof:
   102  		return "i", true
   103  	case Immutable:
   104  		return "i", false
   105  	case Stable:
   106  		return "s", false
   107  	case Volatile:
   108  		return "v", false
   109  	default:
   110  		panic(errors.AssertionFailedf("invalid volatility %s", v))
   111  	}
   112  }
   113  
   114  // FromPostgres returns a Volatility that matches the postgres
   115  // provolatile/proleakproof settings.
   116  func FromPostgres(provolatile string, proleakproof bool) (V, error) {
   117  	switch provolatile {
   118  	case "i":
   119  		if proleakproof {
   120  			return Leakproof, nil
   121  		}
   122  		return Immutable, nil
   123  	case "s":
   124  		return Stable, nil
   125  	case "v":
   126  		return Volatile, nil
   127  	default:
   128  		return 0, errors.AssertionFailedf("invalid provolatile %s", provolatile)
   129  	}
   130  }