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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
//LICENSE Portions Copyright 2019-2021 ZomboDB, LLC.
//LICENSE
//LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc.
//LICENSE
//LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. <contact@pgcentral.org>
//LICENSE
//LICENSE All rights reserved.
//LICENSE
//LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file.
//! Handing for easily converting Postgres Datum types into their corresponding Rust types
//! and converting Rust types into their corresponding Postgres types
// https://github.com/pgcentralfoundation/pgrx/issues/1526
// https://github.com/pgcentralfoundation/pgrx/issues?q=is%3Aissue+is%3Aopen+label%3Alifetime
// https://github.com/pgcentralfoundation/pgrx/issues/1525
pub use *;
pub use cratesupport as datetime_support;
pub use crate*;
pub use *;
pub use *;
pub use *;
pub use *;
pub use *;
pub use *;
pub use *;
pub use *;
pub use *;
pub use ;
pub use *;
pub use *;
pub use *;
use crateMemCx;
use cratepg_sys;
use PhantomData;
use ptr;
/// How Postgres represents datatypes
///
/// The "no-frills" version is [`pg_sys::Datum`], which is abstractly a union of "pointer to void"
/// with other scalar types that can be packed within a pointer's bytes. In practical use, a "raw"
/// Datum can prove to have the same risks as a pointer: code may try to use it without knowing
/// whether its pointee has been deallocated. To lift a Datum into a Rust type requires making
/// implicit lifetimes into explicit bounds.
///
/// Merely having a lifetime does not make `Datum<'src>` "safe" to use. To abstractly represent a
/// full PostgreSQL value needs at least the tuple (Datum, bool, [`pg_sys::Oid`]): a tagged union.
/// `Datum<'src>` itself is effectively a dynamically-typed union *without a type tag*. It exists
/// not to make code manipulating it safe, but to make it possible to write unsafe code correctly,
/// passing Datums to and from Postgres without having to wonder if the implied `&'src T` would
/// actually refer to deallocated data.
///
/// # Designing safe abstractions
/// A function must only be declared safe if *all* inputs **cannot** cause [undefined behavior].
/// Transmuting a raw `pg_sys::Datum` into [`&'a T`] grants a potentially-unbounded lifetime,
/// breaking the rule borrows must not outlive the borrowed. Avoiding such transmutations infects
/// even simple generic functions with soundness obligations. Using only `&'a pg_sys::Datum` lasts
/// only until one must pass by-value, which is the entire point of the original type as Postgres
/// defined it, but can still be preferable.
///
/// `Datum<'src>` makes it theoretically possible to write functions with a signature like
/// ```
/// use pgrx::datum::Datum;
/// # use core::marker::PhantomData;
/// # use pgrx::memcx::MemCx;
/// # struct InCx<'mcx, T>(T, PhantomData<&'mcx MemCx<'mcx>>);
/// fn construct_type_from_datum<'src, T>(
/// datum: Datum<'src>,
/// func: impl FnOnce(Datum<'src>) -> InCx<'src, T>
/// ) -> InCx<'src, T> {
/// func(datum)
/// }
/// ```
/// However, it is possible for `T<'src>` to be insufficient to represent the real lifetime of the
/// abstract Postgres type's allocations. Often a Datum must be "detoasted", which may reallocate.
/// This may demand two constraints on the return type to represent both possible lifetimes, like:
/// ```
/// use pgrx::datum::Datum;
/// use pgrx::memcx::MemCx;
/// # use core::marker::PhantomData;
/// # struct Detoasted<'mcx, T>(T, PhantomData<&'mcx MemCx<'mcx>>);
/// # struct InCx<'mcx, T>(T, PhantomData<&'mcx MemCx<'mcx>>);
/// fn detoast_type_from_datum<'old, 'new, T>(
/// datum: Datum<'old>,
/// memcx: MemCx<'new>,
/// ) -> Detoasted<'new, InCx<'old, T>> {
/// todo!()
/// }
/// ```
/// In actual practice, these can be unified into a single lifetime: the lower bound of both.
/// This is both good and bad: types can use fewer lifetime annotations, even after detoasting.
/// However, in general, because lifetime unification can be done implicitly by the compiler,
/// it is often important to name each and every single lifetime involved in functions that
/// perform these tasks.
///
/// [`&'a T`]: reference
/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
;
/// Represents a typed value as pair of [`Option<Datum>`] and [`Oid`].
///
/// [`Oid`]: pg_sys::Oid
/// A tagging trait to indicate a user type is also meant to be used by Postgres
/// Implemented automatically by `#[derive(PostgresType)]`
/// Creates an array of [`pg_sys::Oid`] with the OID of each provided type
///
/// # Examples
///
/// ```
/// use pgrx::{oids_of, datum::IntoDatum};
///
/// let oids = oids_of![i32, f64];
/// assert_eq!(oids[0], i32::type_oid().into());
/// assert_eq!(oids[1], f64::type_oid().into());
///
/// // the usual conversions or coercions are available
/// let oid_vec = oids_of![i8, i16].to_vec();
/// let no_oid = &oids_of![];
/// assert_eq!(no_oid.len(), 0);
/// ```