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>()?).expect("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(num_bytes.try_into()?);
56                        bytes = new_bytes;
57                        $T::from_sql(PgValue::new_internal(
58                            elem_bytes,
59                            &oid,
60                        ))?
61                    }
62                },)+);
63
64                if bytes.is_empty() {
65                    Ok(result)
66                } else {
67                    Err("Received too many bytes. This tuple likely contains \
68                        an element of the wrong SQL type.".into())
69                }
70            }
71        }
72
73        #[cfg(feature = "postgres_backend")]
74        impl<$($T,)+ $($ST,)+> Queryable<Record<($($ST,)+)>, Pg> for ($($T,)+)
75        where Self: FromSql<Record<($($ST,)+)>, Pg>
76        {
77            type Row = Self;
78
79            fn build(row: Self::Row) -> deserialize::Result<Self> {
80                Ok(row)
81            }
82        }
83
84        #[cfg(feature = "postgres_backend")]
85        impl<$($T,)+ $($ST,)+> AsExpression<Record<($($ST,)+)>> for ($($T,)+)
86        where
87            $($ST: SqlType + TypedExpressionType,)+
88            $($T: AsExpression<$ST>,)+
89            PgTuple<($($T::Expression,)+)>: Expression<SqlType = Record<($($ST,)+)>>,
90        {
91            type Expression = PgTuple<($($T::Expression,)+)>;
92
93            fn as_expression(self) -> Self::Expression {
94                PgTuple(($(
95                    self.$idx.as_expression(),
96                )+))
97            }
98        }
99
100        #[cfg(feature = "postgres_backend")]
101        impl<$($T,)+ $($ST,)+> WriteTuple<($($ST,)+)> for ($($T,)+)
102        where
103            $($T: ToSql<$ST, Pg>,)+
104            $(Pg: HasSqlType<$ST>),+
105        {
106            fn write_tuple(&self, out: &mut Output<'_, '_, Pg>) -> serialize::Result {
107                let mut buffer = Vec::new();
108                out.write_i32::<NetworkEndian>($Tuple)?;
109
110                $(
111                    let oid = <Pg as HasSqlType<$ST>>::metadata(out.metadata_lookup()).oid()?;
112                    out.write_u32::<NetworkEndian>(oid)?;
113                    let is_null = {
114                        let mut temp_buffer = Output::new(ByteWrapper(&mut buffer), out.metadata_lookup());
115                        let is_null = self.$idx.to_sql(&mut temp_buffer)?;
116                        is_null
117                    };
118
119                    if let IsNull::No = is_null {
120                        out.write_i32::<NetworkEndian>(buffer.len().try_into()?)?;
121                        out.write_all(&buffer)?;
122                        buffer.clear();
123                    } else {
124                        out.write_i32::<NetworkEndian>(-1)?;
125                    }
126                )+
127
128                Ok(IsNull::No)
129            }
130        }
131    )+}
132}
133
134impl<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>()?).expect("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(num_bytes.try_into()?);
                        bytes = new_bytes;
                        T::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).expect("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(num_bytes.try_into()?);
                        bytes = new_bytes;
                        T1::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).expect("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(num_bytes.try_into()?);
                        bytes = new_bytes;
                        T2::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).expect("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(num_bytes.try_into()?);
                        bytes = new_bytes;
                        T3::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).expect("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(num_bytes.try_into()?);
                        bytes = new_bytes;
                        T4::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).expect("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(num_bytes.try_into()?);
                        bytes = new_bytes;
                        T5::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).expect("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(num_bytes.try_into()?);
                        bytes = new_bytes;
                        T6::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).expect("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(num_bytes.try_into()?);
                        bytes = new_bytes;
                        T7::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).expect("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(num_bytes.try_into()?);
                        bytes = new_bytes;
                        T8::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).expect("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(num_bytes.try_into()?);
                        bytes = new_bytes;
                        T9::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).expect("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(num_bytes.try_into()?);
                        bytes = new_bytes;
                        T10::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).expect("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(num_bytes.try_into()?);
                        bytes = new_bytes;
                        T11::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).expect("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(num_bytes.try_into()?);
                        bytes = new_bytes;
                        T12::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).expect("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(num_bytes.try_into()?);
                        bytes = new_bytes;
                        T13::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).expect("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(num_bytes.try_into()?);
                        bytes = new_bytes;
                        T14::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).expect("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(num_bytes.try_into()?);
                        bytes = new_bytes;
                        T15::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).expect("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(num_bytes.try_into()?);
                        bytes = new_bytes;
                        T16::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).expect("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(num_bytes.try_into()?);
                        bytes = new_bytes;
                        T17::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).expect("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(num_bytes.try_into()?);
                        bytes = new_bytes;
                        T18::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).expect("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(num_bytes.try_into()?);
                        bytes = new_bytes;
                        T19::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).expect("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(num_bytes.try_into()?);
                        bytes = new_bytes;
                        T20::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).expect("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(num_bytes.try_into()?);
                        bytes = new_bytes;
                        T21::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).expect("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(num_bytes.try_into()?);
                        bytes = new_bytes;
                        T22::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).expect("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(num_bytes.try_into()?);
                        bytes = new_bytes;
                        T23::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).expect("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(num_bytes.try_into()?);
                        bytes = new_bytes;
                        T24::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).expect("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(num_bytes.try_into()?);
                        bytes = new_bytes;
                        T25::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).expect("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(num_bytes.try_into()?);
                        bytes = new_bytes;
                        T26::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).expect("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(num_bytes.try_into()?);
                        bytes = new_bytes;
                        T27::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).expect("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(num_bytes.try_into()?);
                        bytes = new_bytes;
                        T28::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).expect("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(num_bytes.try_into()?);
                        bytes = new_bytes;
                        T29::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).expect("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(num_bytes.try_into()?);
                        bytes = new_bytes;
                        T30::from_sql(PgValue::new_internal(elem_bytes, &oid))?
                    }
                },
                {
                    let oid =
                        NonZeroU32::new(bytes.read_u32::<NetworkEndian>()?).expect("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(num_bytes.try_into()?);
                        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);
135
136#[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)]
137pub struct PgTuple<T>(T);
138
139impl<T> QueryFragment<Pg> for PgTuple<T>
140where
141    T: QueryFragment<Pg>,
142{
143    fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, Pg>) -> QueryResult<()> {
144        out.push_sql("ROW(");
145        self.0.walk_ast(out.reborrow())?;
146        out.push_sql(")");
147        Ok(())
148    }
149}
150
151impl<T> Expression for PgTuple<T>
152where
153    T: Expression,
154    T::SqlType: 'static,
155{
156    type SqlType = Record<T::SqlType>;
157}
158
159impl<T, QS> SelectableExpression<QS> for PgTuple<T>
160where
161    T: SelectableExpression<QS>,
162    Self: AppearsOnTable<QS>,
163{
164}
165
166impl<T, QS> AppearsOnTable<QS> for PgTuple<T>
167where
168    T: AppearsOnTable<QS>,
169    Self: Expression,
170{
171}
172
173#[cfg(test)]
174mod tests {
175    use super::*;
176    use crate::dsl::sql;
177    use crate::prelude::*;
178    use crate::sql_types::*;
179    use crate::test_helpers::*;
180
181    #[diesel_test_helper::test]
182    fn record_deserializes_correctly() {
183        let conn = &mut pg_connection();
184
185        let tup =
186            sql::<Record<(Integer, Text)>>("SELECT (1, 'hi')").get_result::<(i32, String)>(conn);
187        assert_eq!(Ok((1, String::from("hi"))), tup);
188
189        let tup = sql::<Record<(Record<(Integer, Text)>, Integer)>>("SELECT ((2, 'bye'), 3)")
190            .get_result::<((i32, String), i32)>(conn);
191        assert_eq!(Ok(((2, String::from("bye")), 3)), tup);
192
193        let tup = sql::<
194            Record<(
195                Record<(Nullable<Integer>, Nullable<Text>)>,
196                Nullable<Integer>,
197            )>,
198        >("SELECT ((4, NULL), NULL)")
199        .get_result::<((Option<i32>, Option<String>), Option<i32>)>(conn);
200        assert_eq!(Ok(((Some(4), None), None)), tup);
201
202        let tup = sql::<Record<(Integer,)>>("SELECT ROW(1)").get_result::<(i32,)>(conn);
203        assert_eq!(Ok((1,)), tup);
204    }
205
206    #[diesel_test_helper::test]
207    fn record_kinda_sorta_not_really_serializes_correctly() {
208        let conn = &mut pg_connection();
209
210        let tup = sql::<Record<(Integer, Text)>>("(1, 'hi')");
211        let res = crate::select(tup.eq((1, "hi"))).get_result(conn);
212        assert_eq!(Ok(true), res);
213
214        let tup = sql::<Record<(Record<(Integer, Text)>, Integer)>>("((2, 'bye'::text), 3)");
215        let res = crate::select(tup.eq(((2, "bye"), 3))).get_result(conn);
216        assert_eq!(Ok(true), res);
217
218        let tup = sql::<Record<(Integer,)>>("ROW(3)");
219        let res = crate::select(tup.eq((3,))).get_result(conn);
220        assert_eq!(Ok(true), res);
221
222        let tup = sql::<
223            Record<(
224                Record<(Nullable<Integer>, Nullable<Text>)>,
225                Nullable<Integer>,
226            )>,
227        >("((4, NULL::text), NULL::int4)");
228        let res = crate::select(tup.is_not_distinct_from(((Some(4), None::<&str>), None::<i32>)))
229            .get_result(conn);
230        assert_eq!(Ok(true), res);
231    }
232
233    #[diesel_test_helper::test]
234    fn serializing_named_composite_types() {
235        #[derive(SqlType, QueryId, Debug, Clone, Copy)]
236        #[diesel(postgres_type(name = "my_type"))]
237        struct MyType;
238
239        #[derive(Debug, AsExpression)]
240        #[diesel(sql_type = MyType)]
241        struct MyStruct<'a>(i32, &'a str);
242
243        impl ToSql<MyType, Pg> for MyStruct<'_> {
244            fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Pg>) -> serialize::Result {
245                WriteTuple::<(Integer, Text)>::write_tuple(&(self.0, self.1), out)
246            }
247        }
248
249        let conn = &mut pg_connection();
250
251        crate::sql_query("CREATE TYPE my_type AS (i int4, t text)")
252            .execute(conn)
253            .unwrap();
254        let sql = sql::<Bool>("(1, 'hi')::my_type = ").bind::<MyType, _>(MyStruct(1, "hi"));
255        let res = crate::select(sql).get_result(conn);
256        assert_eq!(Ok(true), res);
257    }
258}