github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/sem/tree/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 tree 12 13 import "github.com/cockroachdb/errors" 14 15 // Volatility 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 Volatility int8 26 27 const ( 28 // VolatilityLeakProof 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 leak-proof. 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: VolatilityLeakProof is strictly stronger than VolatilityImmutable. In 41 // principle it could be possible to have leak-proof stable or volatile 42 // functions (perhaps now()); but this is not useful in practice as very few 43 // operators are marked leak-proof. 44 // Examples: integer comparison. 45 VolatilityLeakProof Volatility = 1 + iota 46 // VolatilityImmutable 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. Immutable operators can be constant folded. 50 // Examples: log, from_json. 51 VolatilityImmutable 52 // VolatilityStable 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 VolatilityStable 58 // VolatilityVolatile means that the operator can do anything, including 59 // modifying database state. 60 // Examples: random, crdb_internal.force_error, nextval. 61 VolatilityVolatile 62 ) 63 64 // String returns the byte representation of Volatility as a string. 65 func (v Volatility) String() string { 66 switch v { 67 case VolatilityLeakProof: 68 return "leak-proof" 69 case VolatilityImmutable: 70 return "immutable" 71 case VolatilityStable: 72 return "stable" 73 case VolatilityVolatile: 74 return "volatile" 75 default: 76 return "invalid" 77 } 78 } 79 80 // ToPostgres returns the postgres "provolatile" string ("i" or "s" or "v") and 81 // the "proleakproof" flag. 82 func (v Volatility) ToPostgres() (provolatile string, proleakproof bool) { 83 switch v { 84 case VolatilityLeakProof: 85 return "i", true 86 case VolatilityImmutable: 87 return "i", false 88 case VolatilityStable: 89 return "s", false 90 case VolatilityVolatile: 91 return "v", false 92 default: 93 panic(errors.AssertionFailedf("invalid volatility %s", v)) 94 } 95 } 96 97 // VolatilityFromPostgres returns a Volatility that matches the postgres 98 // provolatile/proleakproof settings. 99 func VolatilityFromPostgres(provolatile string, proleakproof bool) (Volatility, error) { 100 switch provolatile { 101 case "i": 102 if proleakproof { 103 return VolatilityLeakProof, nil 104 } 105 return VolatilityImmutable, nil 106 case "s": 107 return VolatilityStable, nil 108 case "v": 109 return VolatilityVolatile, nil 110 default: 111 return 0, errors.AssertionFailedf("invalid provolatile %s", provolatile) 112 } 113 }