Skip to main content

connectorx/sources/postgres/
mod.rs

1//! Source implementation for Postgres database, including the TLS support (client only).
2
3mod connection;
4mod errors;
5mod typesystem;
6
7pub use self::errors::PostgresSourceError;
8pub use cidr_02::IpInet;
9pub use connection::rewrite_tls_args;
10pub use pgvector::{Bit, HalfVector, SparseVector, Vector};
11pub use typesystem::{PostgresTypePairs, PostgresTypeSystem};
12
13use crate::constants::DB_BUFFER_SIZE;
14use crate::{
15    data_order::DataOrder,
16    errors::ConnectorXError,
17    sources::{PartitionParser, Produce, Source, SourcePartition},
18    sql::{count_query, CXQuery},
19};
20use anyhow::anyhow;
21use chrono::{DateTime, FixedOffset, NaiveDate, NaiveDateTime, NaiveTime, Utc};
22use csv::{ReaderBuilder, StringRecord, StringRecordsIntoIter};
23use fehler::{throw, throws};
24use hex::decode;
25use postgres::{
26    binary_copy::{BinaryCopyOutIter, BinaryCopyOutRow},
27    fallible_iterator::FallibleIterator,
28    tls::{MakeTlsConnect, TlsConnect},
29    Config, CopyOutReader, Row, RowIter, SimpleQueryMessage, Socket,
30};
31use r2d2::{Pool, PooledConnection};
32use r2d2_postgres::PostgresConnectionManager;
33use rust_decimal::Decimal;
34use serde_json::{from_str, Value};
35use sqlparser::dialect::PostgreSqlDialect;
36use std::collections::HashMap;
37use std::convert::TryFrom;
38use std::marker::PhantomData;
39use uuid::Uuid;
40
41/// Protocol - Binary based bulk load
42pub enum BinaryProtocol {}
43
44/// Protocol - CSV based bulk load
45pub enum CSVProtocol {}
46
47/// Protocol - use Cursor
48pub enum CursorProtocol {}
49
50/// Protocol - use Simple Query
51pub enum SimpleProtocol {}
52
53type PgManager<C> = PostgresConnectionManager<C>;
54type PgConn<C> = PooledConnection<PgManager<C>>;
55
56macro_rules! impl_produce_unimplemented {
57    ($(($protocol: ty, $t: ty, $msg: expr),)+) => {
58        $(
59            impl<'r> Produce<'r, $t> for $protocol {
60                type Error = PostgresSourceError;
61
62                #[throws(PostgresSourceError)]
63                fn produce(&'r mut self) -> $t {
64                   unimplemented!($msg);
65                }
66            }
67
68            impl<'r> Produce<'r, Option<$t>> for $protocol {
69                type Error = PostgresSourceError;
70
71                #[throws(PostgresSourceError)]
72                fn produce(&'r mut self) -> Option<$t> {
73                   unimplemented!($msg);
74                }
75            }
76        )+
77    };
78}
79
80impl_produce_unimplemented!(
81    (PostgresCSVSourceParser<'_>, HashMap<String, Option<String>>, "Please use `cursor` protocol for hstore type"),
82    (PostgresCSVSourceParser<'_>, Vector, "Please use `binary` protocol for vector type"),
83    (PostgresCSVSourceParser<'_>, HalfVector, "Please use `binary` protocol for halfvector type"),
84    (PostgresCSVSourceParser<'_>, Bit, "Please use `binary` protocol for bit type"),
85    (PostgresCSVSourceParser<'_>, SparseVector, "Please use `binary` protocol for sparsevector type"),
86
87
88    (PostgresSimpleSourceParser,HashMap<String, Option<String>>, "unimplemented"),
89    (PostgresSimpleSourceParser,Value, "unimplemented"),
90    (PostgresSimpleSourceParser, Vector, "Please use `binary` protocol for vector type"),
91    (PostgresSimpleSourceParser, HalfVector, "Please use `binary` protocol for halfvector type"),
92    (PostgresSimpleSourceParser, Bit, "Please use `binary` protocol for bit type"),
93    (PostgresSimpleSourceParser, SparseVector, "Please use `binary` protocol for sparsevector type"),
94
95);
96
97/// If any columns are range types, wrap the query in a subquery that casts
98/// range columns to `::text`. For example:
99///   SELECT * FROM orders WHERE id < 2
100/// becomes:
101///   SELECT "id", "period"::text, "name" FROM (SELECT * FROM orders WHERE id < 2) AS _cx_sub
102///
103/// This forces PG to serialize ranges as text, which makes binary and cursor
104/// protocols work without needing range-specific FromSql impls.
105/// For CSV and simple protocols the rewrite is harmless (text cast on text is a no-op).
106fn maybe_rewrite_range_query(
107    query: &CXQuery<String>,
108    names: &[String],
109    schema: &[PostgresTypeSystem],
110) -> CXQuery<String> {
111    let range_mask: Vec<bool> = schema
112        .iter()
113        .map(|ts| matches!(ts, PostgresTypeSystem::Range(_)))
114        .collect();
115
116    if !range_mask.iter().any(|&r| r) {
117        return query.clone();
118    }
119
120    let cols: String = names
121        .iter()
122        .zip(range_mask.iter())
123        .map(|(name, is_range)| {
124            let quoted = quote_ident(name);
125            if *is_range {
126                format!("{}::text", quoted)
127            } else {
128                quoted
129            }
130        })
131        .collect::<Vec<_>>()
132        .join(", ");
133
134    let rewritten = format!("SELECT {} FROM ({}) AS _cx_sub", cols, query.as_str());
135    CXQuery::Wrapped(rewritten)
136}
137
138fn quote_ident(ident: &str) -> String {
139    format!("\"{}\"", ident.replace('\"', "\"\""))
140}
141
142#[cfg(test)]
143mod range_rewrite_tests {
144    use super::{maybe_rewrite_range_query, quote_ident, PostgresTypeSystem};
145    use crate::sql::CXQuery;
146
147    #[test]
148    fn quote_ident_escapes_embedded_quotes() {
149        assert_eq!(quote_ident("a\"b"), "\"a\"\"b\"");
150    }
151
152    #[test]
153    fn rewrite_escapes_column_names_and_casts_only_ranges() {
154        let q = CXQuery::Naked("SELECT 1".to_string());
155        let names = vec!["plain".to_string(), "a\"b".to_string()];
156        let schema = vec![
157            PostgresTypeSystem::Int4(true),
158            PostgresTypeSystem::Range(true),
159        ];
160        let rewritten = maybe_rewrite_range_query(&q, &names, &schema);
161        assert_eq!(
162            rewritten.as_str(),
163            "SELECT \"plain\", \"a\"\"b\"::text FROM (SELECT 1) AS _cx_sub"
164        );
165    }
166}
167
168// take a row and unwrap the interior field from column 0
169fn convert_row<'b, R: TryFrom<usize> + postgres::types::FromSql<'b> + Clone>(row: &'b Row) -> R {
170    let nrows: Option<R> = row.get(0);
171    nrows.expect("Could not parse int result from count_query")
172}
173
174#[throws(PostgresSourceError)]
175fn get_total_rows<C>(conn: &mut PgConn<C>, query: &CXQuery<String>) -> usize
176where
177    C: MakeTlsConnect<Socket> + Clone + 'static + Sync + Send,
178    C::TlsConnect: Send,
179    C::Stream: Send,
180    <C::TlsConnect as TlsConnect<Socket>>::Future: Send,
181{
182    let dialect = PostgreSqlDialect {};
183
184    let row = conn.query_one(count_query(query, &dialect)?.as_str(), &[])?;
185    let col_type = PostgresTypeSystem::from(row.columns()[0].type_());
186    match col_type {
187        PostgresTypeSystem::Int2(_) => convert_row::<i16>(&row) as usize,
188        PostgresTypeSystem::Int4(_) => convert_row::<i32>(&row) as usize,
189        PostgresTypeSystem::Int8(_) => convert_row::<i64>(&row) as usize,
190        _ => throw!(anyhow!(
191            "The result of the count query was not an int, aborting."
192        )),
193    }
194}
195
196pub struct PostgresSource<P, C>
197where
198    C: MakeTlsConnect<Socket> + Clone + 'static + Sync + Send,
199    C::TlsConnect: Send,
200    C::Stream: Send,
201    <C::TlsConnect as TlsConnect<Socket>>::Future: Send,
202{
203    pool: Pool<PgManager<C>>,
204    origin_query: Option<String>,
205    queries: Vec<CXQuery<String>>,
206    names: Vec<String>,
207    schema: Vec<PostgresTypeSystem>,
208    pg_schema: Vec<postgres::types::Type>,
209    pre_execution_queries: Option<Vec<String>>,
210    _protocol: PhantomData<P>,
211}
212
213impl<P, C> PostgresSource<P, C>
214where
215    C: MakeTlsConnect<Socket> + Clone + 'static + Sync + Send,
216    C::TlsConnect: Send,
217    C::Stream: Send,
218    <C::TlsConnect as TlsConnect<Socket>>::Future: Send,
219{
220    #[throws(PostgresSourceError)]
221    pub fn new(config: Config, tls: C, nconn: usize) -> Self {
222        let manager = PostgresConnectionManager::new(config, tls);
223        let pool = Pool::builder().max_size(nconn as u32).build(manager)?;
224
225        Self {
226            pool,
227            origin_query: None,
228            queries: vec![],
229            names: vec![],
230            schema: vec![],
231            pg_schema: vec![],
232            pre_execution_queries: None,
233            _protocol: PhantomData,
234        }
235    }
236}
237
238impl<P, C> Source for PostgresSource<P, C>
239where
240    PostgresSourcePartition<P, C>:
241        SourcePartition<TypeSystem = PostgresTypeSystem, Error = PostgresSourceError>,
242    P: Send,
243    C: MakeTlsConnect<Socket> + Clone + 'static + Sync + Send,
244    C::TlsConnect: Send,
245    C::Stream: Send,
246    <C::TlsConnect as TlsConnect<Socket>>::Future: Send,
247{
248    const DATA_ORDERS: &'static [DataOrder] = &[DataOrder::RowMajor];
249    type Partition = PostgresSourcePartition<P, C>;
250    type TypeSystem = PostgresTypeSystem;
251    type Error = PostgresSourceError;
252
253    #[throws(PostgresSourceError)]
254    fn set_data_order(&mut self, data_order: DataOrder) {
255        if !matches!(data_order, DataOrder::RowMajor) {
256            throw!(ConnectorXError::UnsupportedDataOrder(data_order));
257        }
258    }
259
260    fn set_queries<Q: ToString>(&mut self, queries: &[CXQuery<Q>]) {
261        self.queries = queries.iter().map(|q| q.map(Q::to_string)).collect();
262    }
263
264    fn set_origin_query(&mut self, query: Option<String>) {
265        self.origin_query = query;
266    }
267
268    fn set_pre_execution_queries(&mut self, pre_execution_queries: Option<&[String]>) {
269        self.pre_execution_queries = pre_execution_queries.map(|s| s.to_vec());
270    }
271
272    #[throws(PostgresSourceError)]
273    fn fetch_metadata(&mut self) {
274        assert!(!self.queries.is_empty());
275
276        let mut conn = self.pool.get()?;
277        let first_query = &self.queries[0];
278
279        let stmt = conn.prepare(first_query.as_str())?;
280
281        let (names, pg_types): (Vec<String>, Vec<postgres::types::Type>) = stmt
282            .columns()
283            .iter()
284            .map(|col| (col.name().to_string(), col.type_().clone()))
285            .unzip();
286
287        self.names = names;
288        self.schema = pg_types.iter().map(PostgresTypeSystem::from).collect();
289        self.pg_schema = self
290            .schema
291            .iter()
292            .zip(pg_types.iter())
293            .map(|(t1, t2)| PostgresTypePairs(t2, t1).into())
294            .collect();
295    }
296
297    #[throws(PostgresSourceError)]
298    fn result_rows(&mut self) -> Option<usize> {
299        match &self.origin_query {
300            Some(q) => {
301                let cxq = CXQuery::Naked(q.clone());
302                let mut conn = self.pool.get()?;
303                let nrows = get_total_rows(&mut conn, &cxq)?;
304                Some(nrows)
305            }
306            None => None,
307        }
308    }
309
310    fn names(&self) -> Vec<String> {
311        self.names.clone()
312    }
313
314    fn schema(&self) -> Vec<Self::TypeSystem> {
315        self.schema.clone()
316    }
317
318    #[throws(PostgresSourceError)]
319    fn partition(self) -> Vec<Self::Partition> {
320        let mut ret = vec![];
321        for query in self.queries {
322            let mut conn = self.pool.get()?;
323            let rewritten = maybe_rewrite_range_query(&query, &self.names, &self.schema);
324
325            if let Some(pre_queries) = &self.pre_execution_queries {
326                for pre_query in pre_queries {
327                    conn.query(pre_query, &[])?;
328                }
329            }
330
331            ret.push(PostgresSourcePartition::<P, C>::new(
332                conn,
333                &rewritten,
334                &self.schema,
335                &self.pg_schema,
336            ));
337        }
338        ret
339    }
340}
341
342pub struct PostgresSourcePartition<P, C>
343where
344    C: MakeTlsConnect<Socket> + Clone + 'static + Sync + Send,
345    C::TlsConnect: Send,
346    C::Stream: Send,
347    <C::TlsConnect as TlsConnect<Socket>>::Future: Send,
348{
349    conn: PgConn<C>,
350    query: CXQuery<String>,
351    schema: Vec<PostgresTypeSystem>,
352    pg_schema: Vec<postgres::types::Type>,
353    nrows: usize,
354    ncols: usize,
355    _protocol: PhantomData<P>,
356}
357
358impl<P, C> PostgresSourcePartition<P, C>
359where
360    C: MakeTlsConnect<Socket> + Clone + 'static + Sync + Send,
361    C::TlsConnect: Send,
362    C::Stream: Send,
363    <C::TlsConnect as TlsConnect<Socket>>::Future: Send,
364{
365    pub fn new(
366        conn: PgConn<C>,
367        query: &CXQuery<String>,
368        schema: &[PostgresTypeSystem],
369        pg_schema: &[postgres::types::Type],
370    ) -> Self {
371        Self {
372            conn,
373            query: query.clone(),
374            schema: schema.to_vec(),
375            pg_schema: pg_schema.to_vec(),
376            nrows: 0,
377            ncols: schema.len(),
378            _protocol: PhantomData,
379        }
380    }
381}
382
383impl<C> SourcePartition for PostgresSourcePartition<BinaryProtocol, C>
384where
385    C: MakeTlsConnect<Socket> + Clone + 'static + Sync + Send,
386    C::TlsConnect: Send,
387    C::Stream: Send,
388    <C::TlsConnect as TlsConnect<Socket>>::Future: Send,
389{
390    type TypeSystem = PostgresTypeSystem;
391    type Parser<'a> = PostgresBinarySourcePartitionParser<'a>;
392    type Error = PostgresSourceError;
393
394    #[throws(PostgresSourceError)]
395    fn result_rows(&mut self) -> () {
396        self.nrows = get_total_rows(&mut self.conn, &self.query)?;
397    }
398
399    #[throws(PostgresSourceError)]
400    fn parser(&mut self) -> Self::Parser<'_> {
401        let query = format!("COPY ({}) TO STDOUT WITH BINARY", self.query);
402        let reader = self.conn.copy_out(&*query)?; // unless reading the data, it seems like issue the query is fast
403        let iter = BinaryCopyOutIter::new(reader, &self.pg_schema);
404
405        PostgresBinarySourcePartitionParser::new(iter, &self.schema)
406    }
407
408    fn nrows(&self) -> usize {
409        self.nrows
410    }
411
412    fn ncols(&self) -> usize {
413        self.ncols
414    }
415}
416
417impl<C> SourcePartition for PostgresSourcePartition<CSVProtocol, C>
418where
419    C: MakeTlsConnect<Socket> + Clone + 'static + Sync + Send,
420    C::TlsConnect: Send,
421    C::Stream: Send,
422    <C::TlsConnect as TlsConnect<Socket>>::Future: Send,
423{
424    type TypeSystem = PostgresTypeSystem;
425    type Parser<'a> = PostgresCSVSourceParser<'a>;
426    type Error = PostgresSourceError;
427
428    #[throws(PostgresSourceError)]
429    fn result_rows(&mut self) {
430        self.nrows = get_total_rows(&mut self.conn, &self.query)?;
431    }
432
433    #[throws(PostgresSourceError)]
434    fn parser(&mut self) -> Self::Parser<'_> {
435        let query = format!("COPY ({}) TO STDOUT WITH CSV", self.query);
436        let reader = self.conn.copy_out(&*query)?; // unless reading the data, it seems like issue the query is fast
437        let iter = ReaderBuilder::new()
438            .has_headers(false)
439            .from_reader(reader)
440            .into_records();
441
442        PostgresCSVSourceParser::new(iter, &self.schema)
443    }
444
445    fn nrows(&self) -> usize {
446        self.nrows
447    }
448
449    fn ncols(&self) -> usize {
450        self.ncols
451    }
452}
453
454impl<C> SourcePartition for PostgresSourcePartition<CursorProtocol, C>
455where
456    C: MakeTlsConnect<Socket> + Clone + 'static + Sync + Send,
457    C::TlsConnect: Send,
458    C::Stream: Send,
459    <C::TlsConnect as TlsConnect<Socket>>::Future: Send,
460{
461    type TypeSystem = PostgresTypeSystem;
462    type Parser<'a> = PostgresRawSourceParser<'a>;
463    type Error = PostgresSourceError;
464
465    #[throws(PostgresSourceError)]
466    fn result_rows(&mut self) {
467        self.nrows = get_total_rows(&mut self.conn, &self.query)?;
468    }
469
470    #[throws(PostgresSourceError)]
471    fn parser(&mut self) -> Self::Parser<'_> {
472        let iter = self
473            .conn
474            .query_raw::<_, bool, _>(self.query.as_str(), vec![])?; // unless reading the data, it seems like issue the query is fast
475        PostgresRawSourceParser::new(iter, &self.schema)
476    }
477
478    fn nrows(&self) -> usize {
479        self.nrows
480    }
481
482    fn ncols(&self) -> usize {
483        self.ncols
484    }
485}
486pub struct PostgresBinarySourcePartitionParser<'a> {
487    iter: BinaryCopyOutIter<'a>,
488    rowbuf: Vec<BinaryCopyOutRow>,
489    ncols: usize,
490    current_col: usize,
491    current_row: usize,
492    is_finished: bool,
493}
494
495impl<'a> PostgresBinarySourcePartitionParser<'a> {
496    pub fn new(iter: BinaryCopyOutIter<'a>, schema: &[PostgresTypeSystem]) -> Self {
497        Self {
498            iter,
499            rowbuf: Vec::with_capacity(DB_BUFFER_SIZE),
500            ncols: schema.len(),
501            current_row: 0,
502            current_col: 0,
503            is_finished: false,
504        }
505    }
506
507    #[throws(PostgresSourceError)]
508    fn next_loc(&mut self) -> (usize, usize) {
509        let ret = (self.current_row, self.current_col);
510        self.current_row += (self.current_col + 1) / self.ncols;
511        self.current_col = (self.current_col + 1) % self.ncols;
512        ret
513    }
514}
515
516impl<'a> PartitionParser<'a> for PostgresBinarySourcePartitionParser<'a> {
517    type TypeSystem = PostgresTypeSystem;
518    type Error = PostgresSourceError;
519
520    #[throws(PostgresSourceError)]
521    fn fetch_next(&mut self) -> (usize, bool) {
522        assert!(self.current_col == 0);
523        let remaining_rows = self.rowbuf.len() - self.current_row;
524        if remaining_rows > 0 {
525            return (remaining_rows, self.is_finished);
526        } else if self.is_finished {
527            return (0, self.is_finished);
528        }
529
530        // clear the buffer
531        if !self.rowbuf.is_empty() {
532            self.rowbuf.drain(..);
533        }
534        for _ in 0..DB_BUFFER_SIZE {
535            match self.iter.next()? {
536                Some(row) => {
537                    self.rowbuf.push(row);
538                }
539                None => {
540                    self.is_finished = true;
541                    break;
542                }
543            }
544        }
545
546        // reset current cursor positions
547        self.current_row = 0;
548        self.current_col = 0;
549
550        (self.rowbuf.len(), self.is_finished)
551    }
552}
553
554macro_rules! impl_produce {
555    ($($t: ty,)+) => {
556        $(
557            impl<'r, 'a> Produce<'r, $t> for PostgresBinarySourcePartitionParser<'a> {
558                type Error = PostgresSourceError;
559
560                #[throws(PostgresSourceError)]
561                fn produce(&'r mut self) -> $t {
562                    let (ridx, cidx) = self.next_loc()?;
563                    let row = &self.rowbuf[ridx];
564                    let val = row.try_get(cidx)?;
565                    val
566                }
567            }
568
569            impl<'r, 'a> Produce<'r, Option<$t>> for PostgresBinarySourcePartitionParser<'a> {
570                type Error = PostgresSourceError;
571
572                #[throws(PostgresSourceError)]
573                fn produce(&'r mut self) -> Option<$t> {
574                    let (ridx, cidx) = self.next_loc()?;
575                    let row = &self.rowbuf[ridx];
576                    let val = row.try_get(cidx)?;
577                    val
578                }
579            }
580        )+
581    };
582}
583
584impl_produce!(
585    i8,
586    i16,
587    i32,
588    i64,
589    u32,
590    f32,
591    f64,
592    Decimal,
593    bool,
594    &'r str,
595    Vec<u8>,
596    NaiveTime,
597    Uuid,
598    Value,
599    IpInet,
600    Vector,
601    HalfVector,
602    Bit,
603    SparseVector,
604    Vec<Option<bool>>,
605    Vec<Option<i16>>,
606    Vec<Option<i32>>,
607    Vec<Option<i64>>,
608    Vec<Option<Decimal>>,
609    Vec<Option<f32>>,
610    Vec<Option<f64>>,
611    Vec<Option<String>>,
612);
613
614impl<'r> Produce<'r, NaiveDateTime> for PostgresBinarySourcePartitionParser<'_> {
615    type Error = PostgresSourceError;
616
617    #[throws(PostgresSourceError)]
618    fn produce(&'r mut self) -> NaiveDateTime {
619        let (ridx, cidx) = self.next_loc()?;
620        let row = &self.rowbuf[ridx];
621        let val = row.try_get(cidx)?;
622        match val {
623            postgres::types::Timestamp::PosInfinity => NaiveDateTime::MAX,
624            postgres::types::Timestamp::NegInfinity => NaiveDateTime::MIN,
625            postgres::types::Timestamp::Value(t) => t,
626        }
627    }
628}
629
630impl<'r> Produce<'r, Option<NaiveDateTime>> for PostgresBinarySourcePartitionParser<'_> {
631    type Error = PostgresSourceError;
632
633    #[throws(PostgresSourceError)]
634    fn produce(&'r mut self) -> Option<NaiveDateTime> {
635        let (ridx, cidx) = self.next_loc()?;
636        let row = &self.rowbuf[ridx];
637        let val = row.try_get(cidx)?;
638        match val {
639            Some(postgres::types::Timestamp::PosInfinity) => Some(NaiveDateTime::MAX),
640            Some(postgres::types::Timestamp::NegInfinity) => Some(NaiveDateTime::MIN),
641            Some(postgres::types::Timestamp::Value(t)) => t,
642            None => None,
643        }
644    }
645}
646
647impl<'r> Produce<'r, DateTime<Utc>> for PostgresBinarySourcePartitionParser<'_> {
648    type Error = PostgresSourceError;
649
650    #[throws(PostgresSourceError)]
651    fn produce(&'r mut self) -> DateTime<Utc> {
652        let (ridx, cidx) = self.next_loc()?;
653        let row = &self.rowbuf[ridx];
654        let val = row.try_get(cidx)?;
655        match val {
656            postgres::types::Timestamp::PosInfinity => DateTime::<Utc>::MAX_UTC,
657            postgres::types::Timestamp::NegInfinity => DateTime::<Utc>::MIN_UTC,
658            postgres::types::Timestamp::Value(t) => t,
659        }
660    }
661}
662
663impl<'r> Produce<'r, Option<DateTime<Utc>>> for PostgresBinarySourcePartitionParser<'_> {
664    type Error = PostgresSourceError;
665
666    #[throws(PostgresSourceError)]
667    fn produce(&'r mut self) -> Option<DateTime<Utc>> {
668        let (ridx, cidx) = self.next_loc()?;
669        let row = &self.rowbuf[ridx];
670        let val = row.try_get(cidx)?;
671        match val {
672            Some(postgres::types::Timestamp::PosInfinity) => Some(DateTime::<Utc>::MAX_UTC),
673            Some(postgres::types::Timestamp::NegInfinity) => Some(DateTime::<Utc>::MIN_UTC),
674            Some(postgres::types::Timestamp::Value(t)) => t,
675            None => None,
676        }
677    }
678}
679
680impl<'r> Produce<'r, NaiveDate> for PostgresBinarySourcePartitionParser<'_> {
681    type Error = PostgresSourceError;
682
683    #[throws(PostgresSourceError)]
684    fn produce(&'r mut self) -> NaiveDate {
685        let (ridx, cidx) = self.next_loc()?;
686        let row = &self.rowbuf[ridx];
687        let val = row.try_get(cidx)?;
688        match val {
689            postgres::types::Date::PosInfinity => NaiveDate::MAX,
690            postgres::types::Date::NegInfinity => NaiveDate::MIN,
691            postgres::types::Date::Value(t) => t,
692        }
693    }
694}
695
696impl<'r> Produce<'r, Option<NaiveDate>> for PostgresBinarySourcePartitionParser<'_> {
697    type Error = PostgresSourceError;
698
699    #[throws(PostgresSourceError)]
700    fn produce(&'r mut self) -> Option<NaiveDate> {
701        let (ridx, cidx) = self.next_loc()?;
702        let row = &self.rowbuf[ridx];
703        let val = row.try_get(cidx)?;
704        match val {
705            Some(postgres::types::Date::PosInfinity) => Some(NaiveDate::MAX),
706            Some(postgres::types::Date::NegInfinity) => Some(NaiveDate::MIN),
707            Some(postgres::types::Date::Value(t)) => t,
708            None => None,
709        }
710    }
711}
712
713impl Produce<'_, HashMap<String, Option<String>>> for PostgresBinarySourcePartitionParser<'_> {
714    type Error = PostgresSourceError;
715    #[throws(PostgresSourceError)]
716    fn produce(&mut self) -> HashMap<String, Option<String>> {
717        unimplemented!("Please use `cursor` protocol for hstore type");
718    }
719}
720
721impl Produce<'_, Option<HashMap<String, Option<String>>>>
722    for PostgresBinarySourcePartitionParser<'_>
723{
724    type Error = PostgresSourceError;
725    #[throws(PostgresSourceError)]
726    fn produce(&mut self) -> Option<HashMap<String, Option<String>>> {
727        unimplemented!("Please use `cursor` protocol for hstore type");
728    }
729}
730
731pub struct PostgresCSVSourceParser<'a> {
732    iter: StringRecordsIntoIter<CopyOutReader<'a>>,
733    rowbuf: Vec<StringRecord>,
734    ncols: usize,
735    current_col: usize,
736    current_row: usize,
737    is_finished: bool,
738}
739
740impl<'a> PostgresCSVSourceParser<'a> {
741    pub fn new(
742        iter: StringRecordsIntoIter<CopyOutReader<'a>>,
743        schema: &[PostgresTypeSystem],
744    ) -> Self {
745        Self {
746            iter,
747            rowbuf: Vec::with_capacity(DB_BUFFER_SIZE),
748            ncols: schema.len(),
749            current_row: 0,
750            current_col: 0,
751            is_finished: false,
752        }
753    }
754
755    #[throws(PostgresSourceError)]
756    fn next_loc(&mut self) -> (usize, usize) {
757        let ret = (self.current_row, self.current_col);
758        self.current_row += (self.current_col + 1) / self.ncols;
759        self.current_col = (self.current_col + 1) % self.ncols;
760        ret
761    }
762}
763
764impl<'a> PartitionParser<'a> for PostgresCSVSourceParser<'a> {
765    type Error = PostgresSourceError;
766    type TypeSystem = PostgresTypeSystem;
767
768    #[throws(PostgresSourceError)]
769    fn fetch_next(&mut self) -> (usize, bool) {
770        assert!(self.current_col == 0);
771        let remaining_rows = self.rowbuf.len() - self.current_row;
772        if remaining_rows > 0 {
773            return (remaining_rows, self.is_finished);
774        } else if self.is_finished {
775            return (0, self.is_finished);
776        }
777
778        if !self.rowbuf.is_empty() {
779            self.rowbuf.drain(..);
780        }
781        for _ in 0..DB_BUFFER_SIZE {
782            if let Some(row) = self.iter.next() {
783                self.rowbuf.push(row?);
784            } else {
785                self.is_finished = true;
786                break;
787            }
788        }
789        self.current_row = 0;
790        self.current_col = 0;
791        (self.rowbuf.len(), self.is_finished)
792    }
793}
794
795macro_rules! impl_csv_produce {
796    ($($t: ty,)+) => {
797        $(
798            impl<'r, 'a> Produce<'r, $t> for PostgresCSVSourceParser<'a> {
799                type Error = PostgresSourceError;
800
801                #[throws(PostgresSourceError)]
802                fn produce(&'r mut self) -> $t {
803                    let (ridx, cidx) = self.next_loc()?;
804                    self.rowbuf[ridx][cidx].parse().map_err(|_| {
805                        ConnectorXError::cannot_produce::<$t>(Some(self.rowbuf[ridx][cidx].into()))
806                    })?
807                }
808            }
809
810            impl<'r, 'a> Produce<'r, Option<$t>> for PostgresCSVSourceParser<'a> {
811                type Error = PostgresSourceError;
812
813                #[throws(PostgresSourceError)]
814                fn produce(&'r mut self) -> Option<$t> {
815                    let (ridx, cidx) = self.next_loc()?;
816                    match &self.rowbuf[ridx][cidx][..] {
817                        "" => None,
818                        v => Some(v.parse().map_err(|_| {
819                            ConnectorXError::cannot_produce::<$t>(Some(self.rowbuf[ridx][cidx].into()))
820                        })?),
821                    }
822                }
823            }
824        )+
825    };
826}
827
828impl_csv_produce!(i8, i16, i32, i64, u32, f32, f64, Uuid, IpInet,);
829
830macro_rules! impl_csv_vec_produce {
831    ($($t: ty,)+) => {
832        $(
833            impl<'r, 'a> Produce<'r, Vec<Option<$t>>> for PostgresCSVSourceParser<'a> {
834                type Error = PostgresSourceError;
835
836                #[throws(PostgresSourceError)]
837                fn produce(&mut self) -> Vec<Option<$t>> {
838                    let (ridx, cidx) = self.next_loc()?;
839                    let s = &self.rowbuf[ridx][cidx][..];
840                    match s {
841                        "{}" => vec![],
842                        _ if s.len() < 3 => throw!(ConnectorXError::cannot_produce::<$t>(Some(s.into()))),
843                        s => s[1..s.len() - 1]
844                            .split(",")
845                            .map(|v| {
846                                if v == "NULL" {
847                                    Ok(None)
848                                } else {
849                                    match v.parse() {
850                                        Ok(v) => Ok(Some(v)),
851                                        Err(e) => Err(e).map_err(|_| ConnectorXError::cannot_produce::<$t>(Some(s.into())))
852                                    }
853                                }
854                            })
855                            .collect::<Result<Vec<Option<$t>>, ConnectorXError>>()?,
856                    }
857                }
858            }
859
860            impl<'r, 'a> Produce<'r, Option<Vec<Option<$t>>>> for PostgresCSVSourceParser<'a> {
861                type Error = PostgresSourceError;
862
863                #[throws(PostgresSourceError)]
864                fn produce(&mut self) -> Option<Vec<Option<$t>>> {
865                    let (ridx, cidx) = self.next_loc()?;
866                    let s = &self.rowbuf[ridx][cidx][..];
867                    match s {
868                        "" => None,
869                        "{}" => Some(vec![]),
870                        _ if s.len() < 3 => throw!(ConnectorXError::cannot_produce::<$t>(Some(s.into()))),
871                        s => Some(
872                            s[1..s.len() - 1]
873                                .split(",")
874                                .map(|v| {
875                                    if v == "NULL" {
876                                        Ok(None)
877                                    } else {
878                                        match v.parse() {
879                                            Ok(v) => Ok(Some(v)),
880                                            Err(e) => Err(e).map_err(|_| ConnectorXError::cannot_produce::<$t>(Some(s.into())))
881                                        }
882                                    }
883                                })
884                                .collect::<Result<Vec<Option<$t>>, ConnectorXError>>()?,
885                        ),
886                    }
887                }
888            }
889        )+
890    };
891}
892
893impl_csv_vec_produce!(i8, i16, i32, i64, f32, f64, Decimal, String,);
894
895impl Produce<'_, bool> for PostgresCSVSourceParser<'_> {
896    type Error = PostgresSourceError;
897
898    #[throws(PostgresSourceError)]
899    fn produce(&mut self) -> bool {
900        let (ridx, cidx) = self.next_loc()?;
901        let ret = match &self.rowbuf[ridx][cidx][..] {
902            "t" => true,
903            "f" => false,
904            _ => throw!(ConnectorXError::cannot_produce::<bool>(Some(
905                self.rowbuf[ridx][cidx].into()
906            ))),
907        };
908        ret
909    }
910}
911
912impl Produce<'_, Option<bool>> for PostgresCSVSourceParser<'_> {
913    type Error = PostgresSourceError;
914
915    #[throws(PostgresSourceError)]
916    fn produce(&mut self) -> Option<bool> {
917        let (ridx, cidx) = self.next_loc()?;
918        let ret = match &self.rowbuf[ridx][cidx][..] {
919            "" => None,
920            "t" => Some(true),
921            "f" => Some(false),
922            _ => throw!(ConnectorXError::cannot_produce::<bool>(Some(
923                self.rowbuf[ridx][cidx].into()
924            ))),
925        };
926        ret
927    }
928}
929
930impl Produce<'_, Vec<Option<bool>>> for PostgresCSVSourceParser<'_> {
931    type Error = PostgresSourceError;
932
933    #[throws(PostgresSourceError)]
934    fn produce(&mut self) -> Vec<Option<bool>> {
935        let (ridx, cidx) = self.next_loc()?;
936        let s = &self.rowbuf[ridx][cidx][..];
937        match s {
938            "{}" => vec![],
939            _ if s.len() < 3 => throw!(ConnectorXError::cannot_produce::<bool>(Some(s.into()))),
940            s => s[1..s.len() - 1]
941                .split(',')
942                .map(|v| match v {
943                    "NULL" => Ok(None),
944                    "t" => Ok(Some(true)),
945                    "f" => Ok(Some(false)),
946                    _ => throw!(ConnectorXError::cannot_produce::<bool>(Some(s.into()))),
947                })
948                .collect::<Result<Vec<Option<bool>>, ConnectorXError>>()?,
949        }
950    }
951}
952
953impl Produce<'_, Option<Vec<Option<bool>>>> for PostgresCSVSourceParser<'_> {
954    type Error = PostgresSourceError;
955
956    #[throws(PostgresSourceError)]
957    fn produce(&mut self) -> Option<Vec<Option<bool>>> {
958        let (ridx, cidx) = self.next_loc()?;
959        let s = &self.rowbuf[ridx][cidx][..];
960        match s {
961            "" => None,
962            "{}" => Some(vec![]),
963            _ if s.len() < 3 => throw!(ConnectorXError::cannot_produce::<bool>(Some(s.into()))),
964            s => Some(
965                s[1..s.len() - 1]
966                    .split(',')
967                    .map(|v| match v {
968                        "NULL" => Ok(None),
969                        "t" => Ok(Some(true)),
970                        "f" => Ok(Some(false)),
971                        _ => throw!(ConnectorXError::cannot_produce::<bool>(Some(s.into()))),
972                    })
973                    .collect::<Result<Vec<Option<bool>>, ConnectorXError>>()?,
974            ),
975        }
976    }
977}
978
979impl<'r> Produce<'r, Decimal> for PostgresCSVSourceParser<'_> {
980    type Error = PostgresSourceError;
981
982    #[throws(PostgresSourceError)]
983    fn produce(&'r mut self) -> Decimal {
984        let (ridx, cidx) = self.next_loc()?;
985        match &self.rowbuf[ridx][cidx][..] {
986            "Infinity" => Decimal::MAX,
987            "-Infinity" => Decimal::MIN,
988            v => v
989                .parse()
990                .map_err(|_| ConnectorXError::cannot_produce::<Decimal>(Some(v.into())))?,
991        }
992    }
993}
994
995impl<'r> Produce<'r, Option<Decimal>> for PostgresCSVSourceParser<'_> {
996    type Error = PostgresSourceError;
997
998    #[throws(PostgresSourceError)]
999    fn produce(&'r mut self) -> Option<Decimal> {
1000        let (ridx, cidx) = self.next_loc()?;
1001        match &self.rowbuf[ridx][cidx][..] {
1002            "" => None,
1003            "Infinity" => Some(Decimal::MAX),
1004            "-Infinity" => Some(Decimal::MIN),
1005            v => Some(
1006                v.parse()
1007                    .map_err(|_| ConnectorXError::cannot_produce::<Decimal>(Some(v.into())))?,
1008            ),
1009        }
1010    }
1011}
1012
1013impl Produce<'_, DateTime<Utc>> for PostgresCSVSourceParser<'_> {
1014    type Error = PostgresSourceError;
1015
1016    #[throws(PostgresSourceError)]
1017    fn produce(&mut self) -> DateTime<Utc> {
1018        let (ridx, cidx) = self.next_loc()?;
1019        match &self.rowbuf[ridx][cidx][..] {
1020            "infinity" => DateTime::<Utc>::MAX_UTC,
1021            "-infinity" => DateTime::<Utc>::MIN_UTC,
1022            // postgres csv return example: 1970-01-01 00:00:01+00
1023            v => format!("{}:00", v)
1024                .parse()
1025                .map_err(|_| ConnectorXError::cannot_produce::<DateTime<Utc>>(Some(v.into())))?,
1026        }
1027    }
1028}
1029
1030impl Produce<'_, Option<DateTime<Utc>>> for PostgresCSVSourceParser<'_> {
1031    type Error = PostgresSourceError;
1032
1033    #[throws(PostgresSourceError)]
1034    fn produce(&mut self) -> Option<DateTime<Utc>> {
1035        let (ridx, cidx) = self.next_loc()?;
1036        match &self.rowbuf[ridx][cidx][..] {
1037            "" => None,
1038            "infinity" => Some(DateTime::<Utc>::MAX_UTC),
1039            "-infinity" => Some(DateTime::<Utc>::MIN_UTC),
1040            v => {
1041                // postgres csv return example: 1970-01-01 00:00:01+00
1042                Some(format!("{}:00", v).parse().map_err(|_| {
1043                    ConnectorXError::cannot_produce::<DateTime<Utc>>(Some(v.into()))
1044                })?)
1045            }
1046        }
1047    }
1048}
1049
1050impl Produce<'_, NaiveDate> for PostgresCSVSourceParser<'_> {
1051    type Error = PostgresSourceError;
1052
1053    #[throws(PostgresSourceError)]
1054    fn produce(&mut self) -> NaiveDate {
1055        let (ridx, cidx) = self.next_loc()?;
1056        match &self.rowbuf[ridx][cidx][..] {
1057            "infinity" => NaiveDate::MAX,
1058            "-infinity" => NaiveDate::MIN,
1059            v => NaiveDate::parse_from_str(v, "%Y-%m-%d")
1060                .map_err(|_| ConnectorXError::cannot_produce::<NaiveDate>(Some(v.into())))?,
1061        }
1062    }
1063}
1064
1065impl Produce<'_, Option<NaiveDate>> for PostgresCSVSourceParser<'_> {
1066    type Error = PostgresSourceError;
1067
1068    #[throws(PostgresSourceError)]
1069    fn produce(&mut self) -> Option<NaiveDate> {
1070        let (ridx, cidx) = self.next_loc()?;
1071        match &self.rowbuf[ridx][cidx][..] {
1072            "" => None,
1073            "infinity" => Some(NaiveDate::MAX),
1074            "-infinity" => Some(NaiveDate::MIN),
1075            v => Some(
1076                NaiveDate::parse_from_str(v, "%Y-%m-%d")
1077                    .map_err(|_| ConnectorXError::cannot_produce::<NaiveDate>(Some(v.into())))?,
1078            ),
1079        }
1080    }
1081}
1082
1083impl Produce<'_, NaiveDateTime> for PostgresCSVSourceParser<'_> {
1084    type Error = PostgresSourceError;
1085
1086    #[throws(PostgresSourceError)]
1087    fn produce(&mut self) -> NaiveDateTime {
1088        let (ridx, cidx) = self.next_loc()?;
1089        match &self.rowbuf[ridx][cidx] {
1090            "infinity" => NaiveDateTime::MAX,
1091            "-infinity" => NaiveDateTime::MIN,
1092            v => NaiveDateTime::parse_from_str(v, "%Y-%m-%d %H:%M:%S%.f")
1093                .map_err(|_| ConnectorXError::cannot_produce::<NaiveDateTime>(Some(v.into())))?,
1094        }
1095    }
1096}
1097
1098impl Produce<'_, Option<NaiveDateTime>> for PostgresCSVSourceParser<'_> {
1099    type Error = PostgresSourceError;
1100
1101    #[throws(PostgresSourceError)]
1102    fn produce(&mut self) -> Option<NaiveDateTime> {
1103        let (ridx, cidx) = self.next_loc()?;
1104        match &self.rowbuf[ridx][cidx][..] {
1105            "" => None,
1106            "infinity" => Some(NaiveDateTime::MAX),
1107            "-infinity" => Some(NaiveDateTime::MIN),
1108            v => Some(
1109                NaiveDateTime::parse_from_str(v, "%Y-%m-%d %H:%M:%S%.f").map_err(|_| {
1110                    ConnectorXError::cannot_produce::<NaiveDateTime>(Some(v.into()))
1111                })?,
1112            ),
1113        }
1114    }
1115}
1116
1117impl Produce<'_, NaiveTime> for PostgresCSVSourceParser<'_> {
1118    type Error = PostgresSourceError;
1119
1120    #[throws(PostgresSourceError)]
1121    fn produce(&mut self) -> NaiveTime {
1122        let (ridx, cidx) = self.next_loc()?;
1123        NaiveTime::parse_from_str(&self.rowbuf[ridx][cidx], "%H:%M:%S%.f").map_err(|_| {
1124            ConnectorXError::cannot_produce::<NaiveTime>(Some(self.rowbuf[ridx][cidx].into()))
1125        })?
1126    }
1127}
1128
1129impl Produce<'_, Option<NaiveTime>> for PostgresCSVSourceParser<'_> {
1130    type Error = PostgresSourceError;
1131
1132    #[throws(PostgresSourceError)]
1133    fn produce(&mut self) -> Option<NaiveTime> {
1134        let (ridx, cidx) = self.next_loc()?;
1135        match &self.rowbuf[ridx][cidx][..] {
1136            "" => None,
1137            v => Some(
1138                NaiveTime::parse_from_str(v, "%H:%M:%S%.f")
1139                    .map_err(|_| ConnectorXError::cannot_produce::<NaiveTime>(Some(v.into())))?,
1140            ),
1141        }
1142    }
1143}
1144
1145impl<'r> Produce<'r, &'r str> for PostgresCSVSourceParser<'_> {
1146    type Error = PostgresSourceError;
1147
1148    #[throws(PostgresSourceError)]
1149    fn produce(&'r mut self) -> &'r str {
1150        let (ridx, cidx) = self.next_loc()?;
1151        &self.rowbuf[ridx][cidx]
1152    }
1153}
1154
1155impl<'r> Produce<'r, Option<&'r str>> for PostgresCSVSourceParser<'_> {
1156    type Error = PostgresSourceError;
1157
1158    #[throws(PostgresSourceError)]
1159    fn produce(&'r mut self) -> Option<&'r str> {
1160        let (ridx, cidx) = self.next_loc()?;
1161        match &self.rowbuf[ridx][cidx][..] {
1162            "" => None,
1163            v => Some(v),
1164        }
1165    }
1166}
1167
1168impl<'r> Produce<'r, Vec<u8>> for PostgresCSVSourceParser<'_> {
1169    type Error = PostgresSourceError;
1170
1171    #[throws(PostgresSourceError)]
1172    fn produce(&'r mut self) -> Vec<u8> {
1173        let (ridx, cidx) = self.next_loc()?;
1174        decode(&self.rowbuf[ridx][cidx][2..])? // escape \x in the beginning
1175    }
1176}
1177
1178impl<'r> Produce<'r, Option<Vec<u8>>> for PostgresCSVSourceParser<'_> {
1179    type Error = PostgresSourceError;
1180
1181    #[throws(PostgresSourceError)]
1182    fn produce(&'r mut self) -> Option<Vec<u8>> {
1183        let (ridx, cidx) = self.next_loc()?;
1184        match &self.rowbuf[ridx][cidx] {
1185            // escape \x in the beginning, empty if None
1186            "" => None,
1187            v => Some(decode(&v[2..])?),
1188        }
1189    }
1190}
1191
1192impl<'r> Produce<'r, Value> for PostgresCSVSourceParser<'_> {
1193    type Error = PostgresSourceError;
1194
1195    #[throws(PostgresSourceError)]
1196    fn produce(&'r mut self) -> Value {
1197        let (ridx, cidx) = self.next_loc()?;
1198        let v = &self.rowbuf[ridx][cidx];
1199        from_str(v).map_err(|_| ConnectorXError::cannot_produce::<Value>(Some(v.into())))?
1200    }
1201}
1202
1203impl<'r> Produce<'r, Option<Value>> for PostgresCSVSourceParser<'_> {
1204    type Error = PostgresSourceError;
1205
1206    #[throws(PostgresSourceError)]
1207    fn produce(&'r mut self) -> Option<Value> {
1208        let (ridx, cidx) = self.next_loc()?;
1209
1210        match &self.rowbuf[ridx][cidx][..] {
1211            "" => None,
1212            v => {
1213                from_str(v).map_err(|_| ConnectorXError::cannot_produce::<Value>(Some(v.into())))?
1214            }
1215        }
1216    }
1217}
1218
1219pub struct PostgresRawSourceParser<'a> {
1220    iter: RowIter<'a>,
1221    rowbuf: Vec<Row>,
1222    ncols: usize,
1223    current_col: usize,
1224    current_row: usize,
1225    is_finished: bool,
1226}
1227
1228impl<'a> PostgresRawSourceParser<'a> {
1229    pub fn new(iter: RowIter<'a>, schema: &[PostgresTypeSystem]) -> Self {
1230        Self {
1231            iter,
1232            rowbuf: Vec::with_capacity(DB_BUFFER_SIZE),
1233            ncols: schema.len(),
1234            current_row: 0,
1235            current_col: 0,
1236            is_finished: false,
1237        }
1238    }
1239
1240    #[throws(PostgresSourceError)]
1241    fn next_loc(&mut self) -> (usize, usize) {
1242        let ret = (self.current_row, self.current_col);
1243        self.current_row += (self.current_col + 1) / self.ncols;
1244        self.current_col = (self.current_col + 1) % self.ncols;
1245        ret
1246    }
1247}
1248
1249impl<'a> PartitionParser<'a> for PostgresRawSourceParser<'a> {
1250    type TypeSystem = PostgresTypeSystem;
1251    type Error = PostgresSourceError;
1252
1253    #[throws(PostgresSourceError)]
1254    fn fetch_next(&mut self) -> (usize, bool) {
1255        assert!(self.current_col == 0);
1256        let remaining_rows = self.rowbuf.len() - self.current_row;
1257        if remaining_rows > 0 {
1258            return (remaining_rows, self.is_finished);
1259        } else if self.is_finished {
1260            return (0, self.is_finished);
1261        }
1262
1263        if !self.rowbuf.is_empty() {
1264            self.rowbuf.drain(..);
1265        }
1266        for _ in 0..DB_BUFFER_SIZE {
1267            if let Some(row) = self.iter.next()? {
1268                self.rowbuf.push(row);
1269            } else {
1270                self.is_finished = true;
1271                break;
1272            }
1273        }
1274        self.current_row = 0;
1275        self.current_col = 0;
1276        (self.rowbuf.len(), self.is_finished)
1277    }
1278}
1279
1280macro_rules! impl_produce {
1281    ($($t: ty,)+) => {
1282        $(
1283            impl<'r, 'a> Produce<'r, $t> for PostgresRawSourceParser<'a> {
1284                type Error = PostgresSourceError;
1285
1286                #[throws(PostgresSourceError)]
1287                fn produce(&'r mut self) -> $t {
1288                    let (ridx, cidx) = self.next_loc()?;
1289                    let row = &self.rowbuf[ridx];
1290                    let val = row.try_get(cidx)?;
1291                    val
1292                }
1293            }
1294
1295            impl<'r, 'a> Produce<'r, Option<$t>> for PostgresRawSourceParser<'a> {
1296                type Error = PostgresSourceError;
1297
1298                #[throws(PostgresSourceError)]
1299                fn produce(&'r mut self) -> Option<$t> {
1300                    let (ridx, cidx) = self.next_loc()?;
1301                    let row = &self.rowbuf[ridx];
1302                    let val = row.try_get(cidx)?;
1303                    val
1304                }
1305            }
1306        )+
1307    };
1308}
1309
1310impl_produce!(
1311    i8,
1312    i16,
1313    i32,
1314    i64,
1315    u32,
1316    f32,
1317    f64,
1318    Decimal,
1319    bool,
1320    &'r str,
1321    Vec<u8>,
1322    NaiveTime,
1323    Uuid,
1324    Value,
1325    IpInet,
1326    Vector,
1327    HalfVector,
1328    Bit,
1329    SparseVector,
1330    HashMap<String, Option<String>>,
1331    Vec<Option<bool>>,
1332    Vec<Option<String>>,
1333    Vec<Option<i16>>,
1334    Vec<Option<i32>>,
1335    Vec<Option<i64>>,
1336    Vec<Option<f32>>,
1337    Vec<Option<f64>>,
1338    Vec<Option<Decimal>>,
1339);
1340
1341impl<'r> Produce<'r, DateTime<Utc>> for PostgresRawSourceParser<'_> {
1342    type Error = PostgresSourceError;
1343
1344    #[throws(PostgresSourceError)]
1345    fn produce(&'r mut self) -> DateTime<Utc> {
1346        let (ridx, cidx) = self.next_loc()?;
1347        let row = &self.rowbuf[ridx];
1348        let val: postgres::types::Timestamp<DateTime<Utc>> = row.try_get(cidx)?;
1349        match val {
1350            postgres::types::Timestamp::PosInfinity => DateTime::<Utc>::MAX_UTC,
1351            postgres::types::Timestamp::NegInfinity => DateTime::<Utc>::MIN_UTC,
1352            postgres::types::Timestamp::Value(t) => t,
1353        }
1354    }
1355}
1356
1357impl<'r> Produce<'r, Option<DateTime<Utc>>> for PostgresRawSourceParser<'_> {
1358    type Error = PostgresSourceError;
1359
1360    #[throws(PostgresSourceError)]
1361    fn produce(&'r mut self) -> Option<DateTime<Utc>> {
1362        let (ridx, cidx) = self.next_loc()?;
1363        let row = &self.rowbuf[ridx];
1364        let val = row.try_get(cidx)?;
1365        match val {
1366            Some(postgres::types::Timestamp::PosInfinity) => Some(DateTime::<Utc>::MAX_UTC),
1367            Some(postgres::types::Timestamp::NegInfinity) => Some(DateTime::<Utc>::MIN_UTC),
1368            Some(postgres::types::Timestamp::Value(t)) => t,
1369            None => None,
1370        }
1371    }
1372}
1373
1374impl<'r> Produce<'r, NaiveDateTime> for PostgresRawSourceParser<'_> {
1375    type Error = PostgresSourceError;
1376
1377    #[throws(PostgresSourceError)]
1378    fn produce(&'r mut self) -> NaiveDateTime {
1379        let (ridx, cidx) = self.next_loc()?;
1380        let row = &self.rowbuf[ridx];
1381        let val: postgres::types::Timestamp<NaiveDateTime> = row.try_get(cidx)?;
1382        match val {
1383            postgres::types::Timestamp::PosInfinity => NaiveDateTime::MAX,
1384            postgres::types::Timestamp::NegInfinity => NaiveDateTime::MIN,
1385            postgres::types::Timestamp::Value(t) => t,
1386        }
1387    }
1388}
1389
1390impl<'r> Produce<'r, Option<NaiveDateTime>> for PostgresRawSourceParser<'_> {
1391    type Error = PostgresSourceError;
1392
1393    #[throws(PostgresSourceError)]
1394    fn produce(&'r mut self) -> Option<NaiveDateTime> {
1395        let (ridx, cidx) = self.next_loc()?;
1396        let row = &self.rowbuf[ridx];
1397        let val = row.try_get(cidx)?;
1398        match val {
1399            Some(postgres::types::Timestamp::PosInfinity) => Some(NaiveDateTime::MAX),
1400            Some(postgres::types::Timestamp::NegInfinity) => Some(NaiveDateTime::MIN),
1401            Some(postgres::types::Timestamp::Value(t)) => t,
1402            None => None,
1403        }
1404    }
1405}
1406
1407impl<'r> Produce<'r, NaiveDate> for PostgresRawSourceParser<'_> {
1408    type Error = PostgresSourceError;
1409
1410    #[throws(PostgresSourceError)]
1411    fn produce(&'r mut self) -> NaiveDate {
1412        let (ridx, cidx) = self.next_loc()?;
1413        let row = &self.rowbuf[ridx];
1414        let val: postgres::types::Date<NaiveDate> = row.try_get(cidx)?;
1415        match val {
1416            postgres::types::Date::PosInfinity => NaiveDate::MAX,
1417            postgres::types::Date::NegInfinity => NaiveDate::MIN,
1418            postgres::types::Date::Value(t) => t,
1419        }
1420    }
1421}
1422
1423impl<'r> Produce<'r, Option<NaiveDate>> for PostgresRawSourceParser<'_> {
1424    type Error = PostgresSourceError;
1425
1426    #[throws(PostgresSourceError)]
1427    fn produce(&'r mut self) -> Option<NaiveDate> {
1428        let (ridx, cidx) = self.next_loc()?;
1429        let row = &self.rowbuf[ridx];
1430        let val = row.try_get(cidx)?;
1431        match val {
1432            Some(postgres::types::Date::PosInfinity) => Some(NaiveDate::MAX),
1433            Some(postgres::types::Date::NegInfinity) => Some(NaiveDate::MIN),
1434            Some(postgres::types::Date::Value(t)) => t,
1435            None => None,
1436        }
1437    }
1438}
1439
1440impl<C> SourcePartition for PostgresSourcePartition<SimpleProtocol, C>
1441where
1442    C: MakeTlsConnect<Socket> + Clone + 'static + Sync + Send,
1443    C::TlsConnect: Send,
1444    C::Stream: Send,
1445    <C::TlsConnect as TlsConnect<Socket>>::Future: Send,
1446{
1447    type TypeSystem = PostgresTypeSystem;
1448    type Parser<'a> = PostgresSimpleSourceParser;
1449    type Error = PostgresSourceError;
1450
1451    #[throws(PostgresSourceError)]
1452    fn result_rows(&mut self) {
1453        self.nrows = get_total_rows(&mut self.conn, &self.query)?;
1454    }
1455
1456    #[throws(PostgresSourceError)]
1457    fn parser(&mut self) -> Self::Parser<'_> {
1458        let rows = self.conn.simple_query(self.query.as_str())?; // unless reading the data, it seems like issue the query is fast
1459        PostgresSimpleSourceParser::new(rows, &self.schema)
1460    }
1461
1462    fn nrows(&self) -> usize {
1463        self.nrows
1464    }
1465
1466    fn ncols(&self) -> usize {
1467        self.ncols
1468    }
1469}
1470
1471pub struct PostgresSimpleSourceParser {
1472    rows: Vec<SimpleQueryMessage>,
1473    ncols: usize,
1474    current_col: usize,
1475    current_row: usize,
1476}
1477impl PostgresSimpleSourceParser {
1478    pub fn new(rows: Vec<SimpleQueryMessage>, schema: &[PostgresTypeSystem]) -> Self {
1479        Self {
1480            rows,
1481            ncols: schema.len(),
1482            current_row: 0,
1483            current_col: 0,
1484        }
1485    }
1486
1487    #[throws(PostgresSourceError)]
1488    fn next_loc(&mut self) -> (usize, usize) {
1489        let ret = (self.current_row, self.current_col);
1490        self.current_row += (self.current_col + 1) / self.ncols;
1491        self.current_col = (self.current_col + 1) % self.ncols;
1492        ret
1493    }
1494}
1495
1496impl PartitionParser<'_> for PostgresSimpleSourceParser {
1497    type TypeSystem = PostgresTypeSystem;
1498    type Error = PostgresSourceError;
1499
1500    #[throws(PostgresSourceError)]
1501    fn fetch_next(&mut self) -> (usize, bool) {
1502        self.current_row = 0;
1503        self.current_col = 0;
1504        if !self.rows.is_empty() {
1505            if let SimpleQueryMessage::RowDescription(_) = &self.rows[0] {
1506                self.current_row = 1;
1507            }
1508        }
1509
1510        (self.rows.len() - 1 - self.current_row, true) // last message is command complete
1511    }
1512}
1513
1514macro_rules! impl_simple_produce {
1515    ($($t: ty,)+) => {
1516        $(
1517            impl<'r> Produce<'r, $t> for PostgresSimpleSourceParser {
1518                type Error = PostgresSourceError;
1519
1520                #[throws(PostgresSourceError)]
1521                fn produce(&'r mut self) -> $t {
1522                    let (ridx, cidx) = self.next_loc()?;
1523                    let val = match &self.rows[ridx] {
1524                        SimpleQueryMessage::Row(row) => match row.try_get(cidx)? {
1525                            Some(s) => s
1526                                .parse()
1527                                .map_err(|_| ConnectorXError::cannot_produce::<$t>(Some(s.into())))?,
1528                            None => throw!(anyhow!(
1529                                "Cannot parse NULL in NOT NULL column."
1530                            )),
1531                        },
1532                        SimpleQueryMessage::CommandComplete(c) => {
1533                            panic!("get command: {}", c);
1534                        }
1535                        _ => {
1536                            panic!("what?");
1537                        }
1538                    };
1539                    val
1540                }
1541            }
1542
1543            impl<'r, 'a> Produce<'r, Option<$t>> for PostgresSimpleSourceParser {
1544                type Error = PostgresSourceError;
1545
1546                #[throws(PostgresSourceError)]
1547                fn produce(&'r mut self) -> Option<$t> {
1548                    let (ridx, cidx) = self.next_loc()?;
1549                    let val = match &self.rows[ridx] {
1550                        SimpleQueryMessage::Row(row) => match row.try_get(cidx)? {
1551                            Some(s) => Some(
1552                                s.parse()
1553                                    .map_err(|_| ConnectorXError::cannot_produce::<$t>(Some(s.into())))?,
1554                            ),
1555                            None => None,
1556                        },
1557                        SimpleQueryMessage::CommandComplete(c) => {
1558                            panic!("get command: {}", c);
1559                        }
1560                        _ => {
1561                            panic!("what?");
1562                        }
1563                    };
1564                    val
1565                }
1566            }
1567        )+
1568    };
1569}
1570
1571impl_simple_produce!(i8, i16, i32, i64, u32, f32, f64, Uuid, IpInet,);
1572
1573impl<'r> Produce<'r, bool> for PostgresSimpleSourceParser {
1574    type Error = PostgresSourceError;
1575
1576    #[throws(PostgresSourceError)]
1577    fn produce(&'r mut self) -> bool {
1578        let (ridx, cidx) = self.next_loc()?;
1579        let val = match &self.rows[ridx] {
1580            SimpleQueryMessage::Row(row) => match row.try_get(cidx)? {
1581                Some(s) => match s {
1582                    "t" => true,
1583                    "f" => false,
1584                    _ => throw!(ConnectorXError::cannot_produce::<bool>(Some(s.into()))),
1585                },
1586                None => throw!(anyhow!("Cannot parse NULL in non-NULL column.")),
1587            },
1588            SimpleQueryMessage::CommandComplete(c) => {
1589                panic!("get command: {}", c);
1590            }
1591            _ => {
1592                panic!("what?");
1593            }
1594        };
1595        val
1596    }
1597}
1598
1599impl<'r> Produce<'r, Option<bool>> for PostgresSimpleSourceParser {
1600    type Error = PostgresSourceError;
1601
1602    #[throws(PostgresSourceError)]
1603    fn produce(&'r mut self) -> Option<bool> {
1604        let (ridx, cidx) = self.next_loc()?;
1605        let val = match &self.rows[ridx] {
1606            SimpleQueryMessage::Row(row) => match row.try_get(cidx)? {
1607                Some(s) => match s {
1608                    "t" => Some(true),
1609                    "f" => Some(false),
1610                    _ => throw!(ConnectorXError::cannot_produce::<bool>(Some(s.into()))),
1611                },
1612                None => None,
1613            },
1614            SimpleQueryMessage::CommandComplete(c) => {
1615                panic!("get command: {}", c);
1616            }
1617            _ => {
1618                panic!("what?");
1619            }
1620        };
1621        val
1622    }
1623}
1624
1625impl<'r> Produce<'r, Decimal> for PostgresSimpleSourceParser {
1626    type Error = PostgresSourceError;
1627
1628    #[throws(PostgresSourceError)]
1629    fn produce(&'r mut self) -> Decimal {
1630        let (ridx, cidx) = self.next_loc()?;
1631        let val = match &self.rows[ridx] {
1632            SimpleQueryMessage::Row(row) => match row.try_get(cidx)? {
1633                Some("Infinity") => Decimal::MAX,
1634                Some("-Infinity") => Decimal::MIN,
1635                Some(s) => s
1636                    .parse()
1637                    .map_err(|_| ConnectorXError::cannot_produce::<Decimal>(Some(s.into())))?,
1638                None => throw!(anyhow!("Cannot parse NULL in NOT NULL column.")),
1639            },
1640            SimpleQueryMessage::CommandComplete(c) => {
1641                panic!("get command: {}", c);
1642            }
1643            _ => {
1644                panic!("what?");
1645            }
1646        };
1647        val
1648    }
1649}
1650
1651impl<'r> Produce<'r, Option<Decimal>> for PostgresSimpleSourceParser {
1652    type Error = PostgresSourceError;
1653
1654    #[throws(PostgresSourceError)]
1655    fn produce(&'r mut self) -> Option<Decimal> {
1656        let (ridx, cidx) = self.next_loc()?;
1657        let val = match &self.rows[ridx] {
1658            SimpleQueryMessage::Row(row) => match row.try_get(cidx)? {
1659                Some("Infinity") => Some(Decimal::MAX),
1660                Some("-Infinity") => Some(Decimal::MIN),
1661                Some(s) => Some(
1662                    s.parse()
1663                        .map_err(|_| ConnectorXError::cannot_produce::<Decimal>(Some(s.into())))?,
1664                ),
1665                None => None,
1666            },
1667            SimpleQueryMessage::CommandComplete(c) => {
1668                panic!("get command: {}", c);
1669            }
1670            _ => {
1671                panic!("what?");
1672            }
1673        };
1674        val
1675    }
1676}
1677
1678impl<'r> Produce<'r, &'r str> for PostgresSimpleSourceParser {
1679    type Error = PostgresSourceError;
1680
1681    #[throws(PostgresSourceError)]
1682    fn produce(&'r mut self) -> &'r str {
1683        let (ridx, cidx) = self.next_loc()?;
1684        let val = match &self.rows[ridx] {
1685            SimpleQueryMessage::Row(row) => match row.try_get(cidx)? {
1686                Some(s) => s,
1687                None => throw!(anyhow!("Cannot parse NULL in non-NULL column.")),
1688            },
1689            SimpleQueryMessage::CommandComplete(c) => {
1690                panic!("get command: {}", c);
1691            }
1692            _ => {
1693                panic!("what?");
1694            }
1695        };
1696        val
1697    }
1698}
1699
1700impl<'r> Produce<'r, Option<&'r str>> for PostgresSimpleSourceParser {
1701    type Error = PostgresSourceError;
1702
1703    #[throws(PostgresSourceError)]
1704    fn produce(&'r mut self) -> Option<&'r str> {
1705        let (ridx, cidx) = self.next_loc()?;
1706        let val = match &self.rows[ridx] {
1707            SimpleQueryMessage::Row(row) => row.try_get(cidx)?,
1708            SimpleQueryMessage::CommandComplete(c) => {
1709                panic!("get command: {}", c);
1710            }
1711            _ => {
1712                panic!("what?");
1713            }
1714        };
1715        val
1716    }
1717}
1718
1719impl<'r> Produce<'r, Vec<u8>> for PostgresSimpleSourceParser {
1720    type Error = PostgresSourceError;
1721
1722    #[throws(PostgresSourceError)]
1723    fn produce(&'r mut self) -> Vec<u8> {
1724        let (ridx, cidx) = self.next_loc()?;
1725        let val = match &self.rows[ridx] {
1726            SimpleQueryMessage::Row(row) => match row.try_get(cidx)? {
1727                Some(s) => {
1728                    let mut res = s.chars();
1729                    res.next();
1730                    res.next();
1731                    decode(
1732                        res.enumerate()
1733                            .fold(String::new(), |acc, (_i, c)| format!("{}{}", acc, c))
1734                            .chars()
1735                            .map(|c| c as u8)
1736                            .collect::<Vec<u8>>(),
1737                    )?
1738                }
1739                None => throw!(anyhow!("Cannot parse NULL in non-NULL column.")),
1740            },
1741            SimpleQueryMessage::CommandComplete(c) => {
1742                panic!("get command: {}", c);
1743            }
1744            _ => {
1745                panic!("what?");
1746            }
1747        };
1748        val
1749    }
1750}
1751
1752impl<'r> Produce<'r, Option<Vec<u8>>> for PostgresSimpleSourceParser {
1753    type Error = PostgresSourceError;
1754
1755    #[throws(PostgresSourceError)]
1756    fn produce(&'r mut self) -> Option<Vec<u8>> {
1757        let (ridx, cidx) = self.next_loc()?;
1758        let val = match &self.rows[ridx] {
1759            SimpleQueryMessage::Row(row) => match row.try_get(cidx)? {
1760                Some(s) => {
1761                    let mut res = s.chars();
1762                    res.next();
1763                    res.next();
1764                    Some(decode(
1765                        res.enumerate()
1766                            .fold(String::new(), |acc, (_i, c)| format!("{}{}", acc, c))
1767                            .chars()
1768                            .map(|c| c as u8)
1769                            .collect::<Vec<u8>>(),
1770                    )?)
1771                }
1772                None => None,
1773            },
1774            SimpleQueryMessage::CommandComplete(c) => {
1775                panic!("get command: {}", c);
1776            }
1777            _ => {
1778                panic!("what?");
1779            }
1780        };
1781        val
1782    }
1783}
1784
1785fn rem_first_and_last(value: &str) -> &str {
1786    let mut chars = value.chars();
1787    chars.next();
1788    chars.next_back();
1789    chars.as_str()
1790}
1791
1792macro_rules! impl_simple_vec_produce {
1793    ($($t: ty,)+) => {
1794        $(
1795            impl<'r> Produce<'r, Vec<Option<$t>>> for PostgresSimpleSourceParser {
1796                type Error = PostgresSourceError;
1797
1798                #[throws(PostgresSourceError)]
1799                fn produce(&'r mut self) -> Vec<Option<$t>> {
1800                    let (ridx, cidx) = self.next_loc()?;
1801                    let val = match &self.rows[ridx] {
1802                        SimpleQueryMessage::Row(row) => match row.try_get(cidx)? {
1803                            Some(s) => match s{
1804                                "" => throw!(anyhow!("Cannot parse NULL in non-NULL column.")),
1805                                "{}" => vec![],
1806                                _ => rem_first_and_last(s).split(",").map(|v| {
1807                                    if v == "NULL" {
1808                                        Ok(None)
1809                                    } else {
1810                                        match v.parse() {
1811                                            Ok(v) => Ok(Some(v)),
1812                                            Err(e) => Err(e).map_err(|_| ConnectorXError::cannot_produce::<Vec<$t>>(Some(s.into())))
1813                                        }
1814                                    }
1815                                }).collect::<Result<Vec<Option<$t>>, ConnectorXError>>()?
1816                            },
1817                            None => throw!(anyhow!("Cannot parse NULL in non-NULL column.")),
1818                        },
1819                        SimpleQueryMessage::CommandComplete(c) => {
1820                            panic!("get command: {}", c);
1821                        }
1822                        _ => {
1823                            panic!("what?");
1824                        }
1825                    };
1826                    val
1827                }
1828            }
1829
1830            impl<'r, 'a> Produce<'r, Option<Vec<Option<$t>>>> for PostgresSimpleSourceParser {
1831                type Error = PostgresSourceError;
1832
1833                #[throws(PostgresSourceError)]
1834                fn produce(&'r mut self) -> Option<Vec<Option<$t>>> {
1835                    let (ridx, cidx) = self.next_loc()?;
1836                    let val = match &self.rows[ridx] {
1837
1838                        SimpleQueryMessage::Row(row) => match row.try_get(cidx)? {
1839                            Some(s) => match s{
1840                                "" => None,
1841                                "{}" => Some(vec![]),
1842                                _ => Some(rem_first_and_last(s).split(",").map(|v| {
1843                                    if v == "NULL" {
1844                                        Ok(None)
1845                                    } else {
1846                                        match v.parse() {
1847                                            Ok(v) => Ok(Some(v)),
1848                                            Err(e) => Err(e).map_err(|_| ConnectorXError::cannot_produce::<Vec<$t>>(Some(s.into())))
1849                                        }
1850                                    }
1851                                }).collect::<Result<Vec<Option<$t>>, ConnectorXError>>()?)
1852                            },
1853                            None => None,
1854                        },
1855
1856                        SimpleQueryMessage::CommandComplete(c) => {
1857                            panic!("get command: {}", c);
1858                        }
1859                        _ => {
1860                            panic!("what?");
1861                        }
1862                    };
1863                    val
1864                }
1865            }
1866        )+
1867    };
1868}
1869impl_simple_vec_produce!(i16, i32, i64, f32, f64, Decimal, String,);
1870
1871impl<'r> Produce<'r, Vec<Option<bool>>> for PostgresSimpleSourceParser {
1872    type Error = PostgresSourceError;
1873
1874    #[throws(PostgresSourceError)]
1875    fn produce(&'r mut self) -> Vec<Option<bool>> {
1876        let (ridx, cidx) = self.next_loc()?;
1877        let val = match &self.rows[ridx] {
1878            SimpleQueryMessage::Row(row) => match row.try_get(cidx)? {
1879                Some(s) => match s {
1880                    "" => throw!(anyhow!("Cannot parse NULL in non-NULL column.")),
1881                    "{}" => vec![],
1882                    _ => rem_first_and_last(s)
1883                        .split(',')
1884                        .map(|token| match token {
1885                            "NULL" => Ok(None),
1886                            "t" => Ok(Some(true)),
1887                            "f" => Ok(Some(false)),
1888                            _ => {
1889                                throw!(ConnectorXError::cannot_produce::<Vec<bool>>(Some(s.into())))
1890                            }
1891                        })
1892                        .collect::<Result<Vec<Option<bool>>, ConnectorXError>>()?,
1893                },
1894                None => throw!(anyhow!("Cannot parse NULL in non-NULL column.")),
1895            },
1896            SimpleQueryMessage::CommandComplete(c) => {
1897                panic!("get command: {}", c);
1898            }
1899            _ => {
1900                panic!("what?");
1901            }
1902        };
1903        val
1904    }
1905}
1906
1907impl<'r> Produce<'r, Option<Vec<Option<bool>>>> for PostgresSimpleSourceParser {
1908    type Error = PostgresSourceError;
1909
1910    #[throws(PostgresSourceError)]
1911    fn produce(&'r mut self) -> Option<Vec<Option<bool>>> {
1912        let (ridx, cidx) = self.next_loc()?;
1913        let val = match &self.rows[ridx] {
1914            SimpleQueryMessage::Row(row) => match row.try_get(cidx)? {
1915                Some(s) => match s {
1916                    "" => None,
1917                    "{}" => Some(vec![]),
1918                    _ => Some(
1919                        rem_first_and_last(s)
1920                            .split(',')
1921                            .map(|token| match token {
1922                                "NULL" => Ok(None),
1923                                "t" => Ok(Some(true)),
1924                                "f" => Ok(Some(false)),
1925                                _ => {
1926                                    throw!(ConnectorXError::cannot_produce::<Vec<bool>>(Some(
1927                                        s.into()
1928                                    )))
1929                                }
1930                            })
1931                            .collect::<Result<Vec<Option<bool>>, ConnectorXError>>()?,
1932                    ),
1933                },
1934                None => None,
1935            },
1936            SimpleQueryMessage::CommandComplete(c) => {
1937                panic!("get command: {}", c);
1938            }
1939            _ => {
1940                panic!("what?");
1941            }
1942        };
1943        val
1944    }
1945}
1946
1947impl<'r> Produce<'r, NaiveDate> for PostgresSimpleSourceParser {
1948    type Error = PostgresSourceError;
1949
1950    #[throws(PostgresSourceError)]
1951    fn produce(&'r mut self) -> NaiveDate {
1952        let (ridx, cidx) = self.next_loc()?;
1953        let val = match &self.rows[ridx] {
1954            SimpleQueryMessage::Row(row) => match row.try_get(cidx)? {
1955                Some(s) => match s {
1956                    "infinity" => NaiveDate::MAX,
1957                    "-infinity" => NaiveDate::MIN,
1958                    s => NaiveDate::parse_from_str(s, "%Y-%m-%d").map_err(|_| {
1959                        ConnectorXError::cannot_produce::<NaiveDate>(Some(s.into()))
1960                    })?,
1961                },
1962                None => throw!(anyhow!("Cannot parse NULL in non-NULL column.")),
1963            },
1964            SimpleQueryMessage::CommandComplete(c) => {
1965                panic!("get command: {}", c);
1966            }
1967            _ => {
1968                panic!("what?");
1969            }
1970        };
1971        val
1972    }
1973}
1974
1975impl<'r> Produce<'r, Option<NaiveDate>> for PostgresSimpleSourceParser {
1976    type Error = PostgresSourceError;
1977
1978    #[throws(PostgresSourceError)]
1979    fn produce(&'r mut self) -> Option<NaiveDate> {
1980        let (ridx, cidx) = self.next_loc()?;
1981        let val = match &self.rows[ridx] {
1982            SimpleQueryMessage::Row(row) => match row.try_get(cidx)? {
1983                Some(s) => match s {
1984                    "infinity" => Some(NaiveDate::MAX),
1985                    "-infinity" => Some(NaiveDate::MIN),
1986                    s => Some(NaiveDate::parse_from_str(s, "%Y-%m-%d").map_err(|_| {
1987                        ConnectorXError::cannot_produce::<Option<NaiveDate>>(Some(s.into()))
1988                    })?),
1989                },
1990                None => None,
1991            },
1992            SimpleQueryMessage::CommandComplete(c) => {
1993                panic!("get command: {}", c);
1994            }
1995            _ => {
1996                panic!("what?");
1997            }
1998        };
1999        val
2000    }
2001}
2002
2003impl<'r> Produce<'r, NaiveTime> for PostgresSimpleSourceParser {
2004    type Error = PostgresSourceError;
2005
2006    #[throws(PostgresSourceError)]
2007    fn produce(&'r mut self) -> NaiveTime {
2008        let (ridx, cidx) = self.next_loc()?;
2009        let val = match &self.rows[ridx] {
2010            SimpleQueryMessage::Row(row) => match row.try_get(cidx)? {
2011                Some(s) => NaiveTime::parse_from_str(s, "%H:%M:%S%.f")
2012                    .map_err(|_| ConnectorXError::cannot_produce::<NaiveTime>(Some(s.into())))?,
2013                None => throw!(anyhow!("Cannot parse NULL in non-NULL column.")),
2014            },
2015            SimpleQueryMessage::CommandComplete(c) => {
2016                panic!("get command: {}", c);
2017            }
2018            _ => {
2019                panic!("what?");
2020            }
2021        };
2022        val
2023    }
2024}
2025
2026impl<'r> Produce<'r, Option<NaiveTime>> for PostgresSimpleSourceParser {
2027    type Error = PostgresSourceError;
2028
2029    #[throws(PostgresSourceError)]
2030    fn produce(&'r mut self) -> Option<NaiveTime> {
2031        let (ridx, cidx) = self.next_loc()?;
2032        let val = match &self.rows[ridx] {
2033            SimpleQueryMessage::Row(row) => match row.try_get(cidx)? {
2034                Some(s) => Some(NaiveTime::parse_from_str(s, "%H:%M:%S%.f").map_err(|_| {
2035                    ConnectorXError::cannot_produce::<Option<NaiveTime>>(Some(s.into()))
2036                })?),
2037                None => None,
2038            },
2039            SimpleQueryMessage::CommandComplete(c) => {
2040                panic!("get command: {}", c);
2041            }
2042            _ => {
2043                panic!("what?");
2044            }
2045        };
2046        val
2047    }
2048}
2049
2050impl<'r> Produce<'r, NaiveDateTime> for PostgresSimpleSourceParser {
2051    type Error = PostgresSourceError;
2052
2053    #[throws(PostgresSourceError)]
2054    fn produce(&'r mut self) -> NaiveDateTime {
2055        let (ridx, cidx) = self.next_loc()?;
2056        let val =
2057            match &self.rows[ridx] {
2058                SimpleQueryMessage::Row(row) => match row.try_get(cidx)? {
2059                    Some(s) => match s {
2060                        "infinity" => NaiveDateTime::MAX,
2061                        "-infinity" => NaiveDateTime::MIN,
2062                        s => NaiveDateTime::parse_from_str(s, "%Y-%m-%d %H:%M:%S%.f").map_err(
2063                            |_| ConnectorXError::cannot_produce::<NaiveDateTime>(Some(s.into())),
2064                        )?,
2065                    },
2066                    None => throw!(anyhow!("Cannot parse NULL in non-NULL column.")),
2067                },
2068                SimpleQueryMessage::CommandComplete(c) => {
2069                    panic!("get command: {}", c);
2070                }
2071                _ => {
2072                    panic!("what?");
2073                }
2074            };
2075        val
2076    }
2077}
2078
2079impl<'r> Produce<'r, Option<NaiveDateTime>> for PostgresSimpleSourceParser {
2080    type Error = PostgresSourceError;
2081
2082    #[throws(PostgresSourceError)]
2083    fn produce(&'r mut self) -> Option<NaiveDateTime> {
2084        let (ridx, cidx) = self.next_loc()?;
2085        let val = match &self.rows[ridx] {
2086            SimpleQueryMessage::Row(row) => match row.try_get(cidx)? {
2087                Some(s) => match s {
2088                    "infinity" => Some(NaiveDateTime::MAX),
2089                    "-infinity" => Some(NaiveDateTime::MIN),
2090                    s => Some(
2091                        NaiveDateTime::parse_from_str(s, "%Y-%m-%d %H:%M:%S%.f").map_err(|_| {
2092                            ConnectorXError::cannot_produce::<Option<NaiveDateTime>>(Some(s.into()))
2093                        })?,
2094                    ),
2095                },
2096                None => None,
2097            },
2098            SimpleQueryMessage::CommandComplete(c) => {
2099                panic!("get command: {}", c);
2100            }
2101            _ => {
2102                panic!("what?");
2103            }
2104        };
2105        val
2106    }
2107}
2108
2109impl<'r> Produce<'r, DateTime<Utc>> for PostgresSimpleSourceParser {
2110    type Error = PostgresSourceError;
2111
2112    #[throws(PostgresSourceError)]
2113    fn produce(&'r mut self) -> DateTime<Utc> {
2114        let (ridx, cidx) = self.next_loc()?;
2115        let val = match &self.rows[ridx] {
2116            SimpleQueryMessage::Row(row) => match row.try_get(cidx)? {
2117                Some("infinity") => DateTime::<Utc>::MAX_UTC,
2118                Some("-infinity") => DateTime::<Utc>::MIN_UTC,
2119                Some(s) => {
2120                    let time_string = format!("{}:00", s).to_owned();
2121                    let slice: &str = &time_string[..];
2122                    let time: DateTime<FixedOffset> =
2123                        DateTime::parse_from_str(slice, "%Y-%m-%d %H:%M:%S%.f%:z").unwrap();
2124
2125                    time.with_timezone(&Utc)
2126                }
2127                None => throw!(anyhow!("Cannot parse NULL in non-NULL column.")),
2128            },
2129            SimpleQueryMessage::CommandComplete(c) => {
2130                panic!("get command: {}", c);
2131            }
2132            _ => {
2133                panic!("what?");
2134            }
2135        };
2136        val
2137    }
2138}
2139
2140impl<'r> Produce<'r, Option<DateTime<Utc>>> for PostgresSimpleSourceParser {
2141    type Error = PostgresSourceError;
2142
2143    #[throws(PostgresSourceError)]
2144    fn produce(&'r mut self) -> Option<DateTime<Utc>> {
2145        let (ridx, cidx) = self.next_loc()?;
2146        let val = match &self.rows[ridx] {
2147            SimpleQueryMessage::Row(row) => match row.try_get(cidx)? {
2148                Some("infinity") => Some(DateTime::<Utc>::MAX_UTC),
2149                Some("-infinity") => Some(DateTime::<Utc>::MIN_UTC),
2150                Some(s) => {
2151                    let time_string = format!("{}:00", s).to_owned();
2152                    let slice: &str = &time_string[..];
2153                    let time: DateTime<FixedOffset> =
2154                        DateTime::parse_from_str(slice, "%Y-%m-%d %H:%M:%S%.f%:z").unwrap();
2155
2156                    Some(time.with_timezone(&Utc))
2157                }
2158                None => None,
2159            },
2160            SimpleQueryMessage::CommandComplete(c) => {
2161                panic!("get command: {}", c);
2162            }
2163            _ => {
2164                panic!("what?");
2165            }
2166        };
2167        val
2168    }
2169}