Skip to content

Commit

Permalink
Add default values docs (#4371)
Browse files Browse the repository at this point in the history
Resolves #3520 #3617

Co-authored-by: Andrey Aksenov <38073144+andreyaksenov@users.noreply.github.com>
  • Loading branch information
p7nov and andreyaksenov authored Jul 22, 2024
1 parent 9e72c46 commit 163b69c
Show file tree
Hide file tree
Showing 6 changed files with 228 additions and 12 deletions.
65 changes: 65 additions & 0 deletions doc/code_snippets/test/default_values/default_functions_test.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
local fio = require('fio')
local server = require('luatest.server')
local t = require('luatest')
local g = t.group()
g.before_each(function(cg)
cg.server = server:new {
box_cfg = {},
workdir = fio.cwd() .. '/tmp'
}
cg.server:start()
end)

g.after_each(function(cg)
cg.server:drop()
fio.rmtree(cg.server.workdir)
end)

g.test_default_func = function(cg)
cg.server:exec(function()

-- create_no_arg_function_start
box.schema.func.create('current_year', {
language = 'Lua',
body = "function() return require('datetime').now().year end"
})
-- create_no_arg_function_end

-- format_space_default_func_start
local books = box.schema.space.create('books')
books:format({
{ name = 'id', type = 'unsigned' },
{ name = 'isbn', type = 'string' },
{ name = 'title', type = 'string' },
{ name = 'year', type = 'unsigned', default_func = 'current_year' }
})
books:create_index('primary', { parts = { 1 } })
-- format_space_default_func_end

-- insert_ok_start
books:insert { 1, '978000', 'Thinking in Java' }
-- insert_ok_end

-- create_arg_function_start
box.schema.func.create('randomize', {
language = 'Lua',
body = "function(limit) return math.random(limit.min, limit.max) end"
})
-- create_arg_function_end

-- reformat_space_start
books:format({
{ name = 'id', type = 'unsigned', default_func= 'randomize', default = {min = 0, max = 1000} },
{ name = 'isbn', type = 'string' },
{ name = 'title', type = 'string' },
{ name = 'year', type = 'unsigned', default_func = 'current_year' }
})
-- reformat_space_end

books:insert { nil, '978001', 'How to code in Go' }

-- Tests --
t.assert_equals(books:count(), 2)
t.assert_equals(books:get(1), { 1, '978000','Thinking in Java', 2024 })
end)
end
39 changes: 39 additions & 0 deletions doc/code_snippets/test/default_values/explicit_default_test.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
local fio = require('fio')
local server = require('luatest.server')
local t = require('luatest')
local g = t.group()
g.before_each(function(cg)
cg.server = server:new {
box_cfg = {},
workdir = fio.cwd() .. '/tmp'
}
cg.server:start()
end)

g.after_each(function(cg)
cg.server:drop()
fio.rmtree(cg.server.workdir)
end)

g.test_default_values = function(cg)
cg.server:exec(function()
-- configure_space_start
local books = box.schema.space.create('books')
books:format({
{ name = 'id', type = 'number' },
{ name = 'name', type = 'string' },
{ name = 'year', type = 'number', default = 2024 },
})
books:create_index('primary', { parts = { 1 } })
-- configure_space_end

-- insert_ok_start
books:insert { 1, 'Thinking in Java' }
books:insert { 2, 'How to code in Go', nil }
-- insert_ok_end

-- Tests --
t.assert_equals(books:count(), 2)
t.assert_equals(books:get(1), { 1, 'Thinking in Java', 2024 })
end)
end
114 changes: 114 additions & 0 deletions doc/concepts/data_model/value_store.rst
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,120 @@ Charts explaining the precise differences from DUCET order are
in the
`Common Language Data Repository <https://unicode.org/cldr/charts/30/collation>`_.


.. _index-defaults:

Default values
--------------

*Default values* are assigned to tuple fields automatically if these fields are
skipped during the tuple :ref:`insert or update <index-box_data-operations>`.

You can specify a default value for a field in the :ref:`space_object:format() <box_space-format>`
call that defines the space format. Default values apply regardless of the field nullability:
any tuple in which the field is skipped or set to `nil` receives
the default value.

Default values can be set in two ways: explicitly or using a function.

.. _index-defaults-explicit:

Explicit default values
~~~~~~~~~~~~~~~~~~~~~~~

Explicit default values are defined in the ``default`` parameter of the field declaration
in a :ref:`space_object:format() <box_space-format>` call.

.. literalinclude:: /code_snippets/test/default_values/explicit_default_test.lua
:language: lua
:start-after: configure_space_start
:end-before: configure_space_end
:dedent:

To use a default value for a field, skip it or assign `nil`:

.. literalinclude:: /code_snippets/test/default_values/explicit_default_test.lua
:language: lua
:start-after: insert_ok_start
:end-before: insert_ok_end
:dedent:

Any Lua object that can be evaluated during the ``space_object.format()`` call
may be used as a default value, for example:

- a constant: ``default = 100``
- an initialized variable: ``default = default_size``
- an expression: ``default = 10 + default_size``
- a function return value: ``default = count_default()``

.. important::

Explicit default values are evaluated **only** when setting the space format.
If you use a variable as a default value, its further assignments do not affect the default value.

To change the default values, call ``space_object:format()`` again.


See also the :ref:`space_object:format() <box_space-format>` reference.

.. _index-defaults-functions:

Default functions
~~~~~~~~~~~~~~~~~

A default value can be defined as a return value of a stored Lua function. To be
the default, a function must be created with :ref:`box.schema.func.create() <box_schema-func_create>`
with the function body and return one value of the field's type. It also must not :ref:`yield <app-yields>`.

.. literalinclude:: /code_snippets/test/default_values/default_functions_test.lua
:language: lua
:start-after: create_no_arg_function_start
:end-before: create_no_arg_function_end
:dedent:

Default functions are set in the ``default_func`` parameter of the field declaration
in a ``space_object:format()`` call. To make a function with no arguments the default
for a field, specify its name:

.. literalinclude:: /code_snippets/test/default_values/default_functions_test.lua
:language: lua
:start-after: format_space_default_func_start
:end-before: format_space_default_func_end
:dedent:

A default function can also have one argument.

.. literalinclude:: /code_snippets/test/default_values/default_functions_test.lua
:language: lua
:start-after: create_arg_function_start
:end-before: create_arg_function_end
:dedent:

To pass the function argument when setting the default, specify it in the ``default`` parameter
of the ``space_object:format()`` call:

.. literalinclude:: /code_snippets/test/default_values/default_functions_test.lua
:language: lua
:start-after: reformat_space_start
:end-before: reformat_space_end
:dedent:


.. note::

A key difference between a default function (``default_func = 'count_default'``)
and a function return value used as a field default value (``default = count_default()``)
is the following:

- A *default function* is called **every time a default value must be produced**,
that is, a tuple is inserted or updated without specifying the field.
- A return value used a field *default value*: the function is called **once**
when setting the space format. Then, all tuples receive the result of
this exact call if the field is not specified.

See also the :ref:`space_object.format() <box_space-format>` reference.


.. _index-constraints:

Constraints
Expand Down
13 changes: 3 additions & 10 deletions doc/enterprise/read_views.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,6 @@ Tarantool duplicates only blocks modified after a read view is created.
Tarantool Enterprise Edition supports read views starting from v2.11.0 and enables the ability
to work with them using both :ref:`Lua <read_views_lua_api>` and :ref:`C API <read_views_c_api>`.





.. _read_views_limitations:

Limitations
Expand All @@ -34,8 +30,7 @@ Read views have the following limitations:

- Only the :ref:`memtx <engines-memtx>` engine is supported.
- Only TREE and HASH :ref:`indexes <index-types>` are supported.
- Pagination is not supported (the :ref:`after <box_index-select>` option).

- Pagination (the :ref:`after <box_index-select>` option) is supported only for TREE indexes.


.. _working_with_read_views:
Expand Down Expand Up @@ -73,8 +68,6 @@ After creating a read view, you can see the information about it by calling
To list all the created read views, call the :ref:`box.read_view.list() <reference_lua-box_read_view_list>` function.



.. _querying_data:

Querying data
Expand Down Expand Up @@ -112,6 +105,7 @@ Similarly, you can retrieve data by the specific index.
...
ADD example with fech_pos and after

.. _closing_read_view:

Expand All @@ -134,7 +128,6 @@ After the read view is closed,
its :ref:`status <read_view_object-status>` is set to ``closed``.
On an attempt to use it, an error is raised.


.. _read_views_example:

Example
Expand Down Expand Up @@ -202,7 +195,7 @@ as described in :ref:`Using data operations <box_space-operations-detailed-examp
...
??? ADD example with fetch_pos and after
.. toctree::
:maxdepth: 2
:hidden:
Expand Down
4 changes: 4 additions & 0 deletions doc/reference/reference_lua/box_space/format.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ space_object:format()
See also: :ref:`key_part.collation <key_part_collation>`.
* (Optional) The ``constraint`` table specifies the :ref:`constraints <index-constraints>` that the field value must satisfy.
* (Optional) The ``foreign_key`` table specifies the :ref:`foreign keys <index-box_foreign_keys>` for the field.
* (Optional) The ``default`` value specifies the :ref:`explicit default value <index-defaults-explicit>` for the field
or the argument of the default function if ``default_func`` is specified.
* (Optional) The ``default_func`` string value specifies the name of the field's :ref:`default function <index-defaults-functions>`.
To pass the default function's argument, add the ``default`` parameter.

It is not legal for tuples to contain values that have the wrong type.
The example below will cause an error:
Expand Down
5 changes: 3 additions & 2 deletions doc/release/3.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,8 @@ It's possible to revert to the old behavior by toggling the new ``binary_data_de
Default field values
~~~~~~~~~~~~~~~~~~~~

You can now assign the default values for specific fields when defining a :ref:`space format <box_space-format>`.
You can now assign the :ref:`default values <index-defaults>` for specific fields
when defining a :ref:`space format <box_space-format>`.
In this example, the ``isbn`` and ``title`` fields have the specified default values:

.. code-block:: lua
Expand Down Expand Up @@ -490,7 +491,7 @@ Then, assign the function name to ``default_func`` when defining a space format:
{ name = 'year_of_publication', type = 'unsigned', default_func = 'current_year' }
})
Learn more in :ref:`index-defaults`.

.. _3-0-triggers:

Expand Down

0 comments on commit 163b69c

Please sign in to comment.