{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Database.ClickHouseDriver.Column
(
ClickhouseType (..),
readColumn,
writeColumn,
transpose,
Database.ClickHouseDriver.Column.putStrLn,
)
where
import Database.ClickHouseDriver.Types (ClickhouseType (..), Context (..), ServerInfo (..))
import Database.ClickHouseDriver.IO.BufferedReader
( Reader,
readBinaryInt16,
readBinaryInt32,
readBinaryInt64,
readBinaryInt8,
readBinaryStr,
readBinaryStrWithLength,
readBinaryUInt128,
readBinaryUInt16,
readBinaryUInt32,
readBinaryUInt64,
readBinaryUInt8,
)
import Database.ClickHouseDriver.IO.BufferedWriter
( Writer,
writeBinaryFixedLengthStr,
writeBinaryInt16,
writeBinaryInt32,
writeBinaryInt64,
writeBinaryInt8,
writeBinaryStr,
writeBinaryUInt128,
writeBinaryUInt16,
writeBinaryUInt32,
writeBinaryUInt64,
writeBinaryUInt8,
writeVarUInt,
)
import Control.Monad.State.Lazy (MonadIO (..))
import Data.Binary (Word64, Word8)
import Data.Bits (shift, (.&.), (.|.))
import Data.ByteString (ByteString, isPrefixOf)
import qualified Data.ByteString as BS
( drop,
filter,
intercalate,
length,
splitWith,
take,
unpack,
)
import Data.ByteString.Builder (Builder)
import Data.ByteString.Char8 (readInt)
import qualified Data.ByteString.Char8 as C8
import Data.ByteString.Unsafe
( unsafePackCString,
unsafeUseAsCStringLen,
)
import qualified Data.HashMap.Strict as Map
import Data.Hashable (Hashable (hash))
import Data.Int (Int32, Int64)
import qualified Data.List as List
import Data.Maybe (fromJust, fromMaybe)
import Data.Time
( TimeZone (..),
addDays,
diffDays,
fromGregorian,
getCurrentTimeZone,
toGregorian,
)
import Data.UUID as UUID
( fromString,
fromWords,
toString,
toWords,
)
import Data.Vector (Vector, (!))
import qualified Data.Vector as V
( cons,
drop,
foldl',
fromList,
generate,
length,
map,
mapM,
mapM_,
replicateM,
scanl',
sum,
take,
toList,
zipWith,
zipWithM_,
)
import Foreign.C (CString)
import Network.IP.Addr
( IP4 (..),
IP6 (..),
ip4FromOctets,
ip4ToOctets,
ip6FromWords,
ip6ToWords,
)
#define EQUAL 61
#define COMMA 44
#define SPACE 32
#define QUOTE 39
readColumn ::
ServerInfo ->
Int ->
ByteString ->
Reader (Vector ClickhouseType)
readColumn :: ServerInfo -> Int -> ByteString -> Reader (Vector ClickhouseType)
readColumn ServerInfo
server_info Int
n_rows ByteString
spec
| ByteString
"String" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
spec = Int
-> StateT Buffer IO ClickhouseType
-> Reader (Vector ClickhouseType)
forall (m :: * -> *) a. Monad m => Int -> m a -> m (Vector a)
V.replicateM Int
n_rows (ByteString -> ClickhouseType
CKString (ByteString -> ClickhouseType)
-> StateT Buffer IO ByteString -> StateT Buffer IO ClickhouseType
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StateT Buffer IO ByteString
readBinaryStr)
| ByteString
"Array" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
spec = ServerInfo -> Int -> ByteString -> Reader (Vector ClickhouseType)
readArray ServerInfo
server_info Int
n_rows ByteString
spec
| ByteString
"FixedString" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
spec = Int -> ByteString -> Reader (Vector ClickhouseType)
readFixed Int
n_rows ByteString
spec
| ByteString
"DateTime" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
spec = ServerInfo -> Int -> ByteString -> Reader (Vector ClickhouseType)
readDateTime ServerInfo
server_info Int
n_rows ByteString
spec
| ByteString
"Date" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
spec = Int -> Reader (Vector ClickhouseType)
readDate Int
n_rows
| ByteString
"Tuple" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
spec = ServerInfo -> Int -> ByteString -> Reader (Vector ClickhouseType)
readTuple ServerInfo
server_info Int
n_rows ByteString
spec
| ByteString
"Nullable" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
spec = ServerInfo -> Int -> ByteString -> Reader (Vector ClickhouseType)
readNullable ServerInfo
server_info Int
n_rows ByteString
spec
| ByteString
"LowCardinality" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
spec = ServerInfo -> Int -> ByteString -> Reader (Vector ClickhouseType)
readLowCardinality ServerInfo
server_info Int
n_rows ByteString
spec
| ByteString
"Decimal" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
spec = Int -> ByteString -> Reader (Vector ClickhouseType)
readDecimal Int
n_rows ByteString
spec
| ByteString
"Enum" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
spec = Int -> ByteString -> Reader (Vector ClickhouseType)
readEnum Int
n_rows ByteString
spec
| ByteString
"Int" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
spec = Int -> ByteString -> Reader (Vector ClickhouseType)
readIntColumn Int
n_rows ByteString
spec
| ByteString
"UInt" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
spec = Int -> ByteString -> Reader (Vector ClickhouseType)
readIntColumn Int
n_rows ByteString
spec
| ByteString
"IPv4" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
spec = Int -> Reader (Vector ClickhouseType)
readIPv4 Int
n_rows
| ByteString
"IPv6" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
spec = Int -> Reader (Vector ClickhouseType)
readIPv6 Int
n_rows
| ByteString
"SimpleAggregateFunction" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
spec = ServerInfo -> Int -> ByteString -> Reader (Vector ClickhouseType)
readSimpleAggregateFunction ServerInfo
server_info Int
n_rows ByteString
spec
| ByteString
"UUID" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
spec = Int -> Reader (Vector ClickhouseType)
readUUID Int
n_rows
| Bool
otherwise = [Char] -> Reader (Vector ClickhouseType)
forall a. HasCallStack => [Char] -> a
error ([Char]
"Unknown Type: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
Prelude.++ ByteString -> [Char]
C8.unpack ByteString
spec)
writeColumn ::
Context ->
ByteString ->
ByteString ->
Vector ClickhouseType ->
Writer Builder
writeColumn :: Context
-> ByteString
-> ByteString
-> Vector ClickhouseType
-> Writer Builder
writeColumn Context
ctx ByteString
col_name ByteString
cktype Vector ClickhouseType
items
| ByteString
"String" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
cktype = ByteString -> Vector ClickhouseType -> Writer Builder
writeStringColumn ByteString
col_name Vector ClickhouseType
items
| ByteString
"FixedString(" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
cktype = ByteString -> ByteString -> Vector ClickhouseType -> Writer Builder
writeFixedLengthString ByteString
col_name ByteString
cktype Vector ClickhouseType
items
| ByteString
"Int" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
cktype = ByteString -> ByteString -> Vector ClickhouseType -> Writer Builder
writeIntColumn ByteString
col_name ByteString
cktype Vector ClickhouseType
items
| ByteString
"UInt" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
cktype = ByteString -> ByteString -> Vector ClickhouseType -> Writer Builder
writeUIntColumn ByteString
col_name ByteString
cktype Vector ClickhouseType
items
| ByteString
"Nullable(" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
cktype = Context
-> ByteString
-> ByteString
-> Vector ClickhouseType
-> Writer Builder
writeNullable Context
ctx ByteString
col_name ByteString
cktype Vector ClickhouseType
items
| ByteString
"Tuple" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
cktype = Context
-> ByteString
-> ByteString
-> Vector ClickhouseType
-> Writer Builder
writeTuple Context
ctx ByteString
col_name ByteString
cktype Vector ClickhouseType
items
| ByteString
"Enum" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
cktype = ByteString -> ByteString -> Vector ClickhouseType -> Writer Builder
writeEnum ByteString
col_name ByteString
cktype Vector ClickhouseType
items
| ByteString
"Array" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
cktype = Context
-> ByteString
-> ByteString
-> Vector ClickhouseType
-> Writer Builder
writeArray Context
ctx ByteString
col_name ByteString
cktype Vector ClickhouseType
items
| ByteString
"UUID" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
cktype = ByteString -> Vector ClickhouseType -> Writer Builder
writeUUID ByteString
col_name Vector ClickhouseType
items
| ByteString
"IPv4" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
cktype = ByteString -> Vector ClickhouseType -> Writer Builder
writeIPv4 ByteString
col_name Vector ClickhouseType
items
| ByteString
"IPv6" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
cktype = ByteString -> Vector ClickhouseType -> Writer Builder
writeIPv6 ByteString
col_name Vector ClickhouseType
items
| ByteString
"Date" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
cktype = ByteString -> Vector ClickhouseType -> Writer Builder
writeDate ByteString
col_name Vector ClickhouseType
items
| ByteString
"LowCardinality" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
cktype = Context
-> ByteString
-> ByteString
-> Vector ClickhouseType
-> Writer Builder
writeLowCardinality Context
ctx ByteString
col_name ByteString
cktype Vector ClickhouseType
items
| ByteString
"DateTime" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
cktype = ByteString -> ByteString -> Vector ClickhouseType -> Writer Builder
writeDateTime ByteString
col_name ByteString
cktype Vector ClickhouseType
items
| ByteString
"Decimal" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
cktype = ByteString -> ByteString -> Vector ClickhouseType -> Writer Builder
writeDecimal ByteString
col_name ByteString
cktype Vector ClickhouseType
items
| Bool
otherwise = [Char] -> Writer Builder
forall a. HasCallStack => [Char] -> a
error ([Char]
"Unknown Type in the column: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
Prelude.++ ByteString -> [Char]
C8.unpack ByteString
col_name)
readFixed :: Int -> ByteString -> Reader (Vector ClickhouseType)
readFixed :: Int -> ByteString -> Reader (Vector ClickhouseType)
readFixed Int
n_rows ByteString
spec = do
let l :: Int
l = ByteString -> Int
BS.length ByteString
spec
let str_number :: ByteString
str_number = Int -> ByteString -> ByteString
BS.take (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
13) (Int -> ByteString -> ByteString
BS.drop Int
12 ByteString
spec)
let number :: Int
number = case ByteString -> Maybe (Int, ByteString)
readInt ByteString
str_number of
Maybe (Int, ByteString)
Nothing -> Int
0
Just (Int
x, ByteString
_) -> Int
x
Int
-> StateT Buffer IO ClickhouseType
-> Reader (Vector ClickhouseType)
forall (m :: * -> *) a. Monad m => Int -> m a -> m (Vector a)
V.replicateM Int
n_rows (Int -> StateT Buffer IO ClickhouseType
readFixedLengthString Int
number)
readFixedLengthString :: Int -> Reader ClickhouseType
readFixedLengthString :: Int -> StateT Buffer IO ClickhouseType
readFixedLengthString Int
str_len = ByteString -> ClickhouseType
CKString (ByteString -> ClickhouseType)
-> StateT Buffer IO ByteString -> StateT Buffer IO ClickhouseType
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> StateT Buffer IO ByteString
readBinaryStrWithLength Int
str_len
writeStringColumn :: ByteString -> Vector ClickhouseType -> Writer Builder
writeStringColumn :: ByteString -> Vector ClickhouseType -> Writer Builder
writeStringColumn ByteString
col_name =
(ClickhouseType -> Writer Builder)
-> Vector ClickhouseType -> Writer Builder
forall (m :: * -> *) a b. Monad m => (a -> m b) -> Vector a -> m ()
V.mapM_
( \case
CKString ByteString
s -> ByteString -> Writer Builder
forall w. MonoidMap ByteString w => ByteString -> Writer w
writeBinaryStr ByteString
s
ClickhouseType
CKNull -> Word -> Writer Builder
forall w. MonoidMap ByteString w => Word -> Writer w
writeVarUInt Word
0
ClickhouseType
_ -> [Char] -> Writer Builder
forall a. HasCallStack => [Char] -> a
error (ByteString -> [Char]
typeMismatchError ByteString
col_name)
)
writeFixedLengthString :: ByteString -> ByteString -> Vector ClickhouseType -> Writer Builder
writeFixedLengthString :: ByteString -> ByteString -> Vector ClickhouseType -> Writer Builder
writeFixedLengthString ByteString
col_name ByteString
spec Vector ClickhouseType
items = do
let l :: Int
l = ByteString -> Int
BS.length ByteString
spec
let Just (Int
len, ByteString
_) = ByteString -> Maybe (Int, ByteString)
readInt (ByteString -> Maybe (Int, ByteString))
-> ByteString -> Maybe (Int, ByteString)
forall a b. (a -> b) -> a -> b
$ Int -> ByteString -> ByteString
BS.take (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
13) (Int -> ByteString -> ByteString
BS.drop Int
12 ByteString
spec)
(ClickhouseType -> Writer Builder)
-> Vector ClickhouseType -> Writer Builder
forall (m :: * -> *) a b. Monad m => (a -> m b) -> Vector a -> m ()
V.mapM_
( \case
CKString ByteString
s -> Word -> ByteString -> Writer Builder
forall w. MonoidMap ByteString w => Word -> ByteString -> Writer w
writeBinaryFixedLengthStr (Int -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len) ByteString
s
ClickhouseType
CKNull -> () -> Vector () -> ()
forall a b. a -> b -> a
const () (Vector () -> ())
-> WriterT Builder IO (Vector ()) -> Writer Builder
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Writer Builder -> WriterT Builder IO (Vector ())
forall (m :: * -> *) a. Monad m => Int -> m a -> m (Vector a)
V.replicateM (Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len) (Word -> Writer Builder
forall w. MonoidMap ByteString w => Word -> Writer w
writeVarUInt Word
0)
ClickhouseType
x -> [Char] -> Writer Builder
forall a. HasCallStack => [Char] -> a
error (ByteString -> [Char]
typeMismatchError ByteString
col_name [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" got: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ ClickhouseType -> [Char]
forall a. Show a => a -> [Char]
show ClickhouseType
x)
)
Vector ClickhouseType
items
readIntColumn :: Int -> ByteString -> Reader (Vector ClickhouseType)
readIntColumn :: Int -> ByteString -> Reader (Vector ClickhouseType)
readIntColumn Int
n_rows ByteString
"Int8" = Int
-> StateT Buffer IO ClickhouseType
-> Reader (Vector ClickhouseType)
forall (m :: * -> *) a. Monad m => Int -> m a -> m (Vector a)
V.replicateM Int
n_rows (Int8 -> ClickhouseType
CKInt8 (Int8 -> ClickhouseType)
-> StateT Buffer IO Int8 -> StateT Buffer IO ClickhouseType
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StateT Buffer IO Int8
readBinaryInt8)
readIntColumn Int
n_rows ByteString
"Int16" = Int
-> StateT Buffer IO ClickhouseType
-> Reader (Vector ClickhouseType)
forall (m :: * -> *) a. Monad m => Int -> m a -> m (Vector a)
V.replicateM Int
n_rows (Int16 -> ClickhouseType
CKInt16 (Int16 -> ClickhouseType)
-> StateT Buffer IO Int16 -> StateT Buffer IO ClickhouseType
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StateT Buffer IO Int16
readBinaryInt16)
readIntColumn Int
n_rows ByteString
"Int32" = Int
-> StateT Buffer IO ClickhouseType
-> Reader (Vector ClickhouseType)
forall (m :: * -> *) a. Monad m => Int -> m a -> m (Vector a)
V.replicateM Int
n_rows (Int32 -> ClickhouseType
CKInt32 (Int32 -> ClickhouseType)
-> StateT Buffer IO Int32 -> StateT Buffer IO ClickhouseType
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StateT Buffer IO Int32
readBinaryInt32)
readIntColumn Int
n_rows ByteString
"Int64" = Int
-> StateT Buffer IO ClickhouseType
-> Reader (Vector ClickhouseType)
forall (m :: * -> *) a. Monad m => Int -> m a -> m (Vector a)
V.replicateM Int
n_rows (Int64 -> ClickhouseType
CKInt64 (Int64 -> ClickhouseType)
-> StateT Buffer IO Int64 -> StateT Buffer IO ClickhouseType
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StateT Buffer IO Int64
readBinaryInt64)
readIntColumn Int
n_rows ByteString
"UInt8" = Int
-> StateT Buffer IO ClickhouseType
-> Reader (Vector ClickhouseType)
forall (m :: * -> *) a. Monad m => Int -> m a -> m (Vector a)
V.replicateM Int
n_rows (Word8 -> ClickhouseType
CKUInt8 (Word8 -> ClickhouseType)
-> StateT Buffer IO Word8 -> StateT Buffer IO ClickhouseType
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StateT Buffer IO Word8
readBinaryUInt8)
readIntColumn Int
n_rows ByteString
"UInt16" = Int
-> StateT Buffer IO ClickhouseType
-> Reader (Vector ClickhouseType)
forall (m :: * -> *) a. Monad m => Int -> m a -> m (Vector a)
V.replicateM Int
n_rows (Word16 -> ClickhouseType
CKUInt16 (Word16 -> ClickhouseType)
-> StateT Buffer IO Word16 -> StateT Buffer IO ClickhouseType
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StateT Buffer IO Word16
readBinaryUInt16)
readIntColumn Int
n_rows ByteString
"UInt32" = Int
-> StateT Buffer IO ClickhouseType
-> Reader (Vector ClickhouseType)
forall (m :: * -> *) a. Monad m => Int -> m a -> m (Vector a)
V.replicateM Int
n_rows (Word32 -> ClickhouseType
CKUInt32 (Word32 -> ClickhouseType)
-> StateT Buffer IO Word32 -> StateT Buffer IO ClickhouseType
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StateT Buffer IO Word32
readBinaryUInt32)
readIntColumn Int
n_rows ByteString
"UInt64" = Int
-> StateT Buffer IO ClickhouseType
-> Reader (Vector ClickhouseType)
forall (m :: * -> *) a. Monad m => Int -> m a -> m (Vector a)
V.replicateM Int
n_rows (Word64 -> ClickhouseType
CKUInt64 (Word64 -> ClickhouseType)
-> StateT Buffer IO Word64 -> StateT Buffer IO ClickhouseType
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StateT Buffer IO Word64
readBinaryUInt64)
readIntColumn Int
_ ByteString
x = [Char] -> Reader (Vector ClickhouseType)
forall a. HasCallStack => [Char] -> a
error ([Char]
"expect an integer but got: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ ByteString -> [Char]
forall a. Show a => a -> [Char]
show ByteString
x)
writeIntColumn :: ByteString -> ByteString -> Vector ClickhouseType -> Writer Builder
writeIntColumn :: ByteString -> ByteString -> Vector ClickhouseType -> Writer Builder
writeIntColumn ByteString
col_name ByteString
spec Vector ClickhouseType
items = do
let Just (Int
indicator, ByteString
_) = ByteString -> Maybe (Int, ByteString)
readInt (ByteString -> Maybe (Int, ByteString))
-> ByteString -> Maybe (Int, ByteString)
forall a b. (a -> b) -> a -> b
$ Int -> ByteString -> ByteString
BS.drop Int
3 ByteString
spec
Int -> ByteString -> Vector ClickhouseType -> Writer Builder
writeIntColumn' Int
indicator ByteString
col_name Vector ClickhouseType
items
where
writeIntColumn' :: Int -> ByteString -> Vector ClickhouseType -> Writer Builder
writeIntColumn' :: Int -> ByteString -> Vector ClickhouseType -> Writer Builder
writeIntColumn' Int
indicator ByteString
col_name =
case Int
indicator of
Int
8 ->
(ClickhouseType -> Writer Builder)
-> Vector ClickhouseType -> Writer Builder
forall (m :: * -> *) a b. Monad m => (a -> m b) -> Vector a -> m ()
V.mapM_
( \case
CKInt8 Int8
x -> Int8 -> Writer Builder
forall w. MonoidMap ByteString w => Int8 -> Writer w
writeBinaryInt8 Int8
x
ClickhouseType
CKNull -> Int8 -> Writer Builder
forall w. MonoidMap ByteString w => Int8 -> Writer w
writeBinaryInt8 Int8
0
ClickhouseType
_ -> [Char] -> Writer Builder
forall a. HasCallStack => [Char] -> a
error (ByteString -> [Char]
typeMismatchError ByteString
col_name)
)
Int
16 ->
(ClickhouseType -> Writer Builder)
-> Vector ClickhouseType -> Writer Builder
forall (m :: * -> *) a b. Monad m => (a -> m b) -> Vector a -> m ()
V.mapM_
( \case
CKInt16 Int16
x -> Int16 -> Writer Builder
forall w. MonoidMap ByteString w => Int16 -> Writer w
writeBinaryInt16 Int16
x
ClickhouseType
CKNull -> Int16 -> Writer Builder
forall w. MonoidMap ByteString w => Int16 -> Writer w
writeBinaryInt16 Int16
0
ClickhouseType
_ -> [Char] -> Writer Builder
forall a. HasCallStack => [Char] -> a
error (ByteString -> [Char]
typeMismatchError ByteString
col_name)
)
Int
32 ->
(ClickhouseType -> Writer Builder)
-> Vector ClickhouseType -> Writer Builder
forall (m :: * -> *) a b. Monad m => (a -> m b) -> Vector a -> m ()
V.mapM_
( \case
CKInt32 Int32
x -> Int32 -> Writer Builder
forall w. MonoidMap ByteString w => Int32 -> Writer w
writeBinaryInt32 Int32
x
ClickhouseType
CKNull -> Int32 -> Writer Builder
forall w. MonoidMap ByteString w => Int32 -> Writer w
writeBinaryInt32 Int32
0
ClickhouseType
_ -> [Char] -> Writer Builder
forall a. HasCallStack => [Char] -> a
error (ByteString -> [Char]
typeMismatchError ByteString
col_name)
)
Int
64 ->
(ClickhouseType -> Writer Builder)
-> Vector ClickhouseType -> Writer Builder
forall (m :: * -> *) a b. Monad m => (a -> m b) -> Vector a -> m ()
V.mapM_
( \case
CKInt64 Int64
x -> Int64 -> Writer Builder
forall w. MonoidMap ByteString w => Int64 -> Writer w
writeBinaryInt64 Int64
x
ClickhouseType
CKNull -> Int64 -> Writer Builder
forall w. MonoidMap ByteString w => Int64 -> Writer w
writeBinaryInt64 Int64
0
ClickhouseType
_ -> [Char] -> Writer Builder
forall a. HasCallStack => [Char] -> a
error (ByteString -> [Char]
typeMismatchError ByteString
col_name)
)
writeUIntColumn :: ByteString -> ByteString -> Vector ClickhouseType -> Writer Builder
writeUIntColumn :: ByteString -> ByteString -> Vector ClickhouseType -> Writer Builder
writeUIntColumn ByteString
col_name ByteString
spec Vector ClickhouseType
items = do
let Just (Int
indicator, ByteString
_) = ByteString -> Maybe (Int, ByteString)
readInt (ByteString -> Maybe (Int, ByteString))
-> ByteString -> Maybe (Int, ByteString)
forall a b. (a -> b) -> a -> b
$ Int -> ByteString -> ByteString
BS.drop Int
4 ByteString
spec
Int -> ByteString -> Vector ClickhouseType -> Writer Builder
writeUIntColumn' Int
indicator ByteString
col_name Vector ClickhouseType
items
where
writeUIntColumn' :: Int -> ByteString -> Vector ClickhouseType -> Writer Builder
writeUIntColumn' :: Int -> ByteString -> Vector ClickhouseType -> Writer Builder
writeUIntColumn' Int
indicator ByteString
col_name =
case Int
indicator of
Int
8 ->
(ClickhouseType -> Writer Builder)
-> Vector ClickhouseType -> Writer Builder
forall (m :: * -> *) a b. Monad m => (a -> m b) -> Vector a -> m ()
V.mapM_
( \case
CKUInt8 Word8
x -> Word8 -> Writer Builder
forall w. MonoidMap ByteString w => Word8 -> Writer w
writeBinaryUInt8 Word8
x
ClickhouseType
CKNull -> Word8 -> Writer Builder
forall w. MonoidMap ByteString w => Word8 -> Writer w
writeBinaryUInt8 Word8
0
ClickhouseType
_ -> [Char] -> Writer Builder
forall a. HasCallStack => [Char] -> a
error (ByteString -> [Char]
typeMismatchError ByteString
col_name)
)
Int
16 ->
(ClickhouseType -> Writer Builder)
-> Vector ClickhouseType -> Writer Builder
forall (m :: * -> *) a b. Monad m => (a -> m b) -> Vector a -> m ()
V.mapM_
( \case
CKUInt16 Word16
x -> Int16 -> Writer Builder
forall w. MonoidMap ByteString w => Int16 -> Writer w
writeBinaryInt16 (Int16 -> Writer Builder) -> Int16 -> Writer Builder
forall a b. (a -> b) -> a -> b
$ Word16 -> Int16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
x
ClickhouseType
CKNull -> Int16 -> Writer Builder
forall w. MonoidMap ByteString w => Int16 -> Writer w
writeBinaryInt16 Int16
0
ClickhouseType
_ -> [Char] -> Writer Builder
forall a. HasCallStack => [Char] -> a
error (ByteString -> [Char]
typeMismatchError ByteString
col_name)
)
Int
32 ->
(ClickhouseType -> Writer Builder)
-> Vector ClickhouseType -> Writer Builder
forall (m :: * -> *) a b. Monad m => (a -> m b) -> Vector a -> m ()
V.mapM_
( \case
CKUInt32 Word32
x -> Int32 -> Writer Builder
forall w. MonoidMap ByteString w => Int32 -> Writer w
writeBinaryInt32 (Int32 -> Writer Builder) -> Int32 -> Writer Builder
forall a b. (a -> b) -> a -> b
$ Word32 -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
x
ClickhouseType
CKNull -> Int32 -> Writer Builder
forall w. MonoidMap ByteString w => Int32 -> Writer w
writeBinaryInt32 Int32
0
ClickhouseType
_ -> [Char] -> Writer Builder
forall a. HasCallStack => [Char] -> a
error (ByteString -> [Char]
typeMismatchError ByteString
col_name)
)
Int
64 ->
(ClickhouseType -> Writer Builder)
-> Vector ClickhouseType -> Writer Builder
forall (m :: * -> *) a b. Monad m => (a -> m b) -> Vector a -> m ()
V.mapM_
( \case
CKUInt64 Word64
x -> Int64 -> Writer Builder
forall w. MonoidMap ByteString w => Int64 -> Writer w
writeBinaryInt64 (Int64 -> Writer Builder) -> Int64 -> Writer Builder
forall a b. (a -> b) -> a -> b
$ Word64 -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
x
ClickhouseType
CKNull -> Int64 -> Writer Builder
forall w. MonoidMap ByteString w => Int64 -> Writer w
writeBinaryInt64 Int64
0
ClickhouseType
_ -> [Char] -> Writer Builder
forall a. HasCallStack => [Char] -> a
error (ByteString -> [Char]
typeMismatchError ByteString
col_name)
)
readDateTime :: ServerInfo -> Int -> ByteString -> Reader (Vector ClickhouseType)
readDateTime :: ServerInfo -> Int -> ByteString -> Reader (Vector ClickhouseType)
readDateTime ServerInfo
server_info Int
n_rows ByteString
spec = do
let (Maybe Int
scale, Maybe ByteString
spc) = ByteString -> (Maybe Int, Maybe ByteString)
readTimeSpec ByteString
spec
case Maybe ByteString
spc of
Maybe ByteString
Nothing -> ServerInfo
-> Int -> Maybe Int -> ByteString -> Reader (Vector ClickhouseType)
readDateTimeWithSpec ServerInfo
server_info Int
n_rows Maybe Int
scale ByteString
""
Just ByteString
tz_name -> ServerInfo
-> Int -> Maybe Int -> ByteString -> Reader (Vector ClickhouseType)
readDateTimeWithSpec ServerInfo
server_info Int
n_rows Maybe Int
scale ByteString
tz_name
readTimeSpec :: ByteString -> (Maybe Int, Maybe ByteString)
readTimeSpec :: ByteString -> (Maybe Int, Maybe ByteString)
readTimeSpec ByteString
spec'
| ByteString
"DateTime64" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
spec' = do
let l :: Int
l = ByteString -> Int
BS.length ByteString
spec'
let inner_specs :: ByteString
inner_specs = Int -> ByteString -> ByteString
BS.take (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
12) (Int -> ByteString -> ByteString
BS.drop Int
11 ByteString
spec')
let split :: [ByteString]
split = ByteString -> [ByteString]
getSpecs ByteString
inner_specs
case [ByteString]
split of
[] -> (Maybe Int
forall a. Maybe a
Nothing, Maybe ByteString
forall a. Maybe a
Nothing)
[ByteString
x] -> (Int -> Maybe Int
forall a. a -> Maybe a
Just (Int -> Maybe Int) -> Int -> Maybe Int
forall a b. (a -> b) -> a -> b
$ (Int, ByteString) -> Int
forall a b. (a, b) -> a
fst ((Int, ByteString) -> Int) -> (Int, ByteString) -> Int
forall a b. (a -> b) -> a -> b
$ Maybe (Int, ByteString) -> (Int, ByteString)
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe (Int, ByteString) -> (Int, ByteString))
-> Maybe (Int, ByteString) -> (Int, ByteString)
forall a b. (a -> b) -> a -> b
$ ByteString -> Maybe (Int, ByteString)
readInt ByteString
x, Maybe ByteString
forall a. Maybe a
Nothing)
[ByteString
x, ByteString
y] -> (Int -> Maybe Int
forall a. a -> Maybe a
Just (Int -> Maybe Int) -> Int -> Maybe Int
forall a b. (a -> b) -> a -> b
$ (Int, ByteString) -> Int
forall a b. (a, b) -> a
fst ((Int, ByteString) -> Int) -> (Int, ByteString) -> Int
forall a b. (a -> b) -> a -> b
$ Maybe (Int, ByteString) -> (Int, ByteString)
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe (Int, ByteString) -> (Int, ByteString))
-> Maybe (Int, ByteString) -> (Int, ByteString)
forall a b. (a -> b) -> a -> b
$ ByteString -> Maybe (Int, ByteString)
readInt ByteString
x, ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just ByteString
y)
| Bool
otherwise = do
let l :: Int
l = ByteString -> Int
BS.length ByteString
spec'
let inner_specs :: ByteString
inner_specs = Int -> ByteString -> ByteString
BS.take (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
12) (Int -> ByteString -> ByteString
BS.drop Int
10 ByteString
spec')
(Maybe Int
forall a. Maybe a
Nothing, ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just ByteString
inner_specs)
readDateTimeWithSpec :: ServerInfo -> Int -> Maybe Int -> ByteString -> Reader (Vector ClickhouseType)
readDateTimeWithSpec :: ServerInfo
-> Int -> Maybe Int -> ByteString -> Reader (Vector ClickhouseType)
readDateTimeWithSpec ServerInfo {timezone :: ServerInfo -> Maybe ByteString
timezone = Maybe ByteString
maybe_zone} Int
n_rows Maybe Int
Nothing ByteString
tz_name = do
Vector ClickhouseType
data32 <- Int -> ByteString -> Reader (Vector ClickhouseType)
readIntColumn Int
n_rows ByteString
"Int32"
let tz_to_send :: ByteString
tz_to_send =
if ByteString
tz_name ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
/= ByteString
""
then ByteString
"TZ=" ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
tz_name
else ByteString -> Maybe ByteString -> ByteString
forall a. a -> Maybe a -> a
fromMaybe ByteString
"" Maybe ByteString
maybe_zone
let toDateTimeStringM :: IO (Vector ByteString)
toDateTimeStringM =
(ClickhouseType -> IO ByteString)
-> Vector ClickhouseType -> IO (Vector ByteString)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Vector a -> m (Vector b)
V.mapM
( \(CKInt32 Int32
x) -> do
CString
c_str <-
ByteString -> (CStringLen -> IO CString) -> IO CString
forall a. ByteString -> (CStringLen -> IO a) -> IO a
unsafeUseAsCStringLen
ByteString
tz_to_send
((CString -> Int -> IO CString) -> CStringLen -> IO CString
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (Int64 -> CString -> Int -> IO CString
c_convert_time (Int32 -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
x)))
CString -> IO ByteString
unsafePackCString CString
c_str
)
Vector ClickhouseType
data32
Vector ByteString
toDateTimeString <- IO (Vector ByteString) -> StateT Buffer IO (Vector ByteString)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Vector ByteString) -> StateT Buffer IO (Vector ByteString))
-> IO (Vector ByteString) -> StateT Buffer IO (Vector ByteString)
forall a b. (a -> b) -> a -> b
$ IO (Vector ByteString)
toDateTimeStringM
Vector ClickhouseType -> Reader (Vector ClickhouseType)
forall (m :: * -> *) a. Monad m => a -> m a
return (Vector ClickhouseType -> Reader (Vector ClickhouseType))
-> Vector ClickhouseType -> Reader (Vector ClickhouseType)
forall a b. (a -> b) -> a -> b
$ (ByteString -> ClickhouseType)
-> Vector ByteString -> Vector ClickhouseType
forall a b. (a -> b) -> Vector a -> Vector b
V.map ByteString -> ClickhouseType
CKString Vector ByteString
toDateTimeString
readDateTimeWithSpec ServerInfo {timezone :: ServerInfo -> Maybe ByteString
timezone = Maybe ByteString
maybe_zone} Int
n_rows (Just Int
scl) ByteString
tz_name = do
Vector ClickhouseType
data64 <- Int -> ByteString -> Reader (Vector ClickhouseType)
readIntColumn Int
n_rows ByteString
"Int64"
let scale :: Float
scale = Float
10 Float -> Integer -> Float
forall a b. (Num a, Integral b) => a -> b -> a
^ Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
scl
let tz_to_send :: ByteString
tz_to_send =
if ByteString
tz_name ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
/= ByteString
""
then ByteString
"TZ=" ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
tz_name
else ByteString -> Maybe ByteString -> ByteString
forall a. a -> Maybe a -> a
fromMaybe ByteString
"" Maybe ByteString
maybe_zone
let toDateTimeStringM :: IO (Vector ByteString)
toDateTimeStringM =
(ClickhouseType -> IO ByteString)
-> Vector ClickhouseType -> IO (Vector ByteString)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Vector a -> m (Vector b)
V.mapM
( \(CKInt64 Int64
x) -> do
CString
c_str <-
ByteString -> (CStringLen -> IO CString) -> IO CString
forall a. ByteString -> (CStringLen -> IO a) -> IO a
unsafeUseAsCStringLen
ByteString
tz_to_send
((CString -> Int -> IO CString) -> CStringLen -> IO CString
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (Float -> CString -> Int -> IO CString
c_convert_time64 (Int64 -> Float
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
x Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
scale)))
CString -> IO ByteString
unsafePackCString CString
c_str
)
Vector ClickhouseType
data64
Vector ByteString
toDateTimeString <- IO (Vector ByteString) -> StateT Buffer IO (Vector ByteString)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Vector ByteString) -> StateT Buffer IO (Vector ByteString))
-> IO (Vector ByteString) -> StateT Buffer IO (Vector ByteString)
forall a b. (a -> b) -> a -> b
$ IO (Vector ByteString)
toDateTimeStringM
Vector ClickhouseType -> Reader (Vector ClickhouseType)
forall (m :: * -> *) a. Monad m => a -> m a
return (Vector ClickhouseType -> Reader (Vector ClickhouseType))
-> Vector ClickhouseType -> Reader (Vector ClickhouseType)
forall a b. (a -> b) -> a -> b
$ (ByteString -> ClickhouseType)
-> Vector ByteString -> Vector ClickhouseType
forall a b. (a -> b) -> Vector a -> Vector b
V.map ByteString -> ClickhouseType
CKString Vector ByteString
toDateTimeString
writeDateTime :: ByteString -> ByteString -> Vector ClickhouseType -> Writer Builder
writeDateTime :: ByteString -> ByteString -> Vector ClickhouseType -> Writer Builder
writeDateTime ByteString
col_name ByteString
spec Vector ClickhouseType
items = do
let (Maybe Int
scale', Maybe ByteString
spc) = ByteString -> (Maybe Int, Maybe ByteString)
readTimeSpec ByteString
spec
case Maybe Int
scale' of
Maybe Int
Nothing -> do
case Maybe ByteString
spc of
Maybe ByteString
Nothing -> do
TimeZone {timeZoneName :: TimeZone -> [Char]
timeZoneName = [Char]
tz'} <- IO TimeZone -> WriterT Builder IO TimeZone
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO TimeZone -> WriterT Builder IO TimeZone)
-> IO TimeZone -> WriterT Builder IO TimeZone
forall a b. (a -> b) -> a -> b
$ IO TimeZone
getCurrentTimeZone
ByteString -> Writer Builder
writeDateTimeWithSpec (ByteString -> Writer Builder) -> ByteString -> Writer Builder
forall a b. (a -> b) -> a -> b
$ [Char] -> ByteString
C8.pack [Char]
tz'
Just ByteString
spec -> ByteString -> Writer Builder
writeDateTimeWithSpec ByteString
spec
Just Int
_ -> do
Writer Builder
forall a. HasCallStack => a
undefined
where
writeDateTimeWithSpec :: ByteString -> Writer Builder
writeDateTimeWithSpec :: ByteString -> Writer Builder
writeDateTimeWithSpec ByteString
tz_name = do
(ClickhouseType -> Writer Builder)
-> Vector ClickhouseType -> Writer Builder
forall (m :: * -> *) a b. Monad m => (a -> m b) -> Vector a -> m ()
V.mapM_
( \case
(CKInt32 Int32
i32) -> do
Int32
converted <- IO Int32 -> WriterT Builder IO Int32
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Int32 -> WriterT Builder IO Int32)
-> IO Int32 -> WriterT Builder IO Int32
forall a b. (a -> b) -> a -> b
$ Int32 -> IO Int32
convert_time_from_int32 Int32
i32
Int32 -> Writer Builder
forall w. MonoidMap ByteString w => Int32 -> Writer w
writeBinaryInt32 Int32
converted
(CKString ByteString
time_str) -> do
Int32
converted <-
IO Int32 -> WriterT Builder IO Int32
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Int32 -> WriterT Builder IO Int32)
-> IO Int32 -> WriterT Builder IO Int32
forall a b. (a -> b) -> a -> b
$
ByteString -> (CStringLen -> IO Int32) -> IO Int32
forall a. ByteString -> (CStringLen -> IO a) -> IO a
unsafeUseAsCStringLen
ByteString
tz_name
( \(CString
tz, Int
l) ->
ByteString -> (CStringLen -> IO Int32) -> IO Int32
forall a. ByteString -> (CStringLen -> IO a) -> IO a
unsafeUseAsCStringLen
ByteString
time_str
(\(CString
time_str, Int
l2) -> CString -> CString -> Int -> Int -> IO Int32
c_write_time CString
time_str CString
tz Int
l Int
l2)
)
Int32 -> Writer Builder
forall w. MonoidMap ByteString w => Int32 -> Writer w
writeBinaryInt32 Int32
converted
ClickhouseType
_ -> [Char] -> Writer Builder
forall a. HasCallStack => [Char] -> a
error (ByteString -> [Char]
typeMismatchError ByteString
col_name)
)
Vector ClickhouseType
items
foreign import ccall unsafe "datetime.h convert_time" c_convert_time :: Int64 -> CString -> Int -> IO CString
foreign import ccall unsafe "datetime.h convert_time" c_convert_time64 :: Float -> CString -> Int -> IO CString
foreign import ccall unsafe "datetime.h parse_time" c_write_time :: CString -> CString -> Int -> Int -> IO Int32
foreign import ccall unsafe "datetime.h convert_time_from_int32" convert_time_from_int32 :: Int32 -> IO Int32
readLowCardinality :: ServerInfo -> Int -> ByteString -> Reader (Vector ClickhouseType)
readLowCardinality :: ServerInfo -> Int -> ByteString -> Reader (Vector ClickhouseType)
readLowCardinality ServerInfo
_ Int
0 ByteString
_ = Vector ClickhouseType -> Reader (Vector ClickhouseType)
forall (m :: * -> *) a. Monad m => a -> m a
return ([ClickhouseType] -> Vector ClickhouseType
forall a. [a] -> Vector a
V.fromList [])
readLowCardinality ServerInfo
server_info Int
n ByteString
spec = do
StateT Buffer IO Word64
readBinaryUInt64
let l :: Int
l = ByteString -> Int
BS.length ByteString
spec
let inner :: ByteString
inner = Int -> ByteString -> ByteString
BS.take (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
16) (Int -> ByteString -> ByteString
BS.drop Int
15 ByteString
spec)
Word64
serialization_type <- StateT Buffer IO Word64
readBinaryUInt64
let key_type :: Word64
key_type = Word64
serialization_type Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.&. Word64
0xf
Word64
index_size <- StateT Buffer IO Word64
readBinaryUInt64
Vector ClickhouseType
index <- ServerInfo -> Int -> ByteString -> Reader (Vector ClickhouseType)
readColumn ServerInfo
server_info (Word64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
index_size) (ByteString -> ByteString
stripNullable ByteString
inner)
StateT Buffer IO Word64
readBinaryUInt64
Vector Int
keys <- case Word64
key_type of
Word64
0 -> (Word8 -> Int) -> Vector Word8 -> Vector Int
forall a b. (a -> b) -> Vector a -> Vector b
V.map Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector Word8 -> Vector Int)
-> StateT Buffer IO (Vector Word8) -> StateT Buffer IO (Vector Int)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> StateT Buffer IO Word8 -> StateT Buffer IO (Vector Word8)
forall (m :: * -> *) a. Monad m => Int -> m a -> m (Vector a)
V.replicateM Int
n StateT Buffer IO Word8
readBinaryUInt8
Word64
1 -> (Word16 -> Int) -> Vector Word16 -> Vector Int
forall a b. (a -> b) -> Vector a -> Vector b
V.map Word16 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector Word16 -> Vector Int)
-> StateT Buffer IO (Vector Word16)
-> StateT Buffer IO (Vector Int)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> StateT Buffer IO Word16 -> StateT Buffer IO (Vector Word16)
forall (m :: * -> *) a. Monad m => Int -> m a -> m (Vector a)
V.replicateM Int
n StateT Buffer IO Word16
readBinaryUInt16
Word64
2 -> (Word32 -> Int) -> Vector Word32 -> Vector Int
forall a b. (a -> b) -> Vector a -> Vector b
V.map Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector Word32 -> Vector Int)
-> StateT Buffer IO (Vector Word32)
-> StateT Buffer IO (Vector Int)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> StateT Buffer IO Word32 -> StateT Buffer IO (Vector Word32)
forall (m :: * -> *) a. Monad m => Int -> m a -> m (Vector a)
V.replicateM Int
n StateT Buffer IO Word32
readBinaryUInt32
Word64
3 -> (Word64 -> Int) -> Vector Word64 -> Vector Int
forall a b. (a -> b) -> Vector a -> Vector b
V.map Word64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector Word64 -> Vector Int)
-> StateT Buffer IO (Vector Word64)
-> StateT Buffer IO (Vector Int)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> StateT Buffer IO Word64 -> StateT Buffer IO (Vector Word64)
forall (m :: * -> *) a. Monad m => Int -> m a -> m (Vector a)
V.replicateM Int
n StateT Buffer IO Word64
readBinaryUInt64
if ByteString
"Nullable" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
inner
then do
let nullable :: Vector ClickhouseType
nullable = (Int -> ClickhouseType) -> Vector Int -> Vector ClickhouseType
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Int
k -> if Int
k Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then ClickhouseType
CKNull else Vector ClickhouseType
index Vector ClickhouseType -> Int -> ClickhouseType
forall a. Vector a -> Int -> a
! Int
k) Vector Int
keys
Vector ClickhouseType -> Reader (Vector ClickhouseType)
forall (m :: * -> *) a. Monad m => a -> m a
return Vector ClickhouseType
nullable
else Vector ClickhouseType -> Reader (Vector ClickhouseType)
forall (m :: * -> *) a. Monad m => a -> m a
return (Vector ClickhouseType -> Reader (Vector ClickhouseType))
-> Vector ClickhouseType -> Reader (Vector ClickhouseType)
forall a b. (a -> b) -> a -> b
$ (Int -> ClickhouseType) -> Vector Int -> Vector ClickhouseType
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Vector ClickhouseType
index Vector ClickhouseType -> Int -> ClickhouseType
forall a. Vector a -> Int -> a
!) Vector Int
keys
where
stripNullable :: ByteString -> ByteString
stripNullable :: ByteString -> ByteString
stripNullable ByteString
spec
| ByteString
"Nullable" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
spec = Int -> ByteString -> ByteString
BS.take (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
10) (Int -> ByteString -> ByteString
BS.drop Int
9 ByteString
spec)
| Bool
otherwise = ByteString
spec
l :: Int
l = ByteString -> Int
BS.length ByteString
spec
writeLowCardinality :: Context -> ByteString -> ByteString -> Vector ClickhouseType -> Writer Builder
writeLowCardinality :: Context
-> ByteString
-> ByteString
-> Vector ClickhouseType
-> Writer Builder
writeLowCardinality Context
ctx ByteString
col_name ByteString
spec Vector ClickhouseType
items = do
let inner :: ByteString
inner = Int -> ByteString -> ByteString
BS.take (ByteString -> Int
BS.length ByteString
spec Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
16) (Int -> ByteString -> ByteString
BS.drop Int
15 ByteString
spec)
(Vector Int
keys, Vector Int
index) <-
if ByteString
"Nullable" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
inner
then do
let hashedItem :: Vector Int
hashedItem = Bool -> Vector ClickhouseType -> Vector Int
hashItems Bool
True Vector ClickhouseType
items
let key_by_index_element :: HashMap Int Int
key_by_index_element = (HashMap Int Int -> Int -> HashMap Int Int)
-> HashMap Int Int -> Vector Int -> HashMap Int Int
forall a b. (a -> b -> a) -> a -> Vector b -> a
V.foldl' HashMap Int Int -> Int -> HashMap Int Int
forall a. (Hashable a, Eq a) => HashMap a Int -> a -> HashMap a Int
insertKeys HashMap Int Int
forall k v. HashMap k v
Map.empty Vector Int
hashedItem
let keys :: Vector Int
keys = (Int -> Int) -> Vector Int -> Vector Int
forall a b. (a -> b) -> Vector a -> Vector b
V.map (\Int
k -> HashMap Int Int
key_by_index_element HashMap Int Int -> Int -> Int
forall k v.
(Eq k, Hashable k, HasCallStack) =>
HashMap k v -> k -> v
Map.! Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Vector Int
hashedItem
let index :: Vector Int
index = [Int] -> Vector Int
forall a. [a] -> Vector a
V.fromList ([Int] -> Vector Int) -> [Int] -> Vector Int
forall a b. (a -> b) -> a -> b
$ Int
0 Int -> [Int] -> [Int]
forall a. a -> [a] -> [a]
: (HashMap Int Int -> [Int]
forall k v. HashMap k v -> [k]
Map.keys (HashMap Int Int -> [Int]) -> HashMap Int Int -> [Int]
forall a b. (a -> b) -> a -> b
$ HashMap Int Int
key_by_index_element)
(Vector Int, Vector Int)
-> WriterT Builder IO (Vector Int, Vector Int)
forall (m :: * -> *) a. Monad m => a -> m a
return (Vector Int
keys, Vector Int
index)
else do
let hashedItem :: Vector Int
hashedItem = Bool -> Vector ClickhouseType -> Vector Int
hashItems Bool
False Vector ClickhouseType
items
let key_by_index_element :: HashMap Int Int
key_by_index_element = (HashMap Int Int -> Int -> HashMap Int Int)
-> HashMap Int Int -> Vector Int -> HashMap Int Int
forall a b. (a -> b -> a) -> a -> Vector b -> a
V.foldl' HashMap Int Int -> Int -> HashMap Int Int
forall a. (Hashable a, Eq a) => HashMap a Int -> a -> HashMap a Int
insertKeys HashMap Int Int
forall k v. HashMap k v
Map.empty Vector Int
hashedItem
let keys :: Vector Int
keys = (Int -> Int) -> Vector Int -> Vector Int
forall a b. (a -> b) -> Vector a -> Vector b
V.map (HashMap Int Int
key_by_index_element HashMap Int Int -> Int -> Int
forall k v.
(Eq k, Hashable k, HasCallStack) =>
HashMap k v -> k -> v
Map.!) Vector Int
hashedItem
let index :: Vector Int
index = [Int] -> Vector Int
forall a. [a] -> Vector a
V.fromList ([Int] -> Vector Int) -> [Int] -> Vector Int
forall a b. (a -> b) -> a -> b
$ HashMap Int Int -> [Int]
forall k v. HashMap k v -> [k]
Map.keys (HashMap Int Int -> [Int]) -> HashMap Int Int -> [Int]
forall a b. (a -> b) -> a -> b
$ HashMap Int Int
key_by_index_element
(Vector Int, Vector Int)
-> WriterT Builder IO (Vector Int, Vector Int)
forall (m :: * -> *) a. Monad m => a -> m a
return (Vector Int
keys, Vector Int
index)
if Vector Int -> Int
forall a. Vector a -> Int
V.length Vector Int
index Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0
then () -> Writer Builder
forall (m :: * -> *) a. Monad m => a -> m a
return ()
else do
let int_type :: Int64
int_type = Double -> Int64
forall a b. (RealFrac a, Integral b) => a -> b
floor (Double -> Int64) -> Double -> Int64
forall a b. (a -> b) -> a -> b
$ Double -> Double -> Double
forall a. Floating a => a -> a -> a
logBase Double
2 (Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Double) -> Int -> Double
forall a b. (a -> b) -> a -> b
$ Vector Int -> Int
forall a. Vector a -> Int
V.length Vector Int
index) Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
8 :: Int64
let has_additional_keys_bit :: Int64
has_additional_keys_bit = Int64
1 Int64 -> Int -> Int64
forall a. Bits a => a -> Int -> a
`shift` Int
9
let need_update_dictionary :: Int64
need_update_dictionary = Int64
1 Int64 -> Int -> Int64
forall a. Bits a => a -> Int -> a
`shift` Int
10
let serialization_type :: Int64
serialization_type =
Int64
has_additional_keys_bit
Int64 -> Int64 -> Int64
forall a. Bits a => a -> a -> a
.|. Int64
need_update_dictionary
Int64 -> Int64 -> Int64
forall a. Bits a => a -> a -> a
.|. Int64
int_type
let nullsInner :: ByteString
nullsInner =
if ByteString
"Nullable" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
inner
then Int -> ByteString -> ByteString
BS.take (ByteString -> Int
BS.length ByteString
inner Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
10) (Int -> ByteString -> ByteString
BS.drop Int
9 ByteString
spec)
else ByteString
inner
Word64 -> Writer Builder
forall w. MonoidMap ByteString w => Word64 -> Writer w
writeBinaryUInt64 Word64
1
Int64 -> Writer Builder
forall w. MonoidMap ByteString w => Int64 -> Writer w
writeBinaryInt64 Int64
serialization_type
Int64 -> Writer Builder
forall w. MonoidMap ByteString w => Int64 -> Writer w
writeBinaryInt64 (Int64 -> Writer Builder) -> Int64 -> Writer Builder
forall a b. (a -> b) -> a -> b
$ Int -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Int64) -> Int -> Int64
forall a b. (a -> b) -> a -> b
$ Vector Int -> Int
forall a. Vector a -> Int
V.length Vector Int
index
Context
-> ByteString
-> ByteString
-> Vector ClickhouseType
-> Writer Builder
writeColumn Context
ctx ByteString
col_name ByteString
nullsInner Vector ClickhouseType
items
Int64 -> Writer Builder
forall w. MonoidMap ByteString w => Int64 -> Writer w
writeBinaryInt64 (Int64 -> Writer Builder) -> Int64 -> Writer Builder
forall a b. (a -> b) -> a -> b
$ Int -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Int64) -> Int -> Int64
forall a b. (a -> b) -> a -> b
$ Vector ClickhouseType -> Int
forall a. Vector a -> Int
V.length Vector ClickhouseType
items
case Int64
int_type of
Int64
0 -> (Int -> Writer Builder) -> Vector Int -> Writer Builder
forall (m :: * -> *) a b. Monad m => (a -> m b) -> Vector a -> m ()
V.mapM_ (Word8 -> Writer Builder
forall w. MonoidMap ByteString w => Word8 -> Writer w
writeBinaryUInt8 (Word8 -> Writer Builder)
-> (Int -> Word8) -> Int -> Writer Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral) Vector Int
keys
Int64
1 -> (Int -> Writer Builder) -> Vector Int -> Writer Builder
forall (m :: * -> *) a b. Monad m => (a -> m b) -> Vector a -> m ()
V.mapM_ (Word16 -> Writer Builder
forall w. MonoidMap ByteString w => Word16 -> Writer w
writeBinaryUInt16 (Word16 -> Writer Builder)
-> (Int -> Word16) -> Int -> Writer Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral) Vector Int
keys
Int64
2 -> (Int -> Writer Builder) -> Vector Int -> Writer Builder
forall (m :: * -> *) a b. Monad m => (a -> m b) -> Vector a -> m ()
V.mapM_ (Word32 -> Writer Builder
forall w. MonoidMap ByteString w => Word32 -> Writer w
writeBinaryUInt32 (Word32 -> Writer Builder)
-> (Int -> Word32) -> Int -> Writer Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral) Vector Int
keys
Int64
3 -> (Int -> Writer Builder) -> Vector Int -> Writer Builder
forall (m :: * -> *) a b. Monad m => (a -> m b) -> Vector a -> m ()
V.mapM_ (Word64 -> Writer Builder
forall w. MonoidMap ByteString w => Word64 -> Writer w
writeBinaryUInt64 (Word64 -> Writer Builder)
-> (Int -> Word64) -> Int -> Writer Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral) Vector Int
keys
where
insertKeys :: (Hashable a, Eq a) => Map.HashMap a Int -> a -> Map.HashMap a Int
insertKeys :: HashMap a Int -> a -> HashMap a Int
insertKeys HashMap a Int
m a
a = if a -> HashMap a Int -> Bool
forall k a. (Eq k, Hashable k) => k -> HashMap k a -> Bool
Map.member a
a HashMap a Int
m then HashMap a Int
m else a -> Int -> HashMap a Int -> HashMap a Int
forall k v.
(Eq k, Hashable k) =>
k -> v -> HashMap k v -> HashMap k v
Map.insert a
a (HashMap a Int -> Int
forall k v. HashMap k v -> Int
Map.size HashMap a Int
m) HashMap a Int
m
hashItems :: Bool -> Vector ClickhouseType -> Vector Int
hashItems :: Bool -> Vector ClickhouseType -> Vector Int
hashItems Bool
isNullable Vector ClickhouseType
items =
(ClickhouseType -> Int) -> Vector ClickhouseType -> Vector Int
forall a b. (a -> b) -> Vector a -> Vector b
V.map
( \case
CKInt16 Int16
x -> Int16 -> Int
forall a. Hashable a => a -> Int
hash Int16
x
CKInt8 Int8
x -> Int8 -> Int
forall a. Hashable a => a -> Int
hash Int8
x
CKInt32 Int32
x -> Int32 -> Int
forall a. Hashable a => a -> Int
hash Int32
x
CKInt64 Int64
x -> Int64 -> Int
forall a. Hashable a => a -> Int
hash Int64
x
CKUInt8 Word8
x -> Word8 -> Int
forall a. Hashable a => a -> Int
hash Word8
x
CKUInt16 Word16
x -> Word16 -> Int
forall a. Hashable a => a -> Int
hash Word16
x
CKUInt32 Word32
x -> Word32 -> Int
forall a. Hashable a => a -> Int
hash Word32
x
CKUInt64 Word64
x -> Word64 -> Int
forall a. Hashable a => a -> Int
hash Word64
x
CKString ByteString
str -> ByteString -> Int
forall a. Hashable a => a -> Int
hash ByteString
str
ClickhouseType
CKNull ->
if Bool
isNullable
then Int -> Int
forall a. Hashable a => a -> Int
hash (Int
0 :: Int)
else [Char] -> Int
forall a. HasCallStack => [Char] -> a
error ([Char] -> Int) -> [Char] -> Int
forall a b. (a -> b) -> a -> b
$ ByteString -> [Char]
typeMismatchError ByteString
col_name
ClickhouseType
_ -> [Char] -> Int
forall a. HasCallStack => [Char] -> a
error ([Char] -> Int) -> [Char] -> Int
forall a b. (a -> b) -> a -> b
$ ByteString -> [Char]
typeMismatchError ByteString
col_name
)
Vector ClickhouseType
items
readNullable :: ServerInfo -> Int -> ByteString -> Reader (Vector ClickhouseType)
readNullable :: ServerInfo -> Int -> ByteString -> Reader (Vector ClickhouseType)
readNullable ServerInfo
server_info Int
n_rows ByteString
spec = do
let l :: Int
l = ByteString -> Int
BS.length ByteString
spec
let cktype :: ByteString
cktype = Int -> ByteString -> ByteString
BS.take (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
10) (Int -> ByteString -> ByteString
BS.drop Int
9 ByteString
spec)
Vector Word8
config <- Int -> StateT Buffer IO (Vector Word8)
readNullableConfig Int
n_rows
Vector ClickhouseType
items <- ServerInfo -> Int -> ByteString -> Reader (Vector ClickhouseType)
readColumn ServerInfo
server_info Int
n_rows ByteString
cktype
let result :: Vector ClickhouseType
result = Int -> (Int -> ClickhouseType) -> Vector ClickhouseType
forall a. Int -> (Int -> a) -> Vector a
V.generate Int
n_rows (\Int
i -> if Vector Word8
config Vector Word8 -> Int -> Word8
forall a. Vector a -> Int -> a
! Int
i Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
1 then ClickhouseType
CKNull else Vector ClickhouseType
items Vector ClickhouseType -> Int -> ClickhouseType
forall a. Vector a -> Int -> a
! Int
i)
Vector ClickhouseType -> Reader (Vector ClickhouseType)
forall (m :: * -> *) a. Monad m => a -> m a
return Vector ClickhouseType
result
where
readNullableConfig :: Int -> Reader (Vector Word8)
readNullableConfig :: Int -> StateT Buffer IO (Vector Word8)
readNullableConfig Int
n_rows = do
ByteString
config <- Int -> StateT Buffer IO ByteString
readBinaryStrWithLength Int
n_rows
(Vector Word8 -> StateT Buffer IO (Vector Word8)
forall (m :: * -> *) a. Monad m => a -> m a
return (Vector Word8 -> StateT Buffer IO (Vector Word8))
-> (ByteString -> Vector Word8)
-> ByteString
-> StateT Buffer IO (Vector Word8)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Word8] -> Vector Word8
forall a. [a] -> Vector a
V.fromList ([Word8] -> Vector Word8)
-> (ByteString -> [Word8]) -> ByteString -> Vector Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> [Word8]
BS.unpack) ByteString
config
writeNullable :: Context -> ByteString -> ByteString -> Vector ClickhouseType -> Writer Builder
writeNullable :: Context
-> ByteString
-> ByteString
-> Vector ClickhouseType
-> Writer Builder
writeNullable Context
ctx ByteString
col_name ByteString
spec Vector ClickhouseType
items = do
let l :: Int
l = ByteString -> Int
BS.length ByteString
spec
let inner :: ByteString
inner = Int -> ByteString -> ByteString
BS.take (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
10) (Int -> ByteString -> ByteString
BS.drop Int
9 ByteString
spec)
Vector ClickhouseType -> Writer Builder
writeNullsMap Vector ClickhouseType
items
Context
-> ByteString
-> ByteString
-> Vector ClickhouseType
-> Writer Builder
writeColumn Context
ctx ByteString
col_name ByteString
inner Vector ClickhouseType
items
where
writeNullsMap :: Vector ClickhouseType -> Writer Builder
writeNullsMap :: Vector ClickhouseType -> Writer Builder
writeNullsMap =
(ClickhouseType -> Writer Builder)
-> Vector ClickhouseType -> Writer Builder
forall (m :: * -> *) a b. Monad m => (a -> m b) -> Vector a -> m ()
V.mapM_
( \case
ClickhouseType
CKNull -> Int8 -> Writer Builder
forall w. MonoidMap ByteString w => Int8 -> Writer w
writeBinaryInt8 Int8
1
ClickhouseType
_ -> Int8 -> Writer Builder
forall w. MonoidMap ByteString w => Int8 -> Writer w
writeBinaryInt8 Int8
0
)
readArray :: ServerInfo -> Int -> ByteString -> Reader (Vector ClickhouseType)
readArray :: ServerInfo -> Int -> ByteString -> Reader (Vector ClickhouseType)
readArray ServerInfo
server_info Int
n_rows ByteString
spec = do
(ByteString
lastSpec, Vector Word64
x : [Vector Word64]
xs) <- ByteString
-> [Vector Word64] -> Reader (ByteString, [Vector Word64])
genSpecs ByteString
spec [[Word64] -> Vector Word64
forall a. [a] -> Vector a
V.fromList [Int -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n_rows]]
let numElem :: Int
numElem = Word64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> Int) -> Word64 -> Int
forall a b. (a -> b) -> a -> b
$ Vector Word64 -> Word64
forall a. Num a => Vector a -> a
V.sum Vector Word64
x
Vector ClickhouseType
elems <- ServerInfo -> Int -> ByteString -> Reader (Vector ClickhouseType)
readColumn ServerInfo
server_info Int
numElem ByteString
lastSpec
let result' :: Vector ClickhouseType
result' = (Vector ClickhouseType -> Vector Word64 -> Vector ClickhouseType)
-> Vector ClickhouseType
-> [Vector Word64]
-> Vector ClickhouseType
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl Vector ClickhouseType -> Vector Word64 -> Vector ClickhouseType
combine Vector ClickhouseType
elems (Vector Word64
x Vector Word64 -> [Vector Word64] -> [Vector Word64]
forall a. a -> [a] -> [a]
: [Vector Word64]
xs)
let CKArray Vector ClickhouseType
arr = Vector ClickhouseType
result' Vector ClickhouseType -> Int -> ClickhouseType
forall a. Vector a -> Int -> a
! Int
0
Vector ClickhouseType -> Reader (Vector ClickhouseType)
forall (m :: * -> *) a. Monad m => a -> m a
return Vector ClickhouseType
arr
where
combine :: Vector ClickhouseType -> Vector Word64 -> Vector ClickhouseType
combine :: Vector ClickhouseType -> Vector Word64 -> Vector ClickhouseType
combine Vector ClickhouseType
elems Vector Word64
config =
let intervals :: Vector (Int, Int)
intervals = Vector Int -> Vector (Int, Int)
intervalize (Word64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> Int) -> Vector Word64 -> Vector Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Vector Word64
config)
cut :: (Int, Int) -> ClickhouseType
cut (Int
a, Int
b) = Vector ClickhouseType -> ClickhouseType
CKArray (Vector ClickhouseType -> ClickhouseType)
-> Vector ClickhouseType -> ClickhouseType
forall a b. (a -> b) -> a -> b
$ Int -> Vector ClickhouseType -> Vector ClickhouseType
forall a. Int -> Vector a -> Vector a
V.take Int
b (Int -> Vector ClickhouseType -> Vector ClickhouseType
forall a. Int -> Vector a -> Vector a
V.drop Int
a Vector ClickhouseType
elems)
embed :: Vector ClickhouseType
embed = (\(Int
l, Int
r) -> (Int, Int) -> ClickhouseType
cut (Int
l, Int
r Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)) ((Int, Int) -> ClickhouseType)
-> Vector (Int, Int) -> Vector ClickhouseType
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Vector (Int, Int)
intervals
in Vector ClickhouseType
embed
intervalize :: Vector Int -> Vector (Int, Int)
intervalize :: Vector Int -> Vector (Int, Int)
intervalize Vector Int
vec = Int -> Vector (Int, Int) -> Vector (Int, Int)
forall a. Int -> Vector a -> Vector a
V.drop Int
1 (Vector (Int, Int) -> Vector (Int, Int))
-> Vector (Int, Int) -> Vector (Int, Int)
forall a b. (a -> b) -> a -> b
$ ((Int, Int) -> Int -> (Int, Int))
-> (Int, Int) -> Vector Int -> Vector (Int, Int)
forall a b. (a -> b -> a) -> a -> Vector b -> Vector a
V.scanl' (\(Int
_, Int
b) Int
v -> (Int
b Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1, Int
v Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
b)) (-Int
1, -Int
1) Vector Int
vec
readArraySpec :: Vector Word64 -> Reader (Vector Word64)
readArraySpec :: Vector Word64 -> StateT Buffer IO (Vector Word64)
readArraySpec Vector Word64
sizeArr = do
let arrSum :: Int
arrSum = (Word64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> Int)
-> (Vector Word64 -> Word64) -> Vector Word64 -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector Word64 -> Word64
forall a. Num a => Vector a -> a
V.sum) Vector Word64
sizeArr
Vector Word64
offsets <- Int -> StateT Buffer IO Word64 -> StateT Buffer IO (Vector Word64)
forall (m :: * -> *) a. Monad m => Int -> m a -> m (Vector a)
V.replicateM Int
arrSum StateT Buffer IO Word64
readBinaryUInt64
let offsets' :: Vector Word64
offsets' = Word64 -> Vector Word64 -> Vector Word64
forall a. a -> Vector a -> Vector a
V.cons Word64
0 (Int -> Vector Word64 -> Vector Word64
forall a. Int -> Vector a -> Vector a
V.take (Int
arrSum Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) Vector Word64
offsets)
let sizes :: Vector Word64
sizes = (Word64 -> Word64 -> Word64)
-> Vector Word64 -> Vector Word64 -> Vector Word64
forall a b c. (a -> b -> c) -> Vector a -> Vector b -> Vector c
V.zipWith (-) Vector Word64
offsets Vector Word64
offsets'
Vector Word64 -> StateT Buffer IO (Vector Word64)
forall (m :: * -> *) a. Monad m => a -> m a
return Vector Word64
sizes
genSpecs :: ByteString -> [Vector Word64] -> Reader (ByteString, [Vector Word64])
genSpecs :: ByteString
-> [Vector Word64] -> Reader (ByteString, [Vector Word64])
genSpecs ByteString
spec rest :: [Vector Word64]
rest@(Vector Word64
x : [Vector Word64]
_) = do
let l :: Int
l = ByteString -> Int
BS.length ByteString
spec
let cktype :: ByteString
cktype = Int -> ByteString -> ByteString
BS.take (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
7) (Int -> ByteString -> ByteString
BS.drop Int
6 ByteString
spec)
if ByteString
"Array" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
spec
then do
Vector Word64
next <- Vector Word64 -> StateT Buffer IO (Vector Word64)
readArraySpec Vector Word64
x
ByteString
-> [Vector Word64] -> Reader (ByteString, [Vector Word64])
genSpecs ByteString
cktype (Vector Word64
next Vector Word64 -> [Vector Word64] -> [Vector Word64]
forall a. a -> [a] -> [a]
: [Vector Word64]
rest)
else (ByteString, [Vector Word64])
-> Reader (ByteString, [Vector Word64])
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteString
spec, [Vector Word64]
rest)
writeArray :: Context -> ByteString -> ByteString -> Vector ClickhouseType -> Writer Builder
writeArray :: Context
-> ByteString
-> ByteString
-> Vector ClickhouseType
-> Writer Builder
writeArray Context
ctx ByteString
col_name ByteString
spec Vector ClickhouseType
items = do
let lens :: Vector Int
lens =
(Int -> ClickhouseType -> Int)
-> Int -> Vector ClickhouseType -> Vector Int
forall a b. (a -> b -> a) -> a -> Vector b -> Vector a
V.scanl'
( \Int
total ->
( \case
(CKArray Vector ClickhouseType
xs) -> Int
total Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Vector ClickhouseType -> Int
forall a. Vector a -> Int
V.length Vector ClickhouseType
xs
ClickhouseType
x ->
[Char] -> Int
forall a. HasCallStack => [Char] -> a
error ([Char] -> Int) -> [Char] -> Int
forall a b. (a -> b) -> a -> b
$
[Char]
"unexpected type in the column: "
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ ByteString -> [Char]
forall a. Show a => a -> [Char]
show ByteString
col_name
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" with data"
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ ClickhouseType -> [Char]
forall a. Show a => a -> [Char]
show ClickhouseType
x
)
)
Int
0
Vector ClickhouseType
items
(Int -> Writer Builder) -> Vector Int -> Writer Builder
forall (m :: * -> *) a b. Monad m => (a -> m b) -> Vector a -> m ()
V.mapM_ (Int64 -> Writer Builder
forall w. MonoidMap ByteString w => Int64 -> Writer w
writeBinaryInt64 (Int64 -> Writer Builder)
-> (Int -> Int64) -> Int -> Writer Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral) (Int -> Vector Int -> Vector Int
forall a. Int -> Vector a -> Vector a
V.drop Int
1 Vector Int
lens)
let innerSpec :: ByteString
innerSpec = Int -> ByteString -> ByteString
BS.take (ByteString -> Int
BS.length ByteString
spec Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
7) (Int -> ByteString -> ByteString
BS.drop Int
6 ByteString
spec)
let innerVector :: Vector (Vector ClickhouseType)
innerVector = (ClickhouseType -> Vector ClickhouseType)
-> Vector ClickhouseType -> Vector (Vector ClickhouseType)
forall a b. (a -> b) -> Vector a -> Vector b
V.map (\case CKArray Vector ClickhouseType
xs -> Vector ClickhouseType
xs) Vector ClickhouseType
items
let flattenVector :: Vector ClickhouseType
flattenVector =
Vector (Vector ClickhouseType)
innerVector Vector (Vector ClickhouseType)
-> (Vector ClickhouseType -> Vector ClickhouseType)
-> Vector ClickhouseType
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Vector ClickhouseType
v -> do Vector ClickhouseType
v
Context
-> ByteString
-> ByteString
-> Vector ClickhouseType
-> Writer Builder
writeColumn Context
ctx ByteString
col_name ByteString
innerSpec Vector ClickhouseType
flattenVector
readTuple :: ServerInfo -> Int -> ByteString -> Reader (Vector ClickhouseType)
readTuple :: ServerInfo -> Int -> ByteString -> Reader (Vector ClickhouseType)
readTuple ServerInfo
server_info Int
n_rows ByteString
spec = do
let l :: Int
l = ByteString -> Int
BS.length ByteString
spec
let innerSpecString :: ByteString
innerSpecString = Int -> ByteString -> ByteString
BS.take (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
7) (Int -> ByteString -> ByteString
BS.drop Int
6 ByteString
spec)
let arr :: Vector ByteString
arr = [ByteString] -> Vector ByteString
forall a. [a] -> Vector a
V.fromList (ByteString -> [ByteString]
getSpecs ByteString
innerSpecString)
Vector (Vector ClickhouseType)
datas <- (ByteString -> Reader (Vector ClickhouseType))
-> Vector ByteString
-> StateT Buffer IO (Vector (Vector ClickhouseType))
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Vector a -> m (Vector b)
V.mapM (ServerInfo -> Int -> ByteString -> Reader (Vector ClickhouseType)
readColumn ServerInfo
server_info Int
n_rows) Vector ByteString
arr
let transposed :: Vector (Vector ClickhouseType)
transposed = Vector (Vector ClickhouseType) -> Vector (Vector ClickhouseType)
transpose Vector (Vector ClickhouseType)
datas
Vector ClickhouseType -> Reader (Vector ClickhouseType)
forall (m :: * -> *) a. Monad m => a -> m a
return (Vector ClickhouseType -> Reader (Vector ClickhouseType))
-> Vector ClickhouseType -> Reader (Vector ClickhouseType)
forall a b. (a -> b) -> a -> b
$ Vector ClickhouseType -> ClickhouseType
CKTuple (Vector ClickhouseType -> ClickhouseType)
-> Vector (Vector ClickhouseType) -> Vector ClickhouseType
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Vector (Vector ClickhouseType)
transposed
writeTuple :: Context -> ByteString -> ByteString -> Vector ClickhouseType -> Writer Builder
writeTuple :: Context
-> ByteString
-> ByteString
-> Vector ClickhouseType
-> Writer Builder
writeTuple Context
ctx ByteString
col_name ByteString
spec Vector ClickhouseType
items = do
let inner :: ByteString
inner = Int -> ByteString -> ByteString
BS.take (ByteString -> Int
BS.length ByteString
spec Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
7) (Int -> ByteString -> ByteString
BS.drop Int
6 ByteString
spec)
let spec_arr :: Vector ByteString
spec_arr = [ByteString] -> Vector ByteString
forall a. [a] -> Vector a
V.fromList ([ByteString] -> Vector ByteString)
-> [ByteString] -> Vector ByteString
forall a b. (a -> b) -> a -> b
$ ByteString -> [ByteString]
getSpecs ByteString
inner
let transposed :: Vector (Vector ClickhouseType)
transposed =
Vector (Vector ClickhouseType) -> Vector (Vector ClickhouseType)
transpose
( (ClickhouseType -> Vector ClickhouseType)
-> Vector ClickhouseType -> Vector (Vector ClickhouseType)
forall a b. (a -> b) -> Vector a -> Vector b
V.map
( \case
CKTuple Vector ClickhouseType
tupleVec -> Vector ClickhouseType
tupleVec
ClickhouseType
other ->
[Char] -> Vector ClickhouseType
forall a. HasCallStack => [Char] -> a
error
( [Char]
"expected type: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ ClickhouseType -> [Char]
forall a. Show a => a -> [Char]
show ClickhouseType
other
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"in the column:"
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ ByteString -> [Char]
forall a. Show a => a -> [Char]
show ByteString
col_name
)
)
Vector ClickhouseType
items
)
if Vector ByteString -> Int
forall a. Vector a -> Int
V.length Vector ByteString
spec_arr Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Vector (Vector ClickhouseType) -> Int
forall a. Vector a -> Int
V.length Vector (Vector ClickhouseType)
transposed
then
[Char] -> Writer Builder
forall a. HasCallStack => [Char] -> a
error ([Char] -> Writer Builder) -> [Char] -> Writer Builder
forall a b. (a -> b) -> a -> b
$
[Char]
"length of the given array does not match, column name = "
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ ByteString -> [Char]
forall a. Show a => a -> [Char]
show ByteString
col_name
else do
(ByteString -> Vector ClickhouseType -> Writer Builder)
-> Vector ByteString
-> Vector (Vector ClickhouseType)
-> Writer Builder
forall (m :: * -> *) a b c.
Monad m =>
(a -> b -> m c) -> Vector a -> Vector b -> m ()
V.zipWithM_ (Context
-> ByteString
-> ByteString
-> Vector ClickhouseType
-> Writer Builder
writeColumn Context
ctx ByteString
col_name) Vector ByteString
spec_arr Vector (Vector ClickhouseType)
transposed
readEnum :: Int -> ByteString -> Reader (Vector ClickhouseType)
readEnum :: Int -> ByteString -> Reader (Vector ClickhouseType)
readEnum Int
n_rows ByteString
spec = do
let l :: Int
l = ByteString -> Int
BS.length ByteString
spec
innerSpec :: ByteString
innerSpec =
if ByteString
"Enum8" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
spec
then Int -> ByteString -> ByteString
BS.take (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
7) (Int -> ByteString -> ByteString
BS.drop Int
6 ByteString
spec)
else Int -> ByteString -> ByteString
BS.take (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
8) (Int -> ByteString -> ByteString
BS.drop Int
7 ByteString
spec)
pres_pecs :: [ByteString]
pres_pecs = ByteString -> [ByteString]
getSpecs ByteString
innerSpec
specs :: [(Int, ByteString)]
specs =
(\(ByteString
name, Just (Int
n, ByteString
_)) -> (Int
n, ByteString
name))
((ByteString, Maybe (Int, ByteString)) -> (Int, ByteString))
-> [(ByteString, Maybe (Int, ByteString))] -> [(Int, ByteString)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((\[ByteString
x, ByteString
y] -> (ByteString
x, ByteString -> Maybe (Int, ByteString)
readInt ByteString
y)) ([ByteString] -> (ByteString, Maybe (Int, ByteString)))
-> (ByteString -> [ByteString])
-> ByteString
-> (ByteString, Maybe (Int, ByteString))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word8 -> Bool) -> ByteString -> [ByteString]
BS.splitWith (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== EQUAL) <$> pres_pecs)
specsMap :: HashMap Int ByteString
specsMap = [(Int, ByteString)] -> HashMap Int ByteString
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
Map.fromList [(Int, ByteString)]
specs
if ByteString
"Enum8" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
spec
then do
Vector Int8
values <- Int -> StateT Buffer IO Int8 -> StateT Buffer IO (Vector Int8)
forall (m :: * -> *) a. Monad m => Int -> m a -> m (Vector a)
V.replicateM Int
n_rows StateT Buffer IO Int8
readBinaryInt8
Vector ClickhouseType -> Reader (Vector ClickhouseType)
forall (m :: * -> *) a. Monad m => a -> m a
return (Vector ClickhouseType -> Reader (Vector ClickhouseType))
-> Vector ClickhouseType -> Reader (Vector ClickhouseType)
forall a b. (a -> b) -> a -> b
$ ByteString -> ClickhouseType
CKString (ByteString -> ClickhouseType)
-> (Int8 -> ByteString) -> Int8 -> ClickhouseType
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (HashMap Int ByteString
specsMap HashMap Int ByteString -> Int -> ByteString
forall k v.
(Eq k, Hashable k, HasCallStack) =>
HashMap k v -> k -> v
Map.!) (Int -> ByteString) -> (Int8 -> Int) -> Int8 -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int8 -> ClickhouseType) -> Vector Int8 -> Vector ClickhouseType
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Vector Int8
values
else do
Vector Int16
values <- Int -> StateT Buffer IO Int16 -> StateT Buffer IO (Vector Int16)
forall (m :: * -> *) a. Monad m => Int -> m a -> m (Vector a)
V.replicateM Int
n_rows StateT Buffer IO Int16
readBinaryInt16
Vector ClickhouseType -> Reader (Vector ClickhouseType)
forall (m :: * -> *) a. Monad m => a -> m a
return (Vector ClickhouseType -> Reader (Vector ClickhouseType))
-> Vector ClickhouseType -> Reader (Vector ClickhouseType)
forall a b. (a -> b) -> a -> b
$ ByteString -> ClickhouseType
CKString (ByteString -> ClickhouseType)
-> (Int16 -> ByteString) -> Int16 -> ClickhouseType
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (HashMap Int ByteString
specsMap HashMap Int ByteString -> Int -> ByteString
forall k v.
(Eq k, Hashable k, HasCallStack) =>
HashMap k v -> k -> v
Map.!) (Int -> ByteString) -> (Int16 -> Int) -> Int16 -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int16 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int16 -> ClickhouseType) -> Vector Int16 -> Vector ClickhouseType
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Vector Int16
values
writeEnum :: ByteString -> ByteString -> Vector ClickhouseType -> Writer Builder
writeEnum :: ByteString -> ByteString -> Vector ClickhouseType -> Writer Builder
writeEnum ByteString
col_name ByteString
spec Vector ClickhouseType
items = do
let l :: Int
l = ByteString -> Int
BS.length ByteString
spec
innerSpec :: ByteString
innerSpec =
if ByteString
"Enum8" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
spec
then Int -> ByteString -> ByteString
BS.take (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
7) (Int -> ByteString -> ByteString
BS.drop Int
6 ByteString
spec)
else Int -> ByteString -> ByteString
BS.take (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
8) (Int -> ByteString -> ByteString
BS.drop Int
7 ByteString
spec)
pres_pecs :: [ByteString]
pres_pecs = ByteString -> [ByteString]
getSpecs ByteString
innerSpec
specs :: [(ByteString, Int)]
specs =
(\(ByteString
name, Just (Int
n, ByteString
_)) -> (ByteString
name, Int
n))
((ByteString, Maybe (Int, ByteString)) -> (ByteString, Int))
-> [(ByteString, Maybe (Int, ByteString))] -> [(ByteString, Int)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((\[ByteString
x, ByteString
y] -> (ByteString
x, ByteString -> Maybe (Int, ByteString)
readInt ByteString
y)) ([ByteString] -> (ByteString, Maybe (Int, ByteString)))
-> (ByteString -> [ByteString])
-> ByteString
-> (ByteString, Maybe (Int, ByteString))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word8 -> Bool) -> ByteString -> [ByteString]
BS.splitWith (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== EQUAL) . BS.filter (/= QUOTE) <$> pres_pecs)
specsMap :: HashMap ByteString Int
specsMap = [(ByteString, Int)] -> HashMap ByteString Int
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
Map.fromList [(ByteString, Int)]
specs
(ClickhouseType -> Writer Builder)
-> Vector ClickhouseType -> Writer Builder
forall (m :: * -> *) a b. Monad m => (a -> m b) -> Vector a -> m ()
V.mapM_
( \case
CKString ByteString
str ->
( if ByteString
"Enum8" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
spec
then Int8 -> Writer Builder
forall w. MonoidMap ByteString w => Int8 -> Writer w
writeBinaryInt8 (Int8 -> Writer Builder) -> Int8 -> Writer Builder
forall a b. (a -> b) -> a -> b
$ Int -> Int8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Int8) -> Int -> Int8
forall a b. (a -> b) -> a -> b
$ HashMap ByteString Int
specsMap HashMap ByteString Int -> ByteString -> Int
forall k v.
(Eq k, Hashable k, HasCallStack) =>
HashMap k v -> k -> v
Map.! ByteString
str
else Int16 -> Writer Builder
forall w. MonoidMap ByteString w => Int16 -> Writer w
writeBinaryInt16 (Int16 -> Writer Builder) -> Int16 -> Writer Builder
forall a b. (a -> b) -> a -> b
$ Int -> Int16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Int16) -> Int -> Int16
forall a b. (a -> b) -> a -> b
$ HashMap ByteString Int
specsMap HashMap ByteString Int -> ByteString -> Int
forall k v.
(Eq k, Hashable k, HasCallStack) =>
HashMap k v -> k -> v
Map.! ByteString
str
)
ClickhouseType
CKNull ->
if ByteString
"Enum8" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
spec
then Int8 -> Writer Builder
forall w. MonoidMap ByteString w => Int8 -> Writer w
writeBinaryInt8 Int8
0
else Int16 -> Writer Builder
forall w. MonoidMap ByteString w => Int16 -> Writer w
writeBinaryInt16 Int16
0
ClickhouseType
_ -> [Char] -> Writer Builder
forall a. HasCallStack => [Char] -> a
error ([Char] -> Writer Builder) -> [Char] -> Writer Builder
forall a b. (a -> b) -> a -> b
$ ByteString -> [Char]
typeMismatchError ByteString
col_name
)
Vector ClickhouseType
items
readDate :: Int -> Reader (Vector ClickhouseType)
readDate :: Int -> Reader (Vector ClickhouseType)
readDate Int
n_rows = do
let epoch_start :: Day
epoch_start = Integer -> Int -> Int -> Day
fromGregorian Integer
1970 Int
1 Int
1
Vector Word16
days <- Int -> StateT Buffer IO Word16 -> StateT Buffer IO (Vector Word16)
forall (m :: * -> *) a. Monad m => Int -> m a -> m (Vector a)
V.replicateM Int
n_rows StateT Buffer IO Word16
readBinaryUInt16
let dates :: Vector Day
dates = (Word16 -> Day) -> Vector Word16 -> Vector Day
forall a b. (a -> b) -> Vector a -> Vector b
V.map (\Word16
x -> Integer -> Day -> Day
addDays (Word16 -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
x) Day
epoch_start) Vector Word16
days
toTriple :: Vector (Integer, Int, Int)
toTriple = (Day -> (Integer, Int, Int))
-> Vector Day -> Vector (Integer, Int, Int)
forall a b. (a -> b) -> Vector a -> Vector b
V.map Day -> (Integer, Int, Int)
toGregorian Vector Day
dates
toCK :: Vector ClickhouseType
toCK = ((Integer, Int, Int) -> ClickhouseType)
-> Vector (Integer, Int, Int) -> Vector ClickhouseType
forall a b. (a -> b) -> Vector a -> Vector b
V.map (\(Integer
y, Int
m, Int
d) -> Integer -> Int -> Int -> ClickhouseType
CKDate Integer
y Int
m Int
d) Vector (Integer, Int, Int)
toTriple
Vector ClickhouseType -> Reader (Vector ClickhouseType)
forall (m :: * -> *) a. Monad m => a -> m a
return Vector ClickhouseType
toCK
writeDate :: ByteString -> Vector ClickhouseType -> Writer Builder
writeDate :: ByteString -> Vector ClickhouseType -> Writer Builder
writeDate ByteString
col_name Vector ClickhouseType
items = do
let epoch_start :: Day
epoch_start = Integer -> Int -> Int -> Day
fromGregorian Integer
1970 Int
1 Int
1
let serialize :: Vector Integer
serialize =
(ClickhouseType -> Integer)
-> Vector ClickhouseType -> Vector Integer
forall a b. (a -> b) -> Vector a -> Vector b
V.map
( \case
CKDate Integer
y Int
m Int
d -> Day -> Day -> Integer
diffDays (Integer -> Int -> Int -> Day
fromGregorian Integer
y Int
m Int
d) Day
epoch_start
ClickhouseType
_ ->
[Char] -> Integer
forall a. HasCallStack => [Char] -> a
error ([Char] -> Integer) -> [Char] -> Integer
forall a b. (a -> b) -> a -> b
$
[Char]
"unexpected type in the column: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ ByteString -> [Char]
forall a. Show a => a -> [Char]
show ByteString
col_name
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" whose type should be Date"
)
Vector ClickhouseType
items
(Integer -> Writer Builder) -> Vector Integer -> Writer Builder
forall (m :: * -> *) a b. Monad m => (a -> m b) -> Vector a -> m ()
V.mapM_ (Int16 -> Writer Builder
forall w. MonoidMap ByteString w => Int16 -> Writer w
writeBinaryInt16 (Int16 -> Writer Builder)
-> (Integer -> Int16) -> Integer -> Writer Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Int16
forall a b. (Integral a, Num b) => a -> b
fromIntegral) Vector Integer
serialize
readDecimal :: Int -> ByteString -> Reader (Vector ClickhouseType)
readDecimal :: Int -> ByteString -> Reader (Vector ClickhouseType)
readDecimal Int
n_rows ByteString
spec = do
let l :: Int
l = ByteString -> Int
BS.length ByteString
spec
let inner_spec :: [ByteString]
inner_spec = ByteString -> [ByteString]
getSpecs (ByteString -> [ByteString]) -> ByteString -> [ByteString]
forall a b. (a -> b) -> a -> b
$ Int -> ByteString -> ByteString
BS.take (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
9) (Int -> ByteString -> ByteString
BS.drop Int
8 ByteString
spec)
let (Int -> Reader (Vector ClickhouseType)
specific, Just (Int
scale, ByteString
_)) = case [ByteString]
inner_spec of
[] -> [Char]
-> (Int -> Reader (Vector ClickhouseType), Maybe (Int, ByteString))
forall a. HasCallStack => [Char] -> a
error [Char]
"No spec"
[ByteString
scale'] ->
if ByteString
"Decimal32" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
spec
then (Int -> Reader (Vector ClickhouseType)
readDecimal32, ByteString -> Maybe (Int, ByteString)
readInt ByteString
scale')
else
if ByteString
"Decimal64" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
spec
then (Int -> Reader (Vector ClickhouseType)
readDecimal64, ByteString -> Maybe (Int, ByteString)
readInt ByteString
scale')
else (Int -> Reader (Vector ClickhouseType)
readDecimal128, ByteString -> Maybe (Int, ByteString)
readInt ByteString
scale')
[ByteString
precision', ByteString
scale'] -> do
let Just (Int
precision, ByteString
_) = ByteString -> Maybe (Int, ByteString)
readInt ByteString
precision'
if Int
precision Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
9 Bool -> Bool -> Bool
|| ByteString
"Decimal32" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
spec
then (Int -> Reader (Vector ClickhouseType)
readDecimal32, ByteString -> Maybe (Int, ByteString)
readInt ByteString
scale')
else
if Int
precision Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
18 Bool -> Bool -> Bool
|| ByteString
"Decimal64" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
spec
then (Int -> Reader (Vector ClickhouseType)
readDecimal64, ByteString -> Maybe (Int, ByteString)
readInt ByteString
scale')
else (Int -> Reader (Vector ClickhouseType)
readDecimal128, ByteString -> Maybe (Int, ByteString)
readInt ByteString
scale')
Vector ClickhouseType
raw <- Int -> Reader (Vector ClickhouseType)
specific Int
n_rows
let final :: Vector ClickhouseType
final = (ClickhouseType -> ClickhouseType)
-> Vector ClickhouseType -> Vector ClickhouseType
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int -> ClickhouseType -> ClickhouseType
trans Int
scale) Vector ClickhouseType
raw
Vector ClickhouseType -> Reader (Vector ClickhouseType)
forall (m :: * -> *) a. Monad m => a -> m a
return Vector ClickhouseType
final
where
readDecimal32 :: Int -> Reader (Vector ClickhouseType)
readDecimal32 :: Int -> Reader (Vector ClickhouseType)
readDecimal32 Int
n_rows = Int -> ByteString -> Reader (Vector ClickhouseType)
readIntColumn Int
n_rows ByteString
"Int32"
readDecimal64 :: Int -> Reader (Vector ClickhouseType)
readDecimal64 :: Int -> Reader (Vector ClickhouseType)
readDecimal64 Int
n_rows = Int -> ByteString -> Reader (Vector ClickhouseType)
readIntColumn Int
n_rows ByteString
"Int64"
readDecimal128 :: Int -> Reader (Vector ClickhouseType)
readDecimal128 :: Int -> Reader (Vector ClickhouseType)
readDecimal128 Int
n_rows =
Int
-> StateT Buffer IO ClickhouseType
-> Reader (Vector ClickhouseType)
forall (m :: * -> *) a. Monad m => Int -> m a -> m (Vector a)
V.replicateM Int
n_rows (StateT Buffer IO ClickhouseType -> Reader (Vector ClickhouseType))
-> StateT Buffer IO ClickhouseType
-> Reader (Vector ClickhouseType)
forall a b. (a -> b) -> a -> b
$ do
Word64
lo <- StateT Buffer IO Word64
readBinaryUInt64
Word64
hi <- StateT Buffer IO Word64
readBinaryUInt64
ClickhouseType -> StateT Buffer IO ClickhouseType
forall (m :: * -> *) a. Monad m => a -> m a
return (ClickhouseType -> StateT Buffer IO ClickhouseType)
-> ClickhouseType -> StateT Buffer IO ClickhouseType
forall a b. (a -> b) -> a -> b
$ Word64 -> Word64 -> ClickhouseType
CKUInt128 Word64
lo Word64
hi
trans :: Int -> ClickhouseType -> ClickhouseType
trans :: Int -> ClickhouseType -> ClickhouseType
trans Int
scale (CKInt32 Int32
x) = Float -> ClickhouseType
CKDecimal32 (Int32 -> Float
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
x Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Integer -> Float
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
10 Integer -> Int -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ Int
scale))
trans Int
scale (CKInt64 Int64
x) = Double -> ClickhouseType
CKDecimal64 (Int64 -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
x Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Integer -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
10 Integer -> Int -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ Int
scale))
trans Int
scale (CKUInt128 Word64
lo Word64
hi) = Double -> ClickhouseType
CKDecimal128 (Word64 -> Word64 -> Int -> Double
word128_division Word64
hi Word64
lo Int
scale)
writeDecimal :: ByteString -> ByteString -> Vector ClickhouseType -> Writer Builder
writeDecimal :: ByteString -> ByteString -> Vector ClickhouseType -> Writer Builder
writeDecimal ByteString
col_name ByteString
spec Vector ClickhouseType
items = do
let l :: Int
l = ByteString -> Int
BS.length ByteString
spec
let inner_specs :: [ByteString]
inner_specs = ByteString -> [ByteString]
getSpecs (ByteString -> [ByteString]) -> ByteString -> [ByteString]
forall a b. (a -> b) -> a -> b
$ Int -> ByteString -> ByteString
BS.take (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
9) (Int -> ByteString -> ByteString
BS.drop Int
8 ByteString
spec)
let (Int -> Vector ClickhouseType -> Writer Builder
specific, Just (Int
pre_scale, ByteString
_)) = case [ByteString]
inner_specs of
[] -> [Char]
-> (Int -> Vector ClickhouseType -> Writer Builder,
Maybe (Int, ByteString))
forall a. HasCallStack => [Char] -> a
error [Char]
"No spec"
[ByteString
scale'] ->
if ByteString
"Decimal32" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
spec
then (Int -> Vector ClickhouseType -> Writer Builder
writeDecimal32, ByteString -> Maybe (Int, ByteString)
readInt ByteString
scale')
else
if ByteString
"Decimal64" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
spec
then (Int -> Vector ClickhouseType -> Writer Builder
writeDecimal64, ByteString -> Maybe (Int, ByteString)
readInt ByteString
scale')
else (Int -> Vector ClickhouseType -> Writer Builder
writeDecimal128, ByteString -> Maybe (Int, ByteString)
readInt ByteString
scale')
[ByteString
precision', ByteString
scale'] -> do
let Just (Int
precision, ByteString
_) = ByteString -> Maybe (Int, ByteString)
readInt ByteString
precision'
if Int
precision Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
9 Bool -> Bool -> Bool
|| ByteString
"Decimal32" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
spec
then (Int -> Vector ClickhouseType -> Writer Builder
writeDecimal32, ByteString -> Maybe (Int, ByteString)
readInt ByteString
scale')
else
if Int
precision Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
18 Bool -> Bool -> Bool
|| ByteString
"Decimal64" ByteString -> ByteString -> Bool
`isPrefixOf` ByteString
spec
then (Int -> Vector ClickhouseType -> Writer Builder
writeDecimal64, ByteString -> Maybe (Int, ByteString)
readInt ByteString
scale')
else (Int -> Vector ClickhouseType -> Writer Builder
writeDecimal128, ByteString -> Maybe (Int, ByteString)
readInt ByteString
scale')
let scale :: Int
scale = Int
10 Int -> Int -> Int
forall a b. (Num a, Integral b) => a -> b -> a
^ Int
pre_scale
Int -> Vector ClickhouseType -> Writer Builder
specific Int
scale Vector ClickhouseType
items
where
writeDecimal32 :: Int -> Vector ClickhouseType -> Writer Builder
writeDecimal32 :: Int -> Vector ClickhouseType -> Writer Builder
writeDecimal32 Int
scale Vector ClickhouseType
vec =
(ClickhouseType -> Writer Builder)
-> Vector ClickhouseType -> Writer Builder
forall (m :: * -> *) a b. Monad m => (a -> m b) -> Vector a -> m ()
V.mapM_
( \case
CKDecimal32 Float
f32 -> Int32 -> Writer Builder
forall w. MonoidMap ByteString w => Int32 -> Writer w
writeBinaryInt32 (Int32 -> Writer Builder) -> Int32 -> Writer Builder
forall a b. (a -> b) -> a -> b
$ Integer -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer -> Int32) -> Integer -> Int32
forall a b. (a -> b) -> a -> b
$ Float -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
floor (Float -> Integer) -> Float -> Integer
forall a b. (a -> b) -> a -> b
$ (Float
f32 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Int -> Float
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
scale)
ClickhouseType
_ -> [Char] -> Writer Builder
forall a. HasCallStack => [Char] -> a
error ([Char] -> Writer Builder) -> [Char] -> Writer Builder
forall a b. (a -> b) -> a -> b
$ ByteString -> [Char]
typeMismatchError ByteString
col_name
)
Vector ClickhouseType
vec
writeDecimal64 :: Int -> Vector ClickhouseType -> Writer Builder
writeDecimal64 :: Int -> Vector ClickhouseType -> Writer Builder
writeDecimal64 Int
scale Vector ClickhouseType
vec =
(ClickhouseType -> Writer Builder)
-> Vector ClickhouseType -> Writer Builder
forall (m :: * -> *) a b. Monad m => (a -> m b) -> Vector a -> m ()
V.mapM_
( \case
CKDecimal64 Double
f64 -> Int32 -> Writer Builder
forall w. MonoidMap ByteString w => Int32 -> Writer w
writeBinaryInt32 (Int32 -> Writer Builder) -> Int32 -> Writer Builder
forall a b. (a -> b) -> a -> b
$ Integer -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer -> Int32) -> Integer -> Int32
forall a b. (a -> b) -> a -> b
$ Double -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
floor (Double -> Integer) -> Double -> Integer
forall a b. (a -> b) -> a -> b
$ (Double
f64 Double -> Double -> Double
forall a. Num a => a -> a -> a
* Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
scale)
ClickhouseType
_ -> [Char] -> Writer Builder
forall a. HasCallStack => [Char] -> a
error ([Char] -> Writer Builder) -> [Char] -> Writer Builder
forall a b. (a -> b) -> a -> b
$ ByteString -> [Char]
typeMismatchError ByteString
col_name
)
Vector ClickhouseType
vec
writeDecimal128 :: Int -> Vector ClickhouseType -> Writer Builder
writeDecimal128 :: Int -> Vector ClickhouseType -> Writer Builder
writeDecimal128 Int
scale Vector ClickhouseType
items = do
(ClickhouseType -> Writer Builder)
-> Vector ClickhouseType -> Writer Builder
forall (m :: * -> *) a b. Monad m => (a -> m b) -> Vector a -> m ()
V.mapM_
( \case
CKDecimal128 Double
x -> do
if Double
x Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
>= Double
0
then do
Word64 -> Writer Builder
forall w. MonoidMap ByteString w => Word64 -> Writer w
writeBinaryUInt64 (Word64 -> Writer Builder) -> Word64 -> Writer Builder
forall a b. (a -> b) -> a -> b
$ Double -> Int -> Word64
low_bits_128 Double
x Int
scale
Word64 -> Writer Builder
forall w. MonoidMap ByteString w => Word64 -> Writer w
writeBinaryUInt64 (Word64 -> Writer Builder) -> Word64 -> Writer Builder
forall a b. (a -> b) -> a -> b
$ Double -> Int -> Word64
hi_bits_128 Double
x Int
scale
else do
Word64 -> Writer Builder
forall w. MonoidMap ByteString w => Word64 -> Writer w
writeBinaryUInt64 (Word64 -> Writer Builder) -> Word64 -> Writer Builder
forall a b. (a -> b) -> a -> b
$ Double -> Int -> Word64
low_bits_negative_128 (- Double
x) Int
scale
Word64 -> Writer Builder
forall w. MonoidMap ByteString w => Word64 -> Writer w
writeBinaryUInt64 (Word64 -> Writer Builder) -> Word64 -> Writer Builder
forall a b. (a -> b) -> a -> b
$ Double -> Int -> Word64
hi_bits_negative_128 (- Double
x) Int
scale
)
Vector ClickhouseType
items
foreign import ccall unsafe "bigint.h word128_division" word128_division :: Word64 -> Word64 -> Int -> Double
foreign import ccall unsafe "bigint.h low_bits_128" low_bits_128 :: Double -> Int -> Word64
foreign import ccall unsafe "bigint.h hi_bits_128" hi_bits_128 :: Double -> Int -> Word64
foreign import ccall unsafe "bigint.h low_bits_negative_128" low_bits_negative_128 :: Double -> Int -> Word64
foreign import ccall unsafe "bigint.h hi_bits_negative_128" hi_bits_negative_128 :: Double -> Int -> Word64
readIPv4 :: Int -> Reader (Vector ClickhouseType)
readIPv4 :: Int -> Reader (Vector ClickhouseType)
readIPv4 Int
n_rows = Int
-> StateT Buffer IO ClickhouseType
-> Reader (Vector ClickhouseType)
forall (m :: * -> *) a. Monad m => Int -> m a -> m (Vector a)
V.replicateM Int
n_rows ((Word8, Word8, Word8, Word8) -> ClickhouseType
CKIPv4 ((Word8, Word8, Word8, Word8) -> ClickhouseType)
-> (Word32 -> (Word8, Word8, Word8, Word8))
-> Word32
-> ClickhouseType
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IP4 -> (Word8, Word8, Word8, Word8)
ip4ToOctets (IP4 -> (Word8, Word8, Word8, Word8))
-> (Word32 -> IP4) -> Word32 -> (Word8, Word8, Word8, Word8)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word32 -> IP4
IP4 (Word32 -> ClickhouseType)
-> StateT Buffer IO Word32 -> StateT Buffer IO ClickhouseType
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StateT Buffer IO Word32
readBinaryUInt32)
readIPv6 :: Int -> Reader (Vector ClickhouseType)
readIPv6 :: Int -> Reader (Vector ClickhouseType)
readIPv6 Int
n_rows = Int
-> StateT Buffer IO ClickhouseType
-> Reader (Vector ClickhouseType)
forall (m :: * -> *) a. Monad m => Int -> m a -> m (Vector a)
V.replicateM Int
n_rows ((Word16, Word16, Word16, Word16, Word16, Word16, Word16, Word16)
-> ClickhouseType
CKIPv6 ((Word16, Word16, Word16, Word16, Word16, Word16, Word16, Word16)
-> ClickhouseType)
-> (Word128
-> (Word16, Word16, Word16, Word16, Word16, Word16, Word16,
Word16))
-> Word128
-> ClickhouseType
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IP6
-> (Word16, Word16, Word16, Word16, Word16, Word16, Word16, Word16)
ip6ToWords (IP6
-> (Word16, Word16, Word16, Word16, Word16, Word16, Word16,
Word16))
-> (Word128 -> IP6)
-> Word128
-> (Word16, Word16, Word16, Word16, Word16, Word16, Word16, Word16)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word128 -> IP6
IP6 (Word128 -> ClickhouseType)
-> StateT Buffer IO Word128 -> StateT Buffer IO ClickhouseType
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StateT Buffer IO Word128
readBinaryUInt128)
writeIPv4 :: ByteString -> Vector ClickhouseType -> Writer Builder
writeIPv4 :: ByteString -> Vector ClickhouseType -> Writer Builder
writeIPv4 ByteString
col_name =
(ClickhouseType -> Writer Builder)
-> Vector ClickhouseType -> Writer Builder
forall (m :: * -> *) a b. Monad m => (a -> m b) -> Vector a -> m ()
V.mapM_
( \case
CKIPv4 (Word8
w1, Word8
w2, Word8
w3, Word8
w4) ->
Word32 -> Writer Builder
forall w. MonoidMap ByteString w => Word32 -> Writer w
writeBinaryUInt32 (Word32 -> Writer Builder) -> Word32 -> Writer Builder
forall a b. (a -> b) -> a -> b
$
IP4 -> Word32
unIP4 (IP4 -> Word32) -> IP4 -> Word32
forall a b. (a -> b) -> a -> b
$
Word8 -> Word8 -> Word8 -> Word8 -> IP4
ip4FromOctets Word8
w1 Word8
w2 Word8
w3 Word8
w4
ClickhouseType
CKNull -> Int32 -> Writer Builder
forall w. MonoidMap ByteString w => Int32 -> Writer w
writeBinaryInt32 Int32
0
ClickhouseType
_ -> [Char] -> Writer Builder
forall a. HasCallStack => [Char] -> a
error ([Char] -> Writer Builder) -> [Char] -> Writer Builder
forall a b. (a -> b) -> a -> b
$ ByteString -> [Char]
typeMismatchError ByteString
col_name
)
writeIPv6 :: ByteString -> Vector ClickhouseType -> Writer Builder
writeIPv6 :: ByteString -> Vector ClickhouseType -> Writer Builder
writeIPv6 ByteString
col_name =
(ClickhouseType -> Writer Builder)
-> Vector ClickhouseType -> Writer Builder
forall (m :: * -> *) a b. Monad m => (a -> m b) -> Vector a -> m ()
V.mapM_
( \case
CKIPv6 (Word16
w1, Word16
w2, Word16
w3, Word16
w4, Word16
w5, Word16
w6, Word16
w7, Word16
w8) ->
Word128 -> Writer Builder
forall w. MonoidMap ByteString w => Word128 -> Writer w
writeBinaryUInt128 (Word128 -> Writer Builder) -> Word128 -> Writer Builder
forall a b. (a -> b) -> a -> b
$
IP6 -> Word128
unIP6 (IP6 -> Word128) -> IP6 -> Word128
forall a b. (a -> b) -> a -> b
$
Word16
-> Word16
-> Word16
-> Word16
-> Word16
-> Word16
-> Word16
-> Word16
-> IP6
ip6FromWords Word16
w1 Word16
w2 Word16
w3 Word16
w4 Word16
w5 Word16
w6 Word16
w7 Word16
w8
ClickhouseType
CKNull -> Word64 -> Writer Builder
forall w. MonoidMap ByteString w => Word64 -> Writer w
writeBinaryUInt64 Word64
0
ClickhouseType
_ -> [Char] -> Writer Builder
forall a. HasCallStack => [Char] -> a
error ([Char] -> Writer Builder) -> [Char] -> Writer Builder
forall a b. (a -> b) -> a -> b
$ ByteString -> [Char]
typeMismatchError ByteString
col_name
)
readSimpleAggregateFunction :: ServerInfo -> Int -> ByteString -> Reader (Vector ClickhouseType)
readSimpleAggregateFunction :: ServerInfo -> Int -> ByteString -> Reader (Vector ClickhouseType)
readSimpleAggregateFunction ServerInfo
server_info Int
n_rows ByteString
spec = do
let l :: Int
l = ByteString -> Int
BS.length ByteString
spec
let [ByteString
func, ByteString
cktype] = ByteString -> [ByteString]
getSpecs (ByteString -> [ByteString]) -> ByteString -> [ByteString]
forall a b. (a -> b) -> a -> b
$ Int -> ByteString -> ByteString
BS.take (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
25) (Int -> ByteString -> ByteString
BS.drop Int
24 ByteString
spec)
ServerInfo -> Int -> ByteString -> Reader (Vector ClickhouseType)
readColumn ServerInfo
server_info Int
n_rows ByteString
cktype
readUUID :: Int -> Reader (Vector ClickhouseType)
readUUID :: Int -> Reader (Vector ClickhouseType)
readUUID Int
n_rows = do
Int
-> StateT Buffer IO ClickhouseType
-> Reader (Vector ClickhouseType)
forall (m :: * -> *) a. Monad m => Int -> m a -> m (Vector a)
V.replicateM Int
n_rows (StateT Buffer IO ClickhouseType -> Reader (Vector ClickhouseType))
-> StateT Buffer IO ClickhouseType
-> Reader (Vector ClickhouseType)
forall a b. (a -> b) -> a -> b
$ do
Word32
w2 <- StateT Buffer IO Word32
readBinaryUInt32
Word32
w1 <- StateT Buffer IO Word32
readBinaryUInt32
Word32
w3 <- StateT Buffer IO Word32
readBinaryUInt32
Word32
w4 <- StateT Buffer IO Word32
readBinaryUInt32
ClickhouseType -> StateT Buffer IO ClickhouseType
forall (m :: * -> *) a. Monad m => a -> m a
return (ClickhouseType -> StateT Buffer IO ClickhouseType)
-> ClickhouseType -> StateT Buffer IO ClickhouseType
forall a b. (a -> b) -> a -> b
$
ByteString -> ClickhouseType
CKString (ByteString -> ClickhouseType) -> ByteString -> ClickhouseType
forall a b. (a -> b) -> a -> b
$
[Char] -> ByteString
C8.pack ([Char] -> ByteString) -> [Char] -> ByteString
forall a b. (a -> b) -> a -> b
$
UUID -> [Char]
UUID.toString (UUID -> [Char]) -> UUID -> [Char]
forall a b. (a -> b) -> a -> b
$ Word32 -> Word32 -> Word32 -> Word32 -> UUID
UUID.fromWords Word32
w1 Word32
w2 Word32
w3 Word32
w4
writeUUID :: ByteString -> Vector ClickhouseType -> Writer Builder
writeUUID :: ByteString -> Vector ClickhouseType -> Writer Builder
writeUUID ByteString
col_name =
(ClickhouseType -> Writer Builder)
-> Vector ClickhouseType -> Writer Builder
forall (m :: * -> *) a b. Monad m => (a -> m b) -> Vector a -> m ()
V.mapM_
( \case
CKString ByteString
uuid_str -> do
case [Char] -> Maybe UUID
UUID.fromString ([Char] -> Maybe UUID) -> [Char] -> Maybe UUID
forall a b. (a -> b) -> a -> b
$ ByteString -> [Char]
C8.unpack ByteString
uuid_str of
Maybe UUID
Nothing ->
[Char] -> Writer Builder
forall a. HasCallStack => [Char] -> a
error ([Char] -> Writer Builder) -> [Char] -> Writer Builder
forall a b. (a -> b) -> a -> b
$
[Char]
"UUID parsing error in the column"
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ ByteString -> [Char]
forall a. Show a => a -> [Char]
show ByteString
col_name
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" wrong data: "
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ ByteString -> [Char]
forall a. Show a => a -> [Char]
show ByteString
uuid_str
Just UUID
uuid -> do
let (Word32
w2, Word32
w1, Word32
w3, Word32
w4) = UUID -> (Word32, Word32, Word32, Word32)
UUID.toWords UUID
uuid
Word32 -> Writer Builder
forall w. MonoidMap ByteString w => Word32 -> Writer w
writeBinaryUInt32 Word32
w1
Word32 -> Writer Builder
forall w. MonoidMap ByteString w => Word32 -> Writer w
writeBinaryUInt32 Word32
w2
Word32 -> Writer Builder
forall w. MonoidMap ByteString w => Word32 -> Writer w
writeBinaryUInt32 Word32
w3
Word32 -> Writer Builder
forall w. MonoidMap ByteString w => Word32 -> Writer w
writeBinaryUInt32 Word32
w4
ClickhouseType
CKNull -> do
Word64 -> Writer Builder
forall w. MonoidMap ByteString w => Word64 -> Writer w
writeBinaryUInt64 Word64
0
Word64 -> Writer Builder
forall w. MonoidMap ByteString w => Word64 -> Writer w
writeBinaryUInt64 Word64
0
)
#define COMMA 44
#define SPACE 32
getSpecs :: ByteString -> [ByteString]
getSpecs :: ByteString -> [ByteString]
getSpecs ByteString
str = (Word8 -> Bool) -> ByteString -> [ByteString]
BS.splitWith (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== COMMA) (BS.filter (/= SPACE) str)
transpose :: Vector (Vector ClickhouseType) -> Vector (Vector ClickhouseType)
transpose :: Vector (Vector ClickhouseType) -> Vector (Vector ClickhouseType)
transpose = Vector (Vector ClickhouseType) -> Vector (Vector ClickhouseType)
forall a. Vector (Vector a) -> Vector (Vector a)
rotate
where
rotate :: Vector (Vector a) -> Vector (Vector a)
rotate Vector (Vector a)
matrix =
let transposedList :: [[a]]
transposedList = [[a]] -> [[a]]
forall a. [[a]] -> [[a]]
List.transpose (Vector a -> [a]
forall a. Vector a -> [a]
V.toList (Vector a -> [a]) -> [Vector a] -> [[a]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Vector (Vector a) -> [Vector a]
forall a. Vector a -> [a]
V.toList Vector (Vector a)
matrix)
toVector :: Vector (Vector a)
toVector = [a] -> Vector a
forall a. [a] -> Vector a
V.fromList ([a] -> Vector a) -> Vector [a] -> Vector (Vector a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [[a]] -> Vector [a]
forall a. [a] -> Vector a
V.fromList [[a]]
transposedList
in Vector (Vector a)
toVector
typeMismatchError :: ByteString -> String
typeMismatchError :: ByteString -> [Char]
typeMismatchError ByteString
col_name = [Char]
"Type mismatch in the column " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ ByteString -> [Char]
forall a. Show a => a -> [Char]
show ByteString
col_name
putStrLn :: Vector (Vector ClickhouseType) -> IO ()
putStrLn :: Vector (Vector ClickhouseType) -> IO ()
putStrLn Vector (Vector ClickhouseType)
v = ByteString -> IO ()
C8.putStrLn (ByteString -> IO ()) -> ByteString -> IO ()
forall a b. (a -> b) -> a -> b
$ ByteString -> [ByteString] -> ByteString
BS.intercalate ByteString
"\n" ([ByteString] -> ByteString) -> [ByteString] -> ByteString
forall a b. (a -> b) -> a -> b
$ Vector ByteString -> [ByteString]
forall a. Vector a -> [a]
V.toList (Vector ByteString -> [ByteString])
-> Vector ByteString -> [ByteString]
forall a b. (a -> b) -> a -> b
$ (Vector ClickhouseType -> ByteString)
-> Vector (Vector ClickhouseType) -> Vector ByteString
forall a b. (a -> b) -> Vector a -> Vector b
V.map Vector ClickhouseType -> ByteString
to_str Vector (Vector ClickhouseType)
v
where
to_str :: Vector ClickhouseType -> ByteString
to_str :: Vector ClickhouseType -> ByteString
to_str Vector ClickhouseType
row = ByteString -> [ByteString] -> ByteString
BS.intercalate ByteString
"," ([ByteString] -> ByteString) -> [ByteString] -> ByteString
forall a b. (a -> b) -> a -> b
$ Vector ByteString -> [ByteString]
forall a. Vector a -> [a]
V.toList (Vector ByteString -> [ByteString])
-> Vector ByteString -> [ByteString]
forall a b. (a -> b) -> a -> b
$ (ClickhouseType -> ByteString)
-> Vector ClickhouseType -> Vector ByteString
forall a b. (a -> b) -> Vector a -> Vector b
V.map ClickhouseType -> ByteString
help Vector ClickhouseType
row
help :: ClickhouseType -> ByteString
help :: ClickhouseType -> ByteString
help (CKString ByteString
s) = ByteString
s
help (CKDecimal64 Double
n) = [Char] -> ByteString
C8.pack ([Char] -> ByteString) -> [Char] -> ByteString
forall a b. (a -> b) -> a -> b
$ Double -> [Char]
forall a. Show a => a -> [Char]
show Double
n
help (CKDecimal32 Float
n) = [Char] -> ByteString
C8.pack ([Char] -> ByteString) -> [Char] -> ByteString
forall a b. (a -> b) -> a -> b
$ Float -> [Char]
forall a. Show a => a -> [Char]
show Float
n
help (CKDecimal Float
n) = [Char] -> ByteString
C8.pack ([Char] -> ByteString) -> [Char] -> ByteString
forall a b. (a -> b) -> a -> b
$ Float -> [Char]
forall a. Show a => a -> [Char]
show Float
n
help (CKInt8 Int8
n) = [Char] -> ByteString
C8.pack ([Char] -> ByteString) -> [Char] -> ByteString
forall a b. (a -> b) -> a -> b
$ Int8 -> [Char]
forall a. Show a => a -> [Char]
show Int8
n
help (CKInt16 Int16
n) = [Char] -> ByteString
C8.pack ([Char] -> ByteString) -> [Char] -> ByteString
forall a b. (a -> b) -> a -> b
$ Int16 -> [Char]
forall a. Show a => a -> [Char]
show Int16
n
help (CKInt32 Int32
n) = [Char] -> ByteString
C8.pack ([Char] -> ByteString) -> [Char] -> ByteString
forall a b. (a -> b) -> a -> b
$ Int32 -> [Char]
forall a. Show a => a -> [Char]
show Int32
n
help (CKInt64 Int64
n) = [Char] -> ByteString
C8.pack ([Char] -> ByteString) -> [Char] -> ByteString
forall a b. (a -> b) -> a -> b
$ Int64 -> [Char]
forall a. Show a => a -> [Char]
show Int64
n
help (CKUInt8 Word8
n) = [Char] -> ByteString
C8.pack ([Char] -> ByteString) -> [Char] -> ByteString
forall a b. (a -> b) -> a -> b
$ Word8 -> [Char]
forall a. Show a => a -> [Char]
show Word8
n
help (CKUInt16 Word16
n) = [Char] -> ByteString
C8.pack ([Char] -> ByteString) -> [Char] -> ByteString
forall a b. (a -> b) -> a -> b
$ Word16 -> [Char]
forall a. Show a => a -> [Char]
show Word16
n
help (CKUInt32 Word32
n) = [Char] -> ByteString
C8.pack ([Char] -> ByteString) -> [Char] -> ByteString
forall a b. (a -> b) -> a -> b
$ Word32 -> [Char]
forall a. Show a => a -> [Char]
show Word32
n
help (CKUInt64 Word64
n) = [Char] -> ByteString
C8.pack ([Char] -> ByteString) -> [Char] -> ByteString
forall a b. (a -> b) -> a -> b
$ Word64 -> [Char]
forall a. Show a => a -> [Char]
show Word64
n
help (CKTuple Vector ClickhouseType
xs) = ByteString
"(" ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> Vector ClickhouseType -> ByteString
to_str Vector ClickhouseType
xs ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
")"
help (CKArray Vector ClickhouseType
xs) = ByteString
"[" ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> Vector ClickhouseType -> ByteString
to_str Vector ClickhouseType
xs ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
"]"
help ClickhouseType
CKNull = ByteString
"null"
help (CKIPv4 (Word8, Word8, Word8, Word8)
ip4) = [Char] -> ByteString
C8.pack ([Char] -> ByteString) -> [Char] -> ByteString
forall a b. (a -> b) -> a -> b
$ (Word8, Word8, Word8, Word8) -> [Char]
forall a. Show a => a -> [Char]
show (Word8, Word8, Word8, Word8)
ip4
help (CKIPv6 (Word16, Word16, Word16, Word16, Word16, Word16, Word16, Word16)
ip6) = [Char] -> ByteString
C8.pack ([Char] -> ByteString) -> [Char] -> ByteString
forall a b. (a -> b) -> a -> b
$ (Word16, Word16, Word16, Word16, Word16, Word16, Word16, Word16)
-> [Char]
forall a. Show a => a -> [Char]
show (Word16, Word16, Word16, Word16, Word16, Word16, Word16, Word16)
ip6
help (CKDate Integer
y Int
m Int
d) =
[Char] -> ByteString
C8.pack (Integer -> [Char]
forall a. Show a => a -> [Char]
show Integer
y)
ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
"-"
ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> [Char] -> ByteString
C8.pack (Int -> [Char]
forall a. Show a => a -> [Char]
show Int
m)
ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
"-"
ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> [Char] -> ByteString
C8.pack (Int -> [Char]
forall a. Show a => a -> [Char]
show Int
d)