@@ -434,6 +434,47 @@ function _interval_regex()
434
434
return Regex (String (take! (io)))
435
435
end
436
436
437
+ function _split_period (period:: T , :: Type{P} ) where {T<: Period ,P<: Period }
438
+ q, r = divrem (period, convert (T, P (1 )))
439
+ return P (q), r
440
+ end
441
+
442
+ # Splits internal interval types into the expected period types from
443
+ # https://www.postgresql.org/docs/10/datatype-datetime.html#DATATYPE-INTERVAL-INPUT
444
+ function _split_periods (months, days, microseconds)
445
+ periods = Period[]
446
+
447
+ push! (periods, _split_period (months, Year)... )
448
+ push! (periods, _split_period (days, Week)... )
449
+
450
+ seconds, ms = _split_period (microseconds, Second)
451
+ minutes, seconds = _split_period (seconds, Minute)
452
+ hours, minutes = _split_period (minutes, Hour)
453
+
454
+ push! (periods, hours, minutes, seconds, ms)
455
+ filter! (! iszero, periods)
456
+
457
+ return Dates. CompoundPeriod (periods)
458
+ end
459
+
460
+ # Parse binary into postgres interval
461
+ function Base. parse (
462
+ :: Type{Dates.CompoundPeriod} , pqv:: PQBinaryValue{PQ_SYSTEM_TYPES[:interval]}
463
+ )
464
+ current_pointer = data_pointer (pqv)
465
+
466
+ microsecond = Microsecond (ntoh (unsafe_load (Ptr {Int64} (current_pointer))))
467
+ current_pointer += sizeof (Int64)
468
+
469
+ day = Day (ntoh (unsafe_load (Ptr {Int32} (current_pointer))))
470
+ current_pointer += sizeof (Int32)
471
+
472
+ month = Month (ntoh (unsafe_load (Ptr {Int32} (current_pointer))))
473
+
474
+ # Split combined periods to match the output from text queries
475
+ return _split_periods (Month (month), Day (day), Microsecond (microsecond))
476
+ end
477
+
437
478
# parse the iso_8601 interval output format
438
479
# https://www.postgresql.org/docs/10/datatype-datetime.html#DATATYPE-INTERVAL-OUTPUT
439
480
function pqparse (:: Type{Dates.CompoundPeriod} , str:: AbstractString )
0 commit comments