clickhouse-driver 0.2.1__cp39-cp39-win_amd64.whl → 0.2.10__cp39-cp39-win_amd64.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 -9
- clickhouse_driver/block.py +227 -195
- clickhouse_driver/blockstreamprofileinfo.py +22 -22
- clickhouse_driver/bufferedreader.cp39-win_amd64.pyd +0 -0
- clickhouse_driver/bufferedwriter.cp39-win_amd64.pyd +0 -0
- clickhouse_driver/client.py +812 -666
- clickhouse_driver/clientinfo.py +119 -80
- clickhouse_driver/columns/arraycolumn.py +161 -150
- clickhouse_driver/columns/base.py +221 -147
- clickhouse_driver/columns/boolcolumn.py +7 -0
- clickhouse_driver/columns/datecolumn.py +108 -49
- clickhouse_driver/columns/datetimecolumn.py +203 -207
- clickhouse_driver/columns/decimalcolumn.py +116 -118
- clickhouse_driver/columns/enumcolumn.py +129 -119
- clickhouse_driver/columns/exceptions.py +12 -12
- clickhouse_driver/columns/floatcolumn.py +34 -34
- clickhouse_driver/columns/intcolumn.py +157 -157
- clickhouse_driver/columns/intervalcolumn.py +33 -33
- clickhouse_driver/columns/ipcolumn.py +118 -118
- clickhouse_driver/columns/jsoncolumn.py +37 -0
- clickhouse_driver/columns/largeint.cp39-win_amd64.pyd +0 -0
- clickhouse_driver/columns/lowcardinalitycolumn.py +142 -123
- clickhouse_driver/columns/mapcolumn.py +73 -58
- clickhouse_driver/columns/nestedcolumn.py +10 -0
- clickhouse_driver/columns/nothingcolumn.py +13 -13
- clickhouse_driver/columns/nullablecolumn.py +7 -7
- clickhouse_driver/columns/nullcolumn.py +15 -15
- clickhouse_driver/columns/numpy/base.py +47 -14
- clickhouse_driver/columns/numpy/boolcolumn.py +8 -0
- clickhouse_driver/columns/numpy/datecolumn.py +19 -12
- clickhouse_driver/columns/numpy/datetimecolumn.py +146 -145
- clickhouse_driver/columns/numpy/floatcolumn.py +24 -13
- clickhouse_driver/columns/numpy/intcolumn.py +43 -43
- clickhouse_driver/columns/numpy/lowcardinalitycolumn.py +96 -83
- clickhouse_driver/columns/numpy/service.py +58 -80
- clickhouse_driver/columns/numpy/stringcolumn.py +78 -76
- clickhouse_driver/columns/numpy/tuplecolumn.py +37 -0
- clickhouse_driver/columns/service.py +185 -131
- clickhouse_driver/columns/simpleaggregatefunctioncolumn.py +7 -7
- clickhouse_driver/columns/stringcolumn.py +73 -73
- clickhouse_driver/columns/tuplecolumn.py +63 -65
- clickhouse_driver/columns/util.py +61 -0
- clickhouse_driver/columns/uuidcolumn.py +64 -64
- clickhouse_driver/compression/__init__.py +32 -28
- clickhouse_driver/compression/base.py +87 -52
- clickhouse_driver/compression/lz4.py +21 -55
- clickhouse_driver/compression/lz4hc.py +9 -9
- clickhouse_driver/compression/zstd.py +20 -51
- clickhouse_driver/connection.py +825 -632
- clickhouse_driver/context.py +36 -36
- clickhouse_driver/dbapi/__init__.py +62 -62
- clickhouse_driver/dbapi/connection.py +99 -96
- clickhouse_driver/dbapi/cursor.py +370 -368
- clickhouse_driver/dbapi/errors.py +40 -40
- clickhouse_driver/dbapi/extras.py +73 -0
- clickhouse_driver/defines.py +58 -42
- clickhouse_driver/errors.py +453 -446
- clickhouse_driver/log.py +48 -44
- clickhouse_driver/numpy/block.py +8 -8
- clickhouse_driver/numpy/helpers.py +28 -25
- clickhouse_driver/numpy/result.py +123 -123
- clickhouse_driver/opentelemetry.py +43 -0
- clickhouse_driver/progress.py +44 -32
- clickhouse_driver/protocol.py +130 -105
- clickhouse_driver/queryprocessingstage.py +8 -8
- clickhouse_driver/reader.py +69 -69
- clickhouse_driver/readhelpers.py +26 -26
- clickhouse_driver/result.py +144 -144
- clickhouse_driver/settings/available.py +405 -405
- clickhouse_driver/settings/types.py +50 -50
- clickhouse_driver/settings/writer.py +34 -29
- clickhouse_driver/streams/compressed.py +88 -88
- clickhouse_driver/streams/native.py +108 -90
- clickhouse_driver/util/compat.py +39 -0
- clickhouse_driver/util/escape.py +94 -55
- clickhouse_driver/util/helpers.py +173 -57
- clickhouse_driver/varint.cp39-win_amd64.pyd +0 -0
- clickhouse_driver/writer.py +67 -67
- clickhouse_driver-0.2.10.dist-info/METADATA +215 -0
- clickhouse_driver-0.2.10.dist-info/RECORD +89 -0
- {clickhouse_driver-0.2.1.dist-info → clickhouse_driver-0.2.10.dist-info}/WHEEL +1 -1
- {clickhouse_driver-0.2.1.dist-info → clickhouse_driver-0.2.10.dist-info/licenses}/LICENSE +21 -21
- clickhouse_driver-0.2.1.dist-info/METADATA +0 -24
- clickhouse_driver-0.2.1.dist-info/RECORD +0 -80
- {clickhouse_driver-0.2.1.dist-info → clickhouse_driver-0.2.10.dist-info}/top_level.txt +0 -0
clickhouse_driver/clientinfo.py
CHANGED
|
@@ -1,80 +1,119 @@
|
|
|
1
|
-
import socket
|
|
2
|
-
import getpass
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
from . import
|
|
6
|
-
from .
|
|
7
|
-
from .
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def __init__(self, client_name):
|
|
38
|
-
self.query_kind = ClientInfo.QueryKind.NO_QUERY
|
|
39
|
-
|
|
40
|
-
try:
|
|
41
|
-
self.os_user = getpass.getuser()
|
|
42
|
-
except KeyError:
|
|
43
|
-
self.os_user = ''
|
|
44
|
-
self.client_hostname = socket.gethostname()
|
|
45
|
-
self.client_name = client_name
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
1
|
+
import socket
|
|
2
|
+
import getpass
|
|
3
|
+
from time import time
|
|
4
|
+
|
|
5
|
+
from . import defines
|
|
6
|
+
from . import errors
|
|
7
|
+
from .opentelemetry import OpenTelemetryTraceContext
|
|
8
|
+
from .varint import write_varint
|
|
9
|
+
from .writer import write_binary_str, write_binary_uint8, \
|
|
10
|
+
write_binary_uint64, write_binary_uint128
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ClientInfo(object):
|
|
14
|
+
class Interface(object):
|
|
15
|
+
TCP = 1
|
|
16
|
+
HTTP = 2
|
|
17
|
+
|
|
18
|
+
class QueryKind(object):
|
|
19
|
+
# Uninitialized object.
|
|
20
|
+
NO_QUERY = 0
|
|
21
|
+
|
|
22
|
+
INITIAL_QUERY = 1
|
|
23
|
+
|
|
24
|
+
# Query that was initiated by another query for distributed query
|
|
25
|
+
# execution.
|
|
26
|
+
SECONDARY_QUERY = 2
|
|
27
|
+
|
|
28
|
+
client_version_major = defines.CLIENT_VERSION_MAJOR
|
|
29
|
+
client_version_minor = defines.CLIENT_VERSION_MINOR
|
|
30
|
+
client_version_patch = defines.CLIENT_VERSION_PATCH
|
|
31
|
+
interface = Interface.TCP
|
|
32
|
+
|
|
33
|
+
initial_user = ''
|
|
34
|
+
initial_query_id = ''
|
|
35
|
+
initial_address = '0.0.0.0:0'
|
|
36
|
+
|
|
37
|
+
def __init__(self, client_name, context, client_revision):
|
|
38
|
+
self.query_kind = ClientInfo.QueryKind.NO_QUERY
|
|
39
|
+
|
|
40
|
+
try:
|
|
41
|
+
self.os_user = getpass.getuser()
|
|
42
|
+
except (KeyError, OSError):
|
|
43
|
+
self.os_user = ''
|
|
44
|
+
self.client_hostname = socket.gethostname()
|
|
45
|
+
self.client_name = client_name
|
|
46
|
+
self.client_revision = client_revision
|
|
47
|
+
|
|
48
|
+
self.client_trace_context = OpenTelemetryTraceContext(
|
|
49
|
+
context.client_settings['opentelemetry_traceparent'],
|
|
50
|
+
context.client_settings['opentelemetry_tracestate']
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
self.quota_key = context.client_settings['quota_key']
|
|
54
|
+
self.distributed_depth = 0
|
|
55
|
+
self.initial_query_start_time_microseconds = int(time() * 1000000)
|
|
56
|
+
|
|
57
|
+
super(ClientInfo, self).__init__()
|
|
58
|
+
|
|
59
|
+
@property
|
|
60
|
+
def empty(self):
|
|
61
|
+
return self.query_kind == ClientInfo.QueryKind.NO_QUERY
|
|
62
|
+
|
|
63
|
+
def write(self, server_revision, fout):
|
|
64
|
+
revision = server_revision
|
|
65
|
+
if server_revision < defines.DBMS_MIN_REVISION_WITH_CLIENT_INFO:
|
|
66
|
+
raise errors.LogicalError('Method ClientInfo.write is called '
|
|
67
|
+
'for unsupported server revision')
|
|
68
|
+
|
|
69
|
+
write_binary_uint8(self.query_kind, fout)
|
|
70
|
+
if self.empty:
|
|
71
|
+
return
|
|
72
|
+
|
|
73
|
+
write_binary_str(self.initial_user, fout)
|
|
74
|
+
write_binary_str(self.initial_query_id, fout)
|
|
75
|
+
write_binary_str(self.initial_address, fout)
|
|
76
|
+
|
|
77
|
+
if (
|
|
78
|
+
revision >=
|
|
79
|
+
defines.DBMS_MIN_PROTOCOL_VERSION_WITH_INITIAL_QUERY_START_TIME
|
|
80
|
+
):
|
|
81
|
+
write_binary_uint64(
|
|
82
|
+
self.initial_query_start_time_microseconds, fout
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
write_binary_uint8(self.interface, fout)
|
|
86
|
+
|
|
87
|
+
write_binary_str(self.os_user, fout)
|
|
88
|
+
write_binary_str(self.client_hostname, fout)
|
|
89
|
+
write_binary_str(self.client_name, fout)
|
|
90
|
+
write_varint(self.client_version_major, fout)
|
|
91
|
+
write_varint(self.client_version_minor, fout)
|
|
92
|
+
write_varint(self.client_revision, fout)
|
|
93
|
+
|
|
94
|
+
if revision >= defines.DBMS_MIN_REVISION_WITH_QUOTA_KEY_IN_CLIENT_INFO:
|
|
95
|
+
write_binary_str(self.quota_key, fout)
|
|
96
|
+
|
|
97
|
+
if revision >= \
|
|
98
|
+
defines.DBMS_MIN_PROTOCOL_VERSION_WITH_DISTRIBUTED_DEPTH:
|
|
99
|
+
write_varint(self.distributed_depth, fout)
|
|
100
|
+
|
|
101
|
+
if revision >= defines.DBMS_MIN_REVISION_WITH_VERSION_PATCH:
|
|
102
|
+
write_varint(self.client_version_patch, fout)
|
|
103
|
+
|
|
104
|
+
if revision >= defines.DBMS_MIN_REVISION_WITH_OPENTELEMETRY:
|
|
105
|
+
if self.client_trace_context.trace_id is not None:
|
|
106
|
+
# Have OpenTelemetry header.
|
|
107
|
+
write_binary_uint8(1, fout)
|
|
108
|
+
write_binary_uint128(self.client_trace_context.trace_id, fout)
|
|
109
|
+
write_binary_uint64(self.client_trace_context.span_id, fout)
|
|
110
|
+
write_binary_str(self.client_trace_context.tracestate, fout)
|
|
111
|
+
write_binary_uint8(self.client_trace_context.trace_flags, fout)
|
|
112
|
+
else:
|
|
113
|
+
# Don't have OpenTelemetry header.
|
|
114
|
+
write_binary_uint8(0, fout)
|
|
115
|
+
|
|
116
|
+
if revision >= defines.DBMS_MIN_REVISION_WITH_PARALLEL_REPLICAS:
|
|
117
|
+
write_varint(0, fout) # collaborate_with_initiator
|
|
118
|
+
write_varint(0, fout) # count_participating_replicas
|
|
119
|
+
write_varint(0, fout) # number_of_current_replica
|
|
@@ -1,150 +1,161 @@
|
|
|
1
|
-
from itertools import chain
|
|
2
|
-
from struct import Struct
|
|
3
|
-
|
|
4
|
-
from .base import Column
|
|
5
|
-
from .intcolumn import UInt64Column
|
|
6
|
-
from ..util.helpers import pairwise
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class ArrayColumn(Column):
|
|
10
|
-
"""
|
|
11
|
-
Nested arrays written in flatten form after information about their
|
|
12
|
-
sizes (offsets really).
|
|
13
|
-
One element of array of arrays can be represented as tree:
|
|
14
|
-
(0 depth) [[3, 4], [5, 6]]
|
|
15
|
-
| |
|
|
16
|
-
(1 depth) [3, 4] [5, 6]
|
|
17
|
-
| | | |
|
|
18
|
-
(leaf) 3 4 5 6
|
|
19
|
-
|
|
20
|
-
Offsets (sizes) written in breadth-first search order. In example above
|
|
21
|
-
following sequence of offset will be written: 4 -> 2 -> 4
|
|
22
|
-
1) size of whole array: 4
|
|
23
|
-
2) size of array 1 in depth=1: 2
|
|
24
|
-
3) size of array 2 plus size of all array before in depth=1: 2 + 2 = 4
|
|
25
|
-
|
|
26
|
-
After sizes info comes flatten data: 3 -> 4 -> 5 -> 6
|
|
27
|
-
"""
|
|
28
|
-
py_types = (list, tuple)
|
|
29
|
-
|
|
30
|
-
def __init__(self, nested_column, **kwargs):
|
|
31
|
-
self.
|
|
32
|
-
self.
|
|
33
|
-
self.
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
self.
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
self.
|
|
47
|
-
self.
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
if
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
self.
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
1
|
+
from itertools import chain
|
|
2
|
+
from struct import Struct
|
|
3
|
+
|
|
4
|
+
from .base import Column
|
|
5
|
+
from .intcolumn import UInt64Column
|
|
6
|
+
from ..util.helpers import pairwise
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ArrayColumn(Column):
|
|
10
|
+
"""
|
|
11
|
+
Nested arrays written in flatten form after information about their
|
|
12
|
+
sizes (offsets really).
|
|
13
|
+
One element of array of arrays can be represented as tree:
|
|
14
|
+
(0 depth) [[3, 4], [5, 6]]
|
|
15
|
+
| |
|
|
16
|
+
(1 depth) [3, 4] [5, 6]
|
|
17
|
+
| | | |
|
|
18
|
+
(leaf) 3 4 5 6
|
|
19
|
+
|
|
20
|
+
Offsets (sizes) written in breadth-first search order. In example above
|
|
21
|
+
following sequence of offset will be written: 4 -> 2 -> 4
|
|
22
|
+
1) size of whole array: 4
|
|
23
|
+
2) size of array 1 in depth=1: 2
|
|
24
|
+
3) size of array 2 plus size of all array before in depth=1: 2 + 2 = 4
|
|
25
|
+
|
|
26
|
+
After sizes info comes flatten data: 3 -> 4 -> 5 -> 6
|
|
27
|
+
"""
|
|
28
|
+
py_types = (list, tuple)
|
|
29
|
+
|
|
30
|
+
def __init__(self, nested_column, **kwargs):
|
|
31
|
+
self.init_kwargs = kwargs
|
|
32
|
+
self.size_column = UInt64Column(**kwargs)
|
|
33
|
+
self.nested_column = nested_column
|
|
34
|
+
self._write_depth_0_size = True
|
|
35
|
+
super(ArrayColumn, self).__init__(**kwargs)
|
|
36
|
+
self.null_value = []
|
|
37
|
+
|
|
38
|
+
def write_data(self, data, buf):
|
|
39
|
+
# Column of Array(T) is stored in "compact" format and passed to server
|
|
40
|
+
# wrapped into another Array without size of wrapper array.
|
|
41
|
+
self.nested_column = ArrayColumn(
|
|
42
|
+
self.nested_column, **self.init_kwargs
|
|
43
|
+
)
|
|
44
|
+
self.nested_column.nullable = self.nullable
|
|
45
|
+
self.nullable = False
|
|
46
|
+
self._write_depth_0_size = False
|
|
47
|
+
self._write(data, buf)
|
|
48
|
+
|
|
49
|
+
def read_data(self, n_rows, buf):
|
|
50
|
+
self.nested_column = ArrayColumn(
|
|
51
|
+
self.nested_column, **self.init_kwargs
|
|
52
|
+
)
|
|
53
|
+
self.nested_column.nullable = self.nullable
|
|
54
|
+
self.nullable = False
|
|
55
|
+
return self._read(n_rows, buf)[0]
|
|
56
|
+
|
|
57
|
+
def _write_sizes(self, value, buf):
|
|
58
|
+
nulls_map = []
|
|
59
|
+
|
|
60
|
+
column = self
|
|
61
|
+
sizes = [len(value)] if self._write_depth_0_size else []
|
|
62
|
+
|
|
63
|
+
while True:
|
|
64
|
+
nested_column = column.nested_column
|
|
65
|
+
if not isinstance(nested_column, ArrayColumn):
|
|
66
|
+
if column.nullable:
|
|
67
|
+
nulls_map = [x is None for x in value]
|
|
68
|
+
break
|
|
69
|
+
|
|
70
|
+
offset = 0
|
|
71
|
+
new_value = []
|
|
72
|
+
for x in value:
|
|
73
|
+
offset += len(x)
|
|
74
|
+
sizes.append(offset)
|
|
75
|
+
new_value.extend(x)
|
|
76
|
+
|
|
77
|
+
value = new_value
|
|
78
|
+
column = nested_column
|
|
79
|
+
|
|
80
|
+
if nulls_map:
|
|
81
|
+
self._write_nulls_map(nulls_map, buf)
|
|
82
|
+
|
|
83
|
+
ns = Struct('<{}Q'.format(len(sizes)))
|
|
84
|
+
buf.write(ns.pack(*sizes))
|
|
85
|
+
|
|
86
|
+
def _write_data(self, value, buf):
|
|
87
|
+
if self.nullable:
|
|
88
|
+
value = value or []
|
|
89
|
+
|
|
90
|
+
if isinstance(self.nested_column, ArrayColumn):
|
|
91
|
+
value = list(chain.from_iterable(value))
|
|
92
|
+
|
|
93
|
+
if value:
|
|
94
|
+
self.nested_column._write_data(value, buf)
|
|
95
|
+
|
|
96
|
+
def _write_nulls_data(self, value, buf):
|
|
97
|
+
if self.nullable:
|
|
98
|
+
value = value or []
|
|
99
|
+
|
|
100
|
+
if isinstance(self.nested_column, ArrayColumn):
|
|
101
|
+
value = list(chain.from_iterable(value))
|
|
102
|
+
self.nested_column._write_nulls_data(value, buf)
|
|
103
|
+
else:
|
|
104
|
+
if self.nested_column.nullable:
|
|
105
|
+
self.nested_column._write_nulls_map(value, buf)
|
|
106
|
+
|
|
107
|
+
def _write(self, value, buf):
|
|
108
|
+
value = self.prepare_items(value)
|
|
109
|
+
self._write_sizes(value, buf)
|
|
110
|
+
self._write_nulls_data(value, buf)
|
|
111
|
+
self._write_data(value, buf)
|
|
112
|
+
|
|
113
|
+
def read_state_prefix(self, buf):
|
|
114
|
+
super(ArrayColumn, self).read_state_prefix(buf)
|
|
115
|
+
|
|
116
|
+
self.nested_column.read_state_prefix(buf)
|
|
117
|
+
|
|
118
|
+
def write_state_prefix(self, buf):
|
|
119
|
+
super(ArrayColumn, self).write_state_prefix(buf)
|
|
120
|
+
|
|
121
|
+
self.nested_column.write_state_prefix(buf)
|
|
122
|
+
|
|
123
|
+
def _read(self, size, buf):
|
|
124
|
+
slices_series = [[0, size]]
|
|
125
|
+
nested_column = self.nested_column
|
|
126
|
+
|
|
127
|
+
cur_level_slice_size = size
|
|
128
|
+
cur_level_slice = None
|
|
129
|
+
while (isinstance(nested_column, ArrayColumn)):
|
|
130
|
+
if cur_level_slice is None:
|
|
131
|
+
cur_level_slice = [0]
|
|
132
|
+
ns = Struct('<{}Q'.format(cur_level_slice_size))
|
|
133
|
+
nested_sizes = ns.unpack(buf.read(ns.size))
|
|
134
|
+
cur_level_slice.extend(nested_sizes)
|
|
135
|
+
slices_series.append(cur_level_slice)
|
|
136
|
+
cur_level_slice = None
|
|
137
|
+
cur_level_slice_size = nested_sizes[-1] if len(nested_sizes) > 0 \
|
|
138
|
+
else 0
|
|
139
|
+
nested_column = nested_column.nested_column
|
|
140
|
+
|
|
141
|
+
n_items = cur_level_slice_size if size > 0 else 0
|
|
142
|
+
nulls_map = None
|
|
143
|
+
if nested_column.nullable:
|
|
144
|
+
nulls_map = self._read_nulls_map(n_items, buf)
|
|
145
|
+
|
|
146
|
+
data = []
|
|
147
|
+
if n_items:
|
|
148
|
+
data = list(nested_column._read_data(
|
|
149
|
+
n_items, buf, nulls_map=nulls_map
|
|
150
|
+
))
|
|
151
|
+
|
|
152
|
+
# Build nested structure.
|
|
153
|
+
for slices in reversed(slices_series):
|
|
154
|
+
data = [data[begin:end] for begin, end in pairwise(slices)]
|
|
155
|
+
|
|
156
|
+
return tuple(data)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def create_array_column(spec, column_by_spec_getter, column_options):
|
|
160
|
+
inner = spec[6:-1]
|
|
161
|
+
return ArrayColumn(column_by_spec_getter(inner), **column_options)
|