clickhouse-driver 0.2.8__cp37-cp37m-macosx_10_9_x86_64.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.
Files changed (89) hide show
  1. clickhouse_driver/__init__.py +9 -0
  2. clickhouse_driver/block.py +227 -0
  3. clickhouse_driver/blockstreamprofileinfo.py +22 -0
  4. clickhouse_driver/bufferedreader.cpython-37m-darwin.so +0 -0
  5. clickhouse_driver/bufferedwriter.cpython-37m-darwin.so +0 -0
  6. clickhouse_driver/client.py +896 -0
  7. clickhouse_driver/clientinfo.py +119 -0
  8. clickhouse_driver/columns/__init__.py +0 -0
  9. clickhouse_driver/columns/arraycolumn.py +161 -0
  10. clickhouse_driver/columns/base.py +221 -0
  11. clickhouse_driver/columns/boolcolumn.py +7 -0
  12. clickhouse_driver/columns/datecolumn.py +108 -0
  13. clickhouse_driver/columns/datetimecolumn.py +202 -0
  14. clickhouse_driver/columns/decimalcolumn.py +116 -0
  15. clickhouse_driver/columns/enumcolumn.py +119 -0
  16. clickhouse_driver/columns/exceptions.py +12 -0
  17. clickhouse_driver/columns/floatcolumn.py +34 -0
  18. clickhouse_driver/columns/intcolumn.py +157 -0
  19. clickhouse_driver/columns/intervalcolumn.py +33 -0
  20. clickhouse_driver/columns/ipcolumn.py +118 -0
  21. clickhouse_driver/columns/jsoncolumn.py +37 -0
  22. clickhouse_driver/columns/largeint.cpython-37m-darwin.so +0 -0
  23. clickhouse_driver/columns/lowcardinalitycolumn.py +142 -0
  24. clickhouse_driver/columns/mapcolumn.py +73 -0
  25. clickhouse_driver/columns/nestedcolumn.py +10 -0
  26. clickhouse_driver/columns/nothingcolumn.py +13 -0
  27. clickhouse_driver/columns/nullablecolumn.py +7 -0
  28. clickhouse_driver/columns/nullcolumn.py +15 -0
  29. clickhouse_driver/columns/numpy/__init__.py +0 -0
  30. clickhouse_driver/columns/numpy/base.py +47 -0
  31. clickhouse_driver/columns/numpy/boolcolumn.py +8 -0
  32. clickhouse_driver/columns/numpy/datecolumn.py +19 -0
  33. clickhouse_driver/columns/numpy/datetimecolumn.py +143 -0
  34. clickhouse_driver/columns/numpy/floatcolumn.py +24 -0
  35. clickhouse_driver/columns/numpy/intcolumn.py +43 -0
  36. clickhouse_driver/columns/numpy/lowcardinalitycolumn.py +96 -0
  37. clickhouse_driver/columns/numpy/service.py +58 -0
  38. clickhouse_driver/columns/numpy/stringcolumn.py +78 -0
  39. clickhouse_driver/columns/numpy/tuplecolumn.py +37 -0
  40. clickhouse_driver/columns/service.py +185 -0
  41. clickhouse_driver/columns/simpleaggregatefunctioncolumn.py +7 -0
  42. clickhouse_driver/columns/stringcolumn.py +73 -0
  43. clickhouse_driver/columns/tuplecolumn.py +63 -0
  44. clickhouse_driver/columns/util.py +60 -0
  45. clickhouse_driver/columns/uuidcolumn.py +64 -0
  46. clickhouse_driver/compression/__init__.py +28 -0
  47. clickhouse_driver/compression/base.py +87 -0
  48. clickhouse_driver/compression/lz4.py +21 -0
  49. clickhouse_driver/compression/lz4hc.py +9 -0
  50. clickhouse_driver/compression/zstd.py +20 -0
  51. clickhouse_driver/connection.py +784 -0
  52. clickhouse_driver/context.py +36 -0
  53. clickhouse_driver/dbapi/__init__.py +62 -0
  54. clickhouse_driver/dbapi/connection.py +99 -0
  55. clickhouse_driver/dbapi/cursor.py +370 -0
  56. clickhouse_driver/dbapi/errors.py +40 -0
  57. clickhouse_driver/dbapi/extras.py +73 -0
  58. clickhouse_driver/defines.py +55 -0
  59. clickhouse_driver/errors.py +453 -0
  60. clickhouse_driver/log.py +48 -0
  61. clickhouse_driver/numpy/__init__.py +0 -0
  62. clickhouse_driver/numpy/block.py +8 -0
  63. clickhouse_driver/numpy/helpers.py +25 -0
  64. clickhouse_driver/numpy/result.py +123 -0
  65. clickhouse_driver/opentelemetry.py +43 -0
  66. clickhouse_driver/progress.py +38 -0
  67. clickhouse_driver/protocol.py +114 -0
  68. clickhouse_driver/queryprocessingstage.py +8 -0
  69. clickhouse_driver/reader.py +69 -0
  70. clickhouse_driver/readhelpers.py +26 -0
  71. clickhouse_driver/result.py +144 -0
  72. clickhouse_driver/settings/__init__.py +0 -0
  73. clickhouse_driver/settings/available.py +405 -0
  74. clickhouse_driver/settings/types.py +50 -0
  75. clickhouse_driver/settings/writer.py +34 -0
  76. clickhouse_driver/streams/__init__.py +0 -0
  77. clickhouse_driver/streams/compressed.py +88 -0
  78. clickhouse_driver/streams/native.py +102 -0
  79. clickhouse_driver/util/__init__.py +0 -0
  80. clickhouse_driver/util/compat.py +39 -0
  81. clickhouse_driver/util/escape.py +94 -0
  82. clickhouse_driver/util/helpers.py +57 -0
  83. clickhouse_driver/varint.cpython-37m-darwin.so +0 -0
  84. clickhouse_driver/writer.py +67 -0
  85. clickhouse_driver-0.2.8.dist-info/LICENSE +21 -0
  86. clickhouse_driver-0.2.8.dist-info/METADATA +201 -0
  87. clickhouse_driver-0.2.8.dist-info/RECORD +89 -0
  88. clickhouse_driver-0.2.8.dist-info/WHEEL +5 -0
  89. clickhouse_driver-0.2.8.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,7 @@
1
+
2
+
3
+ def create_simple_aggregate_function_column(spec, column_by_spec_getter):
4
+ # SimpleAggregateFunction(Func, Type) -> Type
5
+ inner = spec[24:-1].split(',', 1)[1].strip()
6
+ nested = column_by_spec_getter(inner)
7
+ return nested
@@ -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)