@@ -4,11 +4,13 @@ use std::{str::FromStr, sync::Arc};
44use arrow:: {
55 array:: {
66 timezone:: Tz , Array , BinaryArray , BinaryViewArray , BooleanArray , Date32Array , Date64Array ,
7- Decimal128Array , Decimal256Array , DurationMicrosecondArray , LargeBinaryArray ,
8- LargeListArray , LargeStringArray , ListArray , MapArray , PrimitiveArray , StringArray ,
9- StringViewArray , Time32MillisecondArray , Time32SecondArray , Time64MicrosecondArray ,
10- Time64NanosecondArray , TimestampMicrosecondArray , TimestampMillisecondArray ,
11- TimestampNanosecondArray , TimestampSecondArray ,
7+ Decimal128Array , Decimal256Array , DurationMicrosecondArray , DurationMillisecondArray ,
8+ DurationNanosecondArray , DurationSecondArray , IntervalDayTimeArray ,
9+ IntervalMonthDayNanoArray , IntervalYearMonthArray , LargeBinaryArray , LargeListArray ,
10+ LargeStringArray , ListArray , MapArray , PrimitiveArray , StringArray , StringViewArray ,
11+ Time32MillisecondArray , Time32SecondArray , Time64MicrosecondArray , Time64NanosecondArray ,
12+ TimestampMicrosecondArray , TimestampMillisecondArray , TimestampNanosecondArray ,
13+ TimestampSecondArray ,
1214 } ,
1315 datatypes:: {
1416 DataType , Date32Type , Date64Type , Float32Type , Float64Type , Int16Type , Int32Type ,
@@ -21,11 +23,13 @@ use arrow::{
2123use datafusion:: arrow:: {
2224 array:: {
2325 timezone:: Tz , Array , BinaryArray , BinaryViewArray , BooleanArray , Date32Array , Date64Array ,
24- Decimal128Array , Decimal256Array , DurationMicrosecondArray , LargeBinaryArray ,
25- LargeListArray , LargeStringArray , ListArray , MapArray , PrimitiveArray , StringArray ,
26- StringViewArray , Time32MillisecondArray , Time32SecondArray , Time64MicrosecondArray ,
27- Time64NanosecondArray , TimestampMicrosecondArray , TimestampMillisecondArray ,
28- TimestampNanosecondArray , TimestampSecondArray ,
26+ Decimal128Array , Decimal256Array , DurationMicrosecondArray , DurationMillisecondArray ,
27+ DurationNanosecondArray , DurationSecondArray , IntervalDayTimeArray ,
28+ IntervalMonthDayNanoArray , IntervalYearMonthArray , LargeBinaryArray , LargeListArray ,
29+ LargeStringArray , ListArray , MapArray , PrimitiveArray , StringArray , StringViewArray ,
30+ Time32MillisecondArray , Time32SecondArray , Time64MicrosecondArray , Time64NanosecondArray ,
31+ TimestampMicrosecondArray , TimestampMillisecondArray , TimestampNanosecondArray ,
32+ TimestampSecondArray ,
2933 } ,
3034 datatypes:: {
3135 DataType , Date32Type , Date64Type , Float32Type , Float64Type , Int16Type , Int32Type ,
@@ -36,6 +40,7 @@ use datafusion::arrow::{
3640} ;
3741
3842use chrono:: { DateTime , TimeZone , Utc } ;
43+ use pg_interval:: Interval as PgInterval ;
3944use pgwire:: api:: results:: FieldInfo ;
4045use pgwire:: error:: { PgWireError , PgWireResult } ;
4146use rust_decimal:: Decimal ;
@@ -446,17 +451,98 @@ pub fn encode_list<T: Encoder>(
446451 encoder. encode_field ( & value, pg_field) ?;
447452 Ok ( ( ) )
448453 }
449- DataType :: Duration ( _) => {
450- // Convert duration to microseconds for now
451- let value: Vec < Option < i64 > > = arr
452- . as_any ( )
453- . downcast_ref :: < DurationMicrosecondArray > ( )
454- . unwrap ( )
455- . iter ( )
456- . collect ( ) ;
457- encoder. encode_field ( & value, pg_field) ?;
458- Ok ( ( ) )
459- }
454+ DataType :: Duration ( unit) => match unit {
455+ TimeUnit :: Second => {
456+ let value: Vec < Option < PgInterval > > = arr
457+ . as_any ( )
458+ . downcast_ref :: < DurationSecondArray > ( )
459+ . unwrap ( )
460+ . iter ( )
461+ . map ( |val| val. map ( |v| PgInterval :: new ( 0 , 0 , v * 1_000_000i64 ) ) )
462+ . collect ( ) ;
463+ encoder. encode_field ( & value, pg_field) ?;
464+ Ok ( ( ) )
465+ }
466+ TimeUnit :: Millisecond => {
467+ let value: Vec < Option < PgInterval > > = arr
468+ . as_any ( )
469+ . downcast_ref :: < DurationMillisecondArray > ( )
470+ . unwrap ( )
471+ . iter ( )
472+ . map ( |val| val. map ( |v| PgInterval :: new ( 0 , 0 , v * 1_000i64 ) ) )
473+ . collect ( ) ;
474+ encoder. encode_field ( & value, pg_field) ?;
475+ Ok ( ( ) )
476+ }
477+ TimeUnit :: Microsecond => {
478+ let value: Vec < Option < PgInterval > > = arr
479+ . as_any ( )
480+ . downcast_ref :: < DurationMicrosecondArray > ( )
481+ . unwrap ( )
482+ . iter ( )
483+ . map ( |val| val. map ( |v| PgInterval :: new ( 0 , 0 , v) ) )
484+ . collect ( ) ;
485+ encoder. encode_field ( & value, pg_field) ?;
486+ Ok ( ( ) )
487+ }
488+ TimeUnit :: Nanosecond => {
489+ let value: Vec < Option < PgInterval > > = arr
490+ . as_any ( )
491+ . downcast_ref :: < DurationNanosecondArray > ( )
492+ . unwrap ( )
493+ . iter ( )
494+ . map ( |val| val. map ( |v| PgInterval :: new ( 0 , 0 , v / 1_000i64 ) ) )
495+ . collect ( ) ;
496+ encoder. encode_field ( & value, pg_field) ?;
497+ Ok ( ( ) )
498+ }
499+ } ,
500+ DataType :: Interval ( interval_unit) => match interval_unit {
501+ arrow:: datatypes:: IntervalUnit :: YearMonth => {
502+ let value: Vec < Option < PgInterval > > = arr
503+ . as_any ( )
504+ . downcast_ref :: < IntervalYearMonthArray > ( )
505+ . unwrap ( )
506+ . iter ( )
507+ . map ( |val| val. map ( |v| PgInterval :: new ( v, 0 , 0 ) ) )
508+ . collect ( ) ;
509+ encoder. encode_field ( & value, pg_field) ?;
510+ Ok ( ( ) )
511+ }
512+ arrow:: datatypes:: IntervalUnit :: DayTime => {
513+ let value: Vec < Option < PgInterval > > = arr
514+ . as_any ( )
515+ . downcast_ref :: < IntervalDayTimeArray > ( )
516+ . unwrap ( )
517+ . iter ( )
518+ . map ( |val| {
519+ val. map ( |v| {
520+ let ( days, millis) = arrow:: datatypes:: IntervalDayTimeType :: to_parts ( v) ;
521+ PgInterval :: new ( 0 , days, millis as i64 * 1000i64 )
522+ } )
523+ } )
524+ . collect ( ) ;
525+ encoder. encode_field ( & value, pg_field) ?;
526+ Ok ( ( ) )
527+ }
528+ arrow:: datatypes:: IntervalUnit :: MonthDayNano => {
529+ let value: Vec < Option < PgInterval > > = arr
530+ . as_any ( )
531+ . downcast_ref :: < IntervalMonthDayNanoArray > ( )
532+ . unwrap ( )
533+ . iter ( )
534+ . map ( |val| {
535+ val. map ( |v| {
536+ let ( months, days, nanos) =
537+ arrow:: datatypes:: IntervalMonthDayNanoType :: to_parts ( v) ;
538+ PgInterval :: new ( months, days, nanos / 1000i64 )
539+ } )
540+ } )
541+ . collect ( ) ;
542+ encoder. encode_field ( & value, pg_field) ?;
543+ Ok ( ( ) )
544+ }
545+ } ,
460546 DataType :: List ( _) => {
461547 // Support for nested lists (list of lists)
462548 // For now, convert to string representation
0 commit comments