clickhouse-driver 0.2.10__cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- clickhouse_driver/__init__.py +9 -0
- clickhouse_driver/block.py +227 -0
- clickhouse_driver/blockstreamprofileinfo.py +22 -0
- clickhouse_driver/bufferedreader.cpython-313-powerpc64le-linux-gnu.so +0 -0
- clickhouse_driver/bufferedwriter.cpython-313-powerpc64le-linux-gnu.so +0 -0
- clickhouse_driver/client.py +812 -0
- clickhouse_driver/clientinfo.py +119 -0
- clickhouse_driver/columns/__init__.py +0 -0
- clickhouse_driver/columns/arraycolumn.py +161 -0
- clickhouse_driver/columns/base.py +221 -0
- clickhouse_driver/columns/boolcolumn.py +7 -0
- clickhouse_driver/columns/datecolumn.py +108 -0
- clickhouse_driver/columns/datetimecolumn.py +203 -0
- clickhouse_driver/columns/decimalcolumn.py +116 -0
- clickhouse_driver/columns/enumcolumn.py +129 -0
- clickhouse_driver/columns/exceptions.py +12 -0
- clickhouse_driver/columns/floatcolumn.py +34 -0
- clickhouse_driver/columns/intcolumn.py +157 -0
- clickhouse_driver/columns/intervalcolumn.py +33 -0
- clickhouse_driver/columns/ipcolumn.py +118 -0
- clickhouse_driver/columns/jsoncolumn.py +37 -0
- clickhouse_driver/columns/largeint.cpython-313-powerpc64le-linux-gnu.so +0 -0
- clickhouse_driver/columns/lowcardinalitycolumn.py +142 -0
- clickhouse_driver/columns/mapcolumn.py +73 -0
- clickhouse_driver/columns/nestedcolumn.py +10 -0
- clickhouse_driver/columns/nothingcolumn.py +13 -0
- clickhouse_driver/columns/nullablecolumn.py +7 -0
- clickhouse_driver/columns/nullcolumn.py +15 -0
- clickhouse_driver/columns/numpy/__init__.py +0 -0
- clickhouse_driver/columns/numpy/base.py +47 -0
- clickhouse_driver/columns/numpy/boolcolumn.py +8 -0
- clickhouse_driver/columns/numpy/datecolumn.py +19 -0
- clickhouse_driver/columns/numpy/datetimecolumn.py +146 -0
- clickhouse_driver/columns/numpy/floatcolumn.py +24 -0
- clickhouse_driver/columns/numpy/intcolumn.py +43 -0
- clickhouse_driver/columns/numpy/lowcardinalitycolumn.py +96 -0
- clickhouse_driver/columns/numpy/service.py +58 -0
- clickhouse_driver/columns/numpy/stringcolumn.py +78 -0
- clickhouse_driver/columns/numpy/tuplecolumn.py +37 -0
- clickhouse_driver/columns/service.py +185 -0
- clickhouse_driver/columns/simpleaggregatefunctioncolumn.py +7 -0
- clickhouse_driver/columns/stringcolumn.py +73 -0
- clickhouse_driver/columns/tuplecolumn.py +63 -0
- clickhouse_driver/columns/util.py +61 -0
- clickhouse_driver/columns/uuidcolumn.py +64 -0
- clickhouse_driver/compression/__init__.py +32 -0
- clickhouse_driver/compression/base.py +87 -0
- clickhouse_driver/compression/lz4.py +21 -0
- clickhouse_driver/compression/lz4hc.py +9 -0
- clickhouse_driver/compression/zstd.py +20 -0
- clickhouse_driver/connection.py +825 -0
- clickhouse_driver/context.py +36 -0
- clickhouse_driver/dbapi/__init__.py +62 -0
- clickhouse_driver/dbapi/connection.py +99 -0
- clickhouse_driver/dbapi/cursor.py +370 -0
- clickhouse_driver/dbapi/errors.py +40 -0
- clickhouse_driver/dbapi/extras.py +73 -0
- clickhouse_driver/defines.py +58 -0
- clickhouse_driver/errors.py +453 -0
- clickhouse_driver/log.py +48 -0
- clickhouse_driver/numpy/__init__.py +0 -0
- clickhouse_driver/numpy/block.py +8 -0
- clickhouse_driver/numpy/helpers.py +28 -0
- clickhouse_driver/numpy/result.py +123 -0
- clickhouse_driver/opentelemetry.py +43 -0
- clickhouse_driver/progress.py +44 -0
- clickhouse_driver/protocol.py +130 -0
- clickhouse_driver/queryprocessingstage.py +8 -0
- clickhouse_driver/reader.py +69 -0
- clickhouse_driver/readhelpers.py +26 -0
- clickhouse_driver/result.py +144 -0
- clickhouse_driver/settings/__init__.py +0 -0
- clickhouse_driver/settings/available.py +405 -0
- clickhouse_driver/settings/types.py +50 -0
- clickhouse_driver/settings/writer.py +34 -0
- clickhouse_driver/streams/__init__.py +0 -0
- clickhouse_driver/streams/compressed.py +88 -0
- clickhouse_driver/streams/native.py +108 -0
- clickhouse_driver/util/__init__.py +0 -0
- clickhouse_driver/util/compat.py +39 -0
- clickhouse_driver/util/escape.py +94 -0
- clickhouse_driver/util/helpers.py +173 -0
- clickhouse_driver/varint.cpython-313-powerpc64le-linux-gnu.so +0 -0
- clickhouse_driver/writer.py +67 -0
- clickhouse_driver-0.2.10.dist-info/METADATA +215 -0
- clickhouse_driver-0.2.10.dist-info/RECORD +89 -0
- clickhouse_driver-0.2.10.dist-info/WHEEL +7 -0
- clickhouse_driver-0.2.10.dist-info/licenses/LICENSE +21 -0
- clickhouse_driver-0.2.10.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
|
|
2
|
+
def get_inner_spec(column_name, spec):
|
|
3
|
+
brackets = 0
|
|
4
|
+
offset = len(column_name)
|
|
5
|
+
i = offset
|
|
6
|
+
for i, ch in enumerate(spec[offset:], offset):
|
|
7
|
+
if ch == '(':
|
|
8
|
+
brackets += 1
|
|
9
|
+
|
|
10
|
+
elif ch == ')':
|
|
11
|
+
brackets -= 1
|
|
12
|
+
|
|
13
|
+
if brackets == 0:
|
|
14
|
+
break
|
|
15
|
+
|
|
16
|
+
return spec[offset + 1:i]
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def get_inner_columns(spec):
|
|
20
|
+
brackets = 0
|
|
21
|
+
column_begin = 0
|
|
22
|
+
|
|
23
|
+
columns = []
|
|
24
|
+
for i, x in enumerate(spec + ','):
|
|
25
|
+
if x == ',':
|
|
26
|
+
if brackets == 0:
|
|
27
|
+
columns.append(spec[column_begin:i])
|
|
28
|
+
column_begin = i + 1
|
|
29
|
+
elif x == '(':
|
|
30
|
+
brackets += 1
|
|
31
|
+
elif x == ')':
|
|
32
|
+
brackets -= 1
|
|
33
|
+
elif x == ' ':
|
|
34
|
+
if brackets == 0:
|
|
35
|
+
column_begin = i + 1
|
|
36
|
+
return columns
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def get_inner_columns_with_types(spec):
|
|
40
|
+
spec = spec.strip()
|
|
41
|
+
brackets = 0
|
|
42
|
+
prev_comma = 0
|
|
43
|
+
prev_space = 0
|
|
44
|
+
|
|
45
|
+
columns = []
|
|
46
|
+
for i, x in enumerate(spec.strip() + ','):
|
|
47
|
+
if x == ',':
|
|
48
|
+
if brackets == 0:
|
|
49
|
+
columns.append((
|
|
50
|
+
spec[prev_comma:prev_space].strip(),
|
|
51
|
+
spec[prev_space:i]
|
|
52
|
+
))
|
|
53
|
+
prev_comma = i + 1
|
|
54
|
+
elif x == '(':
|
|
55
|
+
brackets += 1
|
|
56
|
+
elif x == ')':
|
|
57
|
+
brackets -= 1
|
|
58
|
+
elif x == ' ':
|
|
59
|
+
if brackets == 0:
|
|
60
|
+
prev_space = i + 1
|
|
61
|
+
return columns
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
from uuid import UUID
|
|
2
|
+
|
|
3
|
+
from .base import FormatColumn
|
|
4
|
+
from .. import errors
|
|
5
|
+
from ..writer import MAX_UINT64
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class UUIDColumn(FormatColumn):
|
|
9
|
+
ch_type = 'UUID'
|
|
10
|
+
py_types = (str, UUID)
|
|
11
|
+
format = 'Q'
|
|
12
|
+
|
|
13
|
+
# UUID is stored by two uint64 numbers.
|
|
14
|
+
def write_items(self, items, buf):
|
|
15
|
+
n_items = len(items)
|
|
16
|
+
|
|
17
|
+
uint_64_pairs = [None] * 2 * n_items
|
|
18
|
+
for i, x in enumerate(items):
|
|
19
|
+
i2 = 2 * i
|
|
20
|
+
uint_64_pairs[i2] = (x >> 64) & MAX_UINT64
|
|
21
|
+
uint_64_pairs[i2 + 1] = x & MAX_UINT64
|
|
22
|
+
|
|
23
|
+
s = self.make_struct(2 * n_items)
|
|
24
|
+
buf.write(s.pack(*uint_64_pairs))
|
|
25
|
+
|
|
26
|
+
def read_items(self, n_items, buf):
|
|
27
|
+
# TODO: cythonize
|
|
28
|
+
s = self.make_struct(2 * n_items)
|
|
29
|
+
items = s.unpack(buf.read(s.size))
|
|
30
|
+
|
|
31
|
+
uint_128_items = [None] * n_items
|
|
32
|
+
for i in range(n_items):
|
|
33
|
+
i2 = 2 * i
|
|
34
|
+
uint_128_items[i] = (items[i2] << 64) + items[i2 + 1]
|
|
35
|
+
|
|
36
|
+
return tuple(uint_128_items)
|
|
37
|
+
|
|
38
|
+
def after_read_items(self, items, nulls_map=None):
|
|
39
|
+
if nulls_map is None:
|
|
40
|
+
return tuple(UUID(int=item) for item in items)
|
|
41
|
+
else:
|
|
42
|
+
return tuple(
|
|
43
|
+
(None if is_null else UUID(int=items[i]))
|
|
44
|
+
for i, is_null in enumerate(nulls_map)
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
def before_write_items(self, items, nulls_map=None):
|
|
48
|
+
null_value = self.null_value
|
|
49
|
+
|
|
50
|
+
for i, item in enumerate(items):
|
|
51
|
+
if nulls_map and nulls_map[i]:
|
|
52
|
+
items[i] = null_value
|
|
53
|
+
continue
|
|
54
|
+
|
|
55
|
+
try:
|
|
56
|
+
if not isinstance(item, UUID):
|
|
57
|
+
item = UUID(int=item) if item is null_value else UUID(item)
|
|
58
|
+
|
|
59
|
+
except ValueError:
|
|
60
|
+
raise errors.CannotParseUuidError(
|
|
61
|
+
"Cannot parse uuid '{}'".format(item)
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
items[i] = item.int
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import importlib
|
|
2
|
+
import logging
|
|
3
|
+
|
|
4
|
+
from .. import errors
|
|
5
|
+
from ..protocol import CompressionMethodByte
|
|
6
|
+
|
|
7
|
+
logger = logging.getLogger(__name__)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def get_compressor_cls(alg):
|
|
11
|
+
try:
|
|
12
|
+
module = importlib.import_module('.' + alg, __name__)
|
|
13
|
+
return module.Compressor
|
|
14
|
+
|
|
15
|
+
except ImportError:
|
|
16
|
+
logger.warning('Unable to import module %s', alg, exc_info=True)
|
|
17
|
+
raise errors.UnknownCompressionMethod(
|
|
18
|
+
"Unknown compression method: '{}'".format(alg)
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def get_decompressor_cls(method_type):
|
|
23
|
+
if method_type == CompressionMethodByte.LZ4:
|
|
24
|
+
module = importlib.import_module('.lz4', __name__)
|
|
25
|
+
|
|
26
|
+
elif method_type == CompressionMethodByte.ZSTD:
|
|
27
|
+
module = importlib.import_module('.zstd', __name__)
|
|
28
|
+
|
|
29
|
+
else:
|
|
30
|
+
raise errors.UnknownCompressionMethod()
|
|
31
|
+
|
|
32
|
+
return module.Decompressor
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
from io import BytesIO
|
|
2
|
+
|
|
3
|
+
from ..reader import read_binary_uint32
|
|
4
|
+
from ..writer import write_binary_uint8, write_binary_uint32
|
|
5
|
+
from .. import errors
|
|
6
|
+
|
|
7
|
+
try:
|
|
8
|
+
from clickhouse_cityhash.cityhash import CityHash128
|
|
9
|
+
except ImportError:
|
|
10
|
+
raise RuntimeError(
|
|
11
|
+
'Package clickhouse-cityhash is required to use compression'
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class BaseCompressor(object):
|
|
16
|
+
"""
|
|
17
|
+
Partial file-like object with write method.
|
|
18
|
+
"""
|
|
19
|
+
method = None
|
|
20
|
+
method_byte = None
|
|
21
|
+
|
|
22
|
+
def __init__(self):
|
|
23
|
+
self.data = BytesIO()
|
|
24
|
+
|
|
25
|
+
super(BaseCompressor, self).__init__()
|
|
26
|
+
|
|
27
|
+
def get_value(self):
|
|
28
|
+
value = self.data.getvalue()
|
|
29
|
+
self.data.seek(0)
|
|
30
|
+
self.data.truncate()
|
|
31
|
+
return value
|
|
32
|
+
|
|
33
|
+
def write(self, p_str):
|
|
34
|
+
self.data.write(p_str)
|
|
35
|
+
|
|
36
|
+
def compress_data(self, data):
|
|
37
|
+
raise NotImplementedError
|
|
38
|
+
|
|
39
|
+
def get_compressed_data(self, extra_header_size):
|
|
40
|
+
rv = BytesIO()
|
|
41
|
+
|
|
42
|
+
data = self.get_value()
|
|
43
|
+
compressed = self.compress_data(data)
|
|
44
|
+
|
|
45
|
+
header_size = extra_header_size + 4 + 4 # sizes
|
|
46
|
+
|
|
47
|
+
write_binary_uint32(header_size + len(compressed), rv)
|
|
48
|
+
write_binary_uint32(len(data), rv)
|
|
49
|
+
rv.write(compressed)
|
|
50
|
+
|
|
51
|
+
return rv.getvalue()
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class BaseDecompressor(object):
|
|
55
|
+
method = None
|
|
56
|
+
method_byte = None
|
|
57
|
+
|
|
58
|
+
def __init__(self, real_stream):
|
|
59
|
+
self.stream = real_stream
|
|
60
|
+
super(BaseDecompressor, self).__init__()
|
|
61
|
+
|
|
62
|
+
def decompress_data(self, data, uncompressed_size):
|
|
63
|
+
raise NotImplementedError
|
|
64
|
+
|
|
65
|
+
def check_hash(self, compressed_data, compressed_hash):
|
|
66
|
+
if CityHash128(compressed_data) != compressed_hash:
|
|
67
|
+
raise errors.ChecksumDoesntMatchError()
|
|
68
|
+
|
|
69
|
+
def get_decompressed_data(self, method_byte, compressed_hash,
|
|
70
|
+
extra_header_size):
|
|
71
|
+
size_with_header = read_binary_uint32(self.stream)
|
|
72
|
+
compressed_size = size_with_header - extra_header_size - 4
|
|
73
|
+
|
|
74
|
+
compressed = BytesIO(self.stream.read(compressed_size))
|
|
75
|
+
|
|
76
|
+
block_check = BytesIO()
|
|
77
|
+
write_binary_uint8(method_byte, block_check)
|
|
78
|
+
write_binary_uint32(size_with_header, block_check)
|
|
79
|
+
block_check.write(compressed.getvalue())
|
|
80
|
+
|
|
81
|
+
self.check_hash(block_check.getvalue(), compressed_hash)
|
|
82
|
+
|
|
83
|
+
uncompressed_size = read_binary_uint32(compressed)
|
|
84
|
+
|
|
85
|
+
compressed = compressed.read(compressed_size - 4)
|
|
86
|
+
|
|
87
|
+
return self.decompress_data(compressed, uncompressed_size)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from lz4 import block
|
|
2
|
+
|
|
3
|
+
from .base import BaseCompressor, BaseDecompressor
|
|
4
|
+
from ..protocol import CompressionMethod, CompressionMethodByte
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Compressor(BaseCompressor):
|
|
8
|
+
method = CompressionMethod.LZ4
|
|
9
|
+
method_byte = CompressionMethodByte.LZ4
|
|
10
|
+
mode = 'default'
|
|
11
|
+
|
|
12
|
+
def compress_data(self, data):
|
|
13
|
+
return block.compress(data, store_size=False, mode=self.mode)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class Decompressor(BaseDecompressor):
|
|
17
|
+
method = CompressionMethod.LZ4
|
|
18
|
+
method_byte = CompressionMethodByte.LZ4
|
|
19
|
+
|
|
20
|
+
def decompress_data(self, data, uncompressed_size):
|
|
21
|
+
return block.decompress(data, uncompressed_size=uncompressed_size)
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import zstd
|
|
2
|
+
|
|
3
|
+
from .base import BaseCompressor, BaseDecompressor
|
|
4
|
+
from ..protocol import CompressionMethod, CompressionMethodByte
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Compressor(BaseCompressor):
|
|
8
|
+
method = CompressionMethod.ZSTD
|
|
9
|
+
method_byte = CompressionMethodByte.ZSTD
|
|
10
|
+
|
|
11
|
+
def compress_data(self, data):
|
|
12
|
+
return zstd.compress(data)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class Decompressor(BaseDecompressor):
|
|
16
|
+
method = CompressionMethod.ZSTD
|
|
17
|
+
method_byte = CompressionMethodByte.ZSTD
|
|
18
|
+
|
|
19
|
+
def decompress_data(self, data, uncompressed_size):
|
|
20
|
+
return zstd.decompress(data)
|