Skip to content
Snippets Groups Projects
Commit 16ec1e51 authored by Konstantin Osipov's avatar Konstantin Osipov
Browse files

User guide: add information on stored programs.

parent 1579774b
No related merge requests found
......@@ -131,16 +131,16 @@ error: 1:15 expected '('
</para>
<para>
Every value, returned from a stored function by means of
<code>return</code> clause, is converted to a Tarantool/Box tuple
and sent back to the client in binary form. Tuples are
returned as such; an atom, such as a string or an integer, is
converted to a tuple that has only one field. In case of
<emphasis>Lua table</emphasis>, the resulting tuple contains
only table values, but not keys.
<code>return</code> clause, is converted to a Tarantool/Box tuple.
Tuples are returned as such, in binary form; an atom, such as
a string or an integer, is converted to a tuple with only
one field. When the returned value is a <emphasis>Lua
table</emphasis>, the resulting tuple contains only table
values, but not keys.
</para>
<para>
When a function in Lua terminates with an error, it is
returned to the client as <olink targetptr="ER_PROC_LUA" />
When a function in Lua terminates with an error, the error
is sent to the client as <olink targetptr="ER_PROC_LUA" />
return code, with the original error message preserved.
Similarly, an error occurred inside Tarantool (observed on the
client as an error code), when happens during execution of a
......@@ -201,7 +201,6 @@ pack: function
<variablelist>
<title>Package <code>box</code> function index</title>
<varlistentry>
<term>
<emphasis role="lua">box.process(op, request)</emphasis>
......@@ -219,15 +218,16 @@ pack: function
with the binary protocol format (iproto
header excluded). Normally there is no need
to use <code>box.process()</code> directly:
<code>box.select(), box.update(), ...</code>
<code>box.select(), box.update()</code>
and other convenience wrappers
invoke <code>box.process()</code> with
correctly packed arguments.
<bridgehead renderas="sect4">Parameters</bridgehead>
<simplelist>
<member><code>op</code> &mdash; number, Tarantool/Box command code, see
<member><code>op</code> &mdash; number, any
Tarantool/Box command code, except 22 (CALL). See
<link xlink:href="https://github.com/mailru/tarantool/blob/master/doc/box-protocol.txt">
<filename>doc/box-protocol.txt</filename></link>,
<filename>doc/box-protocol.txt</filename></link>.
</member>
<member><code>request</code> &mdash; a request packed in binary format.</member>
</simplelist>
......@@ -240,7 +240,8 @@ pack: function
are converted to YAML. When called from the binary
protocol, the binary format is used.
<bridgehead renderas="sect4">Errors</bridgehead>
Any server error produced by the executed command.
Any server error produced by the executed
command.
</para>
</listitem>
</varlistentry>
......@@ -259,11 +260,14 @@ pack: function
</member>
<member><code>index_no</code> &mdash; index number in the
namespace,</member>
<member><code>...</code> &dash; possibly compound key.
<member><code>...</code>&mdash; possibly compound key.
</member>
</simplelist>
<bridgehead renderas="sect4">Returns</bridgehead>
Returns zero or more tuples.
<bridgehead renderas="sect4">Errors</bridgehead>
Same as in <code>box.process()</code>. Any error
results in a Lua exception.
<bridgehead renderas="sect4">Example</bridgehead>
<programlisting>
localhost> call box.insert(0, 'test', 'my first tuple')
......@@ -291,6 +295,7 @@ localhost> lua box.select(5, 1, 'firstname', 'lastname')
</term>
<listitem><simpara></simpara></listitem>
</varlistentry>
<varlistentry>
<term>
<emphasis role="lua">box.replace(space_no, ...)</emphasis>
......@@ -302,7 +307,7 @@ localhost> lua box.select(5, 1, 'firstname', 'lastname')
the same primary key already exists,
<code>box.insert()</code> returns an error, while
<code>box.replace()</code> replaces the existing
tuple with the new one. These functions are
tuple with a new one. These functions are
wrappers around <code>box.process()</code>
<bridgehead renderas="sect4">Returns</bridgehead>
Returns the inserted tuple.
......@@ -310,6 +315,23 @@ localhost> lua box.select(5, 1, 'firstname', 'lastname')
</listitem>
</varlistentry>
<varlistentry>
<term>
<emphasis role="lua">box.update(space_no, key, format, ...)</emphasis>
</term>
<listitem>
<para>
Update a tuple identified by <code>key</code>. Update
arguments follow, described by <code>format</code>.
Both format and arguments are passed to
<code>box.pack()</code>, and the result then sent
on to <code>box.process()</code>.
<bridgehead renderas="sect4">Returns</bridgehead>
Returns the updated tuple.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<emphasis role="lua">box.delete(space_no, key)</emphasis>
......@@ -318,48 +340,149 @@ localhost> lua box.select(5, 1, 'firstname', 'lastname')
Delete a tuple, identified by a primary key.
<bridgehead renderas="sect4">Returns</bridgehead>
Returns the deleted tuple.
<bridgehead renderas="sect4">Example</bridgehead>
<programlisting>
localhost> call box.delete(0, 'test')
Call OK, 1 rows affected
['test', 'my first tuple']
localhost> call box.delete(0, 'test')
Call OK, 0 rows affected
localhost call box.delete(0, 'tes')
Call ERROR, Illegal parameters, key is not u32 (ER_ILLEGAL_PARAMS)
</programlisting>
</para></listitem>
</varlistentry>
<varlistentry>
<term>
<emphasis role="lua">box.select_range(space_no, index_no limit, ...)</emphasis>
<emphasis role="lua">box.select_range(space_no, index_no, limit, key, ...)</emphasis>
</term>
<listitem><para>
Select a range of tuples, starting from offset
specified by the key.
specified by <code>key</code>. The key can be
multipart.
Limit selection with at most <code>limit</code>
tuples.
If no key is specified, start from the first key in
the index.
</para><para>
For TREE indexes, this returns tuples in sorted order,
and can be used to iterate over the entire space.
For HASH indexes, this returns at most one tuple,
unless <code>key</code> is nil or unspecified, in which case it
returns all tuples.
</para>
<para>
For TREE indexes, this returns tuples in sorted order.
For HASH indexes, the order of tuples is unspecified, and
can change significantly if data is inserted or deleted
between two calls to <code>box.select_range()</code>.
If <code>key</code> is <code>nil</code> or unspecified,
the selection starts from start of the index.
<bridgehead renderas="sect4">Example</bridgehead>
<programlisting>localhost> show configuration
---
...
space[4].cardinality: "-1"
space[4].estimated_rows: "0"
space[4].index[0].type: "HASH"
space[4].index[0].unique: "true"
space[4].index[0].key_field[0].fieldno: "0"
space[4].index[0].key_field[0].type: "STR"
space[4].index[1].type: "TREE"
space[4].index[1].unique: "false"
space[4].index[1].key_field[0].fieldno: "1"
space[4].index[1].key_field[0].type: "STR"
...
localhost> insert into t4 values ('0', '0')
Insert OK, 1 rows affected
localhost> insert into t4 values ('1', '1')
Insert OK, 1 rows affected
localhost> insert into t4 values ('2', '2')
Insert OK, 1 rows affected
localhost> insert into t4 values ('3', '3')
Insert OK, 1 rows affected
ocalhost> lua box.select_range(4, 0, 10)
---
- '3': {'3'}
- '0': {'0'}
- '1': {'1'}
- '2': {'2'}
...
localhost> lua box.select_range(4, 1, 10)
---
- '0': {'0'}
- '1': {'1'}
- '2': {'2'}
- '3': {'3'}
...
localhost> lua box.select_range(4, 1, 2)
---
- '0': {'0'}
- '1': {'1'}
...
localhost> lua box.select_range(4, 1, 2, '1')
---
- '1': {'1'}
- '2': {'2'}
...
</programlisting>
</para></listitem>
</varlistentry>
<varlistentry>
<term><emphasis role="lua">box.pack(format, ...)</emphasis></term>
<listitem><para>
To use Tarantool/Box binary protocol primitives from Lua,
it's necessary to pack Lua variables into a binary representation.
This is a helper function to do it.
It's prototyped aftre Perl 'pack', which takes a format and a list of
arguments, and returns a binary string with all arguments
packed according to the format. See also doc/box-protocol.txt,
the binary protocol description.
To use Tarantool binary protocol primitives from Lua,
it's necessary to convert Lua variables to binary
format. This helper function is prototyped after Perl
'pack'. It takes a format and a list of arguments, and
returns a binary string with all arguments packed
according to the format.
<bridgehead renderas="sect4">Format specifiers</bridgehead>
<simplelist>
<member><code>i</code> &mdash; converts Lua
variable to a 4-byte
integer, and stores the integer in the resulting
string, low byte first,
</member>
<member><code>p</code> &mdash; stores the length
of the argument as a 4-byte int, low byte first,
followed by the argument itself: a 4-byte int, low
byte first, for integers, or a binary blob for
anything else,
</member>
<member><code>=, +, &amp;, |, ^, : </code>&mdash;
stores the corresponding Tarantool UPDATE
operation code: field assignment, addition,
conjunction, disjunction, exclusive disjunction,
splice (from Perl SPLICE function). Expects
field number to update as an argument. These format
specifiers only store the corresponding operation
code and field number to update, but do not
describe operation arguments.
</member>
</simplelist>
<bridgehead renderas="sect4">Errors</bridgehead>
Unknown format specifier.
<bridgehead renderas="sect4">Example</bridgehead>
<programlisting>
pkt = box.pack("iiiiiip", -- pack format
0, -- space id
0, -- index id
0, -- offset
2^32, -- limit
1, -- number of SELECT arguments
1, -- tuple cardinality
key) -- the key to use for SELECT
localhost> lua box.insert(0, 0, 'hello world')
---
- 0: {'hello world'}
...
localhost> lua box.update(0, 0, "=p", 1, 'bye world')
---
- 0: {'bye world'}
...
localhost> lua box.update(0, 0, ":p", 1, box.pack('ppp', 0, 3, 'hello'))
---
- 0: {'hello world'}
...
localhost> lua box.update(0, 0, "=p", 1, 4)
---
- 0: {4}
...
localhost> lua box.update(0, 0, "+p", 1, 4)
---
- 0: {8}
...
localhost> lua box.update(0, 0, "^p", 1, 4)
---
- 0: {12}
...
</programlisting>
</para></listitem>
</varlistentry>
......@@ -367,7 +490,22 @@ localhost> lua box.select(5, 1, 'firstname', 'lastname')
<varlistentry>
<term><emphasis role="lua">box.unpack(format, ...)</emphasis></term>
<listitem><para>
Counterpart to <code>box.pack().</code>
Counterpart to <code>box.pack()</code>. Only supports
<code>'i'</code> format specifier, and can be used
to convert packed integers to Lua numbers.
<bridgehead renderas="sect4">Example</bridgehead>
<programlisting>localhost> lua tuple=box.replace(2, 0)
---
...
localhost> lua string.len(tuple[0])
---
- 4
...
localhost> lua box.unpack('i', tuple[0])
---
- 0
...
</programlisting>
</para></listitem>
</varlistentry>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment