Skip to main content

diesel/pg/query_builder/copy/
copy_from.rs

1use alloc::borrow::Cow;
2use core::marker::PhantomData;
3
4use byteorder::NetworkEndian;
5use byteorder::WriteBytesExt;
6
7use super::CommonOptions;
8use super::CopyFormat;
9use super::CopyTarget;
10use crate::Connection;
11use crate::Insertable;
12use crate::QueryResult;
13use crate::expression::bound::Bound;
14use crate::insertable::ColumnInsertValue;
15use crate::pg::Pg;
16use crate::pg::PgMetadataLookup;
17use crate::pg::backend::FailedToLookupTypeError;
18use crate::pg::metadata_lookup::PgMetadataCacheKey;
19use crate::query_builder::BatchInsert;
20use crate::query_builder::QueryFragment;
21#[cfg(feature = "postgres")]
22use crate::query_builder::QueryId;
23use crate::query_builder::ValuesClause;
24use crate::serialize::IsNull;
25use crate::serialize::ToSql;
26use crate::{Column, Table};
27
28/// Describes the different possible settings for the `HEADER` option
29/// for `COPY FROM` statements
30#[derive(#[automatically_derived]
impl ::core::fmt::Debug for CopyHeader {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            CopyHeader::Set(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Set",
                    &__self_0),
            CopyHeader::Match =>
                ::core::fmt::Formatter::write_str(f, "Match"),
        }
    }
}Debug, #[automatically_derived]
impl ::core::marker::Copy for CopyHeader { }Copy, #[automatically_derived]
impl ::core::clone::Clone for CopyHeader {
    #[inline]
    fn clone(&self) -> CopyHeader {
        let _: ::core::clone::AssertParamIsClone<bool>;
        *self
    }
}Clone)]
31pub enum CopyHeader {
32    /// Is the header set?
33    Set(bool),
34    /// Match the header with the targeted table names
35    /// and fail in the case of a mismatch
36    Match,
37}
38
39#[derive(#[automatically_derived]
impl ::core::fmt::Debug for CopyFromOptions {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f,
            "CopyFromOptions", "common", &self.common, "default",
            &self.default, "header", &&self.header)
    }
}Debug, #[automatically_derived]
impl ::core::default::Default for CopyFromOptions {
    #[inline]
    fn default() -> CopyFromOptions {
        CopyFromOptions {
            common: ::core::default::Default::default(),
            default: ::core::default::Default::default(),
            header: ::core::default::Default::default(),
        }
    }
}Default)]
40pub struct CopyFromOptions {
41    common: CommonOptions,
42    default: Option<String>,
43    header: Option<CopyHeader>,
44}
45
46impl QueryFragment<Pg> for CopyFromOptions {
47    fn walk_ast<'b>(
48        &'b self,
49        mut pass: crate::query_builder::AstPass<'_, 'b, Pg>,
50    ) -> crate::QueryResult<()> {
51        if self.any_set() {
52            let mut comma = "";
53            pass.push_sql(" WITH (");
54            self.common.walk_ast(pass.reborrow(), &mut comma);
55            if let Some(ref default) = self.default {
56                pass.push_sql(comma);
57                comma = ", ";
58                pass.push_sql("DEFAULT '");
59                // we cannot use binds here
60                // so we need to make sure quotes in
61                // the input are handled correctly
62                let default = default.replace('\'', "''");
63                pass.push_sql(&default);
64                pass.push_sql("'");
65            }
66            if let Some(ref header) = self.header {
67                pass.push_sql(comma);
68                // commented out because rustc complains otherwise
69                //comma = ", ";
70                pass.push_sql("HEADER ");
71                match header {
72                    CopyHeader::Set(true) => pass.push_sql("1"),
73                    CopyHeader::Set(false) => pass.push_sql("0"),
74                    CopyHeader::Match => pass.push_sql("MATCH"),
75                }
76            }
77
78            pass.push_sql(")");
79        }
80        Ok(())
81    }
82}
83
84impl CopyFromOptions {
85    fn any_set(&self) -> bool {
86        self.common.any_set() || self.default.is_some() || self.header.is_some()
87    }
88}
89
90#[derive(#[automatically_derived]
impl<S: ::core::fmt::Debug, F: ::core::fmt::Debug> ::core::fmt::Debug for
    CopyFrom<S, F> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f, "CopyFrom",
            "options", &self.options, "copy_callback", &self.copy_callback,
            "p", &&self.p)
    }
}Debug)]
91pub struct CopyFrom<S, F> {
92    options: CopyFromOptions,
93    copy_callback: F,
94    p: PhantomData<S>,
95}
96
97// Same gate as the re-export, only the `postgres` connection builds this.
98#[cfg(feature = "postgres")]
99pub(crate) struct InternalCopyFromQuery<S, T> {
100    pub(crate) target: S,
101    p: PhantomData<T>,
102}
103
104#[cfg(feature = "postgres")]
105impl<S, T> InternalCopyFromQuery<S, T> {
106    pub(crate) fn new(target: S) -> Self {
107        Self {
108            target,
109            p: PhantomData,
110        }
111    }
112}
113
114#[cfg(feature = "postgres")]
115impl<S, T> QueryId for InternalCopyFromQuery<S, T>
116where
117    S: CopyFromExpression<T>,
118{
119    const HAS_STATIC_QUERY_ID: bool = false;
120    type QueryId = ();
121}
122
123#[cfg(feature = "postgres")]
124impl<S, T> QueryFragment<Pg> for InternalCopyFromQuery<S, T>
125where
126    S: CopyFromExpression<T>,
127{
128    fn walk_ast<'b>(
129        &'b self,
130        mut pass: crate::query_builder::AstPass<'_, 'b, Pg>,
131    ) -> crate::QueryResult<()> {
132        pass.unsafe_to_cache_prepared();
133        pass.push_sql("COPY ");
134        self.target.walk_target(pass.reborrow())?;
135        pass.push_sql(" FROM STDIN");
136        self.target.options().walk_ast(pass.reborrow())?;
137        Ok(())
138    }
139}
140
141pub trait CopyFromExpression<T> {
142    type Error: From<crate::result::Error> + core::error::Error;
143
144    fn callback(&mut self, copy: &mut impl std::io::Write) -> Result<(), Self::Error>;
145
146    fn walk_target<'b>(
147        &'b self,
148        pass: crate::query_builder::AstPass<'_, 'b, Pg>,
149    ) -> crate::QueryResult<()>;
150
151    fn options(&self) -> &CopyFromOptions;
152}
153
154impl<S, F, E> CopyFromExpression<S::Table> for CopyFrom<S, F>
155where
156    E: From<crate::result::Error> + core::error::Error,
157    S: CopyTarget,
158    F: Fn(&mut dyn std::io::Write) -> Result<(), E>,
159{
160    type Error = E;
161
162    fn callback(&mut self, copy: &mut impl std::io::Write) -> Result<(), Self::Error> {
163        (self.copy_callback)(copy)
164    }
165
166    fn options(&self) -> &CopyFromOptions {
167        &self.options
168    }
169
170    fn walk_target<'b>(
171        &'b self,
172        pass: crate::query_builder::AstPass<'_, 'b, Pg>,
173    ) -> crate::QueryResult<()> {
174        S::walk_target(pass)
175    }
176}
177
178struct Dummy;
179
180impl PgMetadataLookup for Dummy {
181    fn lookup_type(&mut self, type_name: &str, schema: Option<&str>) -> crate::pg::PgTypeMetadata {
182        let cache_key = PgMetadataCacheKey::new(
183            schema.map(Into::into).map(Cow::Owned),
184            Cow::Owned(type_name.into()),
185        );
186        crate::pg::PgTypeMetadata(Err(FailedToLookupTypeError::new_internal(cache_key)))
187    }
188}
189
190trait CopyFromInsertableHelper {
191    type Target: CopyTarget;
192    const COLUMN_COUNT: u16;
193
194    fn write_to_buffer(&self, idx: u16, out: &mut Vec<u8>) -> QueryResult<IsNull>;
195}
196
197macro_rules! impl_copy_from_insertable_helper_for_values_clause {
198    ($(
199        $Tuple:tt {
200            $(($idx:tt) -> $T:ident, $ST:ident, $TT:ident,)+
201        }
202    )+) => {
203        $(
204            impl<__T, $($ST,)* $($T,)* $($TT,)*> CopyFromInsertableHelper for ValuesClause<
205                ($(ColumnInsertValue<$ST, Bound<$T, $TT>>,)*),
206            __T>
207                where
208                __T: Table,
209                $($ST: Column<Table = __T>,)*
210                ($($ST,)*): CopyTarget,
211                $($TT: ToSql<$T, Pg>,)*
212            {
213                type Target = ($($ST,)*);
214
215                const COLUMN_COUNT: u16 = $Tuple;
216
217                fn write_to_buffer(&self, idx: u16, out: &mut Vec<u8>) -> QueryResult<IsNull> {
218                    use crate::query_builder::ByteWrapper;
219                    use crate::serialize::Output;
220
221                    let values = &self.values;
222                    match idx {
223                        $($idx =>{
224                            let item = &values.$idx.expr.item;
225                            let is_null = ToSql::<$T, Pg>::to_sql(
226                                item,
227                                &mut Output::new( ByteWrapper(out), &mut Dummy as _)
228                            ).map_err(crate::result::Error::SerializationError)?;
229                            return Ok(is_null);
230                        })*
231                        _ => unreachable!(),
232                    }
233                }
234            }
235
236            impl<'a, __T, $($ST,)* $($T,)* $($TT,)*> CopyFromInsertableHelper for ValuesClause<
237                ($(ColumnInsertValue<$ST, &'a Bound<$T, $TT>>,)*),
238            __T>
239                where
240                __T: Table,
241                $($ST: Column<Table = __T>,)*
242                ($($ST,)*): CopyTarget,
243                $($TT: ToSql<$T, Pg>,)*
244            {
245                type Target = ($($ST,)*);
246
247                // statically known to always fit
248                // as we don't support more than 128 columns
249                const COLUMN_COUNT: u16 = $Tuple;
250
251                fn write_to_buffer(&self, idx: u16, out: &mut Vec<u8>) -> QueryResult<IsNull> {
252                    use crate::query_builder::ByteWrapper;
253                    use crate::serialize::Output;
254
255                    let values = &self.values;
256                    match idx {
257                        $($idx =>{
258                            let item = &values.$idx.expr.item;
259                            let is_null = ToSql::<$T, Pg>::to_sql(
260                                item,
261                                &mut Output::new( ByteWrapper(out), &mut Dummy as _)
262                            ).map_err(crate::result::Error::SerializationError)?;
263                            return Ok(is_null);
264                        })*
265                        _ => unreachable!(),
266                    }
267                }
268            }
269        )*
270    }
271}
272
273impl<__T, 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, 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, TT, TT1, TT2, TT3, TT4, TT5,
    TT6, TT7, TT8, TT9, TT10, TT11, TT12, TT13, TT14, TT15, TT16, TT17, TT18,
    TT19, TT20, TT21, TT22, TT23, TT24, TT25, TT26, TT27, TT28, TT29, TT30,
    TT31> CopyFromInsertableHelper for
    ValuesClause<(ColumnInsertValue<ST, Bound<T, TT>>,
    ColumnInsertValue<ST1, Bound<T1, TT1>>,
    ColumnInsertValue<ST2, Bound<T2, TT2>>,
    ColumnInsertValue<ST3, Bound<T3, TT3>>,
    ColumnInsertValue<ST4, Bound<T4, TT4>>,
    ColumnInsertValue<ST5, Bound<T5, TT5>>,
    ColumnInsertValue<ST6, Bound<T6, TT6>>,
    ColumnInsertValue<ST7, Bound<T7, TT7>>,
    ColumnInsertValue<ST8, Bound<T8, TT8>>,
    ColumnInsertValue<ST9, Bound<T9, TT9>>,
    ColumnInsertValue<ST10, Bound<T10, TT10>>,
    ColumnInsertValue<ST11, Bound<T11, TT11>>,
    ColumnInsertValue<ST12, Bound<T12, TT12>>,
    ColumnInsertValue<ST13, Bound<T13, TT13>>,
    ColumnInsertValue<ST14, Bound<T14, TT14>>,
    ColumnInsertValue<ST15, Bound<T15, TT15>>,
    ColumnInsertValue<ST16, Bound<T16, TT16>>,
    ColumnInsertValue<ST17, Bound<T17, TT17>>,
    ColumnInsertValue<ST18, Bound<T18, TT18>>,
    ColumnInsertValue<ST19, Bound<T19, TT19>>,
    ColumnInsertValue<ST20, Bound<T20, TT20>>,
    ColumnInsertValue<ST21, Bound<T21, TT21>>,
    ColumnInsertValue<ST22, Bound<T22, TT22>>,
    ColumnInsertValue<ST23, Bound<T23, TT23>>,
    ColumnInsertValue<ST24, Bound<T24, TT24>>,
    ColumnInsertValue<ST25, Bound<T25, TT25>>,
    ColumnInsertValue<ST26, Bound<T26, TT26>>,
    ColumnInsertValue<ST27, Bound<T27, TT27>>,
    ColumnInsertValue<ST28, Bound<T28, TT28>>,
    ColumnInsertValue<ST29, Bound<T29, TT29>>,
    ColumnInsertValue<ST30, Bound<T30, TT30>>,
    ColumnInsertValue<ST31, Bound<T31, TT31>>), __T> where __T: Table,
    ST: Column<Table = __T>, ST1: Column<Table = __T>,
    ST2: Column<Table = __T>, ST3: Column<Table = __T>,
    ST4: Column<Table = __T>, ST5: Column<Table = __T>,
    ST6: Column<Table = __T>, ST7: Column<Table = __T>,
    ST8: Column<Table = __T>, ST9: Column<Table = __T>,
    ST10: Column<Table = __T>, ST11: Column<Table = __T>,
    ST12: Column<Table = __T>, ST13: Column<Table = __T>,
    ST14: Column<Table = __T>, ST15: Column<Table = __T>,
    ST16: Column<Table = __T>, ST17: Column<Table = __T>,
    ST18: Column<Table = __T>, ST19: Column<Table = __T>,
    ST20: Column<Table = __T>, ST21: Column<Table = __T>,
    ST22: Column<Table = __T>, ST23: Column<Table = __T>,
    ST24: Column<Table = __T>, ST25: Column<Table = __T>,
    ST26: Column<Table = __T>, ST27: Column<Table = __T>,
    ST28: Column<Table = __T>, ST29: Column<Table = __T>,
    ST30: Column<Table = __T>, ST31: Column<Table = __T>,
    (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): CopyTarget, TT: ToSql<T, Pg>,
    TT1: ToSql<T1, Pg>, TT2: ToSql<T2, Pg>, TT3: ToSql<T3, Pg>,
    TT4: ToSql<T4, Pg>, TT5: ToSql<T5, Pg>, TT6: ToSql<T6, Pg>,
    TT7: ToSql<T7, Pg>, TT8: ToSql<T8, Pg>, TT9: ToSql<T9, Pg>,
    TT10: ToSql<T10, Pg>, TT11: ToSql<T11, Pg>, TT12: ToSql<T12, Pg>,
    TT13: ToSql<T13, Pg>, TT14: ToSql<T14, Pg>, TT15: ToSql<T15, Pg>,
    TT16: ToSql<T16, Pg>, TT17: ToSql<T17, Pg>, TT18: ToSql<T18, Pg>,
    TT19: ToSql<T19, Pg>, TT20: ToSql<T20, Pg>, TT21: ToSql<T21, Pg>,
    TT22: ToSql<T22, Pg>, TT23: ToSql<T23, Pg>, TT24: ToSql<T24, Pg>,
    TT25: ToSql<T25, Pg>, TT26: ToSql<T26, Pg>, TT27: ToSql<T27, Pg>,
    TT28: ToSql<T28, Pg>, TT29: ToSql<T29, Pg>, TT30: ToSql<T30, Pg>,
    TT31: ToSql<T31, Pg> {
    type Target =
        (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);
    const COLUMN_COUNT: u16 = 32u16;
    fn write_to_buffer(&self, idx: u16, out: &mut Vec<u8>)
        -> QueryResult<IsNull> {
        use crate::query_builder::ByteWrapper;
        use crate::serialize::Output;
        let values = &self.values;
        match idx {
            0 => {
                let item = &values.0.expr.item;
                let is_null =
                    ToSql::<T,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            1 => {
                let item = &values.1.expr.item;
                let is_null =
                    ToSql::<T1,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            2 => {
                let item = &values.2.expr.item;
                let is_null =
                    ToSql::<T2,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            3 => {
                let item = &values.3.expr.item;
                let is_null =
                    ToSql::<T3,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            4 => {
                let item = &values.4.expr.item;
                let is_null =
                    ToSql::<T4,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            5 => {
                let item = &values.5.expr.item;
                let is_null =
                    ToSql::<T5,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            6 => {
                let item = &values.6.expr.item;
                let is_null =
                    ToSql::<T6,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            7 => {
                let item = &values.7.expr.item;
                let is_null =
                    ToSql::<T7,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            8 => {
                let item = &values.8.expr.item;
                let is_null =
                    ToSql::<T8,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            9 => {
                let item = &values.9.expr.item;
                let is_null =
                    ToSql::<T9,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            10 => {
                let item = &values.10.expr.item;
                let is_null =
                    ToSql::<T10,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            11 => {
                let item = &values.11.expr.item;
                let is_null =
                    ToSql::<T11,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            12 => {
                let item = &values.12.expr.item;
                let is_null =
                    ToSql::<T12,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            13 => {
                let item = &values.13.expr.item;
                let is_null =
                    ToSql::<T13,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            14 => {
                let item = &values.14.expr.item;
                let is_null =
                    ToSql::<T14,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            15 => {
                let item = &values.15.expr.item;
                let is_null =
                    ToSql::<T15,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            16 => {
                let item = &values.16.expr.item;
                let is_null =
                    ToSql::<T16,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            17 => {
                let item = &values.17.expr.item;
                let is_null =
                    ToSql::<T17,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            18 => {
                let item = &values.18.expr.item;
                let is_null =
                    ToSql::<T18,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            19 => {
                let item = &values.19.expr.item;
                let is_null =
                    ToSql::<T19,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            20 => {
                let item = &values.20.expr.item;
                let is_null =
                    ToSql::<T20,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            21 => {
                let item = &values.21.expr.item;
                let is_null =
                    ToSql::<T21,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            22 => {
                let item = &values.22.expr.item;
                let is_null =
                    ToSql::<T22,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            23 => {
                let item = &values.23.expr.item;
                let is_null =
                    ToSql::<T23,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            24 => {
                let item = &values.24.expr.item;
                let is_null =
                    ToSql::<T24,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            25 => {
                let item = &values.25.expr.item;
                let is_null =
                    ToSql::<T25,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            26 => {
                let item = &values.26.expr.item;
                let is_null =
                    ToSql::<T26,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            27 => {
                let item = &values.27.expr.item;
                let is_null =
                    ToSql::<T27,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            28 => {
                let item = &values.28.expr.item;
                let is_null =
                    ToSql::<T28,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            29 => {
                let item = &values.29.expr.item;
                let is_null =
                    ToSql::<T29,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            30 => {
                let item = &values.30.expr.item;
                let is_null =
                    ToSql::<T30,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            31 => {
                let item = &values.31.expr.item;
                let is_null =
                    ToSql::<T31,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            _ =>
                ::core::panicking::panic("internal error: entered unreachable code"),
        }
    }
}
impl<'a, __T, 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, 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, TT, TT1, TT2, TT3, TT4,
    TT5, TT6, TT7, TT8, TT9, TT10, TT11, TT12, TT13, TT14, TT15, TT16, TT17,
    TT18, TT19, TT20, TT21, TT22, TT23, TT24, TT25, TT26, TT27, TT28, TT29,
    TT30, TT31> CopyFromInsertableHelper for
    ValuesClause<(ColumnInsertValue<ST, &'a Bound<T, TT>>,
    ColumnInsertValue<ST1, &'a Bound<T1, TT1>>,
    ColumnInsertValue<ST2, &'a Bound<T2, TT2>>,
    ColumnInsertValue<ST3, &'a Bound<T3, TT3>>,
    ColumnInsertValue<ST4, &'a Bound<T4, TT4>>,
    ColumnInsertValue<ST5, &'a Bound<T5, TT5>>,
    ColumnInsertValue<ST6, &'a Bound<T6, TT6>>,
    ColumnInsertValue<ST7, &'a Bound<T7, TT7>>,
    ColumnInsertValue<ST8, &'a Bound<T8, TT8>>,
    ColumnInsertValue<ST9, &'a Bound<T9, TT9>>,
    ColumnInsertValue<ST10, &'a Bound<T10, TT10>>,
    ColumnInsertValue<ST11, &'a Bound<T11, TT11>>,
    ColumnInsertValue<ST12, &'a Bound<T12, TT12>>,
    ColumnInsertValue<ST13, &'a Bound<T13, TT13>>,
    ColumnInsertValue<ST14, &'a Bound<T14, TT14>>,
    ColumnInsertValue<ST15, &'a Bound<T15, TT15>>,
    ColumnInsertValue<ST16, &'a Bound<T16, TT16>>,
    ColumnInsertValue<ST17, &'a Bound<T17, TT17>>,
    ColumnInsertValue<ST18, &'a Bound<T18, TT18>>,
    ColumnInsertValue<ST19, &'a Bound<T19, TT19>>,
    ColumnInsertValue<ST20, &'a Bound<T20, TT20>>,
    ColumnInsertValue<ST21, &'a Bound<T21, TT21>>,
    ColumnInsertValue<ST22, &'a Bound<T22, TT22>>,
    ColumnInsertValue<ST23, &'a Bound<T23, TT23>>,
    ColumnInsertValue<ST24, &'a Bound<T24, TT24>>,
    ColumnInsertValue<ST25, &'a Bound<T25, TT25>>,
    ColumnInsertValue<ST26, &'a Bound<T26, TT26>>,
    ColumnInsertValue<ST27, &'a Bound<T27, TT27>>,
    ColumnInsertValue<ST28, &'a Bound<T28, TT28>>,
    ColumnInsertValue<ST29, &'a Bound<T29, TT29>>,
    ColumnInsertValue<ST30, &'a Bound<T30, TT30>>,
    ColumnInsertValue<ST31, &'a Bound<T31, TT31>>), __T> where __T: Table,
    ST: Column<Table = __T>, ST1: Column<Table = __T>,
    ST2: Column<Table = __T>, ST3: Column<Table = __T>,
    ST4: Column<Table = __T>, ST5: Column<Table = __T>,
    ST6: Column<Table = __T>, ST7: Column<Table = __T>,
    ST8: Column<Table = __T>, ST9: Column<Table = __T>,
    ST10: Column<Table = __T>, ST11: Column<Table = __T>,
    ST12: Column<Table = __T>, ST13: Column<Table = __T>,
    ST14: Column<Table = __T>, ST15: Column<Table = __T>,
    ST16: Column<Table = __T>, ST17: Column<Table = __T>,
    ST18: Column<Table = __T>, ST19: Column<Table = __T>,
    ST20: Column<Table = __T>, ST21: Column<Table = __T>,
    ST22: Column<Table = __T>, ST23: Column<Table = __T>,
    ST24: Column<Table = __T>, ST25: Column<Table = __T>,
    ST26: Column<Table = __T>, ST27: Column<Table = __T>,
    ST28: Column<Table = __T>, ST29: Column<Table = __T>,
    ST30: Column<Table = __T>, ST31: Column<Table = __T>,
    (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): CopyTarget, TT: ToSql<T, Pg>,
    TT1: ToSql<T1, Pg>, TT2: ToSql<T2, Pg>, TT3: ToSql<T3, Pg>,
    TT4: ToSql<T4, Pg>, TT5: ToSql<T5, Pg>, TT6: ToSql<T6, Pg>,
    TT7: ToSql<T7, Pg>, TT8: ToSql<T8, Pg>, TT9: ToSql<T9, Pg>,
    TT10: ToSql<T10, Pg>, TT11: ToSql<T11, Pg>, TT12: ToSql<T12, Pg>,
    TT13: ToSql<T13, Pg>, TT14: ToSql<T14, Pg>, TT15: ToSql<T15, Pg>,
    TT16: ToSql<T16, Pg>, TT17: ToSql<T17, Pg>, TT18: ToSql<T18, Pg>,
    TT19: ToSql<T19, Pg>, TT20: ToSql<T20, Pg>, TT21: ToSql<T21, Pg>,
    TT22: ToSql<T22, Pg>, TT23: ToSql<T23, Pg>, TT24: ToSql<T24, Pg>,
    TT25: ToSql<T25, Pg>, TT26: ToSql<T26, Pg>, TT27: ToSql<T27, Pg>,
    TT28: ToSql<T28, Pg>, TT29: ToSql<T29, Pg>, TT30: ToSql<T30, Pg>,
    TT31: ToSql<T31, Pg> {
    type Target =
        (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);
    const COLUMN_COUNT: u16 = 32u16;
    fn write_to_buffer(&self, idx: u16, out: &mut Vec<u8>)
        -> QueryResult<IsNull> {
        use crate::query_builder::ByteWrapper;
        use crate::serialize::Output;
        let values = &self.values;
        match idx {
            0 => {
                let item = &values.0.expr.item;
                let is_null =
                    ToSql::<T,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            1 => {
                let item = &values.1.expr.item;
                let is_null =
                    ToSql::<T1,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            2 => {
                let item = &values.2.expr.item;
                let is_null =
                    ToSql::<T2,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            3 => {
                let item = &values.3.expr.item;
                let is_null =
                    ToSql::<T3,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            4 => {
                let item = &values.4.expr.item;
                let is_null =
                    ToSql::<T4,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            5 => {
                let item = &values.5.expr.item;
                let is_null =
                    ToSql::<T5,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            6 => {
                let item = &values.6.expr.item;
                let is_null =
                    ToSql::<T6,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            7 => {
                let item = &values.7.expr.item;
                let is_null =
                    ToSql::<T7,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            8 => {
                let item = &values.8.expr.item;
                let is_null =
                    ToSql::<T8,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            9 => {
                let item = &values.9.expr.item;
                let is_null =
                    ToSql::<T9,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            10 => {
                let item = &values.10.expr.item;
                let is_null =
                    ToSql::<T10,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            11 => {
                let item = &values.11.expr.item;
                let is_null =
                    ToSql::<T11,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            12 => {
                let item = &values.12.expr.item;
                let is_null =
                    ToSql::<T12,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            13 => {
                let item = &values.13.expr.item;
                let is_null =
                    ToSql::<T13,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            14 => {
                let item = &values.14.expr.item;
                let is_null =
                    ToSql::<T14,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            15 => {
                let item = &values.15.expr.item;
                let is_null =
                    ToSql::<T15,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            16 => {
                let item = &values.16.expr.item;
                let is_null =
                    ToSql::<T16,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            17 => {
                let item = &values.17.expr.item;
                let is_null =
                    ToSql::<T17,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            18 => {
                let item = &values.18.expr.item;
                let is_null =
                    ToSql::<T18,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            19 => {
                let item = &values.19.expr.item;
                let is_null =
                    ToSql::<T19,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            20 => {
                let item = &values.20.expr.item;
                let is_null =
                    ToSql::<T20,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            21 => {
                let item = &values.21.expr.item;
                let is_null =
                    ToSql::<T21,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            22 => {
                let item = &values.22.expr.item;
                let is_null =
                    ToSql::<T22,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            23 => {
                let item = &values.23.expr.item;
                let is_null =
                    ToSql::<T23,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            24 => {
                let item = &values.24.expr.item;
                let is_null =
                    ToSql::<T24,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            25 => {
                let item = &values.25.expr.item;
                let is_null =
                    ToSql::<T25,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            26 => {
                let item = &values.26.expr.item;
                let is_null =
                    ToSql::<T26,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            27 => {
                let item = &values.27.expr.item;
                let is_null =
                    ToSql::<T27,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            28 => {
                let item = &values.28.expr.item;
                let is_null =
                    ToSql::<T28,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            29 => {
                let item = &values.29.expr.item;
                let is_null =
                    ToSql::<T29,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            30 => {
                let item = &values.30.expr.item;
                let is_null =
                    ToSql::<T30,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            31 => {
                let item = &values.31.expr.item;
                let is_null =
                    ToSql::<T31,
                                    Pg>::to_sql(item,
                                &mut Output::new(ByteWrapper(out),
                                        &mut Dummy as
                                            _)).map_err(crate::result::Error::SerializationError)?;
                return Ok(is_null);
            }
            _ =>
                ::core::panicking::panic("internal error: entered unreachable code"),
        }
    }
}crate::for_each_tuple!(impl_copy_from_insertable_helper_for_values_clause);
274
275#[derive(#[automatically_derived]
impl<I: ::core::fmt::Debug> ::core::fmt::Debug for InsertableWrapper<I> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_tuple_field1_finish(f,
            "InsertableWrapper", &&self.0)
    }
}Debug)]
276pub struct InsertableWrapper<I>(Option<I>);
277
278impl<I, T, V, QId, const STATIC_QUERY_ID: bool> CopyFromExpression<T> for InsertableWrapper<I>
279where
280    I: Insertable<T, Values = BatchInsert<Vec<V>, T, QId, STATIC_QUERY_ID>>,
281    V: CopyFromInsertableHelper,
282{
283    type Error = crate::result::Error;
284
285    fn callback(&mut self, copy: &mut impl std::io::Write) -> Result<(), Self::Error> {
286        let io_result_mapper = |e| crate::result::Error::DeserializationError(Box::new(e));
287        // see https://www.postgresql.org/docs/current/sql-copy.html for
288        // a description of the binary format
289        //
290        // We don't write oids
291
292        // write the header
293        copy.write_all(&super::COPY_MAGIC_HEADER)
294            .map_err(io_result_mapper)?;
295        copy.write_i32::<NetworkEndian>(0)
296            .map_err(io_result_mapper)?;
297        copy.write_i32::<NetworkEndian>(0)
298            .map_err(io_result_mapper)?;
299        // write the data
300        // we reuse the same buffer here again and again
301        // as we expect the data to be "similar"
302        // this skips reallocating
303        let mut buffer = Vec::<u8>::new();
304        let values = self
305            .0
306            .take()
307            .expect("We only call this callback once")
308            .values();
309        for i in values.values {
310            // column count
311            buffer
312                .write_u16::<NetworkEndian>(V::COLUMN_COUNT)
313                .map_err(io_result_mapper)?;
314            for idx in 0..V::COLUMN_COUNT {
315                // first write the null indicator as dummy value
316                buffer
317                    .write_i32::<NetworkEndian>(-1)
318                    .map_err(io_result_mapper)?;
319                let len_before = buffer.len();
320                let is_null = i.write_to_buffer(idx, &mut buffer)?;
321                if is_null == IsNull::No {
322                    // fill in the length afterwards
323                    let len_after = buffer.len();
324                    let diff = (len_after - len_before)
325                        .try_into()
326                        .map_err(|e| crate::result::Error::SerializationError(Box::new(e)))?;
327                    let bytes = i32::to_be_bytes(diff);
328                    for (b, t) in bytes.into_iter().zip(&mut buffer[len_before - 4..]) {
329                        *t = b;
330                    }
331                }
332            }
333            copy.write_all(&buffer).map_err(io_result_mapper)?;
334            buffer.clear();
335        }
336        // write the trailer
337        copy.write_i16::<NetworkEndian>(-1)
338            .map_err(io_result_mapper)?;
339        Ok(())
340    }
341
342    fn options(&self) -> &CopyFromOptions {
343        &CopyFromOptions {
344            common: CommonOptions {
345                format: Some(CopyFormat::Binary),
346                freeze: None,
347                delimiter: None,
348                null: None,
349                quote: None,
350                escape: None,
351            },
352            default: None,
353            header: None,
354        }
355    }
356
357    fn walk_target<'b>(
358        &'b self,
359        pass: crate::query_builder::AstPass<'_, 'b, Pg>,
360    ) -> crate::QueryResult<()> {
361        <V as CopyFromInsertableHelper>::Target::walk_target(pass)
362    }
363}
364
365/// The structure returned by [`copy_from`]
366///
367/// The [`from_raw_data`] and the [`from_insertable`] methods allow
368/// to configure the data copied into the database
369///
370/// The `with_*` methods allow to configure the settings used for the
371/// copy statement.
372///
373/// [`from_raw_data`]: CopyFromQuery::from_raw_data
374/// [`from_insertable`]: CopyFromQuery::from_insertable
375#[derive(#[automatically_derived]
impl<T: ::core::fmt::Debug, Action: ::core::fmt::Debug> ::core::fmt::Debug for
    CopyFromQuery<T, Action> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f, "CopyFromQuery",
            "table", &self.table, "action", &&self.action)
    }
}Debug)]
376#[must_use = "`COPY FROM` statements are only executed when calling `.execute()`."]
377#[cfg(feature = "postgres_backend")]
378pub struct CopyFromQuery<T, Action> {
379    table: T,
380    action: Action,
381}
382
383impl<T> CopyFromQuery<T, NotSet>
384where
385    T: Table,
386{
387    /// Copy data into the database by directly providing the data in the corresponding format
388    ///
389    /// `target` specifies the column selection that is the target of the `COPY FROM` statement
390    /// `action` expects a callback which accepts a [`std::io::Write`] argument. The necessary format
391    /// accepted by this writer sink depends on the options provided via the `with_*` methods
392    #[allow(clippy::wrong_self_convention)] // the sql struct is named that way
393    pub fn from_raw_data<F, C, E>(self, _target: C, action: F) -> CopyFromQuery<T, CopyFrom<C, F>>
394    where
395        C: CopyTarget<Table = T>,
396        F: Fn(&mut dyn std::io::Write) -> Result<(), E>,
397    {
398        CopyFromQuery {
399            table: self.table,
400            action: CopyFrom {
401                p: PhantomData,
402                options: Default::default(),
403                copy_callback: action,
404            },
405        }
406    }
407
408    /// Copy a set of insertable values into the database.
409    ///
410    /// The `insertable` argument is expected to be a `Vec<I>`, `&[I]` or similar, where `I`
411    /// needs to implement `Insertable<T>`. If you use the [`#[derive(Insertable)]`](derive@crate::prelude::Insertable)
412    /// derive macro make sure to also set the `#[diesel(treat_none_as_default_value = false)]` option
413    /// to disable the default value handling otherwise implemented by `#[derive(Insertable)]`.
414    ///
415    /// This uses the binary format. It internally configures the correct
416    /// set of settings and does not allow to set other options
417    #[allow(clippy::wrong_self_convention)] // the sql struct is named that way
418    pub fn from_insertable<I>(self, insertable: I) -> CopyFromQuery<T, InsertableWrapper<I>>
419    where
420        InsertableWrapper<I>: CopyFromExpression<T>,
421    {
422        CopyFromQuery {
423            table: self.table,
424            action: InsertableWrapper(Some(insertable)),
425        }
426    }
427}
428
429impl<T, C, F> CopyFromQuery<T, CopyFrom<C, F>> {
430    /// The format used for the copy statement
431    ///
432    /// See the [PostgreSQL documentation](https://www.postgresql.org/docs/current/sql-copy.html)
433    /// for more details.
434    pub fn with_format(mut self, format: CopyFormat) -> Self {
435        self.action.options.common.format = Some(format);
436        self
437    }
438
439    /// Whether or not the `freeze` option is set
440    ///
441    /// See the [PostgreSQL documentation](https://www.postgresql.org/docs/current/sql-copy.html)
442    /// for more details.
443    pub fn with_freeze(mut self, freeze: bool) -> Self {
444        self.action.options.common.freeze = Some(freeze);
445        self
446    }
447
448    /// Which delimiter should be used for textual input formats
449    ///
450    /// See the [PostgreSQL documentation](https://www.postgresql.org/docs/current/sql-copy.html)
451    /// for more details.
452    ///
453    /// Diesel will automatically escape the provided delimiter for the default
454    /// PostgreSQL setting `standard_conforming_strings=on`. If you use a non-standard
455    /// conforming setting you need to take care of escaping the value on your own
456    pub fn with_delimiter(mut self, delimiter: char) -> Self {
457        self.action.options.common.delimiter = Some(delimiter);
458        self
459    }
460
461    /// Which string should be used in place of a `NULL` value
462    /// for textual input formats
463    ///
464    /// See the [PostgreSQL documentation](https://www.postgresql.org/docs/current/sql-copy.html)
465    /// for more details.
466    ///
467    /// Diesel will automatically escape the provided delimiter for the default
468    /// PostgreSQL setting `standard_conforming_strings=on`. If you use a non-standard
469    /// conforming setting you need to take care of escaping the value on your own
470    pub fn with_null(mut self, null: impl Into<String>) -> Self {
471        self.action.options.common.null = Some(null.into());
472        self
473    }
474
475    /// Which quote character should be used for textual input formats
476    ///
477    /// See the [PostgreSQL documentation](https://www.postgresql.org/docs/current/sql-copy.html)
478    /// for more details.
479    ///
480    /// Diesel will automatically escape the provided delimiter for the default
481    /// PostgreSQL setting `standard_conforming_strings=on`. If you use a non-standard
482    /// conforming setting you need to take care of escaping the value on your own
483    pub fn with_quote(mut self, quote: char) -> Self {
484        self.action.options.common.quote = Some(quote);
485        self
486    }
487
488    /// Which escape character should be used for textual input formats
489    ///
490    /// See the [PostgreSQL documentation](https://www.postgresql.org/docs/current/sql-copy.html)
491    /// for more details.
492    ///
493    /// Diesel will automatically escape the provided delimiter for the default
494    /// PostgreSQL setting `standard_conforming_strings=on`. If you use a non-standard
495    /// conforming setting you need to take care of escaping the value on your own
496    pub fn with_escape(mut self, escape: char) -> Self {
497        self.action.options.common.escape = Some(escape);
498        self
499    }
500
501    /// Which string should be used to indicate that
502    /// the `default` value should be used in place of that string
503    /// for textual formats
504    ///
505    /// See the [PostgreSQL documentation](https://www.postgresql.org/docs/current/sql-copy.html)
506    /// for more details.
507    ///
508    /// (This parameter was added with PostgreSQL 16)
509    ///
510    /// Diesel will automatically escape the provided delimiter for the default
511    /// PostgreSQL setting `standard_conforming_strings=on`. If you use a non-standard
512    /// conforming setting you need to take care of escaping the value on your own
513    pub fn with_default(mut self, default: impl Into<String>) -> Self {
514        self.action.options.default = Some(default.into());
515        self
516    }
517
518    /// Is a header provided as part of the textual input or not
519    ///
520    /// See the [PostgreSQL documentation](https://www.postgresql.org/docs/current/sql-copy.html)
521    /// for more details.
522    pub fn with_header(mut self, header: CopyHeader) -> Self {
523        self.action.options.header = Some(header);
524        self
525    }
526}
527
528/// A custom execute function tailored for `COPY FROM` statements
529///
530/// This trait can be used to execute `COPY FROM` queries constructed
531/// via [`copy_from]`
532pub trait ExecuteCopyFromDsl<C>
533where
534    C: Connection<Backend = Pg>,
535{
536    /// The error type returned by the execute function
537    type Error: core::error::Error;
538
539    /// See the trait documentation for details
540    fn execute(self, conn: &mut C) -> Result<usize, Self::Error>;
541}
542
543#[cfg(feature = "postgres")]
544impl<T, A> ExecuteCopyFromDsl<crate::PgConnection> for CopyFromQuery<T, A>
545where
546    A: CopyFromExpression<T>,
547{
548    type Error = A::Error;
549
550    fn execute(self, conn: &mut crate::PgConnection) -> Result<usize, A::Error> {
551        conn.copy_from::<A, T>(self.action)
552    }
553}
554
555#[cfg(feature = "r2d2")]
556impl<T, A, C> ExecuteCopyFromDsl<crate::r2d2::PooledConnection<crate::r2d2::ConnectionManager<C>>>
557    for CopyFromQuery<T, A>
558where
559    A: CopyFromExpression<T>,
560    C: crate::r2d2::R2D2Connection<Backend = Pg> + 'static,
561    Self: ExecuteCopyFromDsl<C>,
562{
563    type Error = <Self as ExecuteCopyFromDsl<C>>::Error;
564
565    fn execute(
566        self,
567        conn: &mut crate::r2d2::PooledConnection<crate::r2d2::ConnectionManager<C>>,
568    ) -> Result<usize, Self::Error> {
569        self.execute(&mut **conn)
570    }
571}
572
573#[derive(#[automatically_derived]
impl ::core::fmt::Debug for NotSet {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f, "NotSet")
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for NotSet {
    #[inline]
    fn clone(&self) -> NotSet { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for NotSet { }Copy)]
574pub struct NotSet;
575
576/// Creates a `COPY FROM` statement
577///
578/// This function constructs `COPY FROM` statement which copies data
579/// *from* a source into the database. It's designed to move larger
580/// amounts of data into the database.
581///
582/// This function accepts a target table as argument.
583///
584/// There are two ways to construct a `COPY FROM` statement with
585/// diesel:
586///
587/// * By providing a `Vec<I>` where `I` implements `Insertable` for the
588///   given table
589/// * By providing a target selection (column list or table name)
590///   and a callback that provides the data
591///
592/// The first variant uses the `BINARY` format internally to send
593/// the provided data efficiently to the database. It automatically
594/// sets the right options and does not allow changing them.
595/// Use [`CopyFromQuery::from_insertable`] for this.
596///
597/// The second variant allows you to control the behaviour
598/// of the generated `COPY FROM` statement in detail. It can
599/// be setup via the [`CopyFromQuery::from_raw_data`] function.
600/// The callback accepts an opaque object as argument that allows
601/// to write the corresponding data to the database. The exact
602/// format depends on the settings chosen by the various
603/// `CopyFromQuery::with_*` methods. See
604/// [the postgresql documentation](https://www.postgresql.org/docs/current/sql-copy.html)
605/// for more details about the expected formats.
606///
607/// If you don't have any specific needs you should prefer
608/// using the more convenient first variant.
609///
610/// This functionality is postgresql specific.
611///
612/// # Examples
613///
614/// ## Via [`CopyFromQuery::from_insertable`]
615///
616/// ```rust
617/// # include!("../../../doctest_setup.rs");
618/// # use crate::schema::users;
619///
620/// #[derive(Insertable)]
621/// #[diesel(table_name = users)]
622/// #[diesel(treat_none_as_default_value = false)]
623/// struct NewUser {
624///     name: &'static str,
625/// }
626///
627/// # fn run_test() -> QueryResult<()> {
628/// # let connection = &mut establish_connection();
629///
630/// let data = vec![
631///     NewUser {
632///         name: "Diva Plavalaguna",
633///     },
634///     NewUser {
635///         name: "Father Vito Cornelius",
636///     },
637/// ];
638///
639/// let count = diesel::copy_from(users::table)
640///     .from_insertable(&data)
641///     .execute(connection)?;
642///
643/// assert_eq!(count, 2);
644/// # Ok(())
645/// # }
646/// # fn main() {
647/// #    run_test().unwrap();
648/// # }
649/// ```
650///
651/// ## Via [`CopyFromQuery::from_raw_data`]
652///
653/// ```rust
654/// # include!("../../../doctest_setup.rs");
655/// # fn run_test() -> QueryResult<()> {
656/// # use crate::schema::users;
657/// use diesel::pg::CopyFormat;
658/// # let connection = &mut establish_connection();
659/// let count = diesel::copy_from(users::table)
660///     .from_raw_data(users::table, |copy| {
661///         writeln!(copy, "3,Diva Plavalaguna").unwrap();
662///         writeln!(copy, "4,Father Vito Cornelius").unwrap();
663///         diesel::QueryResult::Ok(())
664///     })
665///     .with_format(CopyFormat::Csv)
666///     .execute(connection)?;
667///
668/// assert_eq!(count, 2);
669/// # Ok(())
670/// # }
671/// # fn main() {
672/// #    run_test().unwrap();
673/// # }
674/// ```
675#[cfg(feature = "postgres_backend")]
676pub fn copy_from<T>(table: T) -> CopyFromQuery<T, NotSet>
677where
678    T: Table,
679{
680    CopyFromQuery {
681        table,
682        action: NotSet,
683    }
684}