1mod 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
41pub enum BinaryProtocol {}
43
44pub enum CSVProtocol {}
46
47pub enum CursorProtocol {}
49
50pub 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
97fn 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
168fn 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)?; 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)?; 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![])?; 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 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 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 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 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..])? }
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 "" => 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())?; 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) }
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}