{-# LANGUAGE OverloadedStrings #-} module DataFrame.IO.Parquet.Dictionary where import Control.Monad import Data.Bits import Data.Char import Data.Int import Data.Maybe import qualified Data.Text as T import Data.Time import Data.Word import DataFrame.IO.Parquet.Binary import DataFrame.IO.Parquet.Encoding import DataFrame.IO.Parquet.Levels import DataFrame.IO.Parquet.Time import DataFrame.IO.Parquet.Types import qualified DataFrame.Internal.Column as DI import GHC.Float dictCardinality :: DictVals -> Int dictCardinality :: DictVals -> Int dictCardinality (DBool [Bool] ds) = [Bool] -> Int forall a. [a] -> Int forall (t :: * -> *) a. Foldable t => t a -> Int length [Bool] ds dictCardinality (DInt32 [Int32] ds) = [Int32] -> Int forall a. [a] -> Int forall (t :: * -> *) a. Foldable t => t a -> Int length [Int32] ds dictCardinality (DInt64 [Int64] ds) = [Int64] -> Int forall a. [a] -> Int forall (t :: * -> *) a. Foldable t => t a -> Int length [Int64] ds dictCardinality (DInt96 [UTCTime] ds) = [UTCTime] -> Int forall a. [a] -> Int forall (t :: * -> *) a. Foldable t => t a -> Int length [UTCTime] ds dictCardinality (DFloat [Float] ds) = [Float] -> Int forall a. [a] -> Int forall (t :: * -> *) a. Foldable t => t a -> Int length [Float] ds dictCardinality (DDouble [Double] ds) = [Double] -> Int forall a. [a] -> Int forall (t :: * -> *) a. Foldable t => t a -> Int length [Double] ds dictCardinality (DText [Text] ds) = [Text] -> Int forall a. [a] -> Int forall (t :: * -> *) a. Foldable t => t a -> Int length [Text] ds readDictVals :: ParquetType -> [Word8] -> Maybe Int32 -> DictVals readDictVals :: ParquetType -> [Word8] -> Maybe Int32 -> DictVals readDictVals ParquetType PBOOLEAN [Word8] bs (Just Int32 count) = [Bool] -> DictVals DBool (Int -> [Bool] -> [Bool] forall a. Int -> [a] -> [a] take (Int32 -> Int forall a b. (Integral a, Num b) => a -> b fromIntegral Int32 count) ([Bool] -> [Bool]) -> [Bool] -> [Bool] forall a b. (a -> b) -> a -> b $ [Word8] -> [Bool] readPageBool [Word8] bs) readDictVals ParquetType PINT32 [Word8] bs Maybe Int32 _ = [Int32] -> DictVals DInt32 ([Word8] -> [Int32] readPageInt32 [Word8] bs) readDictVals ParquetType PINT64 [Word8] bs Maybe Int32 _ = [Int64] -> DictVals DInt64 ([Word8] -> [Int64] readPageInt64 [Word8] bs) readDictVals ParquetType PINT96 [Word8] bs Maybe Int32 _ = [UTCTime] -> DictVals DInt96 ([Word8] -> [UTCTime] readPageInt96Times [Word8] bs) readDictVals ParquetType PFLOAT [Word8] bs Maybe Int32 _ = [Float] -> DictVals DFloat ([Word8] -> [Float] readPageFloat [Word8] bs) readDictVals ParquetType PDOUBLE [Word8] bs Maybe Int32 _ = [Double] -> DictVals DDouble ([Word8] -> [Double] readPageWord64 [Word8] bs) readDictVals ParquetType PBYTE_ARRAY [Word8] bs Maybe Int32 _ = [Text] -> DictVals DText ([Word8] -> [Text] readPageBytes [Word8] bs) readDictVals ParquetType PFIXED_LEN_BYTE_ARRAY [Word8] bs (Just Int32 len) = [Text] -> DictVals DText ([Word8] -> Int -> [Text] readPageFixedBytes [Word8] bs (Int32 -> Int forall a b. (Integral a, Num b) => a -> b fromIntegral Int32 len)) readDictVals ParquetType t [Word8] _ Maybe Int32 _ = [Char] -> DictVals forall a. HasCallStack => [Char] -> a error ([Char] -> DictVals) -> [Char] -> DictVals forall a b. (a -> b) -> a -> b $ [Char] "Unsupported dictionary type: " [Char] -> [Char] -> [Char] forall a. [a] -> [a] -> [a] ++ ParquetType -> [Char] forall a. Show a => a -> [Char] show ParquetType t readPageInt32 :: [Word8] -> [Int32] readPageInt32 :: [Word8] -> [Int32] readPageInt32 [] = [] readPageInt32 [Word8] xs = [Word8] -> Int32 littleEndianInt32 (Int -> [Word8] -> [Word8] forall a. Int -> [a] -> [a] take Int 4 [Word8] xs) Int32 -> [Int32] -> [Int32] forall a. a -> [a] -> [a] : [Word8] -> [Int32] readPageInt32 (Int -> [Word8] -> [Word8] forall a. Int -> [a] -> [a] drop Int 4 [Word8] xs) readPageWord64 :: [Word8] -> [Double] readPageWord64 :: [Word8] -> [Double] readPageWord64 [] = [] readPageWord64 [Word8] xs = Word64 -> Double castWord64ToDouble ([Word8] -> Word64 littleEndianWord64 (Int -> [Word8] -> [Word8] forall a. Int -> [a] -> [a] take Int 8 [Word8] xs)) Double -> [Double] -> [Double] forall a. a -> [a] -> [a] : [Word8] -> [Double] readPageWord64 (Int -> [Word8] -> [Word8] forall a. Int -> [a] -> [a] drop Int 8 [Word8] xs) readPageBytes :: [Word8] -> [T.Text] readPageBytes :: [Word8] -> [Text] readPageBytes [] = [] readPageBytes [Word8] xs = let lenBytes :: Int lenBytes = Int32 -> Int forall a b. (Integral a, Num b) => a -> b fromIntegral ([Word8] -> Int32 littleEndianInt32 ([Word8] -> Int32) -> [Word8] -> Int32 forall a b. (a -> b) -> a -> b $ Int -> [Word8] -> [Word8] forall a. Int -> [a] -> [a] take Int 4 [Word8] xs) totalBytesRead :: Int totalBytesRead = Int lenBytes Int -> Int -> Int forall a. Num a => a -> a -> a + Int 4 in [Char] -> Text T.pack ((Word8 -> Char) -> [Word8] -> [Char] forall a b. (a -> b) -> [a] -> [b] map (Int -> Char chr (Int -> Char) -> (Word8 -> Int) -> Word8 -> Char forall b c a. (b -> c) -> (a -> b) -> a -> c . Word8 -> Int forall a b. (Integral a, Num b) => a -> b fromIntegral) ([Word8] -> [Char]) -> [Word8] -> [Char] forall a b. (a -> b) -> a -> b $ Int -> [Word8] -> [Word8] forall a. Int -> [a] -> [a] take Int lenBytes (Int -> [Word8] -> [Word8] forall a. Int -> [a] -> [a] drop Int 4 [Word8] xs)) Text -> [Text] -> [Text] forall a. a -> [a] -> [a] : [Word8] -> [Text] readPageBytes (Int -> [Word8] -> [Word8] forall a. Int -> [a] -> [a] drop Int totalBytesRead [Word8] xs) readPageBool :: [Word8] -> [Bool] readPageBool :: [Word8] -> [Bool] readPageBool [] = [] readPageBool [Word8] bs = (Word8 -> [Bool]) -> [Word8] -> [Bool] forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b] concatMap (\Word8 b -> (Int -> Bool) -> [Int] -> [Bool] forall a b. (a -> b) -> [a] -> [b] map (\Int i -> (Word8 b Word8 -> Int -> Word8 forall a. Bits a => a -> Int -> a `shiftR` Int i) Word8 -> Word8 -> Word8 forall a. Bits a => a -> a -> a .&. Word8 1 Word8 -> Word8 -> Bool forall a. Eq a => a -> a -> Bool == Word8 1) [Int 0 .. Int 7]) [Word8] bs readPageInt64 :: [Word8] -> [Int64] readPageInt64 :: [Word8] -> [Int64] readPageInt64 [] = [] readPageInt64 [Word8] xs = Word64 -> Int64 forall a b. (Integral a, Num b) => a -> b fromIntegral ([Word8] -> Word64 littleEndianWord64 (Int -> [Word8] -> [Word8] forall a. Int -> [a] -> [a] take Int 8 [Word8] xs)) Int64 -> [Int64] -> [Int64] forall a. a -> [a] -> [a] : [Word8] -> [Int64] readPageInt64 (Int -> [Word8] -> [Word8] forall a. Int -> [a] -> [a] drop Int 8 [Word8] xs) readPageFloat :: [Word8] -> [Float] readPageFloat :: [Word8] -> [Float] readPageFloat [] = [] readPageFloat [Word8] xs = Word32 -> Float castWord32ToFloat ([Word8] -> Word32 littleEndianWord32 (Int -> [Word8] -> [Word8] forall a. Int -> [a] -> [a] take Int 4 [Word8] xs)) Float -> [Float] -> [Float] forall a. a -> [a] -> [a] : [Word8] -> [Float] readPageFloat (Int -> [Word8] -> [Word8] forall a. Int -> [a] -> [a] drop Int 4 [Word8] xs) readNInt96Times :: Int -> [Word8] -> ([UTCTime], [Word8]) readNInt96Times :: Int -> [Word8] -> ([UTCTime], [Word8]) readNInt96Times Int 0 [Word8] bs = ([], [Word8] bs) readNInt96Times Int k [Word8] bs = let timestamp96 :: [Word8] timestamp96 = Int -> [Word8] -> [Word8] forall a. Int -> [a] -> [a] take Int 12 [Word8] bs utcTime :: UTCTime utcTime = [Word8] -> UTCTime int96ToUTCTime [Word8] timestamp96 bs' :: [Word8] bs' = Int -> [Word8] -> [Word8] forall a. Int -> [a] -> [a] drop Int 12 [Word8] bs ([UTCTime] times, [Word8] rest) = Int -> [Word8] -> ([UTCTime], [Word8]) readNInt96Times (Int k Int -> Int -> Int forall a. Num a => a -> a -> a - Int 1) [Word8] bs' in (UTCTime utcTime UTCTime -> [UTCTime] -> [UTCTime] forall a. a -> [a] -> [a] : [UTCTime] times, [Word8] rest) readPageInt96Times :: [Word8] -> [UTCTime] readPageInt96Times :: [Word8] -> [UTCTime] readPageInt96Times [] = [] readPageInt96Times [Word8] bs = let ([UTCTime] times, [Word8] _) = Int -> [Word8] -> ([UTCTime], [Word8]) readNInt96Times ([Word8] -> Int forall a. [a] -> Int forall (t :: * -> *) a. Foldable t => t a -> Int length [Word8] bs Int -> Int -> Int forall a. Integral a => a -> a -> a `div` Int 12) [Word8] bs in [UTCTime] times readPageFixedBytes :: [Word8] -> Int -> [T.Text] readPageFixedBytes :: [Word8] -> Int -> [Text] readPageFixedBytes [] Int _ = [] readPageFixedBytes [Word8] xs Int len = let chunk :: [Word8] chunk = Int -> [Word8] -> [Word8] forall a. Int -> [a] -> [a] take Int len [Word8] xs text :: Text text = [Char] -> Text T.pack ((Word8 -> Char) -> [Word8] -> [Char] forall a b. (a -> b) -> [a] -> [b] map (Int -> Char chr (Int -> Char) -> (Word8 -> Int) -> Word8 -> Char forall b c a. (b -> c) -> (a -> b) -> a -> c . Word8 -> Int forall a b. (Integral a, Num b) => a -> b fromIntegral) [Word8] chunk) in Text text Text -> [Text] -> [Text] forall a. a -> [a] -> [a] : [Word8] -> Int -> [Text] readPageFixedBytes (Int -> [Word8] -> [Word8] forall a. Int -> [a] -> [a] drop Int len [Word8] xs) Int len decodeDictV1 :: Maybe DictVals -> Int -> [Int] -> Int -> [Word8] -> IO DI.Column decodeDictV1 :: Maybe DictVals -> Int -> [Int] -> Int -> [Word8] -> IO Column decodeDictV1 Maybe DictVals dictValsM Int maxDef [Int] defLvls Int nPresent [Word8] bytes = case Maybe DictVals dictValsM of Maybe DictVals Nothing -> [Char] -> IO Column forall a. HasCallStack => [Char] -> a error [Char] "Dictionary-encoded page but dictionary is missing" Just DictVals dictVals -> let ([Int] idxs, [Word8] _rest) = Int -> Int -> [Word8] -> ([Int], [Word8]) decodeDictIndicesV1 Int nPresent (DictVals -> Int dictCardinality DictVals dictVals) [Word8] bytes in do Bool -> IO () -> IO () forall (f :: * -> *). Applicative f => Bool -> f () -> f () when ([Int] -> Int forall a. [a] -> Int forall (t :: * -> *) a. Foldable t => t a -> Int length [Int] idxs Int -> Int -> Bool forall a. Eq a => a -> a -> Bool /= Int nPresent) (IO () -> IO ()) -> IO () -> IO () forall a b. (a -> b) -> a -> b $ [Char] -> IO () forall a. HasCallStack => [Char] -> a error ([Char] -> IO ()) -> [Char] -> IO () forall a b. (a -> b) -> a -> b $ [Char] "dict index count mismatch: got " [Char] -> [Char] -> [Char] forall a. [a] -> [a] -> [a] ++ Int -> [Char] forall a. Show a => a -> [Char] show ([Int] -> Int forall a. [a] -> Int forall (t :: * -> *) a. Foldable t => t a -> Int length [Int] idxs) [Char] -> [Char] -> [Char] forall a. [a] -> [a] -> [a] ++ [Char] ", expected " [Char] -> [Char] -> [Char] forall a. [a] -> [a] -> [a] ++ Int -> [Char] forall a. Show a => a -> [Char] show Int nPresent case DictVals dictVals of DBool [Bool] ds -> do let values :: [Bool] values = [[Bool] ds [Bool] -> Int -> Bool forall a. HasCallStack => [a] -> Int -> a !! Int i | Int i <- [Int] idxs] Column -> IO Column forall a. a -> IO a forall (f :: * -> *) a. Applicative f => a -> f a pure (Int -> [Int] -> [Bool] -> Column toMaybeBool Int maxDef [Int] defLvls [Bool] values) DInt32 [Int32] ds -> do let values :: [Int32] values = [[Int32] ds [Int32] -> Int -> Int32 forall a. HasCallStack => [a] -> Int -> a !! Int i | Int i <- [Int] idxs] Column -> IO Column forall a. a -> IO a forall (f :: * -> *) a. Applicative f => a -> f a pure (Int -> [Int] -> [Int32] -> Column toMaybeInt32 Int maxDef [Int] defLvls [Int32] values) DInt64 [Int64] ds -> do let values :: [Int64] values = [[Int64] ds [Int64] -> Int -> Int64 forall a. HasCallStack => [a] -> Int -> a !! Int i | Int i <- [Int] idxs] Column -> IO Column forall a. a -> IO a forall (f :: * -> *) a. Applicative f => a -> f a pure (Int -> [Int] -> [Int64] -> Column toMaybeInt64 Int maxDef [Int] defLvls [Int64] values) DInt96 [UTCTime] ds -> do let values :: [UTCTime] values = [[UTCTime] ds [UTCTime] -> Int -> UTCTime forall a. HasCallStack => [a] -> Int -> a !! Int i | Int i <- [Int] idxs] Column -> IO Column forall a. a -> IO a forall (f :: * -> *) a. Applicative f => a -> f a pure (Int -> [Int] -> [UTCTime] -> Column toMaybeUTCTime Int maxDef [Int] defLvls [UTCTime] values) DFloat [Float] ds -> do let values :: [Float] values = [[Float] ds [Float] -> Int -> Float forall a. HasCallStack => [a] -> Int -> a !! Int i | Int i <- [Int] idxs] Column -> IO Column forall a. a -> IO a forall (f :: * -> *) a. Applicative f => a -> f a pure (Int -> [Int] -> [Float] -> Column toMaybeFloat Int maxDef [Int] defLvls [Float] values) DDouble [Double] ds -> do let values :: [Double] values = [[Double] ds [Double] -> Int -> Double forall a. HasCallStack => [a] -> Int -> a !! Int i | Int i <- [Int] idxs] Column -> IO Column forall a. a -> IO a forall (f :: * -> *) a. Applicative f => a -> f a pure (Int -> [Int] -> [Double] -> Column toMaybeDouble Int maxDef [Int] defLvls [Double] values) DText [Text] ds -> do let values :: [Text] values = [[Text] ds [Text] -> Int -> Text forall a. HasCallStack => [a] -> Int -> a !! Int i | Int i <- [Int] idxs] Column -> IO Column forall a. a -> IO a forall (f :: * -> *) a. Applicative f => a -> f a pure (Int -> [Int] -> [Text] -> Column toMaybeText Int maxDef [Int] defLvls [Text] values) toMaybeInt32 :: Int -> [Int] -> [Int32] -> DI.Column toMaybeInt32 :: Int -> [Int] -> [Int32] -> Column toMaybeInt32 Int maxDef [Int] def [Int32] xs = let filled :: [Maybe Int32] filled = Int -> [Int] -> [Int32] -> [Maybe Int32] forall a. Int -> [Int] -> [a] -> [Maybe a] stitchNullable Int maxDef [Int] def [Int32] xs in if (Maybe Int32 -> Bool) -> [Maybe Int32] -> Bool forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool all Maybe Int32 -> Bool forall a. Maybe a -> Bool isJust [Maybe Int32] filled then [Int32] -> Column forall a. (Columnable a, ColumnifyRep (KindOf a) a) => [a] -> Column DI.fromList ((Maybe Int32 -> Int32) -> [Maybe Int32] -> [Int32] forall a b. (a -> b) -> [a] -> [b] map (Int32 -> Maybe Int32 -> Int32 forall a. a -> Maybe a -> a fromMaybe Int32 0) [Maybe Int32] filled) else [Maybe Int32] -> Column forall a. (Columnable a, ColumnifyRep (KindOf a) a) => [a] -> Column DI.fromList [Maybe Int32] filled toMaybeDouble :: Int -> [Int] -> [Double] -> DI.Column toMaybeDouble :: Int -> [Int] -> [Double] -> Column toMaybeDouble Int maxDef [Int] def [Double] xs = let filled :: [Maybe Double] filled = Int -> [Int] -> [Double] -> [Maybe Double] forall a. Int -> [Int] -> [a] -> [Maybe a] stitchNullable Int maxDef [Int] def [Double] xs in if (Maybe Double -> Bool) -> [Maybe Double] -> Bool forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool all Maybe Double -> Bool forall a. Maybe a -> Bool isJust [Maybe Double] filled then [Double] -> Column forall a. (Columnable a, ColumnifyRep (KindOf a) a) => [a] -> Column DI.fromList ((Maybe Double -> Double) -> [Maybe Double] -> [Double] forall a b. (a -> b) -> [a] -> [b] map (Double -> Maybe Double -> Double forall a. a -> Maybe a -> a fromMaybe Double 0) [Maybe Double] filled) else [Maybe Double] -> Column forall a. (Columnable a, ColumnifyRep (KindOf a) a) => [a] -> Column DI.fromList [Maybe Double] filled toMaybeText :: Int -> [Int] -> [T.Text] -> DI.Column toMaybeText :: Int -> [Int] -> [Text] -> Column toMaybeText Int maxDef [Int] def [Text] xs = let filled :: [Maybe Text] filled = Int -> [Int] -> [Text] -> [Maybe Text] forall a. Int -> [Int] -> [a] -> [Maybe a] stitchNullable Int maxDef [Int] def [Text] xs in if (Maybe Text -> Bool) -> [Maybe Text] -> Bool forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool all Maybe Text -> Bool forall a. Maybe a -> Bool isJust [Maybe Text] filled then [Text] -> Column forall a. (Columnable a, ColumnifyRep (KindOf a) a) => [a] -> Column DI.fromList ((Maybe Text -> Text) -> [Maybe Text] -> [Text] forall a b. (a -> b) -> [a] -> [b] map (Text -> Maybe Text -> Text forall a. a -> Maybe a -> a fromMaybe Text "") [Maybe Text] filled) else [Maybe Text] -> Column forall a. (Columnable a, ColumnifyRep (KindOf a) a) => [a] -> Column DI.fromList [Maybe Text] filled toMaybeBool :: Int -> [Int] -> [Bool] -> DI.Column toMaybeBool :: Int -> [Int] -> [Bool] -> Column toMaybeBool Int maxDef [Int] def [Bool] xs = let filled :: [Maybe Bool] filled = Int -> [Int] -> [Bool] -> [Maybe Bool] forall a. Int -> [Int] -> [a] -> [Maybe a] stitchNullable Int maxDef [Int] def [Bool] xs in if (Maybe Bool -> Bool) -> [Maybe Bool] -> Bool forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool all Maybe Bool -> Bool forall a. Maybe a -> Bool isJust [Maybe Bool] filled then [Bool] -> Column forall a. (Columnable a, ColumnifyRep (KindOf a) a) => [a] -> Column DI.fromList ((Maybe Bool -> Bool) -> [Maybe Bool] -> [Bool] forall a b. (a -> b) -> [a] -> [b] map (Bool -> Maybe Bool -> Bool forall a. a -> Maybe a -> a fromMaybe Bool False) [Maybe Bool] filled) else [Maybe Bool] -> Column forall a. (Columnable a, ColumnifyRep (KindOf a) a) => [a] -> Column DI.fromList [Maybe Bool] filled toMaybeInt64 :: Int -> [Int] -> [Int64] -> DI.Column toMaybeInt64 :: Int -> [Int] -> [Int64] -> Column toMaybeInt64 Int maxDef [Int] def [Int64] xs = let filled :: [Maybe Int64] filled = Int -> [Int] -> [Int64] -> [Maybe Int64] forall a. Int -> [Int] -> [a] -> [Maybe a] stitchNullable Int maxDef [Int] def [Int64] xs in if (Maybe Int64 -> Bool) -> [Maybe Int64] -> Bool forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool all Maybe Int64 -> Bool forall a. Maybe a -> Bool isJust [Maybe Int64] filled then [Int64] -> Column forall a. (Columnable a, ColumnifyRep (KindOf a) a) => [a] -> Column DI.fromList ((Maybe Int64 -> Int64) -> [Maybe Int64] -> [Int64] forall a b. (a -> b) -> [a] -> [b] map (Int64 -> Maybe Int64 -> Int64 forall a. a -> Maybe a -> a fromMaybe Int64 0) [Maybe Int64] filled) else [Maybe Int64] -> Column forall a. (Columnable a, ColumnifyRep (KindOf a) a) => [a] -> Column DI.fromList [Maybe Int64] filled toMaybeFloat :: Int -> [Int] -> [Float] -> DI.Column toMaybeFloat :: Int -> [Int] -> [Float] -> Column toMaybeFloat Int maxDef [Int] def [Float] xs = let filled :: [Maybe Float] filled = Int -> [Int] -> [Float] -> [Maybe Float] forall a. Int -> [Int] -> [a] -> [Maybe a] stitchNullable Int maxDef [Int] def [Float] xs in if (Maybe Float -> Bool) -> [Maybe Float] -> Bool forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool all Maybe Float -> Bool forall a. Maybe a -> Bool isJust [Maybe Float] filled then [Float] -> Column forall a. (Columnable a, ColumnifyRep (KindOf a) a) => [a] -> Column DI.fromList ((Maybe Float -> Float) -> [Maybe Float] -> [Float] forall a b. (a -> b) -> [a] -> [b] map (Float -> Maybe Float -> Float forall a. a -> Maybe a -> a fromMaybe Float 0.0) [Maybe Float] filled) else [Maybe Float] -> Column forall a. (Columnable a, ColumnifyRep (KindOf a) a) => [a] -> Column DI.fromList [Maybe Float] filled toMaybeUTCTime :: Int -> [Int] -> [UTCTime] -> DI.Column toMaybeUTCTime :: Int -> [Int] -> [UTCTime] -> Column toMaybeUTCTime Int maxDef [Int] def [UTCTime] times = let filled :: [Maybe UTCTime] filled = Int -> [Int] -> [UTCTime] -> [Maybe UTCTime] forall a. Int -> [Int] -> [a] -> [Maybe a] stitchNullable Int maxDef [Int] def [UTCTime] times defaultTime :: UTCTime defaultTime = Day -> DiffTime -> UTCTime UTCTime (Year -> Int -> Int -> Day fromGregorian Year 1970 Int 1 Int 1) (Year -> DiffTime secondsToDiffTime Year 0) in if (Maybe UTCTime -> Bool) -> [Maybe UTCTime] -> Bool forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool all Maybe UTCTime -> Bool forall a. Maybe a -> Bool isJust [Maybe UTCTime] filled then [UTCTime] -> Column forall a. (Columnable a, ColumnifyRep (KindOf a) a) => [a] -> Column DI.fromList ((Maybe UTCTime -> UTCTime) -> [Maybe UTCTime] -> [UTCTime] forall a b. (a -> b) -> [a] -> [b] map (UTCTime -> Maybe UTCTime -> UTCTime forall a. a -> Maybe a -> a fromMaybe UTCTime defaultTime) [Maybe UTCTime] filled) else [Maybe UTCTime] -> Column forall a. (Columnable a, ColumnifyRep (KindOf a) a) => [a] -> Column DI.fromList [Maybe UTCTime] filled