Date: 2022-11-11
Tag: 2.10.4

## Overview

2.10.4 is the 5th [stable][release_policy] version of the 2.10 release
series. It introduces 5 improvements and resolves 28 bugs since
2.10.3.

The "stable" label means that we have all planned features implemented and we
see no high-impact issues. However, if you encounter an issue, feel free to
[report it][issues] on GitHub.

[release_policy]: https://www.tarantool.io/en/doc/latest/dev_guide/release_management/#release-policy
[issues]: https://github.com/tarantool/tarantool/issues

## Compatibility

Tarantool 2.x is backward compatible with Tarantool 1.10.x in the binary data
layout, client-server protocol, and replication protocol.

Please [upgrade][upgrade] using the `box.schema.upgrade()` procedure to unlock
all the new features of the 2.x series.

[upgrade]: https://www.tarantool.io/en/doc/latest/book/admin/upgrades/

## Functionality added or changed

### Core

* The JSON log format can now be used with the syslog logger (gh-7860).

### SQL

* New rules are applied to determine the type of CASE operation (gh-6990).
* Now `NULLIF()` call results have the same type as its first argument (gh-6989).

### Build

* Diagnostics now provide absolute file paths instead of relative ones
  (gh-7808).
* Now the compiler info displayed in `tarantool.build.compiler` and
  `tarantool --version` shows the ID and the version of the compiler
  that was used to build Tarantool. The output has the format
  `${CMAKE_C_COMPILER_ID}-${CMAKE_C_COMPILER_VERSION}`, for example,
  `Clang-14.0.0.14000029` (gh-7888).

## Bugs fixed

### Core

* Fixed creation of spaces with a constraint and a foreign key on the same
  field (gh-7645).
* Now the same error is returned when a password or a username provided
  during authorization is incorrect. This prevents user enumeration (ghs-16).
* Added boundary checking for `getenv()` return values. Also, for security
  reasons, Tarantool code now copies these values instead of using them directly (gh-7797).
* `os.getenv()` now always returns values of sane size (gh-7797).
* Fixed the `BEGIN`, `COMMIT`, and `ROLLBACK` counters in the `box.stat()` output.
  Now they show the number of started, committed, and rolled back transactions
  (gh-7583).
* Fixed a crash that could occur during log rotation and application exit (gh-4450).
* Fixed a possible buffer overflow in `mp_decode_decimal()` and
  `decimal_unpack()` when an input string was too long (ghs-17).
* Fixed a bug in the MsgPack library that could lead to a failure to detect
  invalid MsgPack input and, as a result, an out-of-bounds read (ghs-18).
* If an error occurs during a snapshot recovery, its log now contains
  information about the row that caused the error (gh-7917).

### Memtx

* Fixed possible loss of committed tuples in secondary indexes with MVCC
  transaction manager (gh-7712).
* Fixed an assertion being triggered on `space:drop` (gh-7757).
* Fixed possible violation of the secondary index uniqueness with the transaction
  manager enabled (gh-7761).

### LuaJIT

* Backported patches from vanilla LuaJIT trunk (gh-7230). In the scope of this
activity, the following issues have been resolved:

* Fix overflow check in `unpack()` optimized by a compiler.
* Fix recording of `tonumber()` with cdata argument for failed conversions
  (gh-7655).
* Fix concatenation operation on cdata. It always raises an error now.
* Fixed the Lua stack dump command (`lj-stack`) to support Python 2: unpacking
  arguments within the list initialization is not supported in it (gh-7458).

### Lua

* Fixed a crash in `msgpack.decode` in case the input string contains an invalid
  MsgPack header `0xc1` (gh-7818).

### SQL

* Fixed an assertion when `INDEXED BY` was used with an index that was at
  least third in a space (gh-5976).
* Fixed a crash that could occur when selecting tuples with more fields than specified
  in the space format (gh-5310, gh-4666).
* Fixed an assertion in `JOIN` when using an unsupported index (gh-5678).
* Creating indexes on newly added fields no longer leads to assertions
  in `SELECT` queries (gh-5183).
* Re-running a prepared statement that generates new auto-increment IDs no
  longer causes an error (gh-6422).
* An error is now thrown if too many indexes were created in SQL (gh-5526).

### Box

* Revoked execute access rights to the `LUA` function from the public role (ghs-14).
* **[Breaking change]** Now the empty string, `n`, `nu`, `s`, and `st`
  (that is, leading parts of `num` and `str`) are not accepted as
  valid field types (gh-5940).
* Fixed a bug when `type = box.NULL` in `key_def.new()` resulted in
  `type = 'unsigned'` (gh-5222).
* The `_vfunc` system space now has the same format as `_func` (gh-7822).
* Fixed a crash on recovery from snapshots that don't include system spaces
  (gh-7800).
* Fixed a bug that occurred when a foreign key was created together with fields
  that participate in that foreign key (gh-7652).

### Datetime

* Fixed interval arithmetic for boundaries crossing DST (gh-7700).

  Results of datetime arithmetic operations could get a
  different timezone if the DST boundary has been
  crossed during the operation:

  ```
  tarantool> datetime.new{year=2008, month=1, day=1,
                          tz='Europe/Moscow'} +
             datetime.interval.new{month=6}
  ---
  - 2008-07-01T01:00:00 Europe/Moscow
  ...
  ```

  Now we resolve `tzoffset` at the end of operation if
  `tzindex` is not 0.
* Fixed subtractions for datetimes with different timezones (gh-7698).

  Preivously, the timezone difference (`tzoffset`) was ignored in
  datetime subtraction operations:

  ```
  tarantool> datetime.new{tz='MSK'} - datetime.new{tz='UTC'}
  ---
  - +0 seconds
  ...
  tarantool> datetime.new{tz='MSK'}.timestamp -
             datetime.new{tz='UTC'}.timestamp
  ---
  - -10800
  ...
  ```

  Now this difference is accumulated in the minute component of
  the resulting interval:

  ```
  tarantool> datetime.new{tz='MSK'} - datetime.new{tz='UTC'}
  ---
  - -180 minutes
  ...
  ```
