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
use sqlx_core::bytes::{Buf, Bytes};
use crate::error::Error;
use crate::io::{BufExt, Decode};
use crate::types::Oid;
#[derive(Debug)]
pub struct RowDescription {
pub fields: Vec<Field>,
}
#[derive(Debug)]
pub struct Field {
/// The name of the field.
pub name: String,
/// If the field can be identified as a column of a specific table, the
/// object ID of the table; otherwise zero.
pub relation_id: Option<i32>,
/// If the field can be identified as a column of a specific table, the attribute number of
/// the column; otherwise zero.
pub relation_attribute_no: Option<i16>,
/// The object ID of the field's data type.
pub data_type_id: Oid,
/// The data type size (see pg_type.typlen). Note that negative values denote
/// variable-width types.
pub data_type_size: i16,
/// The type modifier (see pg_attribute.atttypmod). The meaning of the
/// modifier is type-specific.
pub type_modifier: i32,
/// The format code being used for the field.
pub format: i16,
}
impl Decode<'_> for RowDescription {
fn decode_with(mut buf: Bytes, _: ()) -> Result<Self, Error> {
let cnt = buf.get_u16();
let mut fields = Vec::with_capacity(cnt as usize);
for _ in 0..cnt {
let name = buf.get_str_nul()?.to_owned();
let relation_id = buf.get_i32();
let relation_attribute_no = buf.get_i16();
let data_type_id = Oid(buf.get_u32());
let data_type_size = buf.get_i16();
let type_modifier = buf.get_i32();
let format = buf.get_i16();
fields.push(Field {
name,
relation_id: if relation_id == 0 {
None
} else {
Some(relation_id)
},
relation_attribute_no: if relation_attribute_no == 0 {
None
} else {
Some(relation_attribute_no)
},
data_type_id,
data_type_size,
type_modifier,
format,
})
}
Ok(Self { fields })
}
}
// TODO: Unit Test RowDescription
// TODO: Benchmark RowDescription