Submodule box.tuple¶
Overview¶
The box.tuple
submodule provides read-only access for the tuple
userdata type. It allows, for a single tuple: selective
retrieval of the field contents, retrieval of information about size, iteration
over all the fields, and conversion to a Lua table.
Index¶
Below is a list of all box.tuple
functions.
Name | Use |
---|---|
box.tuple.new() | Create a tuple |
box.tuple.is() | Check whether a given object is a tuple cdata object |
#tuple_object | Count tuple fields |
tuple_object:bsize() | Get count of bytes in a tuple |
tuple_object[field-number] | Get a tuple’s field by specifying a number |
tuple_object[field-name] | Get a tuple’s field by specifying a name |
tuple_object[field-path] | Get a tuple’s fields or parts by specifying a path |
tuple_object:find() | Get the number of the first field matching the search value |
tuple_object:findall() | Get the number of all fields matching the search value |
tuple_object:next() | Get the next field value from tuple |
tuple_object:ipairs() | Prepare for iterating |
tuple_object:pairs() | Prepare for iterating |
tuple_object:totable() | Get a tuple’s fields as a table |
tuple_object:tomap() | Get a tuple’s fields as a table along with key:value pairs |
tuple_object:transform() | Remove (and replace) a tuple’s fields |
tuple_object:unpack() | Get a tuple’s fields |
tuple_object:update() | Update a tuple |
tuple_object:upsert() | Update a tuple ignoring errors |
-
box.tuple.
new
(value)¶ Construct a new tuple from either a scalar or a Lua table. Alternatively, one can get new tuples from tarantool’s select or insert or replace or update requests, which can be regarded as statements that do
new()
implicitly.Parameters: - value (lua-value) – the value that will become the tuple contents.
Return: a new tuple
Rtype: tuple
In the following example,
x
will be a new table object containing one tuple andt
will be a new tuple object. Sayingt
returns the entire tuplet
.Example:
tarantool> x = box.space.tester:insert{ > 33, > tonumber('1'), > tonumber64('2') > }:totable() --- ... tarantool> t = box.tuple.new{'abc', 'def', 'ghi', 'abc'} --- ... tarantool> t --- - ['abc', 'def', 'ghi', 'abc'] ...
-
box.tuple.
is
(object)¶ A function to check whether a given object is a tuple cdata object. Never raises nor returns an error.
Return: true or false Rtype: boolean
-
object
tuple_object
¶ -
#
<tuple_object>
¶ The
#
operator in Lua means “return count of components”. So, ift
is a tuple instance,#t
will return the number of fields.Rtype: number In the following example, a tuple named
t
is created and then the number of fields int
is returned.tarantool> t = box.tuple.new{'Fld#1', 'Fld#2', 'Fld#3', 'Fld#4'} --- ... tarantool> #t --- - 4 ...
-
tuple_object:
bsize
()¶ If
t
is a tuple instance,t:bsize()
will return the number of bytes in the tuple. With both the memtx storage engine and the vinyl storage engine the default maximum is one megabyte (memtx_max_tuple_size or vinyl_max_tuple_size). Every field has one or more “length” bytes preceding the actual contents, sobsize()
returns a value which is slightly greater than the sum of the lengths of the contents.The value does not include the size of “struct tuple” (for the current size of this structure look in the tuple.h file in Tarantool’s source code).
Return: number of bytes Rtype: number In the following example, a tuple named
t
is created which has three fields, and for each field it takes one byte to store the length and three bytes to store the contents, and then there is one more byte to store a count of the number of fields, sobsize()
returns3*(1+3)+1
. This is the same as the size of the string that msgpack.encode({‘aaa’,’bbb’,’ccc’}) would return.tarantool> t = box.tuple.new{'aaa', 'bbb', 'ccc'} --- ... tarantool> t:bsize() --- - 13 ...
-
<tuple_object>
[field-number]¶ If
t
is a tuple instance,t[field-number]
will return the field numbered field-number in the tuple. The first field ist[1]
.Return: field value. Rtype: lua-value In the following example, a tuple named
t
is created and then the second field int
is returned.tarantool> t = box.tuple.new{'Fld#1', 'Fld#2', 'Fld#3', 'Fld#4'} --- ... tarantool> t[2] --- - Fld#2 ...
-
<tuple_object>
[field-name] If
t
is a tuple instance,t['field-name']
will return the field named ‘field-name’ in the tuple. Fields have names if the tuple has been retrieved from a space that has an associated format.t[lua-variable-name]
will do the same thing iflua-variable-name
contains'field-name'
.There is a variation which the Lua manual calls “syntactic sugar”: use
t.field-name
as an equivalent oft['field-name']
.Return: field value. Rtype: lua-value In the following example, a tuple named
t
is returned fromreplace
and then the second field int
named ‘field2’ is returned.tarantool> format = {} --- ... tarantool> format[1] = {name = 'field1', type = 'unsigned'} --- ... tarantool> format[2] = {name = 'field2', type = 'string'} --- ... tarantool> s = box.schema.space.create('test', {format = format}) --- ... tarantool> pk = s:create_index('pk') --- ... tarantool> t = s:replace{1, 'Я'} --- ... tarantool> t['field2'] --- - Я ...
-
<tuple_object>
[field-path] If
t
is a tuple instance,t['path']
will return the field or subset of fields that are inpath
.path
must be a well formed JSON specification.path
may contain field names if the tuple has been retrieved from a space that has an associated format.To prevent ambiguity, Tarantool first tries to interpret the request as tuple_object[field-number] or tuple_object[field-name]. If and only if that fails, Tarantool tries to interpret the request as
tuple_object[field-path]
.The path must be a well formed JSON specification, but it may be preceded by ‘.’. The ‘.’ is a signal that the path acts as a suffix for the tuple.
The advantage of specifying a path is that Tarantool will use it to search through a tuple body and get only the tuple part, or parts, that are actually necessary.
In the following example, a tuple named
t
is returned fromreplace
and then only the relevant part (in this case, matching a name) of a relevant field is returned. Namely: the second field, the sixth part, the value following ‘value=’.tarantool> format = {} --- ... tarantool> format[1] = {name = 'field1', type = 'unsigned'} --- ... tarantool> format[2] = {name = 'field2', type = 'array'} --- ... tarantool> format[3] = {name = 'field4', type = 'string' } --- ... tarantool> format[4] = {name = "[2][6]['пw']['Я']", type = 'string'} --- ... tarantool> s = box.schema.space.create('test', {format = format}) --- ... tarantool> pk = s:create_index('pk') --- ... tarantool> field2 = {1, 2, 3, "4", {5,6,7}, {пw={Я="п"}, key="V!", value="K!"}} --- ... tarantool> t = s:replace{1, field2, "123456", "Not K!"} --- ... tarantool> t["[2][6]['value']"] --- - K! ...
-
tuple_object:
find
([field-number, ]search-value)¶ -
tuple_object:
findall
([field-number, ]search-value)¶ If
t
is a tuple instance,t:find(search-value)
will return the number of the first field int
that matches the search value, andt:findall(search-value [, search-value ...])
will return numbers of all fields int
that match the search value. Optionally one can put a numeric argumentfield-number
before the search-value to indicate “start searching at field numberfield-number
.”Return: the number of the field in the tuple. Rtype: number In the following example, a tuple named
t
is created and then: the number of the first field int
which matches ‘a’ is returned, then the numbers of all the fields int
which match ‘a’ are returned, then the numbers of all the fields in t which match ‘a’ and are at or after the second field are returned.tarantool> t = box.tuple.new{'a', 'b', 'c', 'a'} --- ... tarantool> t:find('a') --- - 1 ... tarantool> t:findall('a') --- - 1 - 4 ... tarantool> t:findall(2, 'a') --- - 4 ...
-
tuple_object:
next
(tuple[, pos])¶ An analogue of the Lua
next()
function, but for a tuple object. When called without arguments,tuple:next()
returns the first field from a tuple. Otherwise, it returns the field next to the indicated position.However
tuple:next()
is not really efficient, and it is better to use tuple:pairs()/ipairs().Return: field number and field value Rtype: number and field type tarantool> tuple = box.tuple.new({5, 4, 3, 2, 0}) --- ... tarantool> tuple:next() --- - 1 - 5 ... tarantool> tuple:next(1) --- - 2 - 4 ... tarantool> ctx, field = tuple:next() --- ... tarantool> while field do > print(field) > ctx, field = tuple:next(ctx) > end 5 4 3 2 0 --- ...
-
tuple_object:
pairs
()¶ -
tuple_object:
ipairs
()¶ In Lua, lua-table-value:pairs() is a method which returns:
function
,lua-table-value
,nil
. Tarantool has extended this so thattuple-value:pairs()
returns:function
,tuple-value
,nil
. It is useful for Lua iterators, because Lua iterators traverse a value’s components until an end marker is reached.tuple_object:ipairs()
is the same aspairs()
, because tuple fields are always integers.Return: function, tuple-value, nil Rtype: function, lua-value, nil In the following example, a tuple named
t
is created and then all its fields are selected using a Lua for-end loop.tarantool> t = box.tuple.new{'Fld#1', 'Fld#2', 'Fld#3', 'Fld#4', 'Fld#5'} --- ... tarantool> tmp = '' --- ... tarantool> for k, v in t:pairs() do > tmp = tmp .. v > end --- ... tarantool> tmp --- - Fld#1Fld#2Fld#3Fld#4Fld#5 ...
-
tuple_object:
totable
([start-field-number[, end-field-number]])¶ If
t
is a tuple instance,t:totable()
will return all fields,t:totable(1)
will return all fields starting with field number 1,t:totable(1,5)
will return all fields between field number 1 and field number 5.It is preferable to use
t:totable()
rather thant:unpack()
.Return: field(s) from the tuple Rtype: lua-table In the following example, a tuple named
t
is created, then all its fields are selected, then the result is returned.tarantool> t = box.tuple.new{'Fld#1', 'Fld#2', 'Fld#3', 'Fld#4', 'Fld#5'} --- ... tarantool> t:totable() --- - ['Fld#1', 'Fld#2', 'Fld#3', 'Fld#4', 'Fld#5'] ...
-
tuple_object:
tomap
([options])¶ A Lua table can have indexed values, also called key:value pairs. For example, here:
a = {}; a['field1'] = 10; a['field2'] = 20
a
is a table with “field1: 10” and “field2: 20”.The tuple_object:totable() function only returns a table containing the values. But the
tuple_object:tomap()
function returns a table containing not only the values, but also the key:value pairs.This only works if the tuple comes from a space that has been formatted with a format clause.
Parameters: - options (table) –
the only possible option is
names_only
.If
names_only
is false or omitted (default), then all the fields will appear twice, first with numeric headings and second with name headings.If
names_only
is true, then all the fields will appear only once, with name headings.
Return: field-number:value pair(s) and key:value pair(s) from the tuple
Rtype: lua-table
In the following example, a tuple named
t1
is returned from a space that has been formatted, then tables namedt1map1
andt1map2
are produced fromt1
.format = {{'field1', 'unsigned'}, {'field2', 'unsigned'}} s = box.schema.space.create('test', {format = format}) s:create_index('pk',{parts={1,'unsigned',2,'unsigned'}}) t1 = s:insert{10, 20} t1map = t1:tomap() t1map_names_only = t1:tomap({names_only=true})
t1map
will contain “1: 10”, “2: 20”, “field1: 10”, “field2: 20”.t1map_names_only
will contain “field1: 10”, “field2: 20”.- options (table) –
-
tuple_object:
transform
(start-field-number, fields-to-remove[, field-value, ...])¶ If
t
is a tuple instance,t:transform(start-field-number,fields-to-remove)
will return a tuple where, starting from fieldstart-field-number
, a number of fields (fields-to-remove
) are removed. Optionally one can add more arguments afterfields-to-remove
to indicate new values that will replace what was removed.If the original tuple comes from a space that has been formatted with a format clause, the formatting will not be preserved for the result tuple.
Parameters: - start-field-number (integer) – base 1, may be negative
- fields-to-remove (integer) –
- field-value(s) (lua-value) –
Return: tuple
Rtype: tuple
In the following example, a tuple named
t
is created and then, starting from the second field, two fields are removed but one new one is added, then the result is returned.tarantool> t = box.tuple.new{'Fld#1', 'Fld#2', 'Fld#3', 'Fld#4', 'Fld#5'} --- ... tarantool> t:transform(2, 2, 'x') --- - ['Fld#1', 'x', 'Fld#4', 'Fld#5'] ...
-
tuple_object:
unpack
([start-field-number[, end-field-number]])¶ If
t
is a tuple instance,t:unpack()
will return all fields,t:unpack(1)
will return all fields starting with field number 1,t:unpack(1,5)
will return all fields between field number 1 and field number 5.Return: field(s) from the tuple. Rtype: lua-value(s) In the following example, a tuple named
t
is created and then all its fields are selected, then the result is returned.tarantool> t = box.tuple.new{'Fld#1', 'Fld#2', 'Fld#3', 'Fld#4', 'Fld#5'} --- ... tarantool> t:unpack() --- - Fld#1 - Fld#2 - Fld#3 - Fld#4 - Fld#5 ...
-
tuple_object:
update
({{operator, field_no, value}, ...})¶ Update a tuple.
This function updates a tuple which is not in a space. Compare the function
box.space.space-name:update(key, {{format, field_identifier, value}, ...})
which updates a tuple in a space.For details: see the description for
operator
,field_identifier
, andvalue
in the section box.space.space-name:update{key, format, {field_identifier, value}…).If the original tuple comes from a space that has been formatted with a format clause, the formatting will be preserved for the result tuple.
Parameters: - operator (string) – operation type represented in string (e.g.
‘
=
’ for ‘assign new value’) - field_no (number) – what field the operation will apply to. The field number can be negative, meaning the position from the end of tuple. (#tuple + negative field number + 1)
- value (lua_value) – what value will be applied
Return: new tuple
Rtype: tuple
In the following example, a tuple named
t
is created and then its second field is updated to equal ‘B’.tarantool> t = box.tuple.new{'Fld#1', 'Fld#2', 'Fld#3', 'Fld#4', 'Fld#5'} --- ... tarantool> t:update({{'=', 2, 'B'}}) --- - ['Fld#1', 'B', 'Fld#3', 'Fld#4', 'Fld#5'] ...
Since Tarantool 2.3 a tuple can also be updated via JSON paths.
- operator (string) – operation type represented in string (e.g.
‘
-
tuple_object:
upsert
({{operator, field_no, value}, ...})¶ The same as
tuple_object:update()
, but ignores errors. In case of an error the tuple is left intact, but an error message is printed. Only client errors are ignored, such as a bad field type, or wrong field index/name. System errors, such as OOM, are not ignored and raised just like with a normalupdate()
. Note that only bad operations are ignored. All correct operations are applied.Parameters: - operator (string) – operation type represented as a string (e.g.
‘
=
’ for ‘assign new value’) - field_no (number) – the field to which the operation will be applied. The field number can be negative, meaning the position from the end of tuple. (#tuple + negative field number + 1)
- value (lua_value) – the value which will be applied
Return: new tuple
Rtype: tuple
See the following example where one operation is applied, and one is not.
tarantool> t = box.tuple.new({1, 2, 3}) tarantool> t2 = t:upsert({{'=', 5, 100}}) UPSERT operation failed: ER_NO_SUCH_FIELD_NO: Field 5 was not found in the tuple --- ... tarantool> t --- - [1, 2, 3] ... tarantool> t2 --- - [1, 2, 3] ... tarantool> t2 = t:upsert({{'=', 5, 100}, {'+', 1, 3}}) UPSERT operation failed: ER_NO_SUCH_FIELD_NO: Field 5 was not found in the tuple --- ... tarantool> t --- - [1, 2, 3] ... tarantool> t2 --- - [4, 2, 3] ...
- operator (string) – operation type represented as a string (e.g.
‘
-
Example¶
This function will illustrate how to convert tuples to/from Lua tables and lists of scalars:
tuple = box.tuple.new({scalar1, scalar2, ... scalar_n}) -- scalars to tuple
lua_table = {tuple:unpack()} -- tuple to Lua table
lua_table = tuple:totable() -- tuple to Lua table
scalar1, scalar2, ... scalar_n = tuple:unpack() -- tuple to scalars
tuple = box.tuple.new(lua_table) -- Lua table to tuple
Then it will find the field that contains ‘b’, remove that field from the tuple,
and display how many bytes remain in the tuple. The function uses Tarantool
box.tuple
functions new()
, unpack()
, find()
, transform()
,
bsize()
.
function example()
local tuple1, tuple2, lua_table_1, scalar1, scalar2, scalar3, field_number
local luatable1 = {}
tuple1 = box.tuple.new({'a', 'b', 'c'})
luatable1 = tuple1:totable()
scalar1, scalar2, scalar3 = tuple1:unpack()
tuple2 = box.tuple.new(luatable1[1],luatable1[2],luatable1[3])
field_number = tuple2:find('b')
tuple2 = tuple2:transform(field_number, 1)
return 'tuple2 = ' , tuple2 , ' # of bytes = ' , tuple2:bsize()
end
… And here is what happens when one invokes the function:
tarantool> example()
---
- tuple2 =
- ['a', 'c']
- ' # of bytes = '
- 5
...