Skip to main content

diesel/pg/types/
record.rs

1use byteorder::*;
2use std::io::Write;
3use std::num::NonZeroU32;
4
5use crate::deserialize::{self, FromSql, Queryable};
6use crate::expression::{
7    AppearsOnTable, AsExpression, Expression, SelectableExpression, TypedExpressionType,
8    ValidGrouping,
9};
10use crate::pg::{Pg, PgValue};
11use crate::query_builder::bind_collector::ByteWrapper;
12use crate::query_builder::{AstPass, QueryFragment, QueryId};
13use crate::result::QueryResult;
14use crate::serialize::{self, IsNull, Output, ToSql, WriteTuple};
15use crate::sql_types::{HasSqlType, Record, SqlType};
16
17macro_rules! tuple_impls {
18    ($(
19        $Tuple:tt {
20            $(($idx:tt) -> $T:ident, $ST:ident, $TT:ident,)+
21        }
22    )+) => {$(
23        #[cfg(feature = "postgres_backend")]
24        impl<$($T,)+ $($ST,)+> FromSql<Record<($($ST,)+)>, Pg> for ($($T,)+)
25        where
26            $($T: FromSql<$ST, Pg>,)+
27        {
28            // Yes, we're relying on the order of evaluation of subexpressions
29            // but the only other option would be to use `mem::uninitialized`
30            // and `ptr::write`.
31            #[allow(clippy::mixed_read_write_in_expression)]
32            fn from_sql(value: PgValue<'_>) -> deserialize::Result<Self> {
33                let mut bytes = value.as_bytes();
34                let num_elements = bytes.read_i32::<NetworkEndian>()?;
35
36                if num_elements != $Tuple {
37                    return Err(format!(
38                        "Expected a tuple of {} elements, got {}",
39                        $Tuple,
40                        num_elements,
41                    ).into());
42                }
43
44                let result = ($({
45                    // We could in theory validate the OID here, but that
46                    // ignores cases like text vs varchar where the
47                    // representation is the same and we don't care which we
48                    // got.
49                    let oid = NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).ok_or("Oid's aren't zero")?;
50                    let num_bytes = bytes.read_i32::<NetworkEndian>()?;
51
52                    if num_bytes == -1 {
53                        $T::from_nullable_sql(None)?
54                    } else {
55                        let (elem_bytes, new_bytes) = bytes.split_at_checked(num_bytes.try_into()?).ok_or_else(|| {
56                            format!(
57                                "Invalid element byte count: Expected at least {num_bytes} bytes, but only {} bytes were received",
58                                bytes.len()
59                            )
60                        })?;
61                        bytes = new_bytes;
62                        $T::from_sql(PgValue::new_internal(
63                            elem_bytes,
64                            &oid,
65                        ))?
66                    }
67                },)+);
68
69                if bytes.is_empty() {
70                    Ok(result)
71                } else {
72                    Err("Received too many bytes. This tuple likely contains \
73                        an element of the wrong SQL type.".into())
74                }
75            }
76        }
77
78        #[cfg(feature = "postgres_backend")]
79        impl<$($T,)+ $($ST,)+> Queryable<Record<($($ST,)+)>, Pg> for ($($T,)+)
80        where Self: FromSql<Record<($($ST,)+)>, Pg>
81        {
82            type Row = Self;
83
84            fn build(row: Self::Row) -> deserialize::Result<Self> {
85                Ok(row)
86            }
87        }
88
89        #[cfg(feature = "postgres_backend")]
90        impl<$($T,)+ $($ST,)+> AsExpression<Record<($($ST,)+)>> for ($($T,)+)
91        where
92            $($ST: SqlType + TypedExpressionType,)+
93            $($T: AsExpression<$ST>,)+
94            PgTuple<($($T::Expression,)+)>: Expression<SqlType = Record<($($ST,)+)>>,
95        {
96            type Expression = PgTuple<($($T::Expression,)+)>;
97
98            fn as_expression(self) -> Self::Expression {
99                PgTuple(($(
100                    self.$idx.as_expression(),
101                )+))
102            }
103        }
104
105        #[cfg(feature = "postgres_backend")]
106        impl<$($T,)+ $($ST,)+> WriteTuple<($($ST,)+)> for ($($T,)+)
107        where
108            $($T: ToSql<$ST, Pg>,)+
109            $(Pg: HasSqlType<$ST>),+
110        {
111            fn write_tuple(&self, out: &mut Output<'_, '_, Pg>) -> serialize::Result {
112                let mut buffer = Vec::new();
113                out.write_i32::<NetworkEndian>($Tuple)?;
114
115                $(
116                    let oid = <Pg as HasSqlType<$ST>>::metadata(out.metadata_lookup()).oid()?;
117                    out.write_u32::<NetworkEndian>(oid)?;
118                    let is_null = {
119                        let mut temp_buffer = Output::new(ByteWrapper(&mut buffer), out.metadata_lookup());
120                        let is_null = self.$idx.to_sql(&mut temp_buffer)?;
121                        is_null
122                    };
123
124                    if let IsNull::No = is_null {
125                        out.write_i32::<NetworkEndian>(buffer.len().try_into()?)?;
126                        out.write_all(&buffer)?;
127                        buffer.clear();
128                    } else {
129                        out.write_i32::<NetworkEndian>(-1)?;
130                    }
131                )+
132
133                Ok(IsNull::No)
134            }
135        }
136    )+}
137}
138
139impl<T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16,
    T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31,
    ST, ST1, ST2, ST3, ST4, ST5, ST6, ST7, ST8, ST9, ST10, ST11, ST12, ST13,
    ST14, ST15, ST16, ST17, ST18, ST19, ST20, ST21, ST22, ST23, ST24, ST25,
    ST26, ST27, ST28, ST29, ST30, ST31>
    FromSql<Record<(ST, ST1, ST2, ST3, ST4, ST5, ST6, ST7, ST8, ST9, ST10,
    ST11, ST12, ST13, ST14, ST15, ST16, ST17, ST18, ST19, ST20, ST21, ST22,
    ST23, ST24, ST25, ST26, ST27, ST28, ST29, ST30, ST31)>, Pg> for
    (T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16,
    T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31)
    where T: FromSql<ST, Pg>, T1: FromSql<ST1, Pg>, T2: FromSql<ST2, Pg>,
    T3: FromSql<ST3, Pg>, T4: FromSql<ST4, Pg>, T5: FromSql<ST5, Pg>,
    T6: FromSql<ST6, Pg>, T7: FromSql<ST7, Pg>, T8: FromSql<ST8, Pg>,
    T9: FromSql<ST9, Pg>, T10: FromSql<ST10, Pg>, T11: FromSql<ST11, Pg>,
    T12: FromSql<ST12, Pg>, T13: FromSql<ST13, Pg>, T14: FromSql<ST14, Pg>,
    T15: FromSql<ST15, Pg>, T16: FromSql<ST16, Pg>, T17: FromSql<ST17, Pg>,
    T18: FromSql<ST18, Pg>, T19: FromSql<ST19, Pg>, T20: FromSql<ST20, Pg>,
    T21: FromSql<ST21, Pg>, T22: FromSql<ST22, Pg>, T23: FromSql<ST23, Pg>,
    T24: FromSql<ST24, Pg>, T25: FromSql<ST25, Pg>, T26: FromSql<ST26, Pg>,
    T27: FromSql<ST27, Pg>, T28: FromSql<ST28, Pg>, T29: FromSql<ST29, Pg>,
    T30: FromSql<ST30, Pg>, T31: FromSql<ST31, Pg> {
    #[allow(clippy :: mixed_read_write_in_expression)]
    fn from_sql(value: PgValue<'_>) -> deserialize::Result<Self> {
        let mut bytes = value.as_bytes();
        let num_elements = bytes.read_i32::<NetworkEndian>()?;
        if num_elements != 32i32 {
            return Err(::alloc::__export::must_use({
                                ::alloc::fmt::format(format_args!("Expected a tuple of {0} elements, got {1}",
                                        32i32, num_elements))
                            }).into());
        }
        let result =
            ({
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).ok_or("Oid's aren't zero")?;
                    let num_bytes = bytes.read_i32::<NetworkEndian>()?;
                    if num_bytes == -1 {
                        T::from_nullable_sql(None)?
                    } else {
                        let (elem_bytes, new_bytes) =
                            bytes.split_at_checked(num_bytes.try_into()?).ok_or_else(||
                                        {
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("Invalid element byte count: Expected at least {1} bytes, but only {0} bytes were received",
                                                            bytes.len(), num_bytes))
                                                })
                                        })?;
                        bytes = new_bytes;
                        T::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).ok_or("Oid's aren't zero")?;
                    let num_bytes = bytes.read_i32::<NetworkEndian>()?;
                    if num_bytes == -1 {
                        T1::from_nullable_sql(None)?
                    } else {
                        let (elem_bytes, new_bytes) =
                            bytes.split_at_checked(num_bytes.try_into()?).ok_or_else(||
                                        {
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("Invalid element byte count: Expected at least {1} bytes, but only {0} bytes were received",
                                                            bytes.len(), num_bytes))
                                                })
                                        })?;
                        bytes = new_bytes;
                        T1::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).ok_or("Oid's aren't zero")?;
                    let num_bytes = bytes.read_i32::<NetworkEndian>()?;
                    if num_bytes == -1 {
                        T2::from_nullable_sql(None)?
                    } else {
                        let (elem_bytes, new_bytes) =
                            bytes.split_at_checked(num_bytes.try_into()?).ok_or_else(||
                                        {
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("Invalid element byte count: Expected at least {1} bytes, but only {0} bytes were received",
                                                            bytes.len(), num_bytes))
                                                })
                                        })?;
                        bytes = new_bytes;
                        T2::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).ok_or("Oid's aren't zero")?;
                    let num_bytes = bytes.read_i32::<NetworkEndian>()?;
                    if num_bytes == -1 {
                        T3::from_nullable_sql(None)?
                    } else {
                        let (elem_bytes, new_bytes) =
                            bytes.split_at_checked(num_bytes.try_into()?).ok_or_else(||
                                        {
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("Invalid element byte count: Expected at least {1} bytes, but only {0} bytes were received",
                                                            bytes.len(), num_bytes))
                                                })
                                        })?;
                        bytes = new_bytes;
                        T3::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).ok_or("Oid's aren't zero")?;
                    let num_bytes = bytes.read_i32::<NetworkEndian>()?;
                    if num_bytes == -1 {
                        T4::from_nullable_sql(None)?
                    } else {
                        let (elem_bytes, new_bytes) =
                            bytes.split_at_checked(num_bytes.try_into()?).ok_or_else(||
                                        {
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("Invalid element byte count: Expected at least {1} bytes, but only {0} bytes were received",
                                                            bytes.len(), num_bytes))
                                                })
                                        })?;
                        bytes = new_bytes;
                        T4::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).ok_or("Oid's aren't zero")?;
                    let num_bytes = bytes.read_i32::<NetworkEndian>()?;
                    if num_bytes == -1 {
                        T5::from_nullable_sql(None)?
                    } else {
                        let (elem_bytes, new_bytes) =
                            bytes.split_at_checked(num_bytes.try_into()?).ok_or_else(||
                                        {
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("Invalid element byte count: Expected at least {1} bytes, but only {0} bytes were received",
                                                            bytes.len(), num_bytes))
                                                })
                                        })?;
                        bytes = new_bytes;
                        T5::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).ok_or("Oid's aren't zero")?;
                    let num_bytes = bytes.read_i32::<NetworkEndian>()?;
                    if num_bytes == -1 {
                        T6::from_nullable_sql(None)?
                    } else {
                        let (elem_bytes, new_bytes) =
                            bytes.split_at_checked(num_bytes.try_into()?).ok_or_else(||
                                        {
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("Invalid element byte count: Expected at least {1} bytes, but only {0} bytes were received",
                                                            bytes.len(), num_bytes))
                                                })
                                        })?;
                        bytes = new_bytes;
                        T6::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).ok_or("Oid's aren't zero")?;
                    let num_bytes = bytes.read_i32::<NetworkEndian>()?;
                    if num_bytes == -1 {
                        T7::from_nullable_sql(None)?
                    } else {
                        let (elem_bytes, new_bytes) =
                            bytes.split_at_checked(num_bytes.try_into()?).ok_or_else(||
                                        {
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("Invalid element byte count: Expected at least {1} bytes, but only {0} bytes were received",
                                                            bytes.len(), num_bytes))
                                                })
                                        })?;
                        bytes = new_bytes;
                        T7::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).ok_or("Oid's aren't zero")?;
                    let num_bytes = bytes.read_i32::<NetworkEndian>()?;
                    if num_bytes == -1 {
                        T8::from_nullable_sql(None)?
                    } else {
                        let (elem_bytes, new_bytes) =
                            bytes.split_at_checked(num_bytes.try_into()?).ok_or_else(||
                                        {
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("Invalid element byte count: Expected at least {1} bytes, but only {0} bytes were received",
                                                            bytes.len(), num_bytes))
                                                })
                                        })?;
                        bytes = new_bytes;
                        T8::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).ok_or("Oid's aren't zero")?;
                    let num_bytes = bytes.read_i32::<NetworkEndian>()?;
                    if num_bytes == -1 {
                        T9::from_nullable_sql(None)?
                    } else {
                        let (elem_bytes, new_bytes) =
                            bytes.split_at_checked(num_bytes.try_into()?).ok_or_else(||
                                        {
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("Invalid element byte count: Expected at least {1} bytes, but only {0} bytes were received",
                                                            bytes.len(), num_bytes))
                                                })
                                        })?;
                        bytes = new_bytes;
                        T9::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).ok_or("Oid's aren't zero")?;
                    let num_bytes = bytes.read_i32::<NetworkEndian>()?;
                    if num_bytes == -1 {
                        T10::from_nullable_sql(None)?
                    } else {
                        let (elem_bytes, new_bytes) =
                            bytes.split_at_checked(num_bytes.try_into()?).ok_or_else(||
                                        {
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("Invalid element byte count: Expected at least {1} bytes, but only {0} bytes were received",
                                                            bytes.len(), num_bytes))
                                                })
                                        })?;
                        bytes = new_bytes;
                        T10::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).ok_or("Oid's aren't zero")?;
                    let num_bytes = bytes.read_i32::<NetworkEndian>()?;
                    if num_bytes == -1 {
                        T11::from_nullable_sql(None)?
                    } else {
                        let (elem_bytes, new_bytes) =
                            bytes.split_at_checked(num_bytes.try_into()?).ok_or_else(||
                                        {
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("Invalid element byte count: Expected at least {1} bytes, but only {0} bytes were received",
                                                            bytes.len(), num_bytes))
                                                })
                                        })?;
                        bytes = new_bytes;
                        T11::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).ok_or("Oid's aren't zero")?;
                    let num_bytes = bytes.read_i32::<NetworkEndian>()?;
                    if num_bytes == -1 {
                        T12::from_nullable_sql(None)?
                    } else {
                        let (elem_bytes, new_bytes) =
                            bytes.split_at_checked(num_bytes.try_into()?).ok_or_else(||
                                        {
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("Invalid element byte count: Expected at least {1} bytes, but only {0} bytes were received",
                                                            bytes.len(), num_bytes))
                                                })
                                        })?;
                        bytes = new_bytes;
                        T12::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).ok_or("Oid's aren't zero")?;
                    let num_bytes = bytes.read_i32::<NetworkEndian>()?;
                    if num_bytes == -1 {
                        T13::from_nullable_sql(None)?
                    } else {
                        let (elem_bytes, new_bytes) =
                            bytes.split_at_checked(num_bytes.try_into()?).ok_or_else(||
                                        {
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("Invalid element byte count: Expected at least {1} bytes, but only {0} bytes were received",
                                                            bytes.len(), num_bytes))
                                                })
                                        })?;
                        bytes = new_bytes;
                        T13::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).ok_or("Oid's aren't zero")?;
                    let num_bytes = bytes.read_i32::<NetworkEndian>()?;
                    if num_bytes == -1 {
                        T14::from_nullable_sql(None)?
                    } else {
                        let (elem_bytes, new_bytes) =
                            bytes.split_at_checked(num_bytes.try_into()?).ok_or_else(||
                                        {
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("Invalid element byte count: Expected at least {1} bytes, but only {0} bytes were received",
                                                            bytes.len(), num_bytes))
                                                })
                                        })?;
                        bytes = new_bytes;
                        T14::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).ok_or("Oid's aren't zero")?;
                    let num_bytes = bytes.read_i32::<NetworkEndian>()?;
                    if num_bytes == -1 {
                        T15::from_nullable_sql(None)?
                    } else {
                        let (elem_bytes, new_bytes) =
                            bytes.split_at_checked(num_bytes.try_into()?).ok_or_else(||
                                        {
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("Invalid element byte count: Expected at least {1} bytes, but only {0} bytes were received",
                                                            bytes.len(), num_bytes))
                                                })
                                        })?;
                        bytes = new_bytes;
                        T15::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).ok_or("Oid's aren't zero")?;
                    let num_bytes = bytes.read_i32::<NetworkEndian>()?;
                    if num_bytes == -1 {
                        T16::from_nullable_sql(None)?
                    } else {
                        let (elem_bytes, new_bytes) =
                            bytes.split_at_checked(num_bytes.try_into()?).ok_or_else(||
                                        {
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("Invalid element byte count: Expected at least {1} bytes, but only {0} bytes were received",
                                                            bytes.len(), num_bytes))
                                                })
                                        })?;
                        bytes = new_bytes;
                        T16::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).ok_or("Oid's aren't zero")?;
                    let num_bytes = bytes.read_i32::<NetworkEndian>()?;
                    if num_bytes == -1 {
                        T17::from_nullable_sql(None)?
                    } else {
                        let (elem_bytes, new_bytes) =
                            bytes.split_at_checked(num_bytes.try_into()?).ok_or_else(||
                                        {
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("Invalid element byte count: Expected at least {1} bytes, but only {0} bytes were received",
                                                            bytes.len(), num_bytes))
                                                })
                                        })?;
                        bytes = new_bytes;
                        T17::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).ok_or("Oid's aren't zero")?;
                    let num_bytes = bytes.read_i32::<NetworkEndian>()?;
                    if num_bytes == -1 {
                        T18::from_nullable_sql(None)?
                    } else {
                        let (elem_bytes, new_bytes) =
                            bytes.split_at_checked(num_bytes.try_into()?).ok_or_else(||
                                        {
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("Invalid element byte count: Expected at least {1} bytes, but only {0} bytes were received",
                                                            bytes.len(), num_bytes))
                                                })
                                        })?;
                        bytes = new_bytes;
                        T18::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).ok_or("Oid's aren't zero")?;
                    let num_bytes = bytes.read_i32::<NetworkEndian>()?;
                    if num_bytes == -1 {
                        T19::from_nullable_sql(None)?
                    } else {
                        let (elem_bytes, new_bytes) =
                            bytes.split_at_checked(num_bytes.try_into()?).ok_or_else(||
                                        {
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("Invalid element byte count: Expected at least {1} bytes, but only {0} bytes were received",
                                                            bytes.len(), num_bytes))
                                                })
                                        })?;
                        bytes = new_bytes;
                        T19::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).ok_or("Oid's aren't zero")?;
                    let num_bytes = bytes.read_i32::<NetworkEndian>()?;
                    if num_bytes == -1 {
                        T20::from_nullable_sql(None)?
                    } else {
                        let (elem_bytes, new_bytes) =
                            bytes.split_at_checked(num_bytes.try_into()?).ok_or_else(||
                                        {
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("Invalid element byte count: Expected at least {1} bytes, but only {0} bytes were received",
                                                            bytes.len(), num_bytes))
                                                })
                                        })?;
                        bytes = new_bytes;
                        T20::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).ok_or("Oid's aren't zero")?;
                    let num_bytes = bytes.read_i32::<NetworkEndian>()?;
                    if num_bytes == -1 {
                        T21::from_nullable_sql(None)?
                    } else {
                        let (elem_bytes, new_bytes) =
                            bytes.split_at_checked(num_bytes.try_into()?).ok_or_else(||
                                        {
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("Invalid element byte count: Expected at least {1} bytes, but only {0} bytes were received",
                                                            bytes.len(), num_bytes))
                                                })
                                        })?;
                        bytes = new_bytes;
                        T21::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).ok_or("Oid's aren't zero")?;
                    let num_bytes = bytes.read_i32::<NetworkEndian>()?;
                    if num_bytes == -1 {
                        T22::from_nullable_sql(None)?
                    } else {
                        let (elem_bytes, new_bytes) =
                            bytes.split_at_checked(num_bytes.try_into()?).ok_or_else(||
                                        {
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("Invalid element byte count: Expected at least {1} bytes, but only {0} bytes were received",
                                                            bytes.len(), num_bytes))
                                                })
                                        })?;
                        bytes = new_bytes;
                        T22::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).ok_or("Oid's aren't zero")?;
                    let num_bytes = bytes.read_i32::<NetworkEndian>()?;
                    if num_bytes == -1 {
                        T23::from_nullable_sql(None)?
                    } else {
                        let (elem_bytes, new_bytes) =
                            bytes.split_at_checked(num_bytes.try_into()?).ok_or_else(||
                                        {
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("Invalid element byte count: Expected at least {1} bytes, but only {0} bytes were received",
                                                            bytes.len(), num_bytes))
                                                })
                                        })?;
                        bytes = new_bytes;
                        T23::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).ok_or("Oid's aren't zero")?;
                    let num_bytes = bytes.read_i32::<NetworkEndian>()?;
                    if num_bytes == -1 {
                        T24::from_nullable_sql(None)?
                    } else {
                        let (elem_bytes, new_bytes) =
                            bytes.split_at_checked(num_bytes.try_into()?).ok_or_else(||
                                        {
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("Invalid element byte count: Expected at least {1} bytes, but only {0} bytes were received",
                                                            bytes.len(), num_bytes))
                                                })
                                        })?;
                        bytes = new_bytes;
                        T24::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).ok_or("Oid's aren't zero")?;
                    let num_bytes = bytes.read_i32::<NetworkEndian>()?;
                    if num_bytes == -1 {
                        T25::from_nullable_sql(None)?
                    } else {
                        let (elem_bytes, new_bytes) =
                            bytes.split_at_checked(num_bytes.try_into()?).ok_or_else(||
                                        {
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("Invalid element byte count: Expected at least {1} bytes, but only {0} bytes were received",
                                                            bytes.len(), num_bytes))
                                                })
                                        })?;
                        bytes = new_bytes;
                        T25::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).ok_or("Oid's aren't zero")?;
                    let num_bytes = bytes.read_i32::<NetworkEndian>()?;
                    if num_bytes == -1 {
                        T26::from_nullable_sql(None)?
                    } else {
                        let (elem_bytes, new_bytes) =
                            bytes.split_at_checked(num_bytes.try_into()?).ok_or_else(||
                                        {
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("Invalid element byte count: Expected at least {1} bytes, but only {0} bytes were received",
                                                            bytes.len(), num_bytes))
                                                })
                                        })?;
                        bytes = new_bytes;
                        T26::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).ok_or("Oid's aren't zero")?;
                    let num_bytes = bytes.read_i32::<NetworkEndian>()?;
                    if num_bytes == -1 {
                        T27::from_nullable_sql(None)?
                    } else {
                        let (elem_bytes, new_bytes) =
                            bytes.split_at_checked(num_bytes.try_into()?).ok_or_else(||
                                        {
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("Invalid element byte count: Expected at least {1} bytes, but only {0} bytes were received",
                                                            bytes.len(), num_bytes))
                                                })
                                        })?;
                        bytes = new_bytes;
                        T27::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).ok_or("Oid's aren't zero")?;
                    let num_bytes = bytes.read_i32::<NetworkEndian>()?;
                    if num_bytes == -1 {
                        T28::from_nullable_sql(None)?
                    } else {
                        let (elem_bytes, new_bytes) =
                            bytes.split_at_checked(num_bytes.try_into()?).ok_or_else(||
                                        {
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("Invalid element byte count: Expected at least {1} bytes, but only {0} bytes were received",
                                                            bytes.len(), num_bytes))
                                                })
                                        })?;
                        bytes = new_bytes;
                        T28::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).ok_or("Oid's aren't zero")?;
                    let num_bytes = bytes.read_i32::<NetworkEndian>()?;
                    if num_bytes == -1 {
                        T29::from_nullable_sql(None)?
                    } else {
                        let (elem_bytes, new_bytes) =
                            bytes.split_at_checked(num_bytes.try_into()?).ok_or_else(||
                                        {
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("Invalid element byte count: Expected at least {1} bytes, but only {0} bytes were received",
                                                            bytes.len(), num_bytes))
                                                })
                                        })?;
                        bytes = new_bytes;
                        T29::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).ok_or("Oid's aren't zero")?;
                    let num_bytes = bytes.read_i32::<NetworkEndian>()?;
                    if num_bytes == -1 {
                        T30::from_nullable_sql(None)?
                    } else {
                        let (elem_bytes, new_bytes) =
                            bytes.split_at_checked(num_bytes.try_into()?).ok_or_else(||
                                        {
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("Invalid element byte count: Expected at least {1} bytes, but only {0} bytes were received",
                                                            bytes.len(), num_bytes))
                                                })
                                        })?;
                        bytes = new_bytes;
                        T30::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).ok_or("Oid's aren't zero")?;
                    let num_bytes = bytes.read_i32::<NetworkEndian>()?;
                    if num_bytes == -1 {
                        T31::from_nullable_sql(None)?
                    } else {
                        let (elem_bytes, new_bytes) =
                            bytes.split_at_checked(num_bytes.try_into()?).ok_or_else(||
                                        {
                                            ::alloc::__export::must_use({
                                                    ::alloc::fmt::format(format_args!("Invalid element byte count: Expected at least {1} bytes, but only {0} bytes were received",
                                                            bytes.len(), num_bytes))
                                                })
                                        })?;
                        bytes = new_bytes;
                        T31::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                });
        if bytes.is_empty() {
            Ok(result)
        } else {
            Err("Received too many bytes. This tuple likely contains \
                        an element of the wrong SQL type.".into())
        }
    }
}
impl<T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16,
    T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31,
    ST, ST1, ST2, ST3, ST4, ST5, ST6, ST7, ST8, ST9, ST10, ST11, ST12, ST13,
    ST14, ST15, ST16, ST17, ST18, ST19, ST20, ST21, ST22, ST23, ST24, ST25,
    ST26, ST27, ST28, ST29, ST30, ST31>
    Queryable<Record<(ST, ST1, ST2, ST3, ST4, ST5, ST6, ST7, ST8, ST9, ST10,
    ST11, ST12, ST13, ST14, ST15, ST16, ST17, ST18, ST19, ST20, ST21, ST22,
    ST23, ST24, ST25, ST26, ST27, ST28, ST29, ST30, ST31)>, Pg> for
    (T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16,
    T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31)
    where
    Self: FromSql<Record<(ST, ST1, ST2, ST3, ST4, ST5, ST6, ST7, ST8, ST9,
    ST10, ST11, ST12, ST13, ST14, ST15, ST16, ST17, ST18, ST19, ST20, ST21,
    ST22, ST23, ST24, ST25, ST26, ST27, ST28, ST29, ST30, ST31)>, Pg> {
    type Row = Self;
    fn build(row: Self::Row) -> deserialize::Result<Self> { Ok(row) }
}
impl<T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16,
    T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31,
    ST, ST1, ST2, ST3, ST4, ST5, ST6, ST7, ST8, ST9, ST10, ST11, ST12, ST13,
    ST14, ST15, ST16, ST17, ST18, ST19, ST20, ST21, ST22, ST23, ST24, ST25,
    ST26, ST27, ST28, ST29, ST30, ST31>
    AsExpression<Record<(ST, ST1, ST2, ST3, ST4, ST5, ST6, ST7, ST8, ST9,
    ST10, ST11, ST12, ST13, ST14, ST15, ST16, ST17, ST18, ST19, ST20, ST21,
    ST22, ST23, ST24, ST25, ST26, ST27, ST28, ST29, ST30, ST31)>> for
    (T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16,
    T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31)
    where ST: SqlType + TypedExpressionType, ST1: SqlType +
    TypedExpressionType, ST2: SqlType + TypedExpressionType, ST3: SqlType +
    TypedExpressionType, ST4: SqlType + TypedExpressionType, ST5: SqlType +
    TypedExpressionType, ST6: SqlType + TypedExpressionType, ST7: SqlType +
    TypedExpressionType, ST8: SqlType + TypedExpressionType, ST9: SqlType +
    TypedExpressionType, ST10: SqlType + TypedExpressionType, ST11: SqlType +
    TypedExpressionType, ST12: SqlType + TypedExpressionType, ST13: SqlType +
    TypedExpressionType, ST14: SqlType + TypedExpressionType, ST15: SqlType +
    TypedExpressionType, ST16: SqlType + TypedExpressionType, ST17: SqlType +
    TypedExpressionType, ST18: SqlType + TypedExpressionType, ST19: SqlType +
    TypedExpressionType, ST20: SqlType + TypedExpressionType, ST21: SqlType +
    TypedExpressionType, ST22: SqlType + TypedExpressionType, ST23: SqlType +
    TypedExpressionType, ST24: SqlType + TypedExpressionType, ST25: SqlType +
    TypedExpressionType, ST26: SqlType + TypedExpressionType, ST27: SqlType +
    TypedExpressionType, ST28: SqlType + TypedExpressionType, ST29: SqlType +
    TypedExpressionType, ST30: SqlType + TypedExpressionType, ST31: SqlType +
    TypedExpressionType, T: AsExpression<ST>, T1: AsExpression<ST1>,
    T2: AsExpression<ST2>, T3: AsExpression<ST3>, T4: AsExpression<ST4>,
    T5: AsExpression<ST5>, T6: AsExpression<ST6>, T7: AsExpression<ST7>,
    T8: AsExpression<ST8>, T9: AsExpression<ST9>, T10: AsExpression<ST10>,
    T11: AsExpression<ST11>, T12: AsExpression<ST12>, T13: AsExpression<ST13>,
    T14: AsExpression<ST14>, T15: AsExpression<ST15>, T16: AsExpression<ST16>,
    T17: AsExpression<ST17>, T18: AsExpression<ST18>, T19: AsExpression<ST19>,
    T20: AsExpression<ST20>, T21: AsExpression<ST21>, T22: AsExpression<ST22>,
    T23: AsExpression<ST23>, T24: AsExpression<ST24>, T25: AsExpression<ST25>,
    T26: AsExpression<ST26>, T27: AsExpression<ST27>, T28: AsExpression<ST28>,
    T29: AsExpression<ST29>, T30: AsExpression<ST30>, T31: AsExpression<ST31>,
    PgTuple<(T::Expression, T1::Expression, T2::Expression, T3::Expression,
    T4::Expression, T5::Expression, T6::Expression, T7::Expression,
    T8::Expression, T9::Expression, T10::Expression, T11::Expression,
    T12::Expression, T13::Expression, T14::Expression, T15::Expression,
    T16::Expression, T17::Expression, T18::Expression, T19::Expression,
    T20::Expression, T21::Expression, T22::Expression, T23::Expression,
    T24::Expression, T25::Expression, T26::Expression, T27::Expression,
    T28::Expression, T29::Expression, T30::Expression,
    T31::Expression)>: Expression<SqlType =
    Record<(ST, ST1, ST2, ST3, ST4, ST5, ST6, ST7, ST8, ST9, ST10, ST11, ST12,
    ST13, ST14, ST15, ST16, ST17, ST18, ST19, ST20, ST21, ST22, ST23, ST24,
    ST25, ST26, ST27, ST28, ST29, ST30, ST31)>> {
    type Expression =
        PgTuple<(T::Expression, T1::Expression, T2::Expression,
        T3::Expression, T4::Expression, T5::Expression, T6::Expression,
        T7::Expression, T8::Expression, T9::Expression, T10::Expression,
        T11::Expression, T12::Expression, T13::Expression, T14::Expression,
        T15::Expression, T16::Expression, T17::Expression, T18::Expression,
        T19::Expression, T20::Expression, T21::Expression, T22::Expression,
        T23::Expression, T24::Expression, T25::Expression, T26::Expression,
        T27::Expression, T28::Expression, T29::Expression, T30::Expression,
        T31::Expression)>;
    fn as_expression(self) -> Self::Expression {
        PgTuple((self.0.as_expression(), self.1.as_expression(),
                self.2.as_expression(), self.3.as_expression(),
                self.4.as_expression(), self.5.as_expression(),
                self.6.as_expression(), self.7.as_expression(),
                self.8.as_expression(), self.9.as_expression(),
                self.10.as_expression(), self.11.as_expression(),
                self.12.as_expression(), self.13.as_expression(),
                self.14.as_expression(), self.15.as_expression(),
                self.16.as_expression(), self.17.as_expression(),
                self.18.as_expression(), self.19.as_expression(),
                self.20.as_expression(), self.21.as_expression(),
                self.22.as_expression(), self.23.as_expression(),
                self.24.as_expression(), self.25.as_expression(),
                self.26.as_expression(), self.27.as_expression(),
                self.28.as_expression(), self.29.as_expression(),
                self.30.as_expression(), self.31.as_expression()))
    }
}
impl<T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16,
    T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31,
    ST, ST1, ST2, ST3, ST4, ST5, ST6, ST7, ST8, ST9, ST10, ST11, ST12, ST13,
    ST14, ST15, ST16, ST17, ST18, ST19, ST20, ST21, ST22, ST23, ST24, ST25,
    ST26, ST27, ST28, ST29, ST30, ST31>
    WriteTuple<(ST, ST1, ST2, ST3, ST4, ST5, ST6, ST7, ST8, ST9, ST10, ST11,
    ST12, ST13, ST14, ST15, ST16, ST17, ST18, ST19, ST20, ST21, ST22, ST23,
    ST24, ST25, ST26, ST27, ST28, ST29, ST30, ST31)> for
    (T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16,
    T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31)
    where T: ToSql<ST, Pg>, T1: ToSql<ST1, Pg>, T2: ToSql<ST2, Pg>,
    T3: ToSql<ST3, Pg>, T4: ToSql<ST4, Pg>, T5: ToSql<ST5, Pg>,
    T6: ToSql<ST6, Pg>, T7: ToSql<ST7, Pg>, T8: ToSql<ST8, Pg>,
    T9: ToSql<ST9, Pg>, T10: ToSql<ST10, Pg>, T11: ToSql<ST11, Pg>,
    T12: ToSql<ST12, Pg>, T13: ToSql<ST13, Pg>, T14: ToSql<ST14, Pg>,
    T15: ToSql<ST15, Pg>, T16: ToSql<ST16, Pg>, T17: ToSql<ST17, Pg>,
    T18: ToSql<ST18, Pg>, T19: ToSql<ST19, Pg>, T20: ToSql<ST20, Pg>,
    T21: ToSql<ST21, Pg>, T22: ToSql<ST22, Pg>, T23: ToSql<ST23, Pg>,
    T24: ToSql<ST24, Pg>, T25: ToSql<ST25, Pg>, T26: ToSql<ST26, Pg>,
    T27: ToSql<ST27, Pg>, T28: ToSql<ST28, Pg>, T29: ToSql<ST29, Pg>,
    T30: ToSql<ST30, Pg>, T31: ToSql<ST31, Pg>, Pg: HasSqlType<ST>,
    Pg: HasSqlType<ST1>, Pg: HasSqlType<ST2>, Pg: HasSqlType<ST3>,
    Pg: HasSqlType<ST4>, Pg: HasSqlType<ST5>, Pg: HasSqlType<ST6>,
    Pg: HasSqlType<ST7>, Pg: HasSqlType<ST8>, Pg: HasSqlType<ST9>,
    Pg: HasSqlType<ST10>, Pg: HasSqlType<ST11>, Pg: HasSqlType<ST12>,
    Pg: HasSqlType<ST13>, Pg: HasSqlType<ST14>, Pg: HasSqlType<ST15>,
    Pg: HasSqlType<ST16>, Pg: HasSqlType<ST17>, Pg: HasSqlType<ST18>,
    Pg: HasSqlType<ST19>, Pg: HasSqlType<ST20>, Pg: HasSqlType<ST21>,
    Pg: HasSqlType<ST22>, Pg: HasSqlType<ST23>, Pg: HasSqlType<ST24>,
    Pg: HasSqlType<ST25>, Pg: HasSqlType<ST26>, Pg: HasSqlType<ST27>,
    Pg: HasSqlType<ST28>, Pg: HasSqlType<ST29>, Pg: HasSqlType<ST30>,
    Pg: HasSqlType<ST31> {
    fn write_tuple(&self, out: &mut Output<'_, '_, Pg>) -> serialize::Result {
        let mut buffer = Vec::new();
        out.write_i32::<NetworkEndian>(32i32)?;
        let oid =
            <Pg as HasSqlType<ST>>::metadata(out.metadata_lookup()).oid()?;
        out.write_u32::<NetworkEndian>(oid)?;
        let is_null =
            {
                let mut temp_buffer =
                    Output::new(ByteWrapper(&mut buffer),
                        out.metadata_lookup());
                let is_null = self.0.to_sql(&mut temp_buffer)?;
                is_null
            };
        if let IsNull::No = is_null {
            out.write_i32::<NetworkEndian>(buffer.len().try_into()?)?;
            out.write_all(&buffer)?;
            buffer.clear();
        } else { out.write_i32::<NetworkEndian>(-1)?; }
        let oid =
            <Pg as HasSqlType<ST1>>::metadata(out.metadata_lookup()).oid()?;
        out.write_u32::<NetworkEndian>(oid)?;
        let is_null =
            {
                let mut temp_buffer =
                    Output::new(ByteWrapper(&mut buffer),
                        out.metadata_lookup());
                let is_null = self.1.to_sql(&mut temp_buffer)?;
                is_null
            };
        if let IsNull::No = is_null {
            out.write_i32::<NetworkEndian>(buffer.len().try_into()?)?;
            out.write_all(&buffer)?;
            buffer.clear();
        } else { out.write_i32::<NetworkEndian>(-1)?; }
        let oid =
            <Pg as HasSqlType<ST2>>::metadata(out.metadata_lookup()).oid()?;
        out.write_u32::<NetworkEndian>(oid)?;
        let is_null =
            {
                let mut temp_buffer =
                    Output::new(ByteWrapper(&mut buffer),
                        out.metadata_lookup());
                let is_null = self.2.to_sql(&mut temp_buffer)?;
                is_null
            };
        if let IsNull::No = is_null {
            out.write_i32::<NetworkEndian>(buffer.len().try_into()?)?;
            out.write_all(&buffer)?;
            buffer.clear();
        } else { out.write_i32::<NetworkEndian>(-1)?; }
        let oid =
            <Pg as HasSqlType<ST3>>::metadata(out.metadata_lookup()).oid()?;
        out.write_u32::<NetworkEndian>(oid)?;
        let is_null =
            {
                let mut temp_buffer =
                    Output::new(ByteWrapper(&mut buffer),
                        out.metadata_lookup());
                let is_null = self.3.to_sql(&mut temp_buffer)?;
                is_null
            };
        if let IsNull::No = is_null {
            out.write_i32::<NetworkEndian>(buffer.len().try_into()?)?;
            out.write_all(&buffer)?;
            buffer.clear();
        } else { out.write_i32::<NetworkEndian>(-1)?; }
        let oid =
            <Pg as HasSqlType<ST4>>::metadata(out.metadata_lookup()).oid()?;
        out.write_u32::<NetworkEndian>(oid)?;
        let is_null =
            {
                let mut temp_buffer =
                    Output::new(ByteWrapper(&mut buffer),
                        out.metadata_lookup());
                let is_null = self.4.to_sql(&mut temp_buffer)?;
                is_null
            };
        if let IsNull::No = is_null {
            out.write_i32::<NetworkEndian>(buffer.len().try_into()?)?;
            out.write_all(&buffer)?;
            buffer.clear();
        } else { out.write_i32::<NetworkEndian>(-1)?; }
        let oid =
            <Pg as HasSqlType<ST5>>::metadata(out.metadata_lookup()).oid()?;
        out.write_u32::<NetworkEndian>(oid)?;
        let is_null =
            {
                let mut temp_buffer =
                    Output::new(ByteWrapper(&mut buffer),
                        out.metadata_lookup());
                let is_null = self.5.to_sql(&mut temp_buffer)?;
                is_null
            };
        if let IsNull::No = is_null {
            out.write_i32::<NetworkEndian>(buffer.len().try_into()?)?;
            out.write_all(&buffer)?;
            buffer.clear();
        } else { out.write_i32::<NetworkEndian>(-1)?; }
        let oid =
            <Pg as HasSqlType<ST6>>::metadata(out.metadata_lookup()).oid()?;
        out.write_u32::<NetworkEndian>(oid)?;
        let is_null =
            {
                let mut temp_buffer =
                    Output::new(ByteWrapper(&mut buffer),
                        out.metadata_lookup());
                let is_null = self.6.to_sql(&mut temp_buffer)?;
                is_null
            };
        if let IsNull::No = is_null {
            out.write_i32::<NetworkEndian>(buffer.len().try_into()?)?;
            out.write_all(&buffer)?;
            buffer.clear();
        } else { out.write_i32::<NetworkEndian>(-1)?; }
        let oid =
            <Pg as HasSqlType<ST7>>::metadata(out.metadata_lookup()).oid()?;
        out.write_u32::<NetworkEndian>(oid)?;
        let is_null =
            {
                let mut temp_buffer =
                    Output::new(ByteWrapper(&mut buffer),
                        out.metadata_lookup());
                let is_null = self.7.to_sql(&mut temp_buffer)?;
                is_null
            };
        if let IsNull::No = is_null {
            out.write_i32::<NetworkEndian>(buffer.len().try_into()?)?;
            out.write_all(&buffer)?;
            buffer.clear();
        } else { out.write_i32::<NetworkEndian>(-1)?; }
        let oid =
            <Pg as HasSqlType<ST8>>::metadata(out.metadata_lookup()).oid()?;
        out.write_u32::<NetworkEndian>(oid)?;
        let is_null =
            {
                let mut temp_buffer =
                    Output::new(ByteWrapper(&mut buffer),
                        out.metadata_lookup());
                let is_null = self.8.to_sql(&mut temp_buffer)?;
                is_null
            };
        if let IsNull::No = is_null {
            out.write_i32::<NetworkEndian>(buffer.len().try_into()?)?;
            out.write_all(&buffer)?;
            buffer.clear();
        } else { out.write_i32::<NetworkEndian>(-1)?; }
        let oid =
            <Pg as HasSqlType<ST9>>::metadata(out.metadata_lookup()).oid()?;
        out.write_u32::<NetworkEndian>(oid)?;
        let is_null =
            {
                let mut temp_buffer =
                    Output::new(ByteWrapper(&mut buffer),
                        out.metadata_lookup());
                let is_null = self.9.to_sql(&mut temp_buffer)?;
                is_null
            };
        if let IsNull::No = is_null {
            out.write_i32::<NetworkEndian>(buffer.len().try_into()?)?;
            out.write_all(&buffer)?;
            buffer.clear();
        } else { out.write_i32::<NetworkEndian>(-1)?; }
        let oid =
            <Pg as HasSqlType<ST10>>::metadata(out.metadata_lookup()).oid()?;
        out.write_u32::<NetworkEndian>(oid)?;
        let is_null =
            {
                let mut temp_buffer =
                    Output::new(ByteWrapper(&mut buffer),
                        out.metadata_lookup());
                let is_null = self.10.to_sql(&mut temp_buffer)?;
                is_null
            };
        if let IsNull::No = is_null {
            out.write_i32::<NetworkEndian>(buffer.len().try_into()?)?;
            out.write_all(&buffer)?;
            buffer.clear();
        } else { out.write_i32::<NetworkEndian>(-1)?; }
        let oid =
            <Pg as HasSqlType<ST11>>::metadata(out.metadata_lookup()).oid()?;
        out.write_u32::<NetworkEndian>(oid)?;
        let is_null =
            {
                let mut temp_buffer =
                    Output::new(ByteWrapper(&mut buffer),
                        out.metadata_lookup());
                let is_null = self.11.to_sql(&mut temp_buffer)?;
                is_null
            };
        if let IsNull::No = is_null {
            out.write_i32::<NetworkEndian>(buffer.len().try_into()?)?;
            out.write_all(&buffer)?;
            buffer.clear();
        } else { out.write_i32::<NetworkEndian>(-1)?; }
        let oid =
            <Pg as HasSqlType<ST12>>::metadata(out.metadata_lookup()).oid()?;
        out.write_u32::<NetworkEndian>(oid)?;
        let is_null =
            {
                let mut temp_buffer =
                    Output::new(ByteWrapper(&mut buffer),
                        out.metadata_lookup());
                let is_null = self.12.to_sql(&mut temp_buffer)?;
                is_null
            };
        if let IsNull::No = is_null {
            out.write_i32::<NetworkEndian>(buffer.len().try_into()?)?;
            out.write_all(&buffer)?;
            buffer.clear();
        } else { out.write_i32::<NetworkEndian>(-1)?; }
        let oid =
            <Pg as HasSqlType<ST13>>::metadata(out.metadata_lookup()).oid()?;
        out.write_u32::<NetworkEndian>(oid)?;
        let is_null =
            {
                let mut temp_buffer =
                    Output::new(ByteWrapper(&mut buffer),
                        out.metadata_lookup());
                let is_null = self.13.to_sql(&mut temp_buffer)?;
                is_null
            };
        if let IsNull::No = is_null {
            out.write_i32::<NetworkEndian>(buffer.len().try_into()?)?;
            out.write_all(&buffer)?;
            buffer.clear();
        } else { out.write_i32::<NetworkEndian>(-1)?; }
        let oid =
            <Pg as HasSqlType<ST14>>::metadata(out.metadata_lookup()).oid()?;
        out.write_u32::<NetworkEndian>(oid)?;
        let is_null =
            {
                let mut temp_buffer =
                    Output::new(ByteWrapper(&mut buffer),
                        out.metadata_lookup());
                let is_null = self.14.to_sql(&mut temp_buffer)?;
                is_null
            };
        if let IsNull::No = is_null {
            out.write_i32::<NetworkEndian>(buffer.len().try_into()?)?;
            out.write_all(&buffer)?;
            buffer.clear();
        } else { out.write_i32::<NetworkEndian>(-1)?; }
        let oid =
            <Pg as HasSqlType<ST15>>::metadata(out.metadata_lookup()).oid()?;
        out.write_u32::<NetworkEndian>(oid)?;
        let is_null =
            {
                let mut temp_buffer =
                    Output::new(ByteWrapper(&mut buffer),
                        out.metadata_lookup());
                let is_null = self.15.to_sql(&mut temp_buffer)?;
                is_null
            };
        if let IsNull::No = is_null {
            out.write_i32::<NetworkEndian>(buffer.len().try_into()?)?;
            out.write_all(&buffer)?;
            buffer.clear();
        } else { out.write_i32::<NetworkEndian>(-1)?; }
        let oid =
            <Pg as HasSqlType<ST16>>::metadata(out.metadata_lookup()).oid()?;
        out.write_u32::<NetworkEndian>(oid)?;
        let is_null =
            {
                let mut temp_buffer =
                    Output::new(ByteWrapper(&mut buffer),
                        out.metadata_lookup());
                let is_null = self.16.to_sql(&mut temp_buffer)?;
                is_null
            };
        if let IsNull::No = is_null {
            out.write_i32::<NetworkEndian>(buffer.len().try_into()?)?;
            out.write_all(&buffer)?;
            buffer.clear();
        } else { out.write_i32::<NetworkEndian>(-1)?; }
        let oid =
            <Pg as HasSqlType<ST17>>::metadata(out.metadata_lookup()).oid()?;
        out.write_u32::<NetworkEndian>(oid)?;
        let is_null =
            {
                let mut temp_buffer =
                    Output::new(ByteWrapper(&mut buffer),
                        out.metadata_lookup());
                let is_null = self.17.to_sql(&mut temp_buffer)?;
                is_null
            };
        if let IsNull::No = is_null {
            out.write_i32::<NetworkEndian>(buffer.len().try_into()?)?;
            out.write_all(&buffer)?;
            buffer.clear();
        } else { out.write_i32::<NetworkEndian>(-1)?; }
        let oid =
            <Pg as HasSqlType<ST18>>::metadata(out.metadata_lookup()).oid()?;
        out.write_u32::<NetworkEndian>(oid)?;
        let is_null =
            {
                let mut temp_buffer =
                    Output::new(ByteWrapper(&mut buffer),
                        out.metadata_lookup());
                let is_null = self.18.to_sql(&mut temp_buffer)?;
                is_null
            };
        if let IsNull::No = is_null {
            out.write_i32::<NetworkEndian>(buffer.len().try_into()?)?;
            out.write_all(&buffer)?;
            buffer.clear();
        } else { out.write_i32::<NetworkEndian>(-1)?; }
        let oid =
            <Pg as HasSqlType<ST19>>::metadata(out.metadata_lookup()).oid()?;
        out.write_u32::<NetworkEndian>(oid)?;
        let is_null =
            {
                let mut temp_buffer =
                    Output::new(ByteWrapper(&mut buffer),
                        out.metadata_lookup());
                let is_null = self.19.to_sql(&mut temp_buffer)?;
                is_null
            };
        if let IsNull::No = is_null {
            out.write_i32::<NetworkEndian>(buffer.len().try_into()?)?;
            out.write_all(&buffer)?;
            buffer.clear();
        } else { out.write_i32::<NetworkEndian>(-1)?; }
        let oid =
            <Pg as HasSqlType<ST20>>::metadata(out.metadata_lookup()).oid()?;
        out.write_u32::<NetworkEndian>(oid)?;
        let is_null =
            {
                let mut temp_buffer =
                    Output::new(ByteWrapper(&mut buffer),
                        out.metadata_lookup());
                let is_null = self.20.to_sql(&mut temp_buffer)?;
                is_null
            };
        if let IsNull::No = is_null {
            out.write_i32::<NetworkEndian>(buffer.len().try_into()?)?;
            out.write_all(&buffer)?;
            buffer.clear();
        } else { out.write_i32::<NetworkEndian>(-1)?; }
        let oid =
            <Pg as HasSqlType<ST21>>::metadata(out.metadata_lookup()).oid()?;
        out.write_u32::<NetworkEndian>(oid)?;
        let is_null =
            {
                let mut temp_buffer =
                    Output::new(ByteWrapper(&mut buffer),
                        out.metadata_lookup());
                let is_null = self.21.to_sql(&mut temp_buffer)?;
                is_null
            };
        if let IsNull::No = is_null {
            out.write_i32::<NetworkEndian>(buffer.len().try_into()?)?;
            out.write_all(&buffer)?;
            buffer.clear();
        } else { out.write_i32::<NetworkEndian>(-1)?; }
        let oid =
            <Pg as HasSqlType<ST22>>::metadata(out.metadata_lookup()).oid()?;
        out.write_u32::<NetworkEndian>(oid)?;
        let is_null =
            {
                let mut temp_buffer =
                    Output::new(ByteWrapper(&mut buffer),
                        out.metadata_lookup());
                let is_null = self.22.to_sql(&mut temp_buffer)?;
                is_null
            };
        if let IsNull::No = is_null {
            out.write_i32::<NetworkEndian>(buffer.len().try_into()?)?;
            out.write_all(&buffer)?;
            buffer.clear();
        } else { out.write_i32::<NetworkEndian>(-1)?; }
        let oid =
            <Pg as HasSqlType<ST23>>::metadata(out.metadata_lookup()).oid()?;
        out.write_u32::<NetworkEndian>(oid)?;
        let is_null =
            {
                let mut temp_buffer =
                    Output::new(ByteWrapper(&mut buffer),
                        out.metadata_lookup());
                let is_null = self.23.to_sql(&mut temp_buffer)?;
                is_null
            };
        if let IsNull::No = is_null {
            out.write_i32::<NetworkEndian>(buffer.len().try_into()?)?;
            out.write_all(&buffer)?;
            buffer.clear();
        } else { out.write_i32::<NetworkEndian>(-1)?; }
        let oid =
            <Pg as HasSqlType<ST24>>::metadata(out.metadata_lookup()).oid()?;
        out.write_u32::<NetworkEndian>(oid)?;
        let is_null =
            {
                let mut temp_buffer =
                    Output::new(ByteWrapper(&mut buffer),
                        out.metadata_lookup());
                let is_null = self.24.to_sql(&mut temp_buffer)?;
                is_null
            };
        if let IsNull::No = is_null {
            out.write_i32::<NetworkEndian>(buffer.len().try_into()?)?;
            out.write_all(&buffer)?;
            buffer.clear();
        } else { out.write_i32::<NetworkEndian>(-1)?; }
        let oid =
            <Pg as HasSqlType<ST25>>::metadata(out.metadata_lookup()).oid()?;
        out.write_u32::<NetworkEndian>(oid)?;
        let is_null =
            {
                let mut temp_buffer =
                    Output::new(ByteWrapper(&mut buffer),
                        out.metadata_lookup());
                let is_null = self.25.to_sql(&mut temp_buffer)?;
                is_null
            };
        if let IsNull::No = is_null {
            out.write_i32::<NetworkEndian>(buffer.len().try_into()?)?;
            out.write_all(&buffer)?;
            buffer.clear();
        } else { out.write_i32::<NetworkEndian>(-1)?; }
        let oid =
            <Pg as HasSqlType<ST26>>::metadata(out.metadata_lookup()).oid()?;
        out.write_u32::<NetworkEndian>(oid)?;
        let is_null =
            {
                let mut temp_buffer =
                    Output::new(ByteWrapper(&mut buffer),
                        out.metadata_lookup());
                let is_null = self.26.to_sql(&mut temp_buffer)?;
                is_null
            };
        if let IsNull::No = is_null {
            out.write_i32::<NetworkEndian>(buffer.len().try_into()?)?;
            out.write_all(&buffer)?;
            buffer.clear();
        } else { out.write_i32::<NetworkEndian>(-1)?; }
        let oid =
            <Pg as HasSqlType<ST27>>::metadata(out.metadata_lookup()).oid()?;
        out.write_u32::<NetworkEndian>(oid)?;
        let is_null =
            {
                let mut temp_buffer =
                    Output::new(ByteWrapper(&mut buffer),
                        out.metadata_lookup());
                let is_null = self.27.to_sql(&mut temp_buffer)?;
                is_null
            };
        if let IsNull::No = is_null {
            out.write_i32::<NetworkEndian>(buffer.len().try_into()?)?;
            out.write_all(&buffer)?;
            buffer.clear();
        } else { out.write_i32::<NetworkEndian>(-1)?; }
        let oid =
            <Pg as HasSqlType<ST28>>::metadata(out.metadata_lookup()).oid()?;
        out.write_u32::<NetworkEndian>(oid)?;
        let is_null =
            {
                let mut temp_buffer =
                    Output::new(ByteWrapper(&mut buffer),
                        out.metadata_lookup());
                let is_null = self.28.to_sql(&mut temp_buffer)?;
                is_null
            };
        if let IsNull::No = is_null {
            out.write_i32::<NetworkEndian>(buffer.len().try_into()?)?;
            out.write_all(&buffer)?;
            buffer.clear();
        } else { out.write_i32::<NetworkEndian>(-1)?; }
        let oid =
            <Pg as HasSqlType<ST29>>::metadata(out.metadata_lookup()).oid()?;
        out.write_u32::<NetworkEndian>(oid)?;
        let is_null =
            {
                let mut temp_buffer =
                    Output::new(ByteWrapper(&mut buffer),
                        out.metadata_lookup());
                let is_null = self.29.to_sql(&mut temp_buffer)?;
                is_null
            };
        if let IsNull::No = is_null {
            out.write_i32::<NetworkEndian>(buffer.len().try_into()?)?;
            out.write_all(&buffer)?;
            buffer.clear();
        } else { out.write_i32::<NetworkEndian>(-1)?; }
        let oid =
            <Pg as HasSqlType<ST30>>::metadata(out.metadata_lookup()).oid()?;
        out.write_u32::<NetworkEndian>(oid)?;
        let is_null =
            {
                let mut temp_buffer =
                    Output::new(ByteWrapper(&mut buffer),
                        out.metadata_lookup());
                let is_null = self.30.to_sql(&mut temp_buffer)?;
                is_null
            };
        if let IsNull::No = is_null {
            out.write_i32::<NetworkEndian>(buffer.len().try_into()?)?;
            out.write_all(&buffer)?;
            buffer.clear();
        } else { out.write_i32::<NetworkEndian>(-1)?; }
        let oid =
            <Pg as HasSqlType<ST31>>::metadata(out.metadata_lookup()).oid()?;
        out.write_u32::<NetworkEndian>(oid)?;
        let is_null =
            {
                let mut temp_buffer =
                    Output::new(ByteWrapper(&mut buffer),
                        out.metadata_lookup());
                let is_null = self.31.to_sql(&mut temp_buffer)?;
                is_null
            };
        if let IsNull::No = is_null {
            out.write_i32::<NetworkEndian>(buffer.len().try_into()?)?;
            out.write_all(&buffer)?;
            buffer.clear();
        } else { out.write_i32::<NetworkEndian>(-1)?; }
        Ok(IsNull::No)
    }
}diesel_derives::__diesel_for_each_tuple!(tuple_impls);
140
141#[derive(#[automatically_derived]
impl<T: ::core::fmt::Debug> ::core::fmt::Debug for PgTuple<T> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_tuple_field1_finish(f, "PgTuple",
            &&self.0)
    }
}Debug, #[automatically_derived]
impl<T: ::core::clone::Clone> ::core::clone::Clone for PgTuple<T> {
    #[inline]
    fn clone(&self) -> PgTuple<T> {
        PgTuple(::core::clone::Clone::clone(&self.0))
    }
}Clone, #[automatically_derived]
impl<T: ::core::marker::Copy> ::core::marker::Copy for PgTuple<T> { }Copy, const _: () =
    {
        use diesel;
        #[allow(non_camel_case_types)]
        impl<T: diesel::query_builder::QueryId> diesel::query_builder::QueryId
            for PgTuple<T> {
            type QueryId =
                PgTuple<<T as diesel::query_builder::QueryId>::QueryId>;
            const HAS_STATIC_QUERY_ID: bool =
                <T as diesel::query_builder::QueryId>::HAS_STATIC_QUERY_ID &&
                    true;
            const IS_WINDOW_FUNCTION: bool =
                <T as diesel::query_builder::QueryId>::IS_WINDOW_FUNCTION ||
                    false;
        }
    };QueryId, const _: () =
    {
        use diesel;
        impl<T, __GroupByClause>
            diesel::expression::ValidGrouping<__GroupByClause> for PgTuple<T>
            where T: diesel::expression::ValidGrouping<__GroupByClause> {
            type IsAggregate =
                <T as
                diesel::expression::ValidGrouping<__GroupByClause>>::IsAggregate;
        }
    };ValidGrouping)]
142pub struct PgTuple<T>(T);
143
144impl<T> QueryFragment<Pg> for PgTuple<T>
145where
146    T: QueryFragment<Pg>,
147{
148    fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, Pg>) -> QueryResult<()> {
149        out.push_sql("ROW(");
150        self.0.walk_ast(out.reborrow())?;
151        out.push_sql(")");
152        Ok(())
153    }
154}
155
156impl<T> Expression for PgTuple<T>
157where
158    T: Expression,
159    T::SqlType: 'static,
160{
161    type SqlType = Record<T::SqlType>;
162}
163
164impl<T, QS> SelectableExpression<QS> for PgTuple<T>
165where
166    T: SelectableExpression<QS>,
167    Self: AppearsOnTable<QS>,
168{
169}
170
171impl<T, QS> AppearsOnTable<QS> for PgTuple<T>
172where
173    T: AppearsOnTable<QS>,
174    Self: Expression,
175{
176}
177
178#[cfg(test)]
179mod tests {
180    use super::*;
181    use crate::dsl::sql;
182    use crate::prelude::*;
183    use crate::sql_types::*;
184    use crate::test_helpers::*;
185
186    #[diesel_test_helper::test]
187    fn record_deserializes_correctly() {
188        let conn = &mut pg_connection();
189
190        let tup =
191            sql::<Record<(Integer, Text)>>("SELECT (1, 'hi')").get_result::<(i32, String)>(conn);
192        assert_eq!(Ok((1, String::from("hi"))), tup);
193
194        let tup = sql::<Record<(Record<(Integer, Text)>, Integer)>>("SELECT ((2, 'bye'), 3)")
195            .get_result::<((i32, String), i32)>(conn);
196        assert_eq!(Ok(((2, String::from("bye")), 3)), tup);
197
198        let tup = sql::<
199            Record<(
200                Record<(Nullable<Integer>, Nullable<Text>)>,
201                Nullable<Integer>,
202            )>,
203        >("SELECT ((4, NULL), NULL)")
204        .get_result::<((Option<i32>, Option<String>), Option<i32>)>(conn);
205        assert_eq!(Ok(((Some(4), None), None)), tup);
206
207        let tup = sql::<Record<(Integer,)>>("SELECT ROW(1)").get_result::<(i32,)>(conn);
208        assert_eq!(Ok((1,)), tup);
209    }
210
211    #[diesel_test_helper::test]
212    fn record_kinda_sorta_not_really_serializes_correctly() {
213        let conn = &mut pg_connection();
214
215        let tup = sql::<Record<(Integer, Text)>>("(1, 'hi')");
216        let res = crate::select(tup.eq((1, "hi"))).get_result(conn);
217        assert_eq!(Ok(true), res);
218
219        let tup = sql::<Record<(Record<(Integer, Text)>, Integer)>>("((2, 'bye'::text), 3)");
220        let res = crate::select(tup.eq(((2, "bye"), 3))).get_result(conn);
221        assert_eq!(Ok(true), res);
222
223        let tup = sql::<Record<(Integer,)>>("ROW(3)");
224        let res = crate::select(tup.eq((3,))).get_result(conn);
225        assert_eq!(Ok(true), res);
226
227        let tup = sql::<
228            Record<(
229                Record<(Nullable<Integer>, Nullable<Text>)>,
230                Nullable<Integer>,
231            )>,
232        >("((4, NULL::text), NULL::int4)");
233        let res = crate::select(tup.is_not_distinct_from(((Some(4), None::<&str>), None::<i32>)))
234            .get_result(conn);
235        assert_eq!(Ok(true), res);
236    }
237
238    #[diesel_test_helper::test]
239    fn serializing_named_composite_types() {
240        #[derive(SqlType, QueryId, Debug, Clone, Copy)]
241        #[diesel(postgres_type(name = "my_type"))]
242        struct MyType;
243
244        #[derive(Debug, AsExpression)]
245        #[diesel(sql_type = MyType)]
246        struct MyStruct<'a>(i32, &'a str);
247
248        impl ToSql<MyType, Pg> for MyStruct<'_> {
249            fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Pg>) -> serialize::Result {
250                WriteTuple::<(Integer, Text)>::write_tuple(&(self.0, self.1), out)
251            }
252        }
253
254        let conn = &mut pg_connection();
255
256        crate::sql_query("CREATE TYPE my_type AS (i int4, t text)")
257            .execute(conn)
258            .unwrap();
259        let sql = sql::<Bool>("(1, 'hi')::my_type = ").bind::<MyType, _>(MyStruct(1, "hi"));
260        let res = crate::select(sql).get_result(conn);
261        assert_eq!(Ok(true), res);
262    }
263
264    #[diesel_test_helper::test]
265    fn invalid_element_size_for_records() {
266        // check invalid element sizes
267        let mut value = Vec::<u8>::new();
268
269        // num elements
270        value.write_i32::<NetworkEndian>(1).unwrap();
271        // oid of the first element
272        value.write_i32::<NetworkEndian>(1).unwrap();
273        // element size
274        value.write_i32::<NetworkEndian>(6).unwrap();
275        value.write_i32::<NetworkEndian>(4).unwrap();
276        let value = PgValue::for_test(&value);
277
278        let res = <(i32,) as FromSql<Record<(Integer,)>, Pg>>::from_sql(value);
279        assert!(res.is_err());
280        assert_eq!(
281            format!("{}", res.unwrap_err()),
282            "Invalid element byte count: Expected at least 6 bytes, but only 4 bytes were received",
283        );
284
285        // check for invalid number of elements
286        let mut value = Vec::<u8>::new();
287
288        // num elements
289        value.write_i32::<NetworkEndian>(1).unwrap();
290        let value = PgValue::for_test(&value);
291
292        let res = <(i32,) as FromSql<Record<(Integer,)>, Pg>>::from_sql(value);
293        assert!(res.is_err());
294        assert_eq!(
295            format!("{}", res.unwrap_err()),
296            "failed to fill whole buffer",
297        );
298
299        // check for zero oids
300        // check invalid element sizes
301        let mut value = Vec::<u8>::new();
302
303        // num elements
304        value.write_i32::<NetworkEndian>(1).unwrap();
305        // oid of the first element
306        value.write_i32::<NetworkEndian>(0).unwrap();
307        // size of the first element
308        value.write_i32::<NetworkEndian>(4).unwrap();
309        // the value of the first element
310        value.write_i32::<NetworkEndian>(42).unwrap();
311        let value = PgValue::for_test(&value);
312
313        let res = <(i32,) as FromSql<Record<(Integer,)>, Pg>>::from_sql(value);
314        assert!(res.is_err());
315        assert_eq!(format!("{}", res.unwrap_err()), "Oid's aren't zero");
316    }
317}