-
-
Notifications
You must be signed in to change notification settings - Fork 40
/
types.rs
322 lines (284 loc) · 10 KB
/
types.rs
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
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
use sea_query::RcOrArc;
#[cfg(feature = "with-serde")]
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "with-serde", derive(Serialize, Deserialize))]
/// All built-in types of PostgreSQL, excluding synonyms
pub enum Type {
// Numeric types
/// 16 bit integer
SmallInt,
/// 32 bit integer
Integer,
/// 64 bit integer
BigInt,
/// User-specified precision number
Decimal(ArbitraryPrecisionNumericAttr),
/// User-specified precision number
Numeric(ArbitraryPrecisionNumericAttr),
/// 32 bit floating-point
Real,
/// 64 bit floating-point
DoublePrecision,
/// 16 bit autoincrementing integer
SmallSerial,
/// 32 bit autoincrementing integer
Serial,
/// 64 bit autoincrementing integer
BigSerial,
/// Currency amount; 64 bits with a fractional precision determined by the database's lc_monetary
/// setting
Money,
// Character types
/// Variable-length character array with limit
Varchar(StringAttr),
/// Fixed-length character array; blank padded
Char(StringAttr),
/// Variable, unlimited length character array
Text,
/// Variable length binary string
Bytea,
// Date/Time types
/// Date and time
Timestamp(TimeAttr),
TimestampWithTimeZone(TimeAttr),
/// Date without time of day
Date,
/// Time without date
Time(TimeAttr),
TimeWithTimeZone(TimeAttr),
/// Time interval
Interval(IntervalAttr),
/// One byte boolean value
Boolean,
// TODO:
// /// A type comprised of a static, ordered set of values
// Enum,
// Geometric types
/// Point on a plane
Point,
/// Infinite line
Line,
/// Finite line segment
Lseg,
/// Rectangular box
Box,
/// Closed or open path
Path,
/// Polygon (similar to a closed path)
Polygon,
/// Circle composed of a center point and radius
Circle,
// Network address types
/// IPv4 and IPv6 networks
Cidr,
/// IPPv4 and IPv6 hosts and networks
Inet,
/// 6 byte MAC address
MacAddr,
/// 8 byte MAC address in EUI-64 format
MacAddr8,
/// Fixed length bit string
Bit(BitAttr),
/// Variable length bit string
VarBit(BitAttr),
// Text search types
/// A sorted list of distinct lexemes which are words that have been normalized to merge different
/// variants of the same word
TsVector,
/// A list of lexemes that are to be searched for, and can be combined using Boolean operators AND,
/// OR, and NOT, as well as a phrase search operation
TsQuery,
/// A universally unique identifier as defined by RFC 4122, ISO 9834-8:2005, and related standards
Uuid,
/// XML data checked for well-formedness and with additional support functions
Xml,
/// JSON data checked for validity and with additional functions
Json,
/// JSON data stored in a decomposed binary format that can be subscripted and used in indexes
JsonBinary,
/// Variable-length multidimensional array
Array(ArrayDef),
#[cfg(feature = "postgres-vector")]
/// The postgres vector type introduced by the vector extension.
Vector(VectorDef),
// TODO:
// /// The structure of a row or record; a list of field names and types
// Composite,
// Range types
/// Range of an integer
Int4Range,
/// Range of a bigint
Int8Range,
/// Range of a numeric
NumRange,
/// Range of a timestamp without time zone
TsRange,
/// Range of a timestamp with time zone
TsTzRange,
/// Range of a date
DateRange,
// TODO:
// /// A user-defined data type that is based on another underlying type with optional constraints
// /// that restrict valid values
// Domain,
// TODO: Object identifier types
/// A log sequence number
PgLsn,
// TODO: Pseudo-types
Unknown(String),
/// Defines an PostgreSQL
Enum(EnumDef),
}
impl Type {
// TODO: Support more types
#[allow(clippy::should_implement_trait)]
pub fn from_str(column_type: &str, udt_name: Option<&str>, is_enum: bool) -> Type {
match column_type.to_lowercase().as_str() {
"smallint" | "int2" => Type::SmallInt,
"integer" | "int" | "int4" => Type::Integer,
"bigint" | "int8" => Type::BigInt,
"decimal" => Type::Decimal(ArbitraryPrecisionNumericAttr::default()),
"numeric" => Type::Numeric(ArbitraryPrecisionNumericAttr::default()),
"real" | "float4" => Type::Real,
"double precision" | "double" | "float8" => Type::DoublePrecision,
"smallserial" | "serial2" => Type::SmallSerial,
"serial" | "serial4" => Type::Serial,
"bigserial" | "serial8" => Type::BigSerial,
"money" => Type::Money,
"character varying" | "varchar" => Type::Varchar(StringAttr::default()),
"character" | "char" => Type::Char(StringAttr::default()),
"text" => Type::Text,
"bytea" => Type::Bytea,
"timestamp" | "timestamp without time zone" => Type::Timestamp(TimeAttr::default()),
"timestamp with time zone" => Type::TimestampWithTimeZone(TimeAttr::default()),
"date" => Type::Date,
"time" | "time without time zone" => Type::Time(TimeAttr::default()),
"time with time zone" => Type::TimeWithTimeZone(TimeAttr::default()),
"interval" => Type::Interval(IntervalAttr::default()),
"boolean" | "bool" => Type::Boolean,
"point" => Type::Point,
"line" => Type::Line,
"lseg" => Type::Lseg,
"box" => Type::Box,
"path" => Type::Path,
"polygon" => Type::Polygon,
"circle" => Type::Circle,
"cidr" => Type::Cidr,
"inet" => Type::Inet,
"macaddr" => Type::MacAddr,
"macaddr8" => Type::MacAddr8,
"bit" => Type::Bit(BitAttr::default()),
"bit varying" | "varbit" => Type::VarBit(BitAttr::default()),
"tsvector" => Type::TsVector,
"tsquery" => Type::TsQuery,
"uuid" => Type::Uuid,
"xml" => Type::Xml,
"json" => Type::Json,
"jsonb" => Type::JsonBinary,
// "" => Type::Composite,
"int4range" => Type::Int4Range,
"int8range" => Type::Int8Range,
"numrange" => Type::NumRange,
"tsrange" => Type::TsRange,
"tstzrange" => Type::TsTzRange,
"daterange" => Type::DateRange,
// "" => Type::Domain,
"pg_lsn" => Type::PgLsn,
"user-defined" if is_enum => Type::Enum(EnumDef::default()),
"user-defined" if !is_enum && udt_name.is_some() => {
Type::Unknown(udt_name.unwrap().to_owned())
}
"array" => Type::Array(ArrayDef::default()),
_ => Type::Unknown(column_type.to_owned()),
}
}
}
#[derive(Clone, Debug, PartialEq, Default)]
#[cfg_attr(feature = "with-serde", derive(Serialize, Deserialize))]
/// The precision (number of significan digits) and scale (the number of digits in the fractional
/// portion) of an arbitrary precision number (numeric or decimal). When both the precision and
/// scale are not set, any precision or scale up to the implementation limit may be stored.
pub struct ArbitraryPrecisionNumericAttr {
/// The number of significant digits in the number; a maximum of 1000 when specified
pub precision: Option<u16>,
/// The count of decimal digits in the fractional part; integers have a scale of 0
pub scale: Option<u16>,
}
#[derive(Clone, Debug, PartialEq, Default)]
#[cfg_attr(feature = "with-serde", derive(Serialize, Deserialize))]
pub struct StringAttr {
pub length: Option<u16>,
}
#[derive(Clone, Debug, PartialEq, Default)]
#[cfg_attr(feature = "with-serde", derive(Serialize, Deserialize))]
pub struct TimeAttr {
pub precision: Option<u16>,
}
#[derive(Clone, Debug, PartialEq, Default)]
#[cfg_attr(feature = "with-serde", derive(Serialize, Deserialize))]
pub struct IntervalAttr {
pub field: Option<String>,
pub precision: Option<u16>,
}
#[derive(Clone, Debug, PartialEq, Default)]
#[cfg_attr(feature = "with-serde", derive(Serialize, Deserialize))]
pub struct BitAttr {
pub length: Option<u16>,
}
/// Defines an enum for the PostgreSQL module
#[derive(Clone, Debug, PartialEq, Default)]
#[cfg_attr(feature = "with-serde", derive(Serialize, Deserialize))]
pub struct EnumDef {
/// Holds the fields of the `ENUM`
pub values: Vec<String>,
/// Defines the name of the PostgreSQL enum identifier
pub typename: String,
}
/// Defines an enum for the PostgreSQL module
#[derive(Clone, Debug, PartialEq, Default)]
#[cfg_attr(feature = "with-serde", derive(Serialize, Deserialize))]
pub struct ArrayDef {
/// Array type
pub col_type: Option<RcOrArc<Type>>,
}
#[cfg(feature = "postgres-vector")]
/// Defines an enum for the PostgreSQL module
#[derive(Clone, Debug, PartialEq, Default)]
#[cfg_attr(feature = "with-serde", derive(Serialize, Deserialize))]
pub struct VectorDef {
pub length: Option<u32>,
}
impl Type {
pub fn has_numeric_attr(&self) -> bool {
matches!(self, Type::Numeric(_) | Type::Decimal(_))
}
pub fn has_string_attr(&self) -> bool {
matches!(self, Type::Varchar(_) | Type::Char(_))
}
pub fn has_time_attr(&self) -> bool {
matches!(
self,
Type::Timestamp(_)
| Type::TimestampWithTimeZone(_)
| Type::Time(_)
| Type::TimeWithTimeZone(_)
)
}
pub fn has_interval_attr(&self) -> bool {
matches!(self, Type::Interval(_))
}
pub fn has_bit_attr(&self) -> bool {
matches!(self, Type::Bit(_) | Type::VarBit(_))
}
pub fn has_enum_attr(&self) -> bool {
matches!(self, Type::Enum(_))
}
pub fn has_array_attr(&self) -> bool {
matches!(self, Type::Array(_))
}
#[cfg(feature = "postgres-vector")]
pub fn has_vector_attr(&self) -> bool {
matches!(self, Type::Vector(_))
}
}