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
//! `Value`, one value of any type in the engine.
//!
//! A value does not carry its type. The expression that gives the value has the type OID and the typmod, as a `Datum` of PostgreSQL has no type and the plan node has it. So one variant holds the values of many types: `Text` holds `text`, `name`, `varchar`, `bpchar`, `unknown` and the other types whose value is a string, and `Oid` holds `oid`, `xid`, `cid` and the OID alias types such as `regclass`. [`Datum`](crate::Datum) is the value of the M1 storage, which stores fewer types.
use std::sync::Arc;
use crate::array::Array;
use crate::datetime::Interval;
use crate::jsonpath::JsonPath;
use crate::network::Inet;
use crate::numeric::Numeric;
use crate::range::Range;
use crate::tsquery::QueryItem;
use crate::tsvector::Lexeme;
/// One value of the engine.
#[derive(Clone, Debug, PartialEq)]
pub enum Value {
/// SQL NULL.
Null,
Bool(bool),
Int2(i16),
Int4(i32),
Int8(i64),
Float4(f32),
Float8(f64),
Numeric(Numeric),
/// `oid`, `xid`, `cid` and the OID alias types.
Oid(u32),
/// The type `"char"`. The byte 0 is the empty string.
Char(u8),
/// The string types, `unknown`, `cstring`, `json` and the other types that the engine keeps as their text form.
Text(String),
Bytea(Vec<u8>),
Uuid([u8; 16]),
/// `date`, the days since 1 January 2000.
Date(i32),
/// `time`, the microseconds since midnight.
Time(i64),
/// `timetz`, the microseconds since midnight and the zone offset in seconds west of UTC.
TimeTz(i64, i32),
/// `timestamp`, the microseconds since 1 January 2000.
Timestamp(i64),
/// `timestamptz`, the microseconds since 1 January 2000 UTC.
TimestampTz(i64),
Interval(Interval),
/// `inet` and `cidr`.
Inet(Inet),
/// An array, `int2vector` or `oidvector`. A null element is `None`, and no element is `Some(Value::Null)`.
Array(Box<Array<Value>>),
/// A row of a composite type or of `record`.
Record(Box<Record>),
/// A value of a range type.
Range(Box<Range>),
/// A value of a multirange type: the ranges in order, with no empty range and no two ranges that overlap or touch.
Multirange(Vec<Range>),
/// A value of `tsvector`: the lexemes in order.
TsVector(Vec<Lexeme>),
/// A value of `tsquery`: the operands and operators in prefix order, or no items for a query with no lexemes.
TsQuery(Vec<QueryItem>),
/// A value of `jsonpath`.
JsonPath(Box<JsonPath>),
}
/// The value of a composite type or of `record`, as a `HeapTupleHeader` datum. As that datum keeps the type of the row, a record keeps the type of each field, so that the output of an anonymous `record` can show the fields.
#[derive(Clone, Debug)]
pub struct Record {
/// The type of each field.
pub types: Vec<u32>,
/// The value of each field, with `Null` for a null field.
pub values: Vec<Value>,
/// The names of the fields of an anonymous `record`, as the row descriptor that `BlessTupleDesc` keeps for the typmod of the value. `None` when the type of the value gives the names, or when the fields are `f1`, `f2` and so on.
pub names: Option<Arc<[String]>>,
}
impl Record {
/// A record with no names for its fields.
pub fn new(types: Vec<u32>, values: Vec<Value>) -> Record {
Record { types, values, names: None }
}
}
/// Two records are equal when their fields are equal. The names of the fields are not part of the value.
impl PartialEq for Record {
fn eq(&self, other: &Record) -> bool {
self.types == other.types && self.values == other.values
}
}
impl Value {
/// True for `Null`.
pub fn is_null(&self) -> bool {
matches!(self, Value::Null)
}
/// The value of a `bool`, or `None` for `Null`.
pub fn as_bool(&self) -> Option<bool> {
match self {
Value::Bool(v) => Some(*v),
_ => None,
}
}
/// The string of a value of a string type, or `None` for `Null`.
pub fn as_str(&self) -> Option<&str> {
match self {
Value::Text(v) => Some(v),
_ => None,
}
}
/// The value of an integer type as an `i64`, or `None` for `Null` and for the other types.
pub fn as_i64(&self) -> Option<i64> {
match self {
Value::Int2(v) => Some(i64::from(*v)),
Value::Int4(v) => Some(i64::from(*v)),
Value::Int8(v) => Some(*v),
_ => None,
}
}
/// The value of `oid` or of an OID alias type, or `None` for `Null`.
pub fn as_oid(&self) -> Option<u32> {
match self {
Value::Oid(v) => Some(*v),
_ => None,
}
}
/// A text value.
pub fn text(s: impl Into<String>) -> Value {
Value::Text(s.into())
}
}