1
- .. _internals-msgpack_ext :
2
-
3
- .. _msgpack_ext-decimal :
1
+ .. _internals-msgpack_ext :
4
2
5
3
----------------------------
6
4
MessagePack extensions
7
5
----------------------------
8
6
9
7
Tarantool uses predefined MessagePack extension types to represent some
10
- of the special values. Extension types include ``MP_DECIMAL ``, ``MP_UUID ``
11
- and ``MP_ERROR ``. These types require special attention from the connector
12
- developers, as they must be treated separately from the default MessagePack
13
- types, and correctly mapped to programming language types.
8
+ of the special values. Extension types include ``MP_DECIMAL ``, ``MP_UUID ``,
9
+ ``MP_ERROR ``, ``MP_DATETIME ``, and ``MP_INTERVAL ``.
10
+ These types require special attention from the connector developers,
11
+ as they must be treated separately from the default MessagePack types,
12
+ and correctly mapped to programming language types.
13
+
14
+ .. _msgpack_ext-decimal :
14
15
15
16
*******************************
16
17
The DECIMAL type
@@ -19,19 +20,19 @@ The DECIMAL type
19
20
The MessagePack EXT type ``MP_EXT `` together with the extension type
20
21
``MP_DECIMAL `` is a header for values of the DECIMAL type.
21
22
22
- MP_DECIMAL is 1.
23
+ `` MP_DECIMAL `` type is 1.
23
24
24
- `MessagePack spec <https://github.com/msgpack/msgpack/blob/master/spec.md >`_
25
+ `MessagePack specification <https://github.com/msgpack/msgpack/blob/master/spec.md >`_
25
26
defines two kinds of types:
26
27
27
- * ``fixext 1/2/4/8/16 `` types have fixed length so the length is not encoded explicitly;
28
+ * ``fixext 1/2/4/8/16 `` types have fixed length so the length is not encoded explicitly.
28
29
* ``ext 8/16/32 `` types require the data length to be encoded.
29
30
30
31
``MP_EXP `` + optional ``length `` imply using one of these types.
31
32
32
33
The decimal MessagePack representation looks like this:
33
34
34
- .. code-block :: none
35
+ .. code-block :: none
35
36
36
37
+--------+-------------------+------------+===============+
37
38
| MP_EXT | length (optional) | MP_DECIMAL | PackedDecimal |
@@ -42,7 +43,7 @@ Here ``length`` is the length of ``PackedDecimal`` field, and it is of type
42
43
43
44
``PackedDecimal `` has the following structure:
44
45
45
- .. code-block :: none
46
+ .. code-block :: none
46
47
47
48
<--- length bytes -->
48
49
+-------+=============+
@@ -61,7 +62,7 @@ The rightmost digit in the array is the least significant.
61
62
The first byte of the ``BCD `` array contains the first digit of the number,
62
63
represented as follows:
63
64
64
- .. code-block :: none
65
+ .. code-block :: none
65
66
66
67
| 4 bits | 4 bits |
67
68
= 0x = the 1st digit
@@ -70,7 +71,7 @@ represented as follows:
70
71
The last byte of the ``BCD `` array contains the last digit of the number and the
71
72
final ``nibble ``, represented as follows:
72
73
73
- .. code-block :: none
74
+ .. code-block :: none
74
75
75
76
| 4 bits | 4 bits |
76
77
= the last digit = nibble
@@ -84,21 +85,21 @@ The final ``nibble`` represents the number's sign:
84
85
85
86
The decimal ``-12.34 `` will be encoded as ``0xd6,0x01,0x02,0x01,0x23,0x4d ``:
86
87
87
- .. code-block :: none
88
+ .. code-block :: none
88
89
89
90
|MP_EXT (fixext 4) | MP_DECIMAL | scale | 1 | 2,3 | 4 (minus) |
90
91
| 0xd6 | 0x01 | 0x02 | 0x01 | 0x23 | 0x4d |
91
92
92
93
The decimal 0.000000000000000000000000000000000010
93
94
will be encoded as ``0xc7,0x03,0x01,0x24,0x01,0x0c ``:
94
95
95
- .. code-block :: none
96
+ .. code-block :: none
96
97
97
98
| MP_EXT (ext 8) | length | MP_DECIMAL | scale | 1 | 0 (plus) |
98
99
| 0xc7 | 0x03 | 0x01 | 0x24 | 0x01 | 0x0c |
99
100
100
101
101
- .. _msgpack_ext-uuid :
102
+ .. _msgpack_ext-uuid :
102
103
103
104
**********************************
104
105
The UUID type
@@ -107,31 +108,35 @@ The UUID type
107
108
The MessagePack EXT type ``MP_EXT `` together with the extension type
108
109
``MP_UUID `` for values of the UUID type. Since version :doc: `2.4.1 </release/2.4.1 >`.
109
110
110
- MP_UUID is 2.
111
+ `` MP_UUID `` type is 2.
111
112
112
- The `MessagePack spec <https://github.com/msgpack/msgpack/blob/master/spec.md >`_
113
- defines ``d8 `` to mean fixext with size 16, and a uuid 's size is always 16.
114
- So the uuid MessagePack representation looks like this:
113
+ The `MessagePack specification <https://github.com/msgpack/msgpack/blob/master/spec.md >`_
114
+ defines ``d8 `` to mean `` fixext `` with size 16, and a UUID 's size is always 16.
115
+ So the UUID MessagePack representation looks like this:
115
116
116
- .. code-block :: none
117
+ .. code-block :: none
117
118
118
119
+--------+------------+-----------------+
119
120
| MP_EXT | MP_UUID | UuidValue |
120
121
| = d8 | = 2 | = 16-byte value |
121
122
+--------+------------+-----------------+
122
123
123
-
124
124
The 16-byte value has 2 digits per byte.
125
- Typically it consists of 11 fields, which are encoded as big endian
126
- unsigned integers in the following order: time_low (4 bytes), time_mid
127
- (2 bytes), time_hi_and_version (2 bytes), clock_seq_hi_and_reserved (1
128
- byte), clock_seq_low (1 byte), node[0], ..., node[5] (1 byte each).
125
+ Typically, it consists of 11 fields, which are encoded as big-endian
126
+ unsigned integers in the following order:
127
+
128
+ * ``time_low `` (4 bytes)
129
+ * ``time_mid `` (2 bytes)
130
+ * ``time_hi_and_version `` (2 bytes)
131
+ * ``clock_seq_hi_and_reserved `` (1 byte)
132
+ * ``clock_seq_low `` (1 byte)
133
+ * ``node[0] ``, ..., ``node[5] `` (1 byte each)
129
134
130
135
Some of the functions in :ref: `Module uuid <uuid-module >` can produce values
131
136
which are compatible with the UUID data type.
132
137
For example, after
133
138
134
- .. code-block :: none
139
+ .. code-block :: none
135
140
136
141
uuid = require('uuid')
137
142
box.schema.space.create('t')
@@ -141,26 +146,28 @@ For example, after
141
146
142
147
a peek at the server response packet will show that it contains
143
148
144
- .. code-block :: none
149
+ .. code-block :: none
145
150
146
151
d8 02 f6 42 3b df b4 9e 49 13 b3 61 07 40 c9 70 2e 4b
147
152
148
- .. _msgpack_ext-error :
153
+ .. _msgpack_ext-error :
149
154
150
155
****************************************************
151
156
The ERROR type
152
157
****************************************************
153
158
154
159
Since version :doc: `2.4.1 </release/2.4.1 >`, responses for errors have extra information
155
- following what was described in :ref: ` Box protocol -- responses for errors
156
- <box_protocol-responses_error>`.
160
+ following what was described in
161
+ :ref: ` Box protocol -- responses for errors <box_protocol-responses_error >`.
157
162
This is a "compatible" enhancement, because clients that expect old-style
158
163
server responses should ignore map components that they do not recognize.
159
164
Notice, however, that there has been a renaming of a constant:
160
- formerly IPROTO_ERROR in ./box/iproto_constants.h was 0x31,
161
- now IPROTO_ERROR is 0x52 and IPROTO_ERROR_24 is 0x31.
165
+ formerly `` IPROTO_ERROR `` in :file: ` ./box/iproto_constants.h ` was `` 0x31 `` ,
166
+ now `` IPROTO_ERROR `` is `` 0x52 `` and `` IPROTO_ERROR_24 `` is `` 0x31 `` .
162
167
163
- .. code-block :: none
168
+ ``MP_ERROR `` type is 3.
169
+
170
+ .. code-block :: none
164
171
165
172
++=========================+============================+
166
173
|| | |
@@ -170,8 +177,8 @@ now IPROTO_ERROR is 0x52 and IPROTO_ERROR_24 is 0x31.
170
177
++=========================+============================+
171
178
MP_MAP
172
179
173
- The extra information, most of which is also in :doc: ` error object
174
- </reference/reference_lua/box_error/new>` fields, is:
180
+ The extra information, most of which is also in
181
+ :doc: ` error object </reference/reference_lua/box_error/new >` fields, is:
175
182
176
183
``MP_ERROR_TYPE `` (0x00) (MP_STR) Type that implies source, as in :samp: `{ error_object } .base_type `, for example "ClientError".
177
184
@@ -203,7 +210,7 @@ For example, in version 2.4.1 or later, if we try to create a duplicate space wi
203
210
``conn:eval([[box.schema.space.create('_space');]]) `` |br |
204
211
the server response will look like this:
205
212
206
- .. code-block :: none
213
+ .. code-block :: none
207
214
208
215
ce 00 00 00 88 MP_UINT = HEADER + BODY SIZE
209
216
83 MP_MAP, size 3 (i.e. 3 items in header)
@@ -233,3 +240,141 @@ the server response will look like this:
233
240
00 MP_UINT = error number
234
241
05 MP_ERROR_ERRCODE
235
242
0a MP_UINT = eror code ER_SPACE_EXISTS
243
+
244
+
245
+ .. _msgpack_ext-datetime :
246
+
247
+ **********************************
248
+ The DATETIME type
249
+ **********************************
250
+
251
+ Since version :doc: `2.10.0 </release/2.10.0 >`.
252
+ The MessagePack EXT type ``MP_EXT `` together with the extension type
253
+ ``MP_DATETIME `` is a header for values of the DATETIME type.
254
+ It creates a container with a payload of 8 or 16 bytes.
255
+
256
+ ``MP_DATETIME `` type is 4.
257
+
258
+ The `MessagePack specification <https://github.com/msgpack/msgpack/blob/master/spec.md >`_
259
+ defines ``d7 `` to mean ``fixext `` with size 8 or ``d8 `` to mean ``fixext `` with size 16.
260
+
261
+ So the datetime MessagePack representation looks like this:
262
+
263
+ .. code-block :: none
264
+
265
+ +---------+----------------+==========+-----------------+
266
+ | MP_EXT | MP_DATETIME | seconds | nsec; tzoffset; |
267
+ | = d7/d8 | = 4 | | tzindex; |
268
+ +---------+----------------+==========+-----------------+
269
+
270
+ MessagePack data contains:
271
+
272
+ * Seconds (8 bytes) as an unencoded 64-bit signed integer stored in the little-endian order.
273
+
274
+ * The optional fields (8 bytes), if any of them have a non-zero value.
275
+ The fields include ``nsec ``, ``tzoffset ``, and ``tzindex `` packed in the little-endian order.
276
+
277
+ For more information about the datetime type, see :ref: `datetime field type details <index-box_datetime >`
278
+ and :doc: `reference for the datetime module </reference/reference_lua/datetime >`.
279
+
280
+ .. _msgpack_ext-interval :
281
+
282
+ **********************************
283
+ The INTERVAL type
284
+ **********************************
285
+
286
+ Since version :doc: `2.10.0 </release/2.10.0 >`.
287
+ The MessagePack EXT type ``MP_EXT `` together with the extension type
288
+ ``MP_INTERVAL `` is a header for values of the INTERVAL type.
289
+
290
+ ``MP_INTERVAL `` type is 6.
291
+
292
+ The interval is saved as a variant of a map with a predefined number of known attribute names.
293
+ If some attributes are undefined, they are omitted from the generated payload.
294
+
295
+ The interval MessagePack representation looks like this:
296
+
297
+ .. code-block :: none
298
+
299
+ +--------+-------------------------+-------------+----------------+
300
+ | MP_EXT | Size of packed interval | MP_INTERVAL | PackedInterval |
301
+ +--------+-------------------------+-------------+----------------+
302
+
303
+ Packed interval consists of:
304
+
305
+ * Packed number of non-zero fields.
306
+ * Packed non-null fields.
307
+
308
+ Each packed field has the following structure:
309
+
310
+ .. code-block :: none
311
+
312
+ +----------+=====================+
313
+ | field ID | field value |
314
+ +----------+=====================+
315
+
316
+ The number of defined (non-null) fields can be zero.
317
+ In this case, the packed interval will be encoded as integer 0.
318
+
319
+ List of the field IDs:
320
+
321
+ * 0 -- year
322
+ * 1 -- month
323
+ * 2 -- week
324
+ * 3 -- day
325
+ * 4 -- hour
326
+ * 5 -- minute
327
+ * 6 -- second
328
+ * 7 -- nanosecond
329
+ * 8 -- adjust
330
+
331
+ **Example **
332
+
333
+ Interval value ``1 years, 200 months, -77 days `` is encoded in the following way:
334
+
335
+ .. code-block :: tarantoolsession
336
+
337
+ tarantool> I = datetime.interval.new{year = 1, month = 200, day = -77}
338
+ ---
339
+ ...
340
+
341
+ tarantool> I
342
+ ---
343
+ - +1 years, 200 months, -77 days
344
+ ...
345
+
346
+ tarantool> M = msgpack.encode(I)
347
+ ---
348
+ ...
349
+
350
+ tarantool> M
351
+ ---
352
+ - !!binary xwsGBAABAczIA9CzCAE=
353
+ ...
354
+
355
+ tarantool> tohex = function(s) return (s:gsub('.', function(c) return string.format('%02X ', string.byte(c)) end)) end
356
+ ---
357
+ ...
358
+
359
+ tarantool> tohex(M)
360
+ ---
361
+ - 'C7 0B 06 04 00 01 01 CC C8 03 D0 B3 08 01 '
362
+ ...
363
+
364
+ Where:
365
+
366
+ * C7 -- MP_EXT
367
+ * 0B -- size of a packed interval value (11 bytes)
368
+ * 06 -- MP_INTERVAL type
369
+ * 04 -- number of defined fields
370
+ * 00 -- field ID (year)
371
+ * 01 -- packed value ``1 ``
372
+ * 01 -- field ID (month)
373
+ * CCC8 -- packed value ``200 ``
374
+ * 03 -- field ID (day)
375
+ * D0B3 -- packed value ``-77 ``
376
+ * 08 -- field ID (adjust)
377
+ * 01 -- packed value ``1 `` (DT_LIMIT)
378
+
379
+ For more information about the interval type, see :ref: `interval field type details <index-box_interval >`
380
+ and :doc: `description of the datetime module </reference/reference_lua/datetime >`.
0 commit comments