clickhouse-driver 0.2.10__cp314-cp314-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-314-powerpc64le-linux-gnu.so +0 -0
- clickhouse_driver/bufferedwriter.cpython-314-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-314-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-314-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,43 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from .base import NumpyColumn
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class NumpyInt8Column(NumpyColumn):
|
|
7
|
+
dtype = np.dtype(np.int8)
|
|
8
|
+
ch_type = 'Int8'
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class NumpyUInt8Column(NumpyColumn):
|
|
12
|
+
dtype = np.dtype(np.uint8)
|
|
13
|
+
ch_type = 'UInt8'
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class NumpyInt16Column(NumpyColumn):
|
|
17
|
+
dtype = np.dtype(np.int16)
|
|
18
|
+
ch_type = 'Int16'
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class NumpyUInt16Column(NumpyColumn):
|
|
22
|
+
dtype = np.dtype(np.uint16)
|
|
23
|
+
ch_type = 'UInt16'
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class NumpyInt32Column(NumpyColumn):
|
|
27
|
+
dtype = np.dtype(np.int32)
|
|
28
|
+
ch_type = 'Int32'
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class NumpyUInt32Column(NumpyColumn):
|
|
32
|
+
dtype = np.dtype(np.uint32)
|
|
33
|
+
ch_type = 'UInt32'
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class NumpyInt64Column(NumpyColumn):
|
|
37
|
+
dtype = np.dtype(np.int64)
|
|
38
|
+
ch_type = 'Int64'
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class NumpyUInt64Column(NumpyColumn):
|
|
42
|
+
dtype = np.dtype(np.uint64)
|
|
43
|
+
ch_type = 'UInt64'
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
from math import log
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
import pandas as pd
|
|
5
|
+
|
|
6
|
+
from ..lowcardinalitycolumn import LowCardinalityColumn
|
|
7
|
+
from ...reader import read_binary_uint64
|
|
8
|
+
from ...writer import write_binary_int64
|
|
9
|
+
from .intcolumn import (
|
|
10
|
+
NumpyUInt8Column, NumpyUInt16Column, NumpyUInt32Column, NumpyUInt64Column
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class NumpyLowCardinalityColumn(LowCardinalityColumn):
|
|
15
|
+
int_types = {
|
|
16
|
+
0: NumpyUInt8Column,
|
|
17
|
+
1: NumpyUInt16Column,
|
|
18
|
+
2: NumpyUInt32Column,
|
|
19
|
+
3: NumpyUInt64Column
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
def __init__(self, nested_column, **kwargs):
|
|
23
|
+
super(NumpyLowCardinalityColumn, self).__init__(nested_column,
|
|
24
|
+
**kwargs)
|
|
25
|
+
|
|
26
|
+
def _write_data(self, items, buf):
|
|
27
|
+
# Do not write anything for empty column.
|
|
28
|
+
# May happen while writing empty arrays.
|
|
29
|
+
if not len(items):
|
|
30
|
+
return
|
|
31
|
+
|
|
32
|
+
# Replace nans with defaults if not nullabe.
|
|
33
|
+
if isinstance(items, np.ndarray) and not self.nested_column.nullable:
|
|
34
|
+
nulls = pd.isnull(items)
|
|
35
|
+
items = np.where(nulls, self.nested_column.null_value, items)
|
|
36
|
+
|
|
37
|
+
c = pd.Categorical(items)
|
|
38
|
+
|
|
39
|
+
int_type = int(log(len(c.codes), 2) / 8)
|
|
40
|
+
int_column = self.int_types[int_type](**self.init_kwargs)
|
|
41
|
+
|
|
42
|
+
serialization_type = self.serialization_type | int_type
|
|
43
|
+
|
|
44
|
+
index = c.categories
|
|
45
|
+
keys = c.codes
|
|
46
|
+
|
|
47
|
+
if self.nested_column.nullable:
|
|
48
|
+
# First element represents NULL if column is nullable.
|
|
49
|
+
index = index.insert(0, self.nested_column.null_value)
|
|
50
|
+
keys = keys + 1
|
|
51
|
+
# Prevent null map writing. Reset nested column nullable flag.
|
|
52
|
+
self.nested_column.nullable = False
|
|
53
|
+
|
|
54
|
+
write_binary_int64(serialization_type, buf)
|
|
55
|
+
write_binary_int64(len(index), buf)
|
|
56
|
+
|
|
57
|
+
self.nested_column.write_data(index.to_numpy(items.dtype), buf)
|
|
58
|
+
write_binary_int64(len(items), buf)
|
|
59
|
+
int_column.write_items(keys, buf)
|
|
60
|
+
|
|
61
|
+
def _read_data(self, n_items, buf, nulls_map=None):
|
|
62
|
+
if not n_items:
|
|
63
|
+
return tuple()
|
|
64
|
+
|
|
65
|
+
serialization_type = read_binary_uint64(buf)
|
|
66
|
+
|
|
67
|
+
# Lowest byte contains info about key type.
|
|
68
|
+
key_type = serialization_type & 0xf
|
|
69
|
+
keys_column = self.int_types[key_type](**self.init_kwargs)
|
|
70
|
+
|
|
71
|
+
nullable = self.nested_column.nullable
|
|
72
|
+
# Prevent null map reading. Reset nested column nullable flag.
|
|
73
|
+
self.nested_column.nullable = False
|
|
74
|
+
|
|
75
|
+
index_size = read_binary_uint64(buf)
|
|
76
|
+
index = self.nested_column.read_data(index_size, buf)
|
|
77
|
+
|
|
78
|
+
read_binary_uint64(buf) # number of keys
|
|
79
|
+
keys = keys_column.read_data(n_items, buf)
|
|
80
|
+
|
|
81
|
+
if nullable:
|
|
82
|
+
# Shift all codes by one ("No value" code is -1 for pandas
|
|
83
|
+
# categorical) and drop corresponding first index
|
|
84
|
+
# this is analog of original operation:
|
|
85
|
+
# index = (None, ) + index[1:]
|
|
86
|
+
keys = np.array(keys, dtype='int64') # deal with possible overflow
|
|
87
|
+
keys = keys - 1
|
|
88
|
+
index = index[1:]
|
|
89
|
+
return pd.Categorical.from_codes(keys, index)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def create_numpy_low_cardinality_column(spec, column_by_spec_getter,
|
|
93
|
+
column_options):
|
|
94
|
+
inner = spec[15:-1]
|
|
95
|
+
nested = column_by_spec_getter(inner)
|
|
96
|
+
return NumpyLowCardinalityColumn(nested, **column_options)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
from ..service import aliases
|
|
2
|
+
from ... import errors
|
|
3
|
+
from .datecolumn import NumpyDateColumn
|
|
4
|
+
from .datetimecolumn import create_numpy_datetime_column
|
|
5
|
+
from .floatcolumn import NumpyFloat32Column, NumpyFloat64Column
|
|
6
|
+
from .intcolumn import (
|
|
7
|
+
NumpyInt8Column, NumpyInt16Column, NumpyInt32Column, NumpyInt64Column,
|
|
8
|
+
NumpyUInt8Column, NumpyUInt16Column, NumpyUInt32Column, NumpyUInt64Column
|
|
9
|
+
)
|
|
10
|
+
from .boolcolumn import NumpyBoolColumn
|
|
11
|
+
from .lowcardinalitycolumn import create_numpy_low_cardinality_column
|
|
12
|
+
from .stringcolumn import create_string_column
|
|
13
|
+
from .tuplecolumn import create_tuple_column
|
|
14
|
+
from ..nullablecolumn import create_nullable_column
|
|
15
|
+
|
|
16
|
+
column_by_type = {c.ch_type: c for c in [
|
|
17
|
+
NumpyDateColumn,
|
|
18
|
+
NumpyFloat32Column, NumpyFloat64Column,
|
|
19
|
+
NumpyInt8Column, NumpyInt16Column, NumpyInt32Column, NumpyInt64Column,
|
|
20
|
+
NumpyUInt8Column, NumpyUInt16Column, NumpyUInt32Column, NumpyUInt64Column,
|
|
21
|
+
NumpyBoolColumn
|
|
22
|
+
]}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def get_numpy_column_by_spec(spec, column_options):
|
|
26
|
+
def create_column_with_options(x):
|
|
27
|
+
return get_numpy_column_by_spec(x, column_options)
|
|
28
|
+
|
|
29
|
+
if spec == 'String' or spec.startswith('FixedString'):
|
|
30
|
+
return create_string_column(spec, column_options)
|
|
31
|
+
|
|
32
|
+
elif spec.startswith('DateTime'):
|
|
33
|
+
return create_numpy_datetime_column(spec, column_options)
|
|
34
|
+
|
|
35
|
+
elif spec.startswith('Tuple'):
|
|
36
|
+
return create_tuple_column(
|
|
37
|
+
spec, create_column_with_options, column_options
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
elif spec.startswith('Nullable'):
|
|
41
|
+
return create_nullable_column(spec, create_column_with_options)
|
|
42
|
+
|
|
43
|
+
elif spec.startswith('LowCardinality'):
|
|
44
|
+
return create_numpy_low_cardinality_column(
|
|
45
|
+
spec, create_column_with_options, column_options
|
|
46
|
+
)
|
|
47
|
+
else:
|
|
48
|
+
for alias, primitive in aliases:
|
|
49
|
+
if spec.startswith(alias):
|
|
50
|
+
return create_column_with_options(
|
|
51
|
+
primitive + spec[len(alias):]
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
if spec in column_by_type:
|
|
55
|
+
cls = column_by_type[spec]
|
|
56
|
+
return cls(**column_options)
|
|
57
|
+
|
|
58
|
+
raise errors.UnknownTypeError('Unknown type {}'.format(spec))
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from ... import defines
|
|
4
|
+
from .base import NumpyColumn
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class NumpyStringColumn(NumpyColumn):
|
|
8
|
+
null_value = ''
|
|
9
|
+
|
|
10
|
+
default_encoding = defines.STRINGS_ENCODING
|
|
11
|
+
|
|
12
|
+
def __init__(self, encoding=default_encoding, **kwargs):
|
|
13
|
+
self.encoding = encoding
|
|
14
|
+
super(NumpyStringColumn, self).__init__(**kwargs)
|
|
15
|
+
|
|
16
|
+
def read_items(self, n_items, buf):
|
|
17
|
+
return np.array(
|
|
18
|
+
buf.read_strings(n_items, encoding=self.encoding), dtype=self.dtype
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
def write_items(self, items, buf):
|
|
22
|
+
return buf.write_strings(items.tolist(), encoding=self.encoding)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class NumpyByteStringColumn(NumpyColumn):
|
|
26
|
+
null_value = b''
|
|
27
|
+
|
|
28
|
+
def read_items(self, n_items, buf):
|
|
29
|
+
return np.array(buf.read_strings(n_items), dtype=self.dtype)
|
|
30
|
+
|
|
31
|
+
def write_items(self, items, buf):
|
|
32
|
+
return buf.write_strings(items.tolist())
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class NumpyFixedString(NumpyStringColumn):
|
|
36
|
+
def __init__(self, length, **kwargs):
|
|
37
|
+
self.length = length
|
|
38
|
+
super(NumpyFixedString, self).__init__(**kwargs)
|
|
39
|
+
|
|
40
|
+
def read_items(self, n_items, buf):
|
|
41
|
+
return np.array(buf.read_fixed_strings(
|
|
42
|
+
n_items, self.length, encoding=self.encoding
|
|
43
|
+
), dtype=self.dtype)
|
|
44
|
+
|
|
45
|
+
def write_items(self, items, buf):
|
|
46
|
+
return buf.write_fixed_strings(
|
|
47
|
+
items.tolist(), self.length, encoding=self.encoding
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class NumpyByteFixedString(NumpyByteStringColumn):
|
|
52
|
+
def __init__(self, length, **kwargs):
|
|
53
|
+
self.length = length
|
|
54
|
+
super(NumpyByteFixedString, self).__init__(**kwargs)
|
|
55
|
+
|
|
56
|
+
def read_items(self, n_items, buf):
|
|
57
|
+
return np.array(
|
|
58
|
+
buf.read_fixed_strings(n_items, self.length), dtype=self.dtype
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
def write_items(self, items, buf):
|
|
62
|
+
return buf.write_fixed_strings(items.tolist(), self.length)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def create_string_column(spec, column_options):
|
|
66
|
+
client_settings = column_options['context'].client_settings
|
|
67
|
+
strings_as_bytes = client_settings['strings_as_bytes']
|
|
68
|
+
encoding = client_settings.get(
|
|
69
|
+
'strings_encoding', NumpyStringColumn.default_encoding
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
if spec == 'String':
|
|
73
|
+
cls = NumpyByteStringColumn if strings_as_bytes else NumpyStringColumn
|
|
74
|
+
return cls(encoding=encoding, **column_options)
|
|
75
|
+
else:
|
|
76
|
+
length = int(spec[12:-1])
|
|
77
|
+
cls = NumpyByteFixedString if strings_as_bytes else NumpyFixedString
|
|
78
|
+
return cls(length, encoding=encoding, **column_options)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from .base import NumpyColumn
|
|
4
|
+
from ..util import get_inner_spec, get_inner_columns
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class TupleColumn(NumpyColumn):
|
|
8
|
+
def __init__(self, nested_columns, **kwargs):
|
|
9
|
+
self.nested_columns = nested_columns
|
|
10
|
+
super(TupleColumn, self).__init__(**kwargs)
|
|
11
|
+
|
|
12
|
+
def write_data(self, items, buf):
|
|
13
|
+
names = items.dtype.names
|
|
14
|
+
for i, (x, name) in enumerate(zip(self.nested_columns, names)):
|
|
15
|
+
x.write_data(items[name], buf)
|
|
16
|
+
|
|
17
|
+
def write_items(self, items, buf):
|
|
18
|
+
return self.write_data(items, buf)
|
|
19
|
+
|
|
20
|
+
def read_data(self, n_items, buf):
|
|
21
|
+
data = [x.read_data(n_items, buf) for x in self.nested_columns]
|
|
22
|
+
dtype = [('f{}'.format(i), x.dtype) for i, x in enumerate(data)]
|
|
23
|
+
rv = np.empty(n_items, dtype=dtype)
|
|
24
|
+
for i, x in enumerate(data):
|
|
25
|
+
rv['f{}'.format(i)] = x
|
|
26
|
+
return rv
|
|
27
|
+
|
|
28
|
+
def read_items(self, n_items, buf):
|
|
29
|
+
return self.read_data(n_items, buf)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def create_tuple_column(spec, column_by_spec_getter, column_options):
|
|
33
|
+
inner_spec = get_inner_spec('Tuple', spec)
|
|
34
|
+
columns = get_inner_columns(inner_spec)
|
|
35
|
+
|
|
36
|
+
return TupleColumn([column_by_spec_getter(x) for x in columns],
|
|
37
|
+
**column_options)
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
from .. import errors
|
|
4
|
+
from .arraycolumn import create_array_column
|
|
5
|
+
from .boolcolumn import BoolColumn
|
|
6
|
+
from .datecolumn import DateColumn, Date32Column
|
|
7
|
+
from .datetimecolumn import create_datetime_column
|
|
8
|
+
from .decimalcolumn import create_decimal_column
|
|
9
|
+
from . import exceptions as column_exceptions
|
|
10
|
+
from .enumcolumn import create_enum_column
|
|
11
|
+
from .floatcolumn import Float32Column, Float64Column
|
|
12
|
+
from .intcolumn import (
|
|
13
|
+
Int8Column, Int16Column, Int32Column, Int64Column,
|
|
14
|
+
Int128Column, UInt128Column, Int256Column, UInt256Column,
|
|
15
|
+
UInt8Column, UInt16Column, UInt32Column, UInt64Column
|
|
16
|
+
)
|
|
17
|
+
from .lowcardinalitycolumn import create_low_cardinality_column
|
|
18
|
+
from .jsoncolumn import create_json_column
|
|
19
|
+
from .mapcolumn import create_map_column
|
|
20
|
+
from .nothingcolumn import NothingColumn
|
|
21
|
+
from .nullcolumn import NullColumn
|
|
22
|
+
from .nullablecolumn import create_nullable_column
|
|
23
|
+
from .simpleaggregatefunctioncolumn import (
|
|
24
|
+
create_simple_aggregate_function_column
|
|
25
|
+
)
|
|
26
|
+
from .stringcolumn import create_string_column
|
|
27
|
+
from .tuplecolumn import create_tuple_column
|
|
28
|
+
from .nestedcolumn import create_nested_column
|
|
29
|
+
from .uuidcolumn import UUIDColumn
|
|
30
|
+
from .intervalcolumn import (
|
|
31
|
+
IntervalYearColumn, IntervalMonthColumn, IntervalWeekColumn,
|
|
32
|
+
IntervalDayColumn, IntervalHourColumn, IntervalMinuteColumn,
|
|
33
|
+
IntervalSecondColumn
|
|
34
|
+
)
|
|
35
|
+
from .ipcolumn import IPv4Column, IPv6Column
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
column_by_type = {c.ch_type: c for c in [
|
|
39
|
+
DateColumn, Date32Column, Float32Column, Float64Column,
|
|
40
|
+
Int8Column, Int16Column, Int32Column, Int64Column,
|
|
41
|
+
Int128Column, UInt128Column, Int256Column, UInt256Column,
|
|
42
|
+
UInt8Column, UInt16Column, UInt32Column, UInt64Column,
|
|
43
|
+
NothingColumn, NullColumn, UUIDColumn,
|
|
44
|
+
IntervalYearColumn, IntervalMonthColumn, IntervalWeekColumn,
|
|
45
|
+
IntervalDayColumn, IntervalHourColumn, IntervalMinuteColumn,
|
|
46
|
+
IntervalSecondColumn, IPv4Column, IPv6Column, BoolColumn
|
|
47
|
+
]}
|
|
48
|
+
|
|
49
|
+
logger = logging.getLogger(__name__)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
aliases = [
|
|
53
|
+
# Begin Geo types
|
|
54
|
+
('Point', 'Tuple(Float64, Float64)'),
|
|
55
|
+
('Ring', 'Array(Point)'),
|
|
56
|
+
('Polygon', 'Array(Ring)'),
|
|
57
|
+
('MultiPolygon', 'Array(Polygon)')
|
|
58
|
+
# End Geo types
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def get_column_by_spec(spec, column_options, use_numpy=None):
|
|
63
|
+
context = column_options['context']
|
|
64
|
+
|
|
65
|
+
if use_numpy is None:
|
|
66
|
+
use_numpy = context.client_settings['use_numpy'] if context else False
|
|
67
|
+
|
|
68
|
+
if use_numpy:
|
|
69
|
+
from .numpy.service import get_numpy_column_by_spec
|
|
70
|
+
|
|
71
|
+
try:
|
|
72
|
+
return get_numpy_column_by_spec(spec, column_options)
|
|
73
|
+
except errors.UnknownTypeError:
|
|
74
|
+
use_numpy = False
|
|
75
|
+
logger.warning('NumPy support is not implemented for %s. '
|
|
76
|
+
'Using generic column', spec)
|
|
77
|
+
|
|
78
|
+
def create_column_with_options(x):
|
|
79
|
+
return get_column_by_spec(x, column_options, use_numpy=use_numpy)
|
|
80
|
+
|
|
81
|
+
if spec == 'String' or spec.startswith('FixedString'):
|
|
82
|
+
return create_string_column(spec, column_options)
|
|
83
|
+
|
|
84
|
+
elif spec.startswith('Enum'):
|
|
85
|
+
return create_enum_column(spec, column_options)
|
|
86
|
+
|
|
87
|
+
elif spec.startswith('DateTime'):
|
|
88
|
+
return create_datetime_column(spec, column_options)
|
|
89
|
+
|
|
90
|
+
elif spec.startswith('Decimal'):
|
|
91
|
+
return create_decimal_column(spec, column_options)
|
|
92
|
+
|
|
93
|
+
elif spec.startswith('Array'):
|
|
94
|
+
return create_array_column(
|
|
95
|
+
spec, create_column_with_options, column_options
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
elif spec.startswith('Tuple'):
|
|
99
|
+
return create_tuple_column(
|
|
100
|
+
spec, create_column_with_options, column_options
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
elif spec.startswith('Nested'):
|
|
104
|
+
return create_nested_column(
|
|
105
|
+
spec, create_column_with_options, column_options
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
elif spec.startswith('Nullable'):
|
|
109
|
+
return create_nullable_column(spec, create_column_with_options)
|
|
110
|
+
|
|
111
|
+
elif spec.startswith('LowCardinality'):
|
|
112
|
+
return create_low_cardinality_column(
|
|
113
|
+
spec, create_column_with_options, column_options
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
elif spec.startswith('SimpleAggregateFunction'):
|
|
117
|
+
return create_simple_aggregate_function_column(
|
|
118
|
+
spec, create_column_with_options
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
elif spec.startswith('Map'):
|
|
122
|
+
return create_map_column(
|
|
123
|
+
spec, create_column_with_options, column_options
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
elif spec.startswith("Object('json')"):
|
|
127
|
+
return create_json_column(
|
|
128
|
+
spec, create_column_with_options, column_options
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
else:
|
|
132
|
+
for alias, primitive in aliases:
|
|
133
|
+
if spec.startswith(alias):
|
|
134
|
+
return create_column_with_options(
|
|
135
|
+
primitive + spec[len(alias):]
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
try:
|
|
139
|
+
cls = column_by_type[spec]
|
|
140
|
+
return cls(**column_options)
|
|
141
|
+
|
|
142
|
+
except KeyError:
|
|
143
|
+
raise errors.UnknownTypeError('Unknown type {}'.format(spec))
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def read_column(context, column_spec, n_items, buf, use_numpy=None,
|
|
147
|
+
has_custom_serialization=False):
|
|
148
|
+
column_options = {
|
|
149
|
+
'context': context,
|
|
150
|
+
'has_custom_serialization': has_custom_serialization
|
|
151
|
+
}
|
|
152
|
+
col = get_column_by_spec(column_spec, column_options, use_numpy=use_numpy)
|
|
153
|
+
col.read_state_prefix(buf)
|
|
154
|
+
return col.read_data(n_items, buf)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def write_column(context, column_name, column_spec, items, buf,
|
|
158
|
+
types_check=False):
|
|
159
|
+
column_options = {
|
|
160
|
+
'context': context,
|
|
161
|
+
'types_check': types_check
|
|
162
|
+
}
|
|
163
|
+
column = get_column_by_spec(column_spec, column_options)
|
|
164
|
+
|
|
165
|
+
try:
|
|
166
|
+
column.write_state_prefix(buf)
|
|
167
|
+
column.write_data(items, buf)
|
|
168
|
+
|
|
169
|
+
except column_exceptions.ColumnTypeMismatchException as e:
|
|
170
|
+
raise errors.TypeMismatchError(
|
|
171
|
+
'Type mismatch in VALUES section. '
|
|
172
|
+
'Expected {} got {}: {} for column "{}".'.format(
|
|
173
|
+
column_spec, type(e.args[0]), e.args[0], column_name
|
|
174
|
+
)
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
except (column_exceptions.StructPackException, OverflowError) as e:
|
|
178
|
+
error = e.args[0]
|
|
179
|
+
raise errors.TypeMismatchError(
|
|
180
|
+
'Type mismatch in VALUES section. '
|
|
181
|
+
'Repeat query with types_check=True for detailed info. '
|
|
182
|
+
'Column {}: {}'.format(
|
|
183
|
+
column_name, str(error)
|
|
184
|
+
)
|
|
185
|
+
)
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
|
|
2
|
+
from .. import defines
|
|
3
|
+
from .base import Column
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class String(Column):
|
|
7
|
+
ch_type = 'String'
|
|
8
|
+
py_types = (str, )
|
|
9
|
+
null_value = ''
|
|
10
|
+
|
|
11
|
+
default_encoding = defines.STRINGS_ENCODING
|
|
12
|
+
|
|
13
|
+
def __init__(self, encoding=default_encoding, **kwargs):
|
|
14
|
+
self.encoding = encoding
|
|
15
|
+
super(String, self).__init__(**kwargs)
|
|
16
|
+
|
|
17
|
+
def write_items(self, items, buf):
|
|
18
|
+
buf.write_strings(items, encoding=self.encoding)
|
|
19
|
+
|
|
20
|
+
def read_items(self, n_items, buf):
|
|
21
|
+
return buf.read_strings(n_items, encoding=self.encoding)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class ByteString(String):
|
|
25
|
+
py_types = (bytes, )
|
|
26
|
+
null_value = b''
|
|
27
|
+
|
|
28
|
+
def write_items(self, items, buf):
|
|
29
|
+
buf.write_strings(items)
|
|
30
|
+
|
|
31
|
+
def read_items(self, n_items, buf):
|
|
32
|
+
return buf.read_strings(n_items)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class FixedString(String):
|
|
36
|
+
ch_type = 'FixedString'
|
|
37
|
+
|
|
38
|
+
def __init__(self, length, **kwargs):
|
|
39
|
+
self.length = length
|
|
40
|
+
super(FixedString, self).__init__(**kwargs)
|
|
41
|
+
|
|
42
|
+
def read_items(self, n_items, buf):
|
|
43
|
+
return buf.read_fixed_strings(
|
|
44
|
+
n_items, self.length, encoding=self.encoding
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
def write_items(self, items, buf):
|
|
48
|
+
buf.write_fixed_strings(items, self.length, encoding=self.encoding)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class ByteFixedString(FixedString):
|
|
52
|
+
py_types = (bytearray, bytes)
|
|
53
|
+
null_value = b''
|
|
54
|
+
|
|
55
|
+
def read_items(self, n_items, buf):
|
|
56
|
+
return buf.read_fixed_strings(n_items, self.length)
|
|
57
|
+
|
|
58
|
+
def write_items(self, items, buf):
|
|
59
|
+
buf.write_fixed_strings(items, self.length)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def create_string_column(spec, column_options):
|
|
63
|
+
client_settings = column_options['context'].client_settings
|
|
64
|
+
strings_as_bytes = client_settings['strings_as_bytes']
|
|
65
|
+
encoding = client_settings.get('strings_encoding', String.default_encoding)
|
|
66
|
+
|
|
67
|
+
if spec == 'String':
|
|
68
|
+
cls = ByteString if strings_as_bytes else String
|
|
69
|
+
return cls(encoding=encoding, **column_options)
|
|
70
|
+
else:
|
|
71
|
+
length = int(spec[12:-1])
|
|
72
|
+
cls = ByteFixedString if strings_as_bytes else FixedString
|
|
73
|
+
return cls(length, encoding=encoding, **column_options)
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
|
|
2
|
+
from .base import Column
|
|
3
|
+
from .util import get_inner_spec, get_inner_columns_with_types
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class TupleColumn(Column):
|
|
7
|
+
py_types = (list, tuple)
|
|
8
|
+
|
|
9
|
+
def __init__(self, names, nested_columns, **kwargs):
|
|
10
|
+
self.names = names
|
|
11
|
+
self.nested_columns = nested_columns
|
|
12
|
+
client_settings = kwargs['context'].client_settings
|
|
13
|
+
settings = kwargs['context'].settings
|
|
14
|
+
self.namedtuple_as_json = (
|
|
15
|
+
settings.get('allow_experimental_object_type', False) and
|
|
16
|
+
client_settings.get('namedtuple_as_json', True)
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
super(TupleColumn, self).__init__(**kwargs)
|
|
20
|
+
self.null_value = tuple(x.null_value for x in nested_columns)
|
|
21
|
+
|
|
22
|
+
def write_data(self, items, buf):
|
|
23
|
+
items = self.prepare_items(items)
|
|
24
|
+
items = list(zip(*items))
|
|
25
|
+
|
|
26
|
+
for i, x in enumerate(self.nested_columns):
|
|
27
|
+
x.write_data(list(items[i]), buf)
|
|
28
|
+
|
|
29
|
+
def write_items(self, items, buf):
|
|
30
|
+
return self.write_data(items, buf)
|
|
31
|
+
|
|
32
|
+
def read_data(self, n_items, buf):
|
|
33
|
+
rv = [x.read_data(n_items, buf) for x in self.nested_columns]
|
|
34
|
+
rv = list(zip(*rv))
|
|
35
|
+
|
|
36
|
+
if self.names[0] and self.namedtuple_as_json:
|
|
37
|
+
return [dict(zip(self.names, x)) for x in rv]
|
|
38
|
+
else:
|
|
39
|
+
return rv
|
|
40
|
+
|
|
41
|
+
def read_items(self, n_items, buf):
|
|
42
|
+
return self.read_data(n_items, buf)
|
|
43
|
+
|
|
44
|
+
def read_state_prefix(self, buf):
|
|
45
|
+
super(TupleColumn, self).read_state_prefix(buf)
|
|
46
|
+
|
|
47
|
+
for x in self.nested_columns:
|
|
48
|
+
x.read_state_prefix(buf)
|
|
49
|
+
|
|
50
|
+
def write_state_prefix(self, buf):
|
|
51
|
+
super(TupleColumn, self).write_state_prefix(buf)
|
|
52
|
+
|
|
53
|
+
for x in self.nested_columns:
|
|
54
|
+
x.write_state_prefix(buf)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def create_tuple_column(spec, column_by_spec_getter, column_options):
|
|
58
|
+
inner_spec = get_inner_spec('Tuple', spec)
|
|
59
|
+
columns_with_types = get_inner_columns_with_types(inner_spec)
|
|
60
|
+
names, types = zip(*columns_with_types)
|
|
61
|
+
|
|
62
|
+
return TupleColumn(names, [column_by_spec_getter(x) for x in types],
|
|
63
|
+
**column_options)
|