Skip to main content

rupg_types/
value.rs

1//! `Value`, one value of any type in the engine.
2//!
3//! 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.
4
5use std::sync::Arc;
6
7use crate::array::Array;
8use crate::datetime::Interval;
9use crate::jsonpath::JsonPath;
10use crate::network::Inet;
11use crate::numeric::Numeric;
12use crate::range::Range;
13use crate::tsquery::QueryItem;
14use crate::tsvector::Lexeme;
15
16/// One value of the engine.
17#[derive(Clone, Debug, PartialEq)]
18pub enum Value {
19    /// SQL NULL.
20    Null,
21    Bool(bool),
22    Int2(i16),
23    Int4(i32),
24    Int8(i64),
25    Float4(f32),
26    Float8(f64),
27    Numeric(Numeric),
28    /// `oid`, `xid`, `cid` and the OID alias types.
29    Oid(u32),
30    /// The type `"char"`. The byte 0 is the empty string.
31    Char(u8),
32    /// The string types, `unknown`, `cstring`, `json` and the other types that the engine keeps as their text form.
33    Text(String),
34    Bytea(Vec<u8>),
35    Uuid([u8; 16]),
36    /// `date`, the days since 1 January 2000.
37    Date(i32),
38    /// `time`, the microseconds since midnight.
39    Time(i64),
40    /// `timetz`, the microseconds since midnight and the zone offset in seconds west of UTC.
41    TimeTz(i64, i32),
42    /// `timestamp`, the microseconds since 1 January 2000.
43    Timestamp(i64),
44    /// `timestamptz`, the microseconds since 1 January 2000 UTC.
45    TimestampTz(i64),
46    Interval(Interval),
47    /// `inet` and `cidr`.
48    Inet(Inet),
49    /// An array, `int2vector` or `oidvector`. A null element is `None`, and no element is `Some(Value::Null)`.
50    Array(Box<Array<Value>>),
51    /// A row of a composite type or of `record`.
52    Record(Box<Record>),
53    /// A value of a range type.
54    Range(Box<Range>),
55    /// A value of a multirange type: the ranges in order, with no empty range and no two ranges that overlap or touch.
56    Multirange(Vec<Range>),
57    /// A value of `tsvector`: the lexemes in order.
58    TsVector(Vec<Lexeme>),
59    /// A value of `tsquery`: the operands and operators in prefix order, or no items for a query with no lexemes.
60    TsQuery(Vec<QueryItem>),
61    /// A value of `jsonpath`.
62    JsonPath(Box<JsonPath>),
63}
64
65/// 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.
66#[derive(Clone, Debug)]
67pub struct Record {
68    /// The type of each field.
69    pub types: Vec<u32>,
70    /// The value of each field, with `Null` for a null field.
71    pub values: Vec<Value>,
72    /// 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.
73    pub names: Option<Arc<[String]>>,
74}
75
76impl Record {
77    /// A record with no names for its fields.
78    pub fn new(types: Vec<u32>, values: Vec<Value>) -> Record {
79        Record { types, values, names: None }
80    }
81}
82
83/// Two records are equal when their fields are equal. The names of the fields are not part of the value.
84impl PartialEq for Record {
85    fn eq(&self, other: &Record) -> bool {
86        self.types == other.types && self.values == other.values
87    }
88}
89
90impl Value {
91    /// True for `Null`.
92    pub fn is_null(&self) -> bool {
93        matches!(self, Value::Null)
94    }
95
96    /// The value of a `bool`, or `None` for `Null`.
97    pub fn as_bool(&self) -> Option<bool> {
98        match self {
99            Value::Bool(v) => Some(*v),
100            _ => None,
101        }
102    }
103
104    /// The string of a value of a string type, or `None` for `Null`.
105    pub fn as_str(&self) -> Option<&str> {
106        match self {
107            Value::Text(v) => Some(v),
108            _ => None,
109        }
110    }
111
112    /// The value of an integer type as an `i64`, or `None` for `Null` and for the other types.
113    pub fn as_i64(&self) -> Option<i64> {
114        match self {
115            Value::Int2(v) => Some(i64::from(*v)),
116            Value::Int4(v) => Some(i64::from(*v)),
117            Value::Int8(v) => Some(*v),
118            _ => None,
119        }
120    }
121
122    /// The value of `oid` or of an OID alias type, or `None` for `Null`.
123    pub fn as_oid(&self) -> Option<u32> {
124        match self {
125            Value::Oid(v) => Some(*v),
126            _ => None,
127        }
128    }
129
130    /// A text value.
131    pub fn text(s: impl Into<String>) -> Value {
132        Value::Text(s.into())
133    }
134}