1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
//! r1043 — which built-in functions are IMMUTABLE, as a positive list.
//!
//! Round 597 drew its allowlist of node kinds without function calls, and
//! wrote down why: "a function whose volatility SPG cannot look up". This
//! is that lookup, and it is a list of what has been checked rather than
//! a list of exceptions.
//!
//! The distinction is the whole point. `system_catalog`'s `volatile_names`
//! names seven functions and renders everything else as `provolatile='i'`
//! for `pg_proc`. That is fine for a catalog column a human reads and
//! fatal as a folding gate: a function nobody classified would be folded
//! by DEFAULT, which is how `random()` becomes one draw shared by every
//! row. A positive list fails the other way — an immutable function that
//! is not here is merely not folded, and stays exactly as fast as it was.
//!
//! ## What earns a place
//!
//! The value depends only on the arguments. Not on the catalog, not on
//! the session (`search_path`, `TimeZone`, `lc_*`), not on the clock, not
//! on a sequence, not on a random source. PostgreSQL's own `provolatile`
//! is the reference and every entry below matches `'i'` there, checked
//! against 18.4 with:
//!
//! ```sql
//! SELECT proname, provolatile FROM pg_proc WHERE proname = ANY($1);
//! ```
//!
//! Deliberately absent, and each for a stated reason rather than an
//! oversight:
//!
//! * `now`, `current_timestamp`, `clock_timestamp`, `random`,
//! `gen_random_uuid`, `nextval`, `currval` — volatile or stable-only.
//! * `to_char`, `to_timestamp`, `to_date` — PG marks these STABLE, not
//! immutable: they read `DateStyle` / `lc_time` / `TimeZone`.
//! * `lower`, `upper`, `initcap` — PG marks them immutable, and SPG's
//! own implementations consult the session's collation. Until that is
//! separated they read state this pass cannot supply.
//!
//! Five names were on the first draft of the list and came off it when
//! the query above was actually run, which is the reason to run it:
//!
//! * `concat`, `concat_ws` — PG says `s`. They call the argument types'
//! output functions, and an output function may be stable.
//! * `length`, `quote_literal`, `quote_nullable` — PG has both `i` and
//! `s` overloads under each name. A name that is immutable in one
//! signature and stable in another cannot be cleared by name alone.
//! * `coalesce`, `nullif`, `greatest`, `least`, `trim` — not functions in
//! PG at all (SQL constructs, and `trim` is `btrim`), so `pg_proc` has
//! nothing to check them against. `greatest` and `least` over text
//! would read a collation anyway.
/// Whether this built-in function's value depends only on its arguments.
///
/// The name is matched case-insensitively, as SQL identifiers are.
pub