sqlx_core_guts/postgres/message/
row_description.rs

1use bytes::{Buf, Bytes};
2
3use crate::error::Error;
4use crate::io::{BufExt, Decode};
5use crate::postgres::types::Oid;
6
7#[derive(Debug)]
8pub struct RowDescription {
9    pub fields: Vec<Field>,
10}
11
12#[derive(Debug)]
13pub struct Field {
14    /// The name of the field.
15    pub name: String,
16
17    /// If the field can be identified as a column of a specific table, the
18    /// object ID of the table; otherwise zero.
19    pub relation_id: Option<i32>,
20
21    /// If the field can be identified as a column of a specific table, the attribute number of
22    /// the column; otherwise zero.
23    pub relation_attribute_no: Option<i16>,
24
25    /// The object ID of the field's data type.
26    pub data_type_id: Oid,
27
28    /// The data type size (see pg_type.typlen). Note that negative values denote
29    /// variable-width types.
30    pub data_type_size: i16,
31
32    /// The type modifier (see pg_attribute.atttypmod). The meaning of the
33    /// modifier is type-specific.
34    pub type_modifier: i32,
35
36    /// The format code being used for the field.
37    pub format: i16,
38}
39
40impl Decode<'_> for RowDescription {
41    fn decode_with(mut buf: Bytes, _: ()) -> Result<Self, Error> {
42        let cnt = buf.get_u16();
43        let mut fields = Vec::with_capacity(cnt as usize);
44
45        for _ in 0..cnt {
46            let name = buf.get_str_nul()?.to_owned();
47            let relation_id = buf.get_i32();
48            let relation_attribute_no = buf.get_i16();
49            let data_type_id = Oid(buf.get_u32());
50            let data_type_size = buf.get_i16();
51            let type_modifier = buf.get_i32();
52            let format = buf.get_i16();
53
54            fields.push(Field {
55                name,
56                relation_id: if relation_id == 0 {
57                    None
58                } else {
59                    Some(relation_id)
60                },
61                relation_attribute_no: if relation_attribute_no == 0 {
62                    None
63                } else {
64                    Some(relation_attribute_no)
65                },
66                data_type_id,
67                data_type_size,
68                type_modifier,
69                format,
70            })
71        }
72
73        Ok(Self { fields })
74    }
75}
76
77// TODO: Unit Test RowDescription
78// TODO: Benchmark RowDescription