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 }