From 301bceb2c29b693e7f87fbdcd34c4ab83dcb2b44 Mon Sep 17 00:00:00 2001
From: ocelot-inc <pgulutzan@ocelot.ca>
Date: Wed, 10 Sep 2014 17:29:25 -0600
Subject: [PATCH] Due to IRC chat and 'notes' email

---
 doc/user/configuration-reference.xml |   10 +-
 doc/user/connectors.xml              |    4 +-
 doc/user/databases.xml               |  208 ++---
 doc/user/errcode.xml                 |    1 +
 doc/user/limitations.xml             |    8 +-
 doc/user/stored-procedures.xml       | 1117 +++++++++++++-------------
 doc/user/user.xml                    |    1 +
 7 files changed, 625 insertions(+), 724 deletions(-)

diff --git a/doc/user/configuration-reference.xml b/doc/user/configuration-reference.xml
index da1e8a376a..4398484ac8 100644
--- a/doc/user/configuration-reference.xml
+++ b/doc/user/configuration-reference.xml
@@ -10,7 +10,7 @@
 <title>Configuration reference</title>
 <blockquote><para>
   This chapter provides a reference of options which
-  can be set on the command line or in a configuration file.
+  can be set on the command line or in an initialization file.
 </para></blockquote>
 
 <para>
@@ -82,8 +82,8 @@ Target: Linux-x86_64-Debug
 
 </section>
 
-<section xml:id="configuration-file" xreflabel="configuration file">
-<title>Configuration file</title>
+<section xml:id="initialization-file" xreflabel="initialization file">
+<title>Initialization file</title>
 <para>
 If the command to start Tarantool includes <option><replaceable>lua-initialization-file</replaceable></option>,
 then Tarantool begins by invoking the Lua program in the file,
@@ -253,7 +253,7 @@ Starting  ARG
 1000     22364  2778  0 09:14 pts/0    00:00:00 tarantool: running                  
 1000     22394 22364  0 09:14 pts/0    00:00:00 tarantool: spawner
 tarantool: primary pri: 3301 adm: 3313</programlisting>
-          <para>But if the configuration file contains custom_proc_title='sessions' then
+          <para>But if the configuration parameters include custom_proc_title='sessions' then
           the output looks like:</para>
 <programlisting><prompt>$</prompt> <userinput>ps -ef | grep tarantool</userinput>
 1000     22364  2778  0 09:14 pts/0    00:00:00 tarantool: running@sessions          
@@ -628,7 +628,7 @@ tarantool: primary pri: 3301 adm: 3313</programlisting>
             <anchor xml:id="local_hot_standby" xreflabel="local_hot_standby"/>
           In version 1.6 local hot standby is always on so this is a legacy setting.
           When local_hot_standby=true, the expectation is that there will be two
-          instances of the server using the same configuration file.
+          instances of the server using the same configuration.
           The first one to start will be the "primary" instance.
           The second one to start will be the "standby" instance.
           The standby instance will initialize and will try to connect on listen
diff --git a/doc/user/connectors.xml b/doc/user/connectors.xml
index 6582bfcf8b..6c8b16a218 100644
--- a/doc/user/connectors.xml
+++ b/doc/user/connectors.xml
@@ -252,7 +252,7 @@ sudo cpan install DR::Tarantool
     Before trying to run, check that the server
     (tarantool) is running on localhost (127.0.0.1) and its listen address is the default
     (local host, port 3301) and
-    space[0]'s primary key type is numeric (space[0].index[0].key_field[1].type = "NUM" in configuration file).
+    space[0]'s primary key type is numeric (space[0].index[0].key_field[1].type = "NUM").
     To run, paste the code into a file named example.pl and say <code>perl example.pl</code>.
     The program will connect using an application-specific definition of the space.
     The program will open a socket connection
@@ -329,7 +329,7 @@ export PHP_INI_SCAN_DIR=~/tarantool-php/test/share
     Before trying to run, check that the server
     (tarantool) is running on localhost (127.0.0.1) and its listen address is the default
     (local host, port 3301) and
-    space[0]'s primary key type is numeric (space[0].index[0].key_field[1].type = "NUM" in configuration file).
+    space[0]'s primary key type is numeric (space[0].index[0].key_field[1].type = "NUM").
     To run, paste the code into a file named example.php and say <code>php example.php</code>.
     The program will open a socket connection
     with the tarantool server at localhost:3301, then send an INSERT request,
diff --git a/doc/user/databases.xml b/doc/user/databases.xml
index 52552bd74f..d3055c8976 100644
--- a/doc/user/databases.xml
+++ b/doc/user/databases.xml
@@ -2791,68 +2791,6 @@ error: can't save snapshot, errno 17 (File exists)
 
 </section>
 
-<section xml:id="limitations">
-
-<title>Limitations</title>
-
-<variablelist>
-
-  <varlistentry>
-    <term xml:id="limitations-index-field-count" xreflabel="limitations-index-field-count">Number of fields in an index</term>
-    <listitem><para>For BITSET indexes, the maximum is 1.
-    For TREE indexes, the theoretical maximum is about 4 billion (BOX_FIELD_MAX)
-    but the practical maximum is the number of fields in a tuple.
-    </para></listitem>
-  </varlistentry>
-  
-  <varlistentry>
-    <term xml:id="limitations-index-count" xreflabel="limitations-index-count">Number of indexes in a space</term>
-    <listitem><para>10 (BOX_INDEX_MAX).
-    </para></listitem>
-  </varlistentry>
-
-  <varlistentry>
-    <term xml:id="limitations-tuple-field-count" xreflabel="limitations-tuple-field-count">Number of fields in a tuple</term>
-    <listitem><para>There is no theoretical maximum.
-    The practical maximum is whatever is specified by the space's <code>field_count</code> member,
-    or the maximum tuple length.
-    </para></listitem>
-  </varlistentry>
-  
-  <varlistentry>
-    <term xml:id="limitations-space-count" xreflabel="limitations-space-count">Number of spaces</term>
-    <listitem><para>65535.
-    </para></listitem>
-  </varlistentry>
-
-  <varlistentry>
-    <term xml:id="limitations-connections-count" xreflabel="limitations-connections-count">Number of connections</term>
-    <listitem><para>The practical limit is the number of file descriptors that one can set with
-    the operating system.
-    </para></listitem>
-  </varlistentry>
-
-  <varlistentry>
-    <term xml:id="limitations-slab-alloc-arena-size" xreflabel="limitations-slab-alloc-arena-size">Space size</term>
-    <listitem><para>The total maximum size for all spaces is in effect set by <olink targetptr="slab_alloc_arena"/>,
-    which in turn is limited by the total available memory.
-    </para></listitem>
-  </varlistentry>
-
-  <varlistentry>
-    <term xml:id="limitations-update-count" xreflabel="limitations-updae-count">Update operations count</term>
-    <listitem><para>The maximum number of operations that can be in a single update is 4000 (BOX_UPDATE_OP_CNT_MAX).
-    </para></listitem>
-  </varlistentry>
-  
-  <varlistentry>
-    <term xml:id="limitations-user-count" xreflabel="limitations-user-count">Number of users</term>
-    <listitem><para>32.
-    </para></listitem>
-  </varlistentry>
-
-</variablelist>
-</section>
 
 <section xml:id="multitasking">
 <title>Atomic execution</title>
@@ -2977,89 +2915,6 @@ console.delimiter('')!</programlisting>
 </para>
 </section>
 
-<section xml:id="errcode">
-
-<title>List of error codes</title>
-
-<para>In the current version of the binary protocol, error message,
-which is normally more descriptive than error code,
-is not present in server response. The actual message may contain
-a file name, a detailed reason or operating system error code.
-All such messages, however, are logged in the error log. 
-Below follow only general descriptions
-of some popular codes. A complete list of errors can be found in
-file <filename xlink:href="https://github.com/tarantool/tarantool/blob/master/src/errcode.h">errcode.h</filename> in the source tree.
-
-</para>
-<variablelist>
-<title>List of error codes</title>
-
-  <varlistentry>
-    <term xml:id="ER_NONMASTER" xreflabel="ER_NONMASTER">ER_NONMASTER</term>
-    <listitem><para>Can't modify data on a replication slave.
-    </para></listitem>
-  </varlistentry>
-
-  <varlistentry>
-    <term xml:id="ER_ILLEGAL_PARAMS" xreflabel="ER_ILLEGAL_PARAMS">ER_ILLEGAL_PARAMS</term>
-    <listitem><para>Illegal parameters. Malformed protocol
-    message.
-    </para></listitem>
-  </varlistentry>
-
-  <varlistentry>
-    <term xml:id="ER_MEMORY_ISSUE" xreflabel="ER_MEMORY_ISSUE">ER_MEMORY_ISSUE</term>
-    <listitem><para>Out of memory: <olink targetptr="slab_alloc_arena"/> limit is reached.
-    </para></listitem>
-  </varlistentry>
-
-  <varlistentry>
-    <term xml:id="ER_WAL_IO" xreflabel="ER_WAL_IO">ER_WAL_IO</term>
-    <listitem><para>Failed to write to disk. May mean: failed to record a change in
-    the write-ahead log. Some sort of disk error.
-    </para></listitem>
-  </varlistentry>
-
-  <varlistentry>
-    <term xml:id="ER_KEY_PART_COUNT" xreflabel="ER_KEY_PART_COUNT">ER_KEY_PART_COUNT</term>
-    <listitem><para>Key part count is not the same as index part count
-    </para></listitem>
-  </varlistentry>
-
-  <varlistentry>
-    <term xml:id="ER_NO_SUCH_SPACE" xreflabel="ER_NO_SUCH_SPACE">ER_NO_SUCH_SPACE</term>
-    <listitem><para>Attempt to access a space that does not exist.
-    </para></listitem>
-  </varlistentry>
-
-  <varlistentry>
-    <term xml:id="ER_NO_SUCH_INDEX" xreflabel="ER_NO_SUCH_INDEX">ER_NO_SUCH_INDEX</term>
-    <listitem><para>The specified index does not exist for the specified space.
-    </para></listitem>
-  </varlistentry>
-
-  <varlistentry>
-    <term xml:id="ER_PROC_LUA" xreflabel="ER_PROC_LUA">ER_PROC_LUA</term>
-    <listitem><para>An error inside a Lua procedure.
-    </para></listitem>
-  </varlistentry>
-
-  <varlistentry>
-    <term xml:id="ER_FIBER_STACK" xreflabel="ER_FIBER_STACK">ER_FIBER_STACK</term>
-    <listitem><para>Recursion limit reached when creating a new fiber. This is
-    usually an indicator of a bug in a stored procedure, recursively invoking itself
-    ad infinitum.
-    </para></listitem>
-  </varlistentry>
-
-  <varlistentry>
-    <term xml:id="ER_UPDATE_FIELD" xreflabel="ER_UPDATE_FIELD">ER_UPDATE_FIELD</term>
-    <listitem><para>An error occurred during update of a field.
-    </para></listitem>
-  </varlistentry>
-
-</variablelist>
-</section>
 
 <section xml:id="authentication" xreflabel="authentication">
 <title>Authentication and access control</title>
@@ -3318,6 +3173,69 @@ box.space.payroll:select{'Jones'}</programlisting>
 
 </section>
 
+<section xml:id="limitations">
+
+<title>Limitations</title>
+
+<variablelist>
+
+  <varlistentry>
+    <term xml:id="limitations-index-field-count" xreflabel="limitations-index-field-count">Number of fields in an index</term>
+    <listitem><para>For BITSET indexes, the maximum is 1.
+    For TREE indexes, the theoretical maximum is about 4 billion (BOX_FIELD_MAX)
+    but the practical maximum is the number of fields in a tuple.
+    </para></listitem>
+  </varlistentry>
+  
+  <varlistentry>
+    <term xml:id="limitations-index-count" xreflabel="limitations-index-count">Number of indexes in a space</term>
+    <listitem><para>10 (BOX_INDEX_MAX).
+    </para></listitem>
+  </varlistentry>
+
+  <varlistentry>
+    <term xml:id="limitations-tuple-field-count" xreflabel="limitations-tuple-field-count">Number of fields in a tuple</term>
+    <listitem><para>There is no theoretical maximum.
+    The practical maximum is whatever is specified by the space's <code>field_count</code> member,
+    or the maximum tuple length.
+    </para></listitem>
+  </varlistentry>
+  
+  <varlistentry>
+    <term xml:id="limitations-space-count" xreflabel="limitations-space-count">Number of spaces</term>
+    <listitem><para>65535.
+    </para></listitem>
+  </varlistentry>
+
+  <varlistentry>
+    <term xml:id="limitations-connections-count" xreflabel="limitations-connections-count">Number of connections</term>
+    <listitem><para>The practical limit is the number of file descriptors that one can set with
+    the operating system.
+    </para></listitem>
+  </varlistentry>
+
+  <varlistentry>
+    <term xml:id="limitations-slab-alloc-arena-size" xreflabel="limitations-slab-alloc-arena-size">Space size</term>
+    <listitem><para>The total maximum size for all spaces is in effect set by <olink targetptr="slab_alloc_arena"/>,
+    which in turn is limited by the total available memory.
+    </para></listitem>
+  </varlistentry>
+
+  <varlistentry>
+    <term xml:id="limitations-update-count" xreflabel="limitations-updae-count">Update operations count</term>
+    <listitem><para>The maximum number of operations that can be in a single update is 4000 (BOX_UPDATE_OP_CNT_MAX).
+    </para></listitem>
+  </varlistentry>
+  
+  <varlistentry>
+    <term xml:id="limitations-user-count" xreflabel="limitations-user-count">Number of users</term>
+    <listitem><para>32.
+    </para></listitem>
+  </varlistentry>
+
+</variablelist>
+</section>
+
 
 </chapter>
 <!--
diff --git a/doc/user/errcode.xml b/doc/user/errcode.xml
index 36b20e3365..7e650aca94 100644
--- a/doc/user/errcode.xml
+++ b/doc/user/errcode.xml
@@ -82,6 +82,7 @@ file <filename xlink:href="https://github.com/tarantool/tarantool/blob/master/sr
   </varlistentry>
 
 </variablelist>
+
 </appendix>
 
 <!--
diff --git a/doc/user/limitations.xml b/doc/user/limitations.xml
index e0404d76d6..b606909779 100644
--- a/doc/user/limitations.xml
+++ b/doc/user/limitations.xml
@@ -24,11 +24,11 @@
   <varlistentry>
     <term xml:id="limitations-tuple-field-count" xreflabel="limitations-tuple-field-count">Number of fields in a tuple</term>
     <listitem><para>There is no theoretical maximum.
-    The practical maximum is whatever is specified by space.cardinality in the configuration file,
+    The practical maximum is whatever is specified by the space's <code>field_count</code> member,
     or the maximum tuple length.
     </para></listitem>
   </varlistentry>
-  
+
   <varlistentry>
     <term xml:id="limitations-space-count" xreflabel="limitations-space-count">Number of spaces</term>
     <listitem><para>255.
@@ -44,8 +44,8 @@
 
   <varlistentry>
     <term xml:id="limitations-slab-alloc-arena-size" xreflabel="limitations-slab-alloc-arena-size">Space size</term>
-    <listitem><para>The total maximum size for all spaces is in effect set by the slab_alloc_arena_size
-    parameter in the configuration file, which in turn is limited by the total available memory.
+    <listitem><para>The total maximum size for all spaces is in effect set by slab_alloc_arena,
+    which in turn is limited by the total available memory.
     </para></listitem>
   </varlistentry>
 
diff --git a/doc/user/stored-procedures.xml b/doc/user/stored-procedures.xml
index 0a8528c602..58316d104d 100644
--- a/doc/user/stored-procedures.xml
+++ b/doc/user/stored-procedures.xml
@@ -42,7 +42,7 @@ tarantool> <userinput>'hello' .. ' world' -- '..' means 'concatenate'</userinput
     </para>
     <para>
     Lua functions could also be called at the time of initialization with a script in a
-    <olink targetptr="configuration-file">configuration file</olink>.
+    <olink targetptr="configuration-file">lua-initialization file</olink>.
     An example and discussion of such a script will appear later in section
     <link linkend="sp-expirationd">expirationd</link>.
     </para>
@@ -76,42 +76,6 @@ tarantool> <userinput>'hello' .. ' world' -- '..' means 'concatenate'</userinput
       <link xlink:href="http://www.lua.org/pil/6.1.html">
       <emphasis>closure</emphasis> section</link> of the Lua manual. 
     </para>
-    <para>
-      The
-      CALL request packet contains the command code for CALL (22), the name
-      of a procedure to be called, and a tuple for procedure
-      arguments. Fields of the tuple are passed into the function
-      as arguments of type <quote>string</quote> or <quote>number</quote>
-      or <quote>boolean</quote>.. For example:
-<programlisting><computeroutput>kostja@atlas:~<prompt>$</prompt> <userinput>cat arg.lua</userinput>
-function f1(a)
-    local s = a
-    if type(a) == 'string' then
-        s = ''
-        for i = 1, #a, 1 do
-            s = s..string.format('0x%x ', string.byte(a, i))
-        end
-    end
-    return type(a), s
-end
-kostja@atlas:~<prompt>$</prompt> <userinput>tarantool</userinput>
-tarantool> <userinput>dofile('arg.lua')</userinput>
----
-...
-tarantool> <userinput>f1('1234')</userinput>
----
- - string
- - 0x31 0x32 0x33 0x34
-...
-tarantool> <userinput>f1(1234)</userinput>
----
- - number
- - 1234
-...</computeroutput></programlisting>
-      In the above example, the function finds out the type of the
-      argument (Lua 'string' or 'number') at runtime, gets the byte codes
-      if it's a string, and returns the type plus the value.
-    </para>
     <para>
       In addition to conventional method invocation,
       Lua provides object-oriented syntax. Typically this involves
@@ -194,7 +158,7 @@ digest, JSON, <link xlink:href="http://en.wikipedia.org/wiki/Yaml">YAML</link>,
 </para>
 
 <para>
-LUAJIT is a processor for the entire Lua language. 
+<emphasis>LuaJIT</emphasis> is a processor for the entire Lua language. 
 This differs from the original Lua interpreter from
 <link xlink:href="http://www.puc-rio.br/index.html">Pontifícia Universidade Católica do Rio de Janeiro</link>
 ("RIO-PUC" <link xlink:href="http://www.lua.org/">Lua</link>) 
@@ -223,21 +187,21 @@ provided one takes advantage of it where <link xlink:href="http://wiki.luajit.or
     </para>
 
 <para>
-FIBERS are like Lua coroutines, but as <link xlink:href="http://members.chello.nl/~w.couwenberg/fibers.htm">one fiber developer</link>
+<emphasis>Fibers</emphasis> are like Lua coroutines, but as <link xlink:href="http://members.chello.nl/~w.couwenberg/fibers.htm">one fiber developer</link>
 put it: "The main difference between a coroutine and a fiber
 is that a running fiber can be suspended anywhere in a call
 chain, regardless of its C and Lua call stack nesting levels."       
 </para>
 
 <para>
-MSGPACK is a relatively new way to serialize data.                    
+<emphasis>MsgPack</emphasis> is a relatively new way to serialize data.                    
 The point of MsgPack is that it can
 handle Lua types and C types, with structures and nesting,
 without the overhead of an SGML-style markup language.
 </para>
 
 <para>
-DIGEST is a cryptography package for CRC32, SHA, and MDA.
+<emphasis>Digest</emphasis> is a cryptography package for CRC32, SHA, and MDA.
 Nothing new here -- except that Tarantool has made them into a
 package, so that one doesn't have to get each one of these
 things individually from the <link xlink:href="http://lua-users.org/wiki/CryptographyStuff">many that are available</link>.
@@ -246,7 +210,7 @@ API, the routines should run faster on LuaJIT.
 </para>
 
 <para>
-JSON is a serialization format which has
+<emphasis>JSON</emphasis> is a serialization format which has
 become popular in the web world. The package within
 Tarantool is derived from <link xlink:href="http://www.kyne.com.au/~mark/software/lua-cjson-manual.html">CJSON</link>
 which, according to <link xlink:href="http://lua-users.org/wiki/JsonModules">a survey</link>, 
@@ -255,18 +219,18 @@ edge cases come up.
 </para>
 
 <para>
-YAML is short for "YAML Ain't a Markup Language". YAML is a            
+<emphasis>YAML</emphasis> is short for "YAML Ain't a Markup Language". YAML is a            
 way to show data in human-readable form, without losing
 underlying information about typing, arrays, and structures.
 </para>
 
 <para>
-IPC is Inter-Process Communication.
+<emphasis>IPC</emphasis> is Inter-Process Communication.
 this is useful for implementations of task queues and long polling.
 </para>
 
 <para>
-BOX is the NoSQL DBMS that was developed by Tarantool
+<emphasis>Box</emphasis> is the NoSQL DBMS that was developed by Tarantool
 and its community. Box's architecture and routines will be the
 subject of the next chapter.
 </para>
@@ -302,613 +266,363 @@ administration with the built-in packages.
 </para>
 
 
+<section xml:id="sp-digest">
+    <title>Package <code>digest</code></title>
+    <para>
+    A "digest" is a value which is returned by a
 
-<variablelist>
-<title>Lua functions <code>tonumber64</code> and <code>dostring</code></title>
-    <varlistentry>
-        <term xml:id="tonumber64" xreflabel="tonumber64"> <emphasis role="lua">tonumber64(<replaceable>value</replaceable>)</emphasis></term>
-        <listitem>
-            <para>
-              Convert a string or a Lua number to a
-              64-bit integer. The result can be used in arithmetic,
-              and the arithmetic will be 64-bit integer arithmetic
-              rather than floating-point arithmetic. (Operations on
-              an unconverted Lua number use floating-point arithmetic.)
-              The tonumber64() function is added by Tarantool; the name is global.
-              <bridgehead renderas="sect4">Example</bridgehead>
-<programlisting>
-tarantool> <userinput>type(123456789012345), type(tonumber64(123456789012345))</userinput>
+    <link xlink:href="https://en.wikipedia.org/wiki/Cryptographic_hash_function">Cryptographic hash function</link>
+    applied against a string.
+    Tarantool supports five types of cryptographic hash functions
+    (<link xlink:href="https://en.wikipedia.org/wiki/Md4">MD4</link>,
+    <link xlink:href="https://en.wikipedia.org/wiki/Md5">MD5</link>,
+    <link xlink:href="https://en.wikipedia.org/wiki/Sha-0">SHA-0</link>,
+    
+    <link xlink:href="https://en.wikipedia.org/wiki/Sha-1">SHA-1</link>,
+    <link xlink:href="https://en.wikipedia.org/wiki/Sha-2">SHA-2</link>)
+
+    as well as a checksum function
+    (<link xlink:href="https://en.wikipedia.org/wiki/Cyclic_redundancy_check">CRC32</link>).
+    The functions in <code>digest</code> are:
+    <informaltable>
+    <tgroup cols="2" align="left" colsep="1" rowsep="0">
+     <thead>
+      <row><entry>name</entry><entry>effect</entry></row>
+     </thead>
+    <tbody>
+    <row><entry><code>digest.crc32(<replaceable>string</replaceable>)</code></entry><entry>                  Returns 32-bit checksum made with CRC32.</entry></row>
+    <row><entry><code>digest.crc32_update(<replaceable>number</replaceable>,<replaceable>string</replaceable>)</code></entry><entry>    Returns update of a checksum calculated with crc32.</entry></row>
+    <row><entry><code>digest.sha(<replaceable>string</replaceable>)</code></entry><entry>                    Returns 160-bit digest made with SHA-0. Not recommended.</entry></row>
+    <row><entry><code>digest.sha_hex(<replaceable>string</replaceable>)</code></entry><entry>                Returns hexadecimal of a digest calculated with sha.</entry></row>
+    <row><entry><code>digest.sha1(<replaceable>string</replaceable>)</code></entry><entry>                   Returns 160-bit digest made with SHA-1.</entry></row>
+    <row><entry><code>digest.sha1_hex(<replaceable>string</replaceable>)</code></entry><entry>               Returns hexadecimal of a digest calculated with sha1.</entry></row>
+    <row><entry><code>digest.sha224(<replaceable>string</replaceable>)</code></entry><entry>                 Returns 224-bit digest made with SHA-2.</entry></row>
+    <row><entry><code>digest.sha224_hex(<replaceable>string</replaceable>)</code></entry><entry>             Returns hexadecimal of a digest calculated with sha224.</entry></row>
+    <row><entry><code>digest.sha256(<replaceable>string</replaceable>)</code></entry><entry>                 Returns 256-bit digest made with SHA-2.</entry></row>
+    <row><entry><code>digest.sha256_hex(<replaceable>string</replaceable>)</code></entry><entry>             Returns hexadecimal of a digest calculated with sha256.</entry></row>
+    <row><entry><code>digest.sha384(<replaceable>string</replaceable>)</code></entry><entry>                 Returns 384-bit digest made with SHA-2.</entry></row>
+    <row><entry><code>digest.sha384_hex(<replaceable>string</replaceable>)</code></entry><entry>             Returns hexadecimal of a digest calculated with sha384.</entry></row>
+    <row><entry><code>digest.sha512(<replaceable>string</replaceable>)</code></entry><entry>                 Returns 512-bit digest made with SHA-2.</entry></row>
+    <row><entry><code>digest.sha512_hex(<replaceable>string</replaceable>)</code></entry><entry>             Returns hexadecimal of a digest calculated with sha512.</entry></row>
+    <row><entry><code>digest.md4(<replaceable>string</replaceable>)</code></entry><entry>                    Returns 128-bit digest made with MD4.</entry></row>
+    <row><entry><code>digest.md4_hex(<replaceable>string</replaceable>)</code></entry><entry>                Returns hexadecimal of a digest calculated with md4.</entry></row>
+    <row><entry><code>digest.md5(<replaceable>string</replaceable>)</code></entry><entry>                    Returns 256-bit digest made with MD5.</entry></row>
+    <row><entry><code>digest.md5_hex(<replaceable>string</replaceable>)</code></entry><entry>                Returns hexadecimal of a digest calculated with md5.</entry></row>
+    </tbody>
+    </tgroup>                                   
+    </informaltable>
+
+   </para>
+<bridgehead renderas="sect4">Example</bridgehead>
+    <para>
+    In the following example, the user creates two functions, password_insert() 
+    which inserts a SHA-1 digest of the word "^S^e^c^ret Wordpass" into a tuple set,
+    and password_check() which requires input of a password.<programlisting>
+<prompt>localhost&gt;</prompt> <userinput>digest = require('digest')</userinput>
+<prompt>localhost&gt;</prompt> <userinput>console = require('console'); console.delimiter('!') --this means ignore line feeds until next '!'</userinput>
+<prompt>localhost&gt;</prompt> <userinput>function password_insert()</userinput>
+        <prompt>-&gt;</prompt> <userinput>  box.space.tester:insert{12345,digest.sha1('^S^e^c^ret Wordpass')}</userinput>
+        <prompt>-&gt;</prompt> <userinput>  return 'OK'</userinput>
+        <prompt>-&gt;</prompt> <userinput>  end!</userinput>
 ---
-- number
-- cdata
 ...
-tarantool> <userinput>i = tonumber64('1000000000')</userinput>
+<prompt>localhost&gt;</prompt> <userinput>function password_check(password)</userinput>
+        <prompt>-&gt;</prompt>  <userinput> local t</userinput>
+        <prompt>-&gt;</prompt>  <userinput> t=box.space.tester:select{12345}</userinput>
+        <prompt>-&gt;</prompt>  <userinput> if (digest.sha1(password)==t[2]) then</userinput>
+        <prompt>-&gt;</prompt>  <userinput>   print('Password is valid')</userinput>
+        <prompt>-&gt;</prompt>  <userinput>   else</userinput>
+        <prompt>-&gt;</prompt>  <userinput>     print('Password is not valid')</userinput>
+        <prompt>-&gt;</prompt>  <userinput>   end</userinput>
+        <prompt>-&gt;</prompt> <userinput>end!</userinput>
 ---
 ...
-tarantool> <userinput>type(i), i / 2, i - 2, i * 2, i + 2, i % 2, i ^ 2</userinput>
+<prompt>localhost&gt;</prompt> <userinput>password_insert()!</userinput>
+Call OK, 1 rows affected
+['OK']
+<prompt>localhost></prompt> <userinput>console.delimiter('') --  back to normal: commands end with line feed!</userinput>
+</programlisting></para>
+<para>
+  If a later user calls
+  the password_check() function and enters the wrong password, the result is an
+  error.<programlisting><prompt>localhost&gt;</prompt> <userinput>password_check ('Secret Password')</userinput>
 ---
- - cdata
- - 500000000
- - 999999998
- - 2000000000
- - 1000000002
- - 0
- - 1000000000000000000
-...
-</programlisting>
+Password is not valid
+...</programlisting></para>
+</section>
+
+<section xml:id="sp-box-uuid">
+    <title>Package <code>uuid</code></title>
+
+<para>
+  A "UUID" is a 
+  <link xlink:href="https://en.wikipedia.org/wiki/Universally_unique_identifier">Universally unique identifier</link>.
+  If an application requires that a value be unique only within a single computer or
+  on a single database, then a simple counter is better than a UUID, because getting
+  a UUID is time-consuming (it requires a
+  <link xlink:href="https://en.wikipedia.org/wiki/Syscall">syscall</link>).
+  For clusters of computers, or widely distributed applications, UUIDs are better.
+</para>
+<para>
+  The functions that can return a UUID are: <code>uuid()</code>, <code>uuid.bin()</code>, <code>uuid.str()</code>.
+  The functions that can convert between different types of UUID are: <code>:bin()</code>, <code>:str()</code>, <code>uuid.fromstr()</code>, <code>uuid.frombin()</code>.
+  The function that can determine whether a UUID is an all-zero value is: <code>:isnil()</code>.
+</para>
+
+<variablelist xml:id="x-uuid" xreflabel="x-uuid">
+
+    <varlistentry>
+        <term>
+            <emphasis role="lua">uuid()</emphasis>
+        </term>
+        <listitem>
+            <para>
+                Returns: a UUID with type = cdata.
             </para>
         </listitem>
     </varlistentry>
-    
+
     <varlistentry>
         <term>
-            <emphasis role="lua">dostring(<replaceable>lua-chunk-string [, lua-chunk-string-argument ...]</replaceable>)</emphasis>
+            <emphasis role="lua">uuid.bin()</emphasis>
         </term>
         <listitem>
             <para>
-              Parse and execute an arbitrary chunk of Lua code.
-              This function is mainly useful to define and run
-              Lua code without having to
-              introduce changes to the global Lua environment.
+                Returns: a UUID with type = 16-byte binary string.
+            </para>
+        </listitem>
+    </varlistentry>
+
+    <varlistentry>
+        <term>
+            <emphasis role="lua">uuid.str()</emphasis>
+        </term>
+        <listitem>
+            <para>
+                Returns: a UUID with type = 36-byte hexadecimal string.
             </para>
+        </listitem>
+    </varlistentry>
+
+    <varlistentry>
+        <term>
+         <emphasis role="lua"><replaceable>uuid_with_type_cdata</replaceable>:bin([<replaceable>byte-order</replaceable>])</emphasis>
+        </term>
+        <listitem>
             <para>
-              Parameters: <code>lua-chunk-string</code> = string containing Lua code,
-              <code>lua-chunk-string-argument(s)</code> = zero or more scalar values
-               which will be appended to, or substitute for, items in the Lua chunk.
-             </para>
-             <para>
-               Returns: whatever is returned by the Lua code chunk.
+                Parameters: byte-order can be 'l' (little-endian), 'b' (big-endian), 'h' (endianness depends on host) (default), or 'n' (endianness depends on network).
+            </para>         
+            <para>
+                Returns: UUID with type = 16-byte binary string converted from cdata input value.
+            </para>
+        </listitem>
+    </varlistentry>
+
+    <varlistentry>
+        <term>
+            <emphasis role="lua">  <replaceable>uuid_with_type_cdata</replaceable>:str()</emphasis>
+        </term>
+        <listitem>
+            <para>
+                Returns: UUID with type = 36-byte hexadecimal string converted from cdata input value.
             </para>
+        </listitem>
+    </varlistentry>
+
+    <varlistentry>
+        <term>
+            <emphasis role="lua">  uuid.fromstr(<replaceable>uuid_with_type_string</replaceable>)</emphasis>
+        </term>
+        <listitem>
             <para>
-               Possible errors: If there is a compilation error,
-               it is raised as a Lua error.
+                Returns: UUID with type = cdata converted from 36-byte hexadecimal string input value.
+            </para>
+        </listitem>
+    </varlistentry>
+
+    <varlistentry>
+        <term>
+            <emphasis role="lua">uuid.frombin(<replaceable>uuid_with_type_binary_string</replaceable>)</emphasis>
+        </term>
+        <listitem>
+            <para>
+                Returns: UUID with type = cdata converted from 16-byte binary string input value.
             </para>
+        </listitem>
+    </varlistentry>
+
+    <varlistentry>
+        <term>
+            <emphasis role="lua">:isnil(<replaceable>uuid_with_type_cdata</replaceable>)</emphasis>
+        </term>
+        <listitem>
             <para>
+                Returns: true if the value is all zero, otherwise false.
+                The all-zero UUID value can be expressed as <code>uuid.NULL</code>, or as
+                uuid.fromstr('00000000-0000-0000-0000-000000000000').
+                The comparison with an all-zero value can also be expressed as
+                <replaceable>uuid_with_type_cdata</replaceable> == uuid.NULL.
+            </para>
+        </listitem>
+    </varlistentry>
+
+</variablelist>
+<para>
             <bridgehead renderas="sect4">Example</bridgehead>
 <programlisting>
-tarantool&gt; <userinput>dostring('abc')</userinput>
+tarantool&gt; <userinput>uuid = require('uuid')</userinput>
 ---
-error: '[string "abc"]:1: ''='' expected near ''&lt;eof&gt;'''
 ...
-tarantool&gt; <userinput>dostring('return 1')</userinput>
+tarantool&gt; <userinput>uuid(), uuid.bin(), uuid.str()</userinput>
 ---
-- 1
+- 16ffedc8-cbae-4f93-a05e-349f3ab70baa
+- !!binary FvG+Vy1MfUC6kIyeM81DYw==
+- 67c999d2-5dce-4e58-be16-ac1bcb93160f
 ...
-tarantool&gt; <userinput>dostring('return ...', 'hello', 'world')</userinput>
+tarantool&gt; <userinput>uu = uuid()</userinput>
 ---
-- hello
-- world
 ...
-tarantool&gt; <userinput>console = require('console'); console.delimiter('!') --<link linkend="utility-tarantool-delim">this</link> means ignore line feeds until next '!'</userinput>
-tarantool&gt; <userinput>-- Use <link xlink:href="http://www.lua.org/pil/2.4.html">double square brackets</link> to enclose multi-line literal here!</userinput>
-tarantool&gt; <userinput>dostring([[local f = function(key)</userinput>
-        -&gt; <userinput>              t = box.space.tester:select{key};</userinput>
-        -&gt; <userinput>              if t ~= nil then return t[1] else return nil end</userinput>
-        -&gt; <userinput>              end</userinput>
-        -&gt; <userinput>              return f(...)]], 1)!</userinput>
+tarantool&gt; <userinput>#uu:bin(), #uu:str(), type(uu), uu:isnil()</userinput>
 ---
-- null
+- 16
+- 36
+- cdata
+- false
 ...
-tarantool&gt; <userinput>console.delimiter('')!</userinput>
 </programlisting>
-            </para>
-        </listitem>
-    </varlistentry>
-    
-</variablelist>
+</para>
 
-<section xml:id="sp-pickle">
-    <title>Package <code>pickle</code></title>
-<variablelist xml:id="x-pickle" xreflabel="x-pickle">
+</section>
+
+<section xml:id="sp-box-cjson">
+    <title>Package <code>json</code></title>
+
+<variablelist xml:id="box.cjson" xreflabel="box.cjson">
+    <para>
+        The <code>json</code> package provides JSON manipulation routines.
+        It is based on the <link xlink:href="http://www.kyne.com.au/~mark/software/lua-cjson.php">
+        Lua-CJSON package by Mark Pulford</link>.
+
+        For a complete manual on Lua-CJSON please read <link xlink:href="http://www.kyne.com.au/~mark/software/lua-cjson-manual.html">the official documentation</link>.
+    </para>
     <varlistentry>
-        <term><emphasis role="lua">pickle.pack(<replaceable>format, argument [, argument ...]</replaceable>)</emphasis></term>
-        <listitem><para>
-            To use Tarantool binary protocol primitives from Lua,
-            it's necessary to convert Lua variables to binary
-            format. The pickle.pack() helper function is prototyped after Perl
-            <link xlink:href="http://perldoc.perl.org/functions/pack.html">
-             'pack'</link>.
-            </para>
-            <para>
-               Parameters: <code>format</code> = string containing format specifiers, <code>argument(s)</code> = scalar values to be formatted.
-            </para>
+        <term><emphasis role="lua">json.encode(<replaceable>scalar-value | Lua-table-value</replaceable>)</emphasis></term>
+        <listitem>
             <para>
-            <bridgehead renderas="sect4">Format specifiers</bridgehead>
-            <simplelist>
-                <member><code>b</code> or <code>B</code> &mdash; converts Lua
-                variable to a 1-byte
-                integer, and stores the integer in the resulting
-                string,
-                </member>
-                <member><code>s</code> or <code>S</code> &mdash; converts Lua
-                variable to a 2-byte
-                integer, and stores the integer in the resulting
-                string, low byte first,
-                </member>
-                <member><code>i</code> or <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>l</code> or <code>L</code> &mdash; converts Lua
-                variable to an 8-byte
-                integer, and stores the integer in the resulting
-                string, low byte first,
-                </member>
-                <member><code>n</code> or <code>N</code> &mdash; converts Lua
-                variable to a 4-byte
-                integer, and stores the integer in the resulting
-                string, big endian,
-                </member>
-                <member><code>q</code> or <code>Q</code> &mdash; converts Lua
-                variable to an 8-byte
-                integer, and stores the integer in the resulting
-                string, big endian,
-                </member>
-                <member><code>f</code> &mdash; converts Lua
-                variable to a 4-byte
-                float, and stores the float in the resulting
-                string,
-                </member>
-                <member><code>d</code> &mdash; converts Lua
-                variable to a 8-byte
-                double, and stores the double in the resulting
-                string,
-                </member>
-                <member><code>d</code> &mdash; converts Lua
-                variable to a sequence of bytes,
-                and stores the sequence in the resulting
-                string,
-                </member>
-            </simplelist>
+              Convert a Lua object to a JSON string.
             </para>
             <para>
-              Returns: a binary string containing all arguments, packed
-              according to the format specifiers.
+              Parameters: either a scalar value or a Lua table value.
             </para>
             <para>
-              Possible Errors: Unknown format specifier.
+              Returns: (type = string) the original value reformatted as a JSON string.
             </para>
-            <para>
-        <bridgehead renderas="sect4">Example</bridgehead>
+            <bridgehead renderas="sect4">Example</bridgehead>
 <programlisting>
-tarantool> <userinput>pickle = require('pickle')</userinput>
----
-...
-tarantool> <userinput>box.space.tester:insert{0, 'hello world'}</userinput>
+tarantool&gt; <userinput>json=require('json')</userinput>
 ---
-- [0, 'hello world']
 ...
-tarantool> <userinput>box.space.tester:update({0}, {{'=', 2, 'bye world'}})</userinput>
+tarantool&gt; <userinput>json.encode(123)</userinput>
 ---
-- [0, 'bye world']
+- '123'
 ...
-tarantool> <userinput>box.space.tester:update({0}, {{'=', 2, pickle.pack('iiA', 0, 3, 'hello')}})</userinput>
+tarantool&gt; <userinput>json.encode({123})</userinput>
 ---
-- [0, "\0\0\0\0\x03\0\0\0hello"]
+- '[123]'
 ...
-tarantool> <userinput>box.space.tester:update({0}, {{'=', 2, 4}})</userinput>
+tarantool&gt; <userinput>json.encode({123, 234, 345})</userinput>
 ---
-- [0, 4]
+- '[123,234,345]'
 ...
-tarantool> <userinput>box.space.tester:update({0}, {{'+', 2, 4}})</userinput>
+tarantool&gt; <userinput>json.encode({abc = 234, cde = 345})</userinput>
 ---
-- [0, 8]
+- '{"cde":345,"abc":234}'
 ...
-tarantool> <userinput>box.space.tester:update({0}, {{'^', 2, 4}})</userinput>
+tarantool&gt; <userinput>json.encode({hello = {'world'}})</userinput>
 ---
-- [0, 12]
+- '{"hello":["world"]}'
 ...
 </programlisting>
-            </para>
         </listitem>
     </varlistentry>
-
     <varlistentry>
-        <term><emphasis role="lua">pickle.unpack(<replaceable>format, binary-string</replaceable>)</emphasis></term>
+        <term><emphasis role="lua">json.decode(<replaceable>string-value</replaceable>)</emphasis></term>
         <listitem>
             <para>
-              Counterpart to <code>pickle.pack()</code>.
+              Convert a JSON string to a Lua object.
             </para>
             <para>
-              Parameters: <code>format</code>, <code>binary-string</code>.
+              Parameters: <code>string-value</code> = a string formatted as JSON.
             </para>
             <para>
-             Returns: (type = scalar) A list of strings or numbers.
+              Returns: (type = Lua table) the original contents formatted as a Lua table.
             </para>
-            <para>
             <bridgehead renderas="sect4">Example</bridgehead>
-<programlisting>
-<prompt>tarantool</prompt> <userinput>pickle = require('pickle')</userinput>
----
-...
-<prompt>tarantool></prompt> <userinput>console = require('console'); console.delimiter('!') -- this means following commands must end with '!'</userinput>
-<prompt>tarantool></prompt> <userinput>tuple = box.space.tester:replace{0}!</userinput>
+<programlisting>tarantool&gt; <userinput>json=require('json')</userinput>
 ---
 ...
-<prompt>tarantool></prompt> <userinput>string.len(tuple[1])!</userinput>
+ tarantool&gt; <userinput>json.decode('123')</userinput>
 ---
-- 1
+- 123
 ...
-<prompt>tarantool></prompt> <userinput>pickle.unpack('b', tuple[1])!</userinput>
+tarantool&gt; <userinput>json.decode('[123, "hello"]')[2]</userinput>
 ---
-- 48
+- hello
 ...
-<prompt>tarantool></prompt> <userinput>pickle.unpack('bsi', pickle.pack('bsi', 255, 65535, 4294967295))!</userinput>
+tarantool&gt; <userinput>json.decode('{"hello": "world"}').hello</userinput>
 ---
-- 255
-- 65535
-- 4294967295
+- world
 ...
-<prompt>tarantool></prompt> <userinput>pickle.unpack('ls', pickle.pack('ls', tonumber64('18446744073709551615'), 65535))!</userinput>
+</programlisting>
+        </listitem>
+    </varlistentry>
+    <varlistentry>
+        <term><emphasis role="lua" xml:id="json-null" xreflabel="json-null">json.NULL</emphasis></term>
+        <listitem>
+            <para>
+              Return a value comparable to Lua "nil" which may be useful as a placeholder in a tuple or Lua table.
+            </para>
+            <para>
+              Parameters: none.
+            </para>
+            <para>
+              Returns: the comparable value.
+            </para>
+            <bridgehead renderas="sect4">Example</bridgehead>
+<programlisting>
+<prompt>tarantool&gt;</prompt> <userinput>-- When nil is assigned to a Lua-table field, the field disappears</userinput>
+<prompt>tarantool&gt;</prompt> <userinput>{nil, 'a', 'b'}</userinput>
 ---
-- 18446744073709551615
-- 65535
+- 2: a
+  3: b
 ...
-<prompt>tarantool></prompt> <userinput>num, str, num64 = pickle.unpack('sAl', pickle.pack('sAl', 666, 'string',</userinput>
-<prompt>        -></prompt> <userinput>                  tonumber64('666666666666666')))!</userinput>
+<prompt>tarantool&gt;</prompt> <userinput> -- When json.NULL is assigned to a Lua-table field, the field is json.NULL</userinput>
+<prompt>tarantool&gt;</prompt> <userinput>{json.NULL, 'a', 'b'}</userinput>
 ---
+- - null
+  - a
+  - b
 ...
-<prompt>tarantool></prompt> <userinput>num, str, num64!</userinput>
+<prompt>tarantool&gt;</prompt> <userinput>-- When json.NULL is assigned to a JSON field, the field is null</userinput>
+<prompt>tarantool&gt;</prompt> <userinput>json.encode({field2 = json.NULL, field1 = 'a',  field3 = 'c'})</userinput>
 ---
-- 666
-- string
-- 666666666666666
-...
-<prompt>tarantool></prompt> <userinput>console.delimiter('') -- back to normal: commands end with line feed!</userinput>
-</programlisting>
-            </para>
+- '{"field2":null,"field1":"a","field3":"c"}'
+...</programlisting>
         </listitem>
     </varlistentry>
 </variablelist>
-</section>
-
-<section xml:id="sp-digest">
-    <title>Package <code>digest</code></title>
-    <para>
-    A "digest" is a value which is returned by a
-
-    <link xlink:href="https://en.wikipedia.org/wiki/Cryptographic_hash_function">Cryptographic hash function</link>
-    applied against a string.
-    Tarantool supports five types of cryptographic hash functions
-    (<link xlink:href="https://en.wikipedia.org/wiki/Md4">MD4</link>,
-    <link xlink:href="https://en.wikipedia.org/wiki/Md5">MD5</link>,
-    <link xlink:href="https://en.wikipedia.org/wiki/Sha-0">SHA-0</link>,
-    
-    <link xlink:href="https://en.wikipedia.org/wiki/Sha-1">SHA-1</link>,
-    <link xlink:href="https://en.wikipedia.org/wiki/Sha-2">SHA-2</link>)
 
-    as well as a checksum function
-    (<link xlink:href="https://en.wikipedia.org/wiki/Cyclic_redundancy_check">CRC32</link>).
-    The functions in <code>digest</code> are:<programlisting><code>    digest.crc32(<replaceable>string</replaceable>)                  Returns 32-bit checksum made with CRC32.
-    digest.crc32_update(<replaceable>number</replaceable>,<replaceable>string</replaceable>)    Returns update of a checksum calculated with crc32.
-    digest.sha(<replaceable>string</replaceable>)                    Returns 160-bit digest made with SHA-0. Not recommended.
-    digest.sha_hex(<replaceable>string</replaceable>)                Returns hexadecimal of a digest calculated with sha.
-    digest.sha1(<replaceable>string</replaceable>)                   Returns 160-bit digest made with SHA-1.
-    digest.sha1_hex(<replaceable>string</replaceable>)               Returns hexadecimal of a digest calculated with sha1.
-    digest.sha224(<replaceable>string</replaceable>)                 Returns 224-bit digest made with SHA-2.
-    digest.sha224_hex(<replaceable>string</replaceable>)             Returns hexadecimal of a digest calculated with sha224.
-    digest.sha256(<replaceable>string</replaceable>)                 Returns 256-bit digest made with SHA-2.
-    digest.sha256_hex(<replaceable>string</replaceable>)             Returns hexadecimal of a digest calculated with sha256.
-    digest.sha384(<replaceable>string</replaceable>)                 Returns 384-bit digest made with SHA-2.
-    digest.sha384_hex(<replaceable>string</replaceable>)             Returns hexadecimal of a digest calculated with sha384.
--   digest.sha512(<replaceable>string</replaceable>)                 Returns 512-bit digest made with SHA-2.
-    digest.sha512_hex(<replaceable>string</replaceable>)             Returns hexadecimal of a digest calculated with sha512.
-    digest.md4(<replaceable>string</replaceable>)                    Returns 128-bit digest made with MD4.
-    digest.md4_hex(<replaceable>string</replaceable>)                Returns hexadecimal of a digest calculated with md4.
-    digest.md5(<replaceable>string</replaceable>)                    Returns 256-bit digest made with MD5.
-    digest.md5_hex(<replaceable>string</replaceable>)                Returns hexadecimal of a digest calculated with md5.</code></programlisting>
-   </para>
-<bridgehead renderas="sect4">Example</bridgehead>
-    <para>
-    In the following example, the user creates two functions, password_insert() 
-    which inserts a SHA-1 digest of the word "^S^e^c^ret Wordpass" into a tuple set,
-    and password_check() which requires input of a password.<programlisting>
-<prompt>localhost&gt;</prompt> <userinput>digest = require('digest')</userinput>
-<prompt>localhost&gt;</prompt> <userinput>console = require('console'); console.delimiter('!') --this means ignore line feeds until next '!'</userinput>
-<prompt>localhost&gt;</prompt> <userinput>function password_insert()</userinput>
-        <prompt>-&gt;</prompt> <userinput>  box.space.tester:insert{12345,digest.sha1('^S^e^c^ret Wordpass')}</userinput>
-        <prompt>-&gt;</prompt> <userinput>  return 'OK'</userinput>
-        <prompt>-&gt;</prompt> <userinput>  end!</userinput>
----
-...
-<prompt>localhost&gt;</prompt> <userinput>function password_check(password)</userinput>
-        <prompt>-&gt;</prompt>  <userinput> local t</userinput>
-        <prompt>-&gt;</prompt>  <userinput> t=box.space.tester:select{12345}</userinput>
-        <prompt>-&gt;</prompt>  <userinput> if (digest.sha1(password)==t[2]) then</userinput>
-        <prompt>-&gt;</prompt>  <userinput>   print('Password is valid')</userinput>
-        <prompt>-&gt;</prompt>  <userinput>   else</userinput>
-        <prompt>-&gt;</prompt>  <userinput>     print('Password is not valid')</userinput>
-        <prompt>-&gt;</prompt>  <userinput>   end</userinput>
-        <prompt>-&gt;</prompt> <userinput>end!</userinput>
----
-...
-<prompt>localhost&gt;</prompt> <userinput>password_insert()!</userinput>
-Call OK, 1 rows affected
-['OK']
-<prompt>localhost></prompt> <userinput>console.delimiter('') --  back to normal: commands end with line feed!</userinput>
-</programlisting></para>
-<para>
-  If a later user calls
-  the password_check() function and enters the wrong password, the result is an
-  error.<programlisting><prompt>localhost&gt;</prompt> <userinput>password_check ('Secret Password')</userinput>
----
-Password is not valid
-...</programlisting></para>
 </section>
 
-<section xml:id="sp-box-uuid">
-    <title>Package <code>uuid</code></title>
-
-<para>
-  A "UUID" is a 
-  <link xlink:href="https://en.wikipedia.org/wiki/Universally_unique_identifier">Universally unique identifier</link>.
-  If an application requires that a value be unique only within a single computer or
-  on a single database, then a simple counter is better than a UUID, because getting
-  a UUID is time-consuming (it requires a
-  <link xlink:href="https://en.wikipedia.org/wiki/Syscall">syscall</link>).
-  For clusters of computers, or widely distributed applications, UUIDs are better.
-</para>
-<para>
-  The functions that can return a UUID are: <code>uuid()</code>, <code>uuid.bin()</code>, <code>uuid.str()</code>.
-  The functions that can convert between different types of UUID are: <code>:bin()</code>, <code>:str()</code>, <code>uuid.fromstr()</code>, <code>uuid.frombin()</code>.
-  The function that can determine whether a UUID is an all-zero value is: <code>:isnil()</code>.
-</para>
-
-<variablelist xml:id="x-uuid" xreflabel="x-uuid">
-
+<section xml:id="sp-yaml">
+    <title>Package <code>yaml</code></title>
+    <para>
+     The <code>yaml</code> package takes strings in YAML format and decodes them,
+     or takes a series of non-YAML values and encodes them.
+    </para>
+<variablelist xml:id="yaml">
     <varlistentry>
-        <term>
-            <emphasis role="lua">uuid()</emphasis>
-        </term>
-        <listitem>
-            <para>
-                Returns: a UUID with type = cdata.
-            </para>
-        </listitem>
-    </varlistentry>
-
-    <varlistentry>
-        <term>
-            <emphasis role="lua">uuid.bin()</emphasis>
-        </term>
-        <listitem>
-            <para>
-                Returns: a UUID with type = 16-byte binary string.
-            </para>
-        </listitem>
-    </varlistentry>
-
-    <varlistentry>
-        <term>
-            <emphasis role="lua">uuid.str()</emphasis>
-        </term>
-        <listitem>
-            <para>
-                Returns: a UUID with type = 36-byte hexadecimal string.
-            </para>
-        </listitem>
-    </varlistentry>
-
-    <varlistentry>
-        <term>
-         <emphasis role="lua"><replaceable>uuid_with_type_cdata</replaceable>:bin([<replaceable>byte-order</replaceable>])</emphasis>
-        </term>
-        <listitem>
-            <para>
-                Parameters: byte-order can be 'l' (little-endian), 'b' (big-endian), 'h' (endianness depends on host) (default), or 'n' (endianness depends on network).
-            </para>         
-            <para>
-                Returns: UUID with type = 16-byte binary string converted from cdata input value.
-            </para>
-        </listitem>
-    </varlistentry>
-
-    <varlistentry>
-        <term>
-            <emphasis role="lua">  <replaceable>uuid_with_type_cdata</replaceable>:str()</emphasis>
-        </term>
-        <listitem>
-            <para>
-                Returns: UUID with type = 36-byte hexadecimal string converted from cdata input value.
-            </para>
-        </listitem>
-    </varlistentry>
-
-    <varlistentry>
-        <term>
-            <emphasis role="lua">  uuid.fromstr(<replaceable>uuid_with_type_string</replaceable>)</emphasis>
-        </term>
-        <listitem>
-            <para>
-                Returns: UUID with type = cdata converted from 36-byte hexadecimal string input value.
-            </para>
-        </listitem>
-    </varlistentry>
-
-    <varlistentry>
-        <term>
-            <emphasis role="lua">uuid.frombin(<replaceable>uuid_with_type_binary_string</replaceable>)</emphasis>
-        </term>
-        <listitem>
-            <para>
-                Returns: UUID with type = cdata converted from 16-byte binary string input value.
-            </para>
-        </listitem>
-    </varlistentry>
-
-    <varlistentry>
-        <term>
-            <emphasis role="lua">:isnil(<replaceable>uuid_with_type_cdata</replaceable>)</emphasis>
-        </term>
-        <listitem>
-            <para>
-                Returns: true if the value is all zero, otherwise false.
-                The all-zero UUID value can be expressed as <code>uuid.NULL</code>, or as
-                uuid.fromstr('00000000-0000-0000-0000-000000000000').
-                The comparison with an all-zero value can also be expressed as
-                <replaceable>uuid_with_type_cdata</replaceable> == uuid.NULL.
-            </para>
-        </listitem>
-    </varlistentry>
-
-</variablelist>
-<para>
-            <bridgehead renderas="sect4">Example</bridgehead>
-<programlisting>
-tarantool&gt; <userinput>uuid = require('uuid')</userinput>
----
-...
-tarantool&gt; <userinput>uuid(), uuid.bin(), uuid.str()</userinput>
----
-- 16ffedc8-cbae-4f93-a05e-349f3ab70baa
-- !!binary FvG+Vy1MfUC6kIyeM81DYw==
-- 67c999d2-5dce-4e58-be16-ac1bcb93160f
-...
-tarantool&gt; <userinput>uu = uuid()</userinput>
----
-...
-tarantool&gt; <userinput>#uu:bin(), #uu:str(), type(uu), uu:isnil()</userinput>
----
-- 16
-- 36
-- cdata
-- false
-...
-</programlisting>
-</para>
-
-</section>
-
-<section xml:id="sp-box-cjson">
-    <title>Package <code>json</code></title>
-
-<variablelist xml:id="box.cjson" xreflabel="box.cjson">
-    <para>
-        The <code>json</code> package provides JSON manipulation routines.
-        It is based on the <link xlink:href="http://www.kyne.com.au/~mark/software/lua-cjson.php">
-        Lua-CJSON package by Mark Pulford</link>.
-
-        For a complete manual on Lua-CJSON please read <link xlink:href="http://www.kyne.com.au/~mark/software/lua-cjson-manual.html">the official documentation</link>.
-    </para>
-    <varlistentry>
-        <term><emphasis role="lua">json.encode(<replaceable>scalar-value | Lua-table-value</replaceable>)</emphasis></term>
-        <listitem>
-            <para>
-              Convert a Lua object to a JSON string.
-            </para>
-            <para>
-              Parameters: either a scalar value or a Lua table value.
-            </para>
-            <para>
-              Returns: (type = string) the original value reformatted as a JSON string.
-            </para>
-            <bridgehead renderas="sect4">Example</bridgehead>
-<programlisting>
-tarantool&gt; <userinput>json=require('json')</userinput>
----
-...
-tarantool&gt; <userinput>json.encode(123)</userinput>
----
-- '123'
-...
-tarantool&gt; <userinput>json.encode({123})</userinput>
----
-- '[123]'
-...
-tarantool&gt; <userinput>json.encode({123, 234, 345})</userinput>
----
-- '[123,234,345]'
-...
-tarantool&gt; <userinput>json.encode({abc = 234, cde = 345})</userinput>
----
-- '{"cde":345,"abc":234}'
-...
-tarantool&gt; <userinput>json.encode({hello = {'world'}})</userinput>
----
-- '{"hello":["world"]}'
-...
-</programlisting>
-        </listitem>
-    </varlistentry>
-    <varlistentry>
-        <term><emphasis role="lua">json.decode(<replaceable>string-value</replaceable>)</emphasis></term>
-        <listitem>
-            <para>
-              Convert a JSON string to a Lua object.
-            </para>
-            <para>
-              Parameters: <code>string-value</code> = a string formatted as JSON.
-            </para>
-            <para>
-              Returns: (type = Lua table) the original contents formatted as a Lua table.
-            </para>
-            <bridgehead renderas="sect4">Example</bridgehead>
-<programlisting>tarantool&gt; <userinput>json=require('json')</userinput>
----
-...
- tarantool&gt; <userinput>json.decode('123')</userinput>
----
-- 123
-...
-tarantool&gt; <userinput>json.decode('[123, "hello"]')[2]</userinput>
----
-- hello
-...
-tarantool&gt; <userinput>json.decode('{"hello": "world"}').hello</userinput>
----
-- world
-...
-</programlisting>
-        </listitem>
-    </varlistentry>
-    <varlistentry>
-        <term><emphasis role="lua" xml:id="json-null" xreflabel="json-null">json.NULL</emphasis></term>
-        <listitem>
-            <para>
-              Return a value comparable to Lua "nil" which may be useful as a placeholder in a tuple or Lua table.
-            </para>
-            <para>
-              Parameters: none.
-            </para>
-            <para>
-              Returns: the comparable value.
-            </para>
-            <bridgehead renderas="sect4">Example</bridgehead>
-<programlisting>
-<prompt>tarantool&gt;</prompt> <userinput>-- When nil is assigned to a Lua-table field, the field disappears</userinput>
-<prompt>tarantool&gt;</prompt> <userinput>{nil, 'a', 'b'}</userinput>
----
-- 2: a
-  3: b
-...
-<prompt>tarantool&gt;</prompt> <userinput> -- When json.NULL is assigned to a Lua-table field, the field is json.NULL</userinput>
-<prompt>tarantool&gt;</prompt> <userinput>{json.NULL, 'a', 'b'}</userinput>
----
-- - null
-  - a
-  - b
-...
-<prompt>tarantool&gt;</prompt> <userinput>-- When json.NULL is assigned to a JSON field, the field is null</userinput>
-<prompt>tarantool&gt;</prompt> <userinput>json.encode({field2 = json.NULL, field1 = 'a',  field3 = 'c'})</userinput>
----
-- '{"field2":null,"field1":"a","field3":"c"}'
-...</programlisting>
-        </listitem>
-    </varlistentry>
-</variablelist>
-
-</section>
-
-<section xml:id="sp-yaml">
-    <title>Package <code>yaml</code></title>
-    <para>
-     The <code>yaml</code> package takes strings in YAML format and decodes them,
-     or takes a series of non-YAML values and encodes them.
-    </para>
-<variablelist xml:id="yaml">
-    <varlistentry>
-        <term><emphasis role="lua">yaml.encode(<replaceable>scalar-value | Lua-table-value</replaceable>)</emphasis></term>
+        <term><emphasis role="lua">yaml.encode(<replaceable>scalar-value | Lua-table-value</replaceable>)</emphasis></term>
         <listitem>
             <para>
               Convert a Lua object to a YAML string.
@@ -2817,6 +2531,273 @@ end
 
 </section>
 
+<section xml:id="sp-tonumber64">
+ <title>Lua functions <code>tonumber64</code> and <code>dostring</code></title>
+
+<variablelist>
+
+    <varlistentry>
+        <term xml:id="tonumber64" xreflabel="tonumber64"> <emphasis role="lua">tonumber64(<replaceable>value</replaceable>)</emphasis></term>
+        <listitem>
+            <para>
+              Convert a string or a Lua number to a
+              64-bit integer. The result can be used in arithmetic,
+              and the arithmetic will be 64-bit integer arithmetic
+              rather than floating-point arithmetic. (Operations on
+              an unconverted Lua number use floating-point arithmetic.)
+              The tonumber64() function is added by Tarantool; the name is global.
+              <bridgehead renderas="sect4">Example</bridgehead>
+<programlisting>
+tarantool> <userinput>type(123456789012345), type(tonumber64(123456789012345))</userinput>
+---
+- number
+- cdata
+...
+tarantool> <userinput>i = tonumber64('1000000000')</userinput>
+---
+...
+tarantool> <userinput>type(i), i / 2, i - 2, i * 2, i + 2, i % 2, i ^ 2</userinput>
+---
+ - cdata
+ - 500000000
+ - 999999998
+ - 2000000000
+ - 1000000002
+ - 0
+ - 1000000000000000000
+...
+</programlisting>
+            </para>
+        </listitem>
+    </varlistentry>
+    
+    <varlistentry>
+        <term>
+            <emphasis role="lua">dostring(<replaceable>lua-chunk-string [, lua-chunk-string-argument ...]</replaceable>)</emphasis>
+        </term>
+        <listitem>
+            <para>
+              Parse and execute an arbitrary chunk of Lua code.
+              This function is mainly useful to define and run
+              Lua code without having to
+              introduce changes to the global Lua environment.
+            </para>
+            <para>
+              Parameters: <code>lua-chunk-string</code> = string containing Lua code,
+              <code>lua-chunk-string-argument(s)</code> = zero or more scalar values
+               which will be appended to, or substitute for, items in the Lua chunk.
+             </para>
+             <para>
+               Returns: whatever is returned by the Lua code chunk.
+            </para>
+            <para>
+               Possible errors: If there is a compilation error,
+               it is raised as a Lua error.
+            </para>
+            <para>
+            <bridgehead renderas="sect4">Example</bridgehead>
+<programlisting>
+tarantool&gt; <userinput>dostring('abc')</userinput>
+---
+error: '[string "abc"]:1: ''='' expected near ''&lt;eof&gt;'''
+...
+tarantool&gt; <userinput>dostring('return 1')</userinput>
+---
+- 1
+...
+tarantool&gt; <userinput>dostring('return ...', 'hello', 'world')</userinput>
+---
+- hello
+- world
+...
+tarantool&gt; <userinput>console = require('console'); console.delimiter('!') --<link linkend="utility-tarantool-delim">this</link> means ignore line feeds until next '!'</userinput>
+tarantool&gt; <userinput>-- Use <link xlink:href="http://www.lua.org/pil/2.4.html">double square brackets</link> to enclose multi-line literal here!</userinput>
+tarantool&gt; <userinput>dostring([[local f = function(key)</userinput>
+        -&gt; <userinput>              t = box.space.tester:select{key};</userinput>
+        -&gt; <userinput>              if t ~= nil then return t[1] else return nil end</userinput>
+        -&gt; <userinput>              end</userinput>
+        -&gt; <userinput>              return f(...)]], 1)!</userinput>
+---
+- null
+...
+tarantool&gt; <userinput>console.delimiter('')!</userinput>
+</programlisting>
+            </para>
+        </listitem>
+    </varlistentry>
+    
+</variablelist>
+
+</section>
+
+
+<section xml:id="sp-pickle">
+    <title>Package <code>pickle</code></title>
+<variablelist xml:id="x-pickle" xreflabel="x-pickle">
+    <varlistentry>
+        <term><emphasis role="lua">pickle.pack(<replaceable>format, argument [, argument ...]</replaceable>)</emphasis></term>
+        <listitem><para>
+            To use Tarantool binary protocol primitives from Lua,
+            it's necessary to convert Lua variables to binary
+            format. The pickle.pack() helper function is prototyped after Perl
+            <link xlink:href="http://perldoc.perl.org/functions/pack.html">
+             'pack'</link>.
+            </para>
+            <para>
+               Parameters: <code>format</code> = string containing format specifiers, <code>argument(s)</code> = scalar values to be formatted.
+            </para>
+            <para>
+            <bridgehead renderas="sect4">Format specifiers</bridgehead>
+            <simplelist>
+                <member><code>b</code> or <code>B</code> &mdash; converts Lua
+                variable to a 1-byte
+                integer, and stores the integer in the resulting
+                string,
+                </member>
+                <member><code>s</code> or <code>S</code> &mdash; converts Lua
+                variable to a 2-byte
+                integer, and stores the integer in the resulting
+                string, low byte first,
+                </member>
+                <member><code>i</code> or <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>l</code> or <code>L</code> &mdash; converts Lua
+                variable to an 8-byte
+                integer, and stores the integer in the resulting
+                string, low byte first,
+                </member>
+                <member><code>n</code> or <code>N</code> &mdash; converts Lua
+                variable to a 4-byte
+                integer, and stores the integer in the resulting
+                string, big endian,
+                </member>
+                <member><code>q</code> or <code>Q</code> &mdash; converts Lua
+                variable to an 8-byte
+                integer, and stores the integer in the resulting
+                string, big endian,
+                </member>
+                <member><code>f</code> &mdash; converts Lua
+                variable to a 4-byte
+                float, and stores the float in the resulting
+                string,
+                </member>
+                <member><code>d</code> &mdash; converts Lua
+                variable to a 8-byte
+                double, and stores the double in the resulting
+                string,
+                </member>
+                <member><code>d</code> &mdash; converts Lua
+                variable to a sequence of bytes,
+                and stores the sequence in the resulting
+                string,
+                </member>
+            </simplelist>
+            </para>
+            <para>
+              Returns: a binary string containing all arguments, packed
+              according to the format specifiers.
+            </para>
+            <para>
+              Possible Errors: Unknown format specifier.
+            </para>
+            <para>
+        <bridgehead renderas="sect4">Example</bridgehead>
+<programlisting>
+tarantool> <userinput>pickle = require('pickle')</userinput>
+---
+...
+tarantool> <userinput>box.space.tester:insert{0, 'hello world'}</userinput>
+---
+- [0, 'hello world']
+...
+tarantool> <userinput>box.space.tester:update({0}, {{'=', 2, 'bye world'}})</userinput>
+---
+- [0, 'bye world']
+...
+tarantool> <userinput>box.space.tester:update({0}, {{'=', 2, pickle.pack('iiA', 0, 3, 'hello')}})</userinput>
+---
+- [0, "\0\0\0\0\x03\0\0\0hello"]
+...
+tarantool> <userinput>box.space.tester:update({0}, {{'=', 2, 4}})</userinput>
+---
+- [0, 4]
+...
+tarantool> <userinput>box.space.tester:update({0}, {{'+', 2, 4}})</userinput>
+---
+- [0, 8]
+...
+tarantool> <userinput>box.space.tester:update({0}, {{'^', 2, 4}})</userinput>
+---
+- [0, 12]
+...
+</programlisting>
+            </para>
+        </listitem>
+    </varlistentry>
+
+    <varlistentry>
+        <term><emphasis role="lua">pickle.unpack(<replaceable>format, binary-string</replaceable>)</emphasis></term>
+        <listitem>
+            <para>
+              Counterpart to <code>pickle.pack()</code>.
+            </para>
+            <para>
+              Parameters: <code>format</code>, <code>binary-string</code>.
+            </para>
+            <para>
+             Returns: (type = scalar) A list of strings or numbers.
+            </para>
+            <para>
+            <bridgehead renderas="sect4">Example</bridgehead>
+<programlisting>
+<prompt>tarantool</prompt> <userinput>pickle = require('pickle')</userinput>
+---
+...
+<prompt>tarantool></prompt> <userinput>console = require('console'); console.delimiter('!') -- this means following commands must end with '!'</userinput>
+<prompt>tarantool></prompt> <userinput>tuple = box.space.tester:replace{0}!</userinput>
+---
+...
+<prompt>tarantool></prompt> <userinput>string.len(tuple[1])!</userinput>
+---
+- 1
+...
+<prompt>tarantool></prompt> <userinput>pickle.unpack('b', tuple[1])!</userinput>
+---
+- 48
+...
+<prompt>tarantool></prompt> <userinput>pickle.unpack('bsi', pickle.pack('bsi', 255, 65535, 4294967295))!</userinput>
+---
+- 255
+- 65535
+- 4294967295
+...
+<prompt>tarantool></prompt> <userinput>pickle.unpack('ls', pickle.pack('ls', tonumber64('18446744073709551615'), 65535))!</userinput>
+---
+- 18446744073709551615
+- 65535
+...
+<prompt>tarantool></prompt> <userinput>num, str, num64 = pickle.unpack('sAl', pickle.pack('sAl', 666, 'string',</userinput>
+<prompt>        -></prompt> <userinput>                  tonumber64('666666666666666')))!</userinput>
+---
+...
+<prompt>tarantool></prompt> <userinput>num, str, num64!</userinput>
+---
+- 666
+- string
+- 666666666666666
+...
+<prompt>tarantool></prompt> <userinput>console.delimiter('') -- back to normal: commands end with line feed!</userinput>
+</programlisting>
+            </para>
+        </listitem>
+    </varlistentry>
+</variablelist>
+</section>
+
+
 <section xml:id="sp-expirationd">
  <title>expirationd -- the daemon that shifts expired tuples to a long-term archive</title>
 
diff --git a/doc/user/user.xml b/doc/user/user.xml
index 6c55e5b529..f5fca8486e 100644
--- a/doc/user/user.xml
+++ b/doc/user/user.xml
@@ -16,6 +16,7 @@
 <xi:include href="server-administration.xml"/>
 <xi:include href="configuration-reference.xml"/>
 <xi:include href="connectors.xml"/>
+<xi:include href="errcode.xml"/>
 <xi:include href="proctitle.xml"/>
 <xi:include href="lua-tutorial.xml"/>
 <xi:include href="plugins.xml"/>
-- 
GitLab