Tarantool development patches archive
 help / color / mirror / Atom feed
* [Tarantool-patches] [PATCH v2 0/4] introduce indices over UUID
@ 2020-04-09 23:50 Serge Petrenko
  2020-04-09 23:50 ` [Tarantool-patches] [PATCH v2 1/4] refactoring: extract mpstream into a separate library Serge Petrenko
                   ` (6 more replies)
  0 siblings, 7 replies; 14+ messages in thread
From: Serge Petrenko @ 2020-04-09 23:50 UTC (permalink / raw)
  To: v.shpilevoy; +Cc: tarantool-patches

https://github.com/tarantool/tarantool/issues/4268
https://github.com/tarantool/tarantool/tree/sp/gh-4268-uuid-type

Changes in v2:
  - disallow to insert strings and binstrings
    to uuid fields.
  - move mp_uuid  files to uuid lib
  - extract mpstream to a separate lib
  - review fixes as per review from Vlad

Serge Petrenko (4):
  refactoring: extract mpstream into a separate library
  uuid: expose tt_uuid_validate method
  box: add MsgPack encoding/decoding for UUID
  box: introduce indices by UUID

 extra/exports                         |  3 +
 src/CMakeLists.txt                    |  2 +-
 src/box/CMakeLists.txt                |  2 +-
 src/box/field_def.c                   | 32 +++++----
 src/box/field_def.h                   |  1 +
 src/box/lua/call.c                    |  2 +-
 src/box/lua/misc.cc                   |  2 +-
 src/box/lua/net_box.c                 |  2 +-
 src/box/lua/tuple.c                   |  2 +-
 src/box/sql.c                         |  3 +-
 src/box/sql/func.c                    |  2 +-
 src/box/sql/vdbe.c                    |  2 +-
 src/box/sql/vdbemem.c                 |  2 +-
 src/box/tuple_compare.cc              | 59 ++++++++++++++++
 src/box/xrow.c                        |  2 +-
 src/lib/CMakeLists.txt                |  1 +
 src/lib/core/CMakeLists.txt           |  1 -
 src/lib/core/mp_extension_types.h     |  2 +
 src/lib/mpstream/CMakeLists.txt       |  2 +
 src/lib/{core => mpstream}/mpstream.c | 13 +++-
 src/lib/{core => mpstream}/mpstream.h |  5 ++
 src/lib/msgpuck                       |  2 +-
 src/lib/uuid/CMakeLists.txt           |  2 +-
 src/lib/uuid/mp_uuid.c                | 98 +++++++++++++++++++++++++++
 src/lib/uuid/mp_uuid.h                | 90 ++++++++++++++++++++++++
 src/lib/uuid/tt_uuid.c                |  3 +
 src/lib/uuid/tt_uuid.h                | 16 +++--
 src/lua/msgpack.c                     | 29 ++++++--
 src/lua/msgpackffi.lua                | 14 ++++
 src/lua/utils.c                       | 20 ++++++
 src/lua/utils.h                       |  5 ++
 src/lua/uuid.lua                      |  9 ---
 test/app-tap/lua/serializer_test.lua  |  8 +++
 test/app-tap/msgpackffi.test.lua      |  3 +-
 test/app/msgpack.result               | 21 ++++++
 test/app/msgpack.test.lua             | 13 ++++
 test/app/uuid.result                  | 13 +++-
 test/app/uuid.test.lua                |  5 ++
 test/box/tuple.result                 | 81 ++++++++++++++++++++++
 test/box/tuple.test.lua               | 25 +++++++
 test/engine/ddl.result                | 97 +++++++++++++++++++++++++-
 test/engine/ddl.test.lua              | 42 +++++++++++-
 test/engine/uuid.result               | 55 +++++++++++++++
 test/engine/uuid.test.lua             | 27 ++++++++
 test/unit/uuid.c                      | 25 ++++++-
 test/unit/uuid.result                 |  8 ++-
 third_party/lua-cjson/lua_cjson.c     | 27 +++++---
 third_party/lua-yaml/lyaml.cc         | 17 ++++-
 48 files changed, 829 insertions(+), 68 deletions(-)
 create mode 100644 src/lib/mpstream/CMakeLists.txt
 rename src/lib/{core => mpstream}/mpstream.c (95%)
 rename src/lib/{core => mpstream}/mpstream.h (97%)
 create mode 100644 src/lib/uuid/mp_uuid.c
 create mode 100644 src/lib/uuid/mp_uuid.h
 create mode 100644 test/engine/uuid.result
 create mode 100644 test/engine/uuid.test.lua

-- 
2.21.1 (Apple Git-122.3)

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Tarantool-patches] [PATCH v2 1/4] refactoring: extract mpstream into a separate library
  2020-04-09 23:50 [Tarantool-patches] [PATCH v2 0/4] introduce indices over UUID Serge Petrenko
@ 2020-04-09 23:50 ` Serge Petrenko
  2020-04-10 16:56   ` Vladislav Shpilevoy
  2020-04-09 23:50 ` [Tarantool-patches] [PATCH v2 2/4] uuid: expose tt_uuid_validate method Serge Petrenko
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 14+ messages in thread
From: Serge Petrenko @ 2020-04-09 23:50 UTC (permalink / raw)
  To: v.shpilevoy; +Cc: tarantool-patches

mpstream is part of core library, which, since the introduction of
messagepack extension types, leads to circular dependencies between core
and any other library having extension type encoding/decoding methods
(e.g. uuid library which will soon be expanded with such methods).

Prerequisite #4268
---
 src/CMakeLists.txt                    | 2 +-
 src/box/CMakeLists.txt                | 2 +-
 src/box/lua/call.c                    | 2 +-
 src/box/lua/misc.cc                   | 2 +-
 src/box/lua/net_box.c                 | 2 +-
 src/box/lua/tuple.c                   | 2 +-
 src/box/sql.c                         | 3 +--
 src/box/sql/func.c                    | 2 +-
 src/box/sql/vdbe.c                    | 2 +-
 src/box/sql/vdbemem.c                 | 2 +-
 src/box/xrow.c                        | 2 +-
 src/lib/CMakeLists.txt                | 1 +
 src/lib/core/CMakeLists.txt           | 1 -
 src/lib/mpstream/CMakeLists.txt       | 2 ++
 src/lib/{core => mpstream}/mpstream.c | 2 +-
 src/lib/{core => mpstream}/mpstream.h | 0
 src/lib/msgpuck                       | 2 +-
 src/lua/msgpack.c                     | 2 +-
 18 files changed, 17 insertions(+), 16 deletions(-)
 create mode 100644 src/lib/mpstream/CMakeLists.txt
 rename src/lib/{core => mpstream}/mpstream.c (99%)
 rename src/lib/{core => mpstream}/mpstream.h (100%)

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 7d865472d..de9680bcc 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -170,7 +170,7 @@ set_source_files_compile_flags(${server_sources})
 add_library(server STATIC ${server_sources})
 add_dependencies(server build_bundled_libs)
 target_link_libraries(server core coll http_parser bit uri uuid swim swim_udp
-                      swim_ev crypto)
+                      swim_ev crypto mpstream)
 
 # Rule of thumb: if exporting a symbol from a static library, list the
 # library here.
diff --git a/src/box/CMakeLists.txt b/src/box/CMakeLists.txt
index 56758bd2f..6688303a9 100644
--- a/src/box/CMakeLists.txt
+++ b/src/box/CMakeLists.txt
@@ -34,7 +34,7 @@ target_link_libraries(vclock core)
 
 add_library(xrow STATIC xrow.c iproto_constants.c)
 target_link_libraries(xrow server core small vclock misc box_error
-                      scramble ${MSGPUCK_LIBRARIES})
+                      scramble mpstream ${MSGPUCK_LIBRARIES})
 
 add_library(tuple STATIC
     tuple.c
diff --git a/src/box/lua/call.c b/src/box/lua/call.c
index 5d3579eff..1d294948c 100644
--- a/src/box/lua/call.c
+++ b/src/box/lua/call.c
@@ -45,7 +45,7 @@
 #include "box/lua/tuple.h"
 #include "small/obuf.h"
 #include "trivia/util.h"
-#include "mpstream.h"
+#include "mpstream/mpstream.h"
 
 /**
  * A helper to find a Lua function by name and put it
diff --git a/src/box/lua/misc.cc b/src/box/lua/misc.cc
index 79b6cfe3a..4348dcbb2 100644
--- a/src/box/lua/misc.cc
+++ b/src/box/lua/misc.cc
@@ -40,7 +40,7 @@
 #include "box/tuple.h"
 #include "box/tuple_format.h"
 #include "box/lua/tuple.h"
-#include "mpstream.h"
+#include "mpstream/mpstream.h"
 
 static uint32_t CTID_STRUCT_TUPLE_FORMAT_PTR;
 
diff --git a/src/box/lua/net_box.c b/src/box/lua/net_box.c
index c7bd016c3..0b6c362ae 100644
--- a/src/box/lua/net_box.c
+++ b/src/box/lua/net_box.c
@@ -47,7 +47,7 @@
 #include "coio.h"
 #include "box/errcode.h"
 #include "lua/fiber.h"
-#include "mpstream.h"
+#include "mpstream/mpstream.h"
 #include "misc.h" /* lbox_check_tuple_format() */
 
 #define cfg luaL_msgpack_default
diff --git a/src/box/lua/tuple.c b/src/box/lua/tuple.c
index 1e3c3d65c..4b0701edf 100644
--- a/src/box/lua/tuple.c
+++ b/src/box/lua/tuple.c
@@ -42,7 +42,7 @@
 #include "box/tuple_convert.h"
 #include "box/errcode.h"
 #include "json/json.h"
-#include "mpstream.h"
+#include "mpstream/mpstream.h"
 
 /** {{{ box.tuple Lua library
  *
diff --git a/src/box/sql.c b/src/box/sql.c
index 1256df856..fa41b4517 100644
--- a/src/box/sql.c
+++ b/src/box/sql.c
@@ -35,7 +35,6 @@
 #include "sql/sqlInt.h"
 #include "sql/tarantoolInt.h"
 #include "sql/vdbeInt.h"
-#include "mpstream.h"
 
 #include "index.h"
 #include "info/info.h"
@@ -53,7 +52,7 @@
 #include "xrow.h"
 #include "iproto_constants.h"
 #include "fk_constraint.h"
-#include "mpstream.h"
+#include "mpstream/mpstream.h"
 #include "sql_stmt_cache.h"
 
 static sql *db = NULL;
diff --git a/src/box/sql/func.c b/src/box/sql/func.c
index 6e724c824..e3a6e8875 100644
--- a/src/box/sql/func.c
+++ b/src/box/sql/func.c
@@ -51,7 +51,7 @@
 #include "box/tuple.h"
 #include "lua/msgpack.h"
 #include "lua/utils.h"
-#include "mpstream.h"
+#include "mpstream/mpstream.h"
 
 /*
  * Return the collating function associated with a function.
diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index e8a029a8a..1296dbbbe 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -50,7 +50,7 @@
 #include "tarantoolInt.h"
 
 #include "msgpuck/msgpuck.h"
-#include "mpstream.h"
+#include "mpstream/mpstream.h"
 
 #include "box/schema.h"
 #include "box/space.h"
diff --git a/src/box/sql/vdbemem.c b/src/box/sql/vdbemem.c
index aad030df9..18fe958a2 100644
--- a/src/box/sql/vdbemem.c
+++ b/src/box/sql/vdbemem.c
@@ -41,7 +41,7 @@
 #include "tarantoolInt.h"
 #include "box/schema.h"
 #include "box/tuple.h"
-#include "mpstream.h"
+#include "mpstream/mpstream.h"
 
 #ifdef SQL_DEBUG
 /*
diff --git a/src/box/xrow.c b/src/box/xrow.c
index be026a43c..a494d1f46 100644
--- a/src/box/xrow.c
+++ b/src/box/xrow.c
@@ -42,7 +42,7 @@
 #include "vclock.h"
 #include "scramble.h"
 #include "iproto_constants.h"
-#include "mpstream.h"
+#include "mpstream/mpstream.h"
 
 static_assert(IPROTO_DATA < 0x7f && IPROTO_METADATA < 0x7f &&
 	      IPROTO_SQL_INFO < 0x7f, "encoded IPROTO_BODY keys must fit into "\
diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt
index b306634e7..61b87fb9e 100644
--- a/src/lib/CMakeLists.txt
+++ b/src/lib/CMakeLists.txt
@@ -12,6 +12,7 @@ add_subdirectory(uuid)
 add_subdirectory(coll)
 add_subdirectory(crypto)
 add_subdirectory(swim)
+add_subdirectory(mpstream)
 if(ENABLE_BUNDLED_MSGPUCK)
     add_subdirectory(msgpuck EXCLUDE_FROM_ALL)
 endif()
diff --git a/src/lib/core/CMakeLists.txt b/src/lib/core/CMakeLists.txt
index 3f13ff904..13ed1e7ab 100644
--- a/src/lib/core/CMakeLists.txt
+++ b/src/lib/core/CMakeLists.txt
@@ -25,7 +25,6 @@ set(core_sources
     util.c
     random.c
     trigger.cc
-    mpstream.c
     port.c
     decimal.c
     mp_decimal.c
diff --git a/src/lib/mpstream/CMakeLists.txt b/src/lib/mpstream/CMakeLists.txt
new file mode 100644
index 000000000..60ed20030
--- /dev/null
+++ b/src/lib/mpstream/CMakeLists.txt
@@ -0,0 +1,2 @@
+add_library(mpstream STATIC mpstream.c)
+target_link_libraries(mpstream core uuid ${MSGPUCK_LIBRARIES})
diff --git a/src/lib/core/mpstream.c b/src/lib/mpstream/mpstream.c
similarity index 99%
rename from src/lib/core/mpstream.c
rename to src/lib/mpstream/mpstream.c
index 2be1797d0..a737212c1 100644
--- a/src/lib/core/mpstream.c
+++ b/src/lib/mpstream/mpstream.c
@@ -33,7 +33,7 @@
 #include <assert.h>
 #include <stdint.h>
 #include "msgpuck.h"
-#include "mp_decimal.h"
+#include "core/mp_decimal.h"
 
 void
 mpstream_reserve_slow(struct mpstream *stream, size_t size)
diff --git a/src/lib/core/mpstream.h b/src/lib/mpstream/mpstream.h
similarity index 100%
rename from src/lib/core/mpstream.h
rename to src/lib/mpstream/mpstream.h
diff --git a/src/lib/msgpuck b/src/lib/msgpuck
index 8ae606a16..e476ad192 160000
--- a/src/lib/msgpuck
+++ b/src/lib/msgpuck
@@ -1 +1 @@
-Subproject commit 8ae606a1636dd89b2d61b154e5a1db03dce91657
+Subproject commit e476ad19281b29d2ee3e11e74c564c0eceea37d5
diff --git a/src/lua/msgpack.c b/src/lua/msgpack.c
index edbc15b72..73ed3ece6 100644
--- a/src/lua/msgpack.c
+++ b/src/lua/msgpack.c
@@ -29,7 +29,7 @@
  * SUCH DAMAGE.
  */
 #include "lua/msgpack.h"
-#include "mpstream.h"
+#include "mpstream/mpstream.h"
 #include "lua/utils.h"
 
 #if defined(LUAJIT)
-- 
2.21.1 (Apple Git-122.3)

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Tarantool-patches] [PATCH v2 2/4] uuid: expose tt_uuid_validate method
  2020-04-09 23:50 [Tarantool-patches] [PATCH v2 0/4] introduce indices over UUID Serge Petrenko
  2020-04-09 23:50 ` [Tarantool-patches] [PATCH v2 1/4] refactoring: extract mpstream into a separate library Serge Petrenko
@ 2020-04-09 23:50 ` Serge Petrenko
  2020-04-09 23:50 ` [Tarantool-patches] [PATCH v2 3/4] box: add MsgPack encoding/decoding for UUID Serge Petrenko
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 14+ messages in thread
From: Serge Petrenko @ 2020-04-09 23:50 UTC (permalink / raw)
  To: v.shpilevoy; +Cc: tarantool-patches

Expose the code used to check UUID variant to a separate function:
tt_uuid_validate(). The function will be used for msgpack uuid decoding
when checking whether the buffer contains a valid uuid value.

Prerequisite #4268
---
 src/lib/uuid/tt_uuid.c |  3 +++
 src/lib/uuid/tt_uuid.h | 16 +++++++++++-----
 2 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/src/lib/uuid/tt_uuid.c b/src/lib/uuid/tt_uuid.c
index 1bd2e2cfe..8bc9bc7af 100644
--- a/src/lib/uuid/tt_uuid.c
+++ b/src/lib/uuid/tt_uuid.c
@@ -65,6 +65,9 @@ tt_uuid_create(struct tt_uuid *uu)
 }
 #endif
 
+extern inline int
+tt_uuid_validate(struct tt_uuid *uu);
+
 extern inline int
 tt_uuid_from_string(const char *in, struct tt_uuid *uu);
 
diff --git a/src/lib/uuid/tt_uuid.h b/src/lib/uuid/tt_uuid.h
index 48cd68e69..c2c436ed4 100644
--- a/src/lib/uuid/tt_uuid.h
+++ b/src/lib/uuid/tt_uuid.h
@@ -62,6 +62,16 @@ struct tt_uuid {
 void
 tt_uuid_create(struct tt_uuid *uu);
 
+inline int
+tt_uuid_validate(struct tt_uuid *uu)
+{
+	/* Check variant (NCS, RFC4122, MSFT) */
+	uint8_t n = uu->clock_seq_hi_and_reserved;
+	if ((n & 0x80) != 0x00 && (n & 0xc0) != 0x80 &&	(n & 0xe0) != 0xc0)
+		return 1;
+	return 0;
+}
+
 /**
  * \brief Parse UUID from string.
  * \param in string
@@ -79,11 +89,7 @@ tt_uuid_from_string(const char *in, struct tt_uuid *uu)
 		   &uu->node[4], &uu->node[5]) != 11)
 		return 1;
 
-	/* Check variant (NCS, RFC4122, MSFT) */
-	uint8_t n = uu->clock_seq_hi_and_reserved;
-	if ((n & 0x80) != 0x00 && (n & 0xc0) != 0x80 &&	(n & 0xe0) != 0xc0)
-		return 1;
-	return 0;
+	return tt_uuid_validate(uu);
 }
 
 /**
-- 
2.21.1 (Apple Git-122.3)

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Tarantool-patches] [PATCH v2 3/4] box: add MsgPack encoding/decoding for UUID
  2020-04-09 23:50 [Tarantool-patches] [PATCH v2 0/4] introduce indices over UUID Serge Petrenko
  2020-04-09 23:50 ` [Tarantool-patches] [PATCH v2 1/4] refactoring: extract mpstream into a separate library Serge Petrenko
  2020-04-09 23:50 ` [Tarantool-patches] [PATCH v2 2/4] uuid: expose tt_uuid_validate method Serge Petrenko
@ 2020-04-09 23:50 ` Serge Petrenko
  2020-04-10 16:56   ` Vladislav Shpilevoy
  2020-04-09 23:50 ` [Tarantool-patches] [PATCH v2 4/4] box: introduce indices by UUID Serge Petrenko
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 14+ messages in thread
From: Serge Petrenko @ 2020-04-09 23:50 UTC (permalink / raw)
  To: v.shpilevoy; +Cc: tarantool-patches

A special format for encoding UUIDs to MsgPack is introduced.
It is supported by both lua and C encoders/decoders, and it is now
possible to insert UUIDs into spaces, but only into unindexed fields
without format for now.

Prerequisite #4268

@TarantoolBot document
Title: Internals: msgpack format for UUID

UUID values share the MessagePack type with decimals:
both use MP_EXT. A new subtype is introduced for UUIDs,
MP_UUID = `0x02`
UUID is encoded as follows:
```
    +--------+---------+-----------+
    | MP_EXT | MP_UUID | UuidValue |
    +--------+---------+-----------+
```
Since UUID is 16 bytes in size, the header, MP_EXT, is always the same:
`0xd8`. MP_UUID = `0x02` follows. The header is followed by the 16
bytes of the UuidValue.

UuidValue consists of 11 fields, which are encoded as big endian
unsigned integers in the following order: `time_low` (4 bytes), `time_mid`
(2 bytes), `time_hi_and_version` (2 bytes), `clock_seq_hi_and_reserved` (1
byte), `clock_seq_low` (1 byte), `node[0], ..., node[5]` (1 byte each).

The total size of such a representation is 18 bytes, whereas storing
uuids as strings requires from 34 (when '-'s are ommitted) to 38 bytes
per UUID, giving a 2x space usage improvement.
---
 extra/exports                        |  3 +
 src/lib/core/mp_extension_types.h    |  2 +
 src/lib/mpstream/mpstream.c          | 11 ++++
 src/lib/mpstream/mpstream.h          |  5 ++
 src/lib/uuid/CMakeLists.txt          |  2 +-
 src/lib/uuid/mp_uuid.c               | 98 ++++++++++++++++++++++++++++
 src/lib/uuid/mp_uuid.h               | 90 +++++++++++++++++++++++++
 src/lua/msgpack.c                    | 27 ++++++--
 src/lua/msgpackffi.lua               | 14 ++++
 src/lua/utils.c                      | 20 ++++++
 src/lua/utils.h                      |  5 ++
 src/lua/uuid.lua                     |  9 ---
 test/app-tap/lua/serializer_test.lua |  8 +++
 test/app-tap/msgpackffi.test.lua     |  3 +-
 test/app/msgpack.result              | 21 ++++++
 test/app/msgpack.test.lua            | 13 ++++
 test/app/uuid.result                 | 13 +++-
 test/app/uuid.test.lua               |  5 ++
 test/box/tuple.result                | 81 +++++++++++++++++++++++
 test/box/tuple.test.lua              | 25 +++++++
 test/unit/uuid.c                     | 25 ++++++-
 test/unit/uuid.result                |  8 ++-
 third_party/lua-cjson/lua_cjson.c    | 27 +++++---
 third_party/lua-yaml/lyaml.cc        | 17 ++++-
 24 files changed, 500 insertions(+), 32 deletions(-)
 create mode 100644 src/lib/uuid/mp_uuid.c
 create mode 100644 src/lib/uuid/mp_uuid.h

diff --git a/extra/exports b/extra/exports
index 9323996c1..1a20cc69f 100644
--- a/extra/exports
+++ b/extra/exports
@@ -63,11 +63,14 @@ crc32_calc
 mp_encode_double
 mp_encode_float
 mp_encode_decimal
+mp_encode_uuid
 mp_decode_double
 mp_decode_float
 mp_decode_extl
 mp_sizeof_decimal
+mp_sizeof_uuid
 decimal_unpack
+uuid_unpack
 
 log_type
 say_set_log_level
diff --git a/src/lib/core/mp_extension_types.h b/src/lib/core/mp_extension_types.h
index bc9873f68..7d42f212b 100644
--- a/src/lib/core/mp_extension_types.h
+++ b/src/lib/core/mp_extension_types.h
@@ -42,6 +42,8 @@
 enum mp_extension_type {
     MP_UNKNOWN_EXTENSION = 0,
     MP_DECIMAL = 1,
+    MP_UUID = 2,
+    mp_extension_type_MAX,
 };
 
 #endif
diff --git a/src/lib/mpstream/mpstream.c b/src/lib/mpstream/mpstream.c
index a737212c1..01b2925f5 100644
--- a/src/lib/mpstream/mpstream.c
+++ b/src/lib/mpstream/mpstream.c
@@ -34,6 +34,7 @@
 #include <stdint.h>
 #include "msgpuck.h"
 #include "core/mp_decimal.h"
+#include "uuid/mp_uuid.h"
 
 void
 mpstream_reserve_slow(struct mpstream *stream, size_t size)
@@ -197,6 +198,16 @@ mpstream_encode_decimal(struct mpstream *stream, const decimal_t *val)
 	mpstream_advance(stream, pos - data);
 }
 
+void
+mpstream_encode_uuid(struct mpstream *stream, const struct tt_uuid *uuid)
+{
+	char *data = mpstream_reserve(stream, mp_sizeof_uuid());
+	if (data == NULL)
+		return;
+	char *pos = mp_encode_uuid(data, uuid);
+	mpstream_advance(stream, pos - data);
+}
+
 void
 mpstream_memcpy(struct mpstream *stream, const void *src, uint32_t n)
 {
diff --git a/src/lib/mpstream/mpstream.h b/src/lib/mpstream/mpstream.h
index 3a022daa0..a60add143 100644
--- a/src/lib/mpstream/mpstream.h
+++ b/src/lib/mpstream/mpstream.h
@@ -38,6 +38,8 @@
 extern "C" {
 #endif /* defined(__cplusplus) */
 
+struct tt_uuid;
+
 /**
 * Ask the allocator to reserve at least size bytes. It can reserve
 * more, and update *size with the new size.
@@ -140,6 +142,9 @@ mpstream_encode_binl(struct mpstream *stream, uint32_t len);
 void
 mpstream_encode_decimal(struct mpstream *stream, const decimal_t *val);
 
+void
+mpstream_encode_uuid(struct mpstream *stream, const struct tt_uuid *uuid);
+
 /** Copies n bytes from memory area src to stream. */
 void
 mpstream_memcpy(struct mpstream *stream, const void *src, uint32_t n);
diff --git a/src/lib/uuid/CMakeLists.txt b/src/lib/uuid/CMakeLists.txt
index 581e4495a..a3316647b 100644
--- a/src/lib/uuid/CMakeLists.txt
+++ b/src/lib/uuid/CMakeLists.txt
@@ -1,2 +1,2 @@
-add_library(uuid STATIC tt_uuid.c)
+add_library(uuid STATIC tt_uuid.c mp_uuid.c)
 target_link_libraries(uuid core bit)
diff --git a/src/lib/uuid/mp_uuid.c b/src/lib/uuid/mp_uuid.c
new file mode 100644
index 000000000..7acfbc797
--- /dev/null
+++ b/src/lib/uuid/mp_uuid.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2020, Tarantool AUTHORS, please see AUTHORS file.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ *    copyright notice, this list of conditions and the
+ *    following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials
+ *    provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "mp_uuid.h"
+#include "msgpuck.h"
+#include "mp_extension_types.h"
+#include "lib/uuid/tt_uuid.h"
+
+inline uint32_t
+mp_sizeof_uuid(void)
+{
+	return mp_sizeof_ext(UUID_PACKED_LEN);
+}
+
+char *
+uuid_pack(char *data, const struct tt_uuid *uuid)
+{
+	data = mp_store_u32(data, uuid->time_low);
+	data = mp_store_u16(data, uuid->time_mid);
+	data = mp_store_u16(data, uuid->time_hi_and_version);
+	data = mp_store_u8(data, uuid->clock_seq_hi_and_reserved);
+	data = mp_store_u8(data, uuid->clock_seq_low);
+	for (int i = 0; i < 6; i++)
+		data = mp_store_u8(data, uuid->node[i]);
+	return data;
+}
+
+struct tt_uuid *
+uuid_unpack(const char **data, uint32_t len, struct tt_uuid *uuid)
+{
+	const char *const svp = *data;
+	if (len != UUID_PACKED_LEN)
+		return NULL;
+	uuid->time_low = mp_load_u32(data);
+	uuid->time_mid = mp_load_u16(data);
+	uuid->time_hi_and_version = mp_load_u16(data);
+	uuid->clock_seq_hi_and_reserved = mp_load_u8(data);
+	uuid->clock_seq_low = mp_load_u8(data);
+	for (int i = 0; i < 6; i++)
+		uuid->node[i] = mp_load_u8(data);
+
+	if (tt_uuid_validate(uuid) != 0) {
+		*data = svp;
+		return NULL;
+	}
+	return uuid;
+}
+
+struct tt_uuid *
+mp_decode_uuid(const char **data, struct tt_uuid *uuid)
+{
+	if (mp_typeof(**data) != MP_EXT)
+		return NULL;
+	int8_t type;
+	const char *const svp = *data;
+
+	uint32_t len = mp_decode_extl(data, &type);
+	if (type != MP_UUID || uuid_unpack(data, len, uuid) == NULL) {
+		*data = svp;
+		return NULL;
+	}
+	return uuid;
+}
+
+char *
+mp_encode_uuid(char *data, const struct tt_uuid *uuid)
+{
+	data = mp_encode_extl(data, MP_UUID, UUID_PACKED_LEN);
+	return uuid_pack(data, uuid);
+}
diff --git a/src/lib/uuid/mp_uuid.h b/src/lib/uuid/mp_uuid.h
new file mode 100644
index 000000000..430cb96d2
--- /dev/null
+++ b/src/lib/uuid/mp_uuid.h
@@ -0,0 +1,90 @@
+#pragma once
+
+/*
+ * Copyright 2020, Tarantool AUTHORS, please see AUTHORS file.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ *    copyright notice, this list of conditions and the
+ *    following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials
+ *    provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* defined(__cplusplus) */
+
+struct tt_uuid;
+
+#define UUID_PACKED_LEN sizeof(struct tt_uuid)
+
+/**
+ * \brief Return the number of bytes an encoded uuid value takes.
+ */
+uint32_t
+mp_sizeof_uuid(void);
+
+/**
+ * Load a uuid value from the buffer. Can be used in a combination
+ * with mp_decode_extl() instead of mp_decode_uuid() when multiple
+ * extension types are possible.
+ *
+ * \param data A buffer.
+ * \param len Length returned by mp_decode_extl, has to be equal
+ *            to sizeof(struct tt_uuid), otherwise an error is
+ *            returned.
+ * \param[out] uuid Uuid to be decoded.
+ * \return A pointer to the decoded uuid.
+ *         NULL in case of an error.
+ * \post *data = *data + sizeof(struct tt_uuid).
+ */
+struct tt_uuid *
+uuid_unpack(const char **data, uint32_t len, struct tt_uuid *uuid);
+
+/**
+ * \brief Decode a uuid from MsgPack \a data.
+ * \param data A buffer.
+ * \param[out] uuid Uuid to be decoded.
+ * \return A pointer to the decoded uuid.
+ *         NULL in case of an error.
+ * \post *data = *data + mp_sizeof_uuid().
+ */
+struct tt_uuid *
+mp_decode_uuid(const char **data, struct tt_uuid *uuid);
+
+/**
+ * \brief Encode a uuid.
+ * \param data A buffer.
+ * \param uuid A uuid to encode.
+ *
+ * \return \a data + mp_sizeof_uuid()
+ */
+char *
+mp_encode_uuid(char *data, const struct tt_uuid *uuid);
+
+#if defined(__cplusplus)
+} /* extern "C" */
+#endif /* defined(__cplusplus) */
diff --git a/src/lua/msgpack.c b/src/lua/msgpack.c
index 73ed3ece6..e4fb0cf43 100644
--- a/src/lua/msgpack.c
+++ b/src/lua/msgpack.c
@@ -43,6 +43,7 @@
 
 #include "lua/decimal.h" /* lua_pushdecimal() */
 #include "lib/core/decimal.h" /* decimal_unpack() */
+#include "lib/uuid/mp_uuid.h" /* mp_decode_uuid() */
 #include "lib/core/mp_extension_types.h"
 
 #include <fiber.h>
@@ -114,7 +115,7 @@ luamp_encode_r(struct lua_State *L, struct luaL_serializer *cfg,
 	int top = lua_gettop(L);
 	enum mp_type type;
 
-restart: /* used by MP_EXT */
+restart: /* used by MP_EXT of unidentified subtype */
 	switch (field->type) {
 	case MP_UINT:
 		mpstream_encode_uint(stream, field->ival);
@@ -190,7 +191,10 @@ restart: /* used by MP_EXT */
 		switch (field->ext_type) {
 		case MP_DECIMAL:
 			mpstream_encode_decimal(stream, field->decval);
-			return MP_EXT;
+			break;
+		case MP_UUID:
+			mpstream_encode_uuid(stream, field->uuidval);
+			break;
 		default:
 			/* Run trigger if type can't be encoded */
 			type = luamp_encode_extension(L, top, stream);
@@ -310,10 +314,17 @@ luamp_decode(struct lua_State *L, struct luaL_serializer *cfg,
 		{
 			decimal_t *dec = lua_pushdecimal(L);
 			dec = decimal_unpack(data, len, dec);
-			if (dec == NULL) {
-				lua_pop(L, -1);
-				luaL_error(L, "msgpack.decode: invalid MsgPack");
-			}
+			if (dec == NULL)
+				goto ext_decode_err;
+			return;
+		}
+		case MP_UUID:
+		{
+			struct tt_uuid *uuid = luaL_pushuuid(L);
+			*data = svp;
+			uuid = mp_decode_uuid(data, uuid);
+			if (uuid == NULL)
+				goto ext_decode_err;
 			return;
 		}
 		default:
@@ -325,6 +336,10 @@ luamp_decode(struct lua_State *L, struct luaL_serializer *cfg,
 		break;
 	}
 	}
+	return;
+ext_decode_err:
+	lua_pop(L, -1);
+	luaL_error(L, "msgpack.decode: invalid MsgPack");
 }
 
 
diff --git a/src/lua/msgpackffi.lua b/src/lua/msgpackffi.lua
index f775f2d41..f01ffaef0 100644
--- a/src/lua/msgpackffi.lua
+++ b/src/lua/msgpackffi.lua
@@ -20,6 +20,10 @@ char *
 mp_encode_decimal(char *data, decimal_t *dec);
 uint32_t
 mp_sizeof_decimal(const decimal_t *dec);
+char *
+mp_encode_uuid(char *data, const struct tt_uuid *uuid);
+uint32_t
+mp_sizeof_uuid();
 float
 mp_decode_float(const char **data);
 double
@@ -28,6 +32,8 @@ uint32_t
 mp_decode_extl(const char **data, int8_t *type);
 decimal_t *
 decimal_unpack(const char **data, uint32_t len, decimal_t *dec);
+struct tt_uuid *
+uuid_unpack(const char **data, uint32_t len, struct tt_uuid *uuid);
 ]])
 
 local strict_alignment = (jit.arch == 'arm')
@@ -129,6 +135,11 @@ local function encode_decimal(buf, num)
     builtin.mp_encode_decimal(p, num)
 end
 
+local function encode_uuid(buf, uuid)
+    local p = buf:alloc(builtin.mp_sizeof_uuid())
+    builtin.mp_encode_uuid(p, uuid)
+end
+
 local function encode_int(buf, num)
     if num >= 0 then
         if num <= 0x7f then
@@ -311,6 +322,7 @@ on_encode(ffi.typeof('bool'), encode_bool_cdata)
 on_encode(ffi.typeof('float'), encode_float)
 on_encode(ffi.typeof('double'), encode_double)
 on_encode(ffi.typeof('decimal_t'), encode_decimal)
+on_encode(ffi.typeof('struct tt_uuid'), encode_uuid)
 
 --------------------------------------------------------------------------------
 -- Decoder
@@ -495,6 +507,8 @@ local ext_decoder = {
     [0] = function(data, len) error("unsupported extension type") end,
     -- MP_DECIMAL
     [1] = function(data, len) local num = ffi.new("decimal_t") builtin.decimal_unpack(data, len, num) return num end,
+    -- MP_UUID
+    [2] = function(data, len) local uuid = ffi.new("struct tt_uuid") builtin.uuid_unpack(data, len, uuid) return uuid end,
 }
 
 local function decode_ext(data)
diff --git a/src/lua/utils.c b/src/lua/utils.c
index 54d18ac89..bd6bfb008 100644
--- a/src/lua/utils.c
+++ b/src/lua/utils.c
@@ -45,6 +45,7 @@ static uint32_t CTID_STRUCT_IBUF;
 static uint32_t CTID_STRUCT_IBUF_PTR;
 static uint32_t CTID_CHAR_PTR;
 static uint32_t CTID_CONST_CHAR_PTR;
+static uint32_t CTID_UUID;
 uint32_t CTID_DECIMAL;
 
 
@@ -101,6 +102,12 @@ luaL_pushcdata(struct lua_State *L, uint32_t ctypeid)
 	return cdataptr(cd);
 }
 
+struct tt_uuid *
+luaL_pushuuid(struct lua_State *L)
+{
+	return luaL_pushcdata(L, CTID_UUID);
+}
+
 void *
 luaL_checkcdata(struct lua_State *L, int idx, uint32_t *ctypeid)
 {
@@ -746,6 +753,9 @@ luaL_tofield(struct lua_State *L, struct luaL_serializer *cfg, int index,
 			if (cd->ctypeid == CTID_DECIMAL) {
 				field->ext_type = MP_DECIMAL;
 				field->decval = (decimal_t *) cdata;
+			} else if (cd->ctypeid == CTID_UUID) {
+				field->ext_type = MP_UUID;
+				field->uuidval = (struct tt_uuid *) cdata;
 			} else {
 				field->ext_type = MP_UNKNOWN_EXTENSION;
 			}
@@ -1286,5 +1296,15 @@ tarantool_lua_utils_init(struct lua_State *L)
 	assert(CTID_CHAR_PTR != 0);
 	CTID_CONST_CHAR_PTR = luaL_ctypeid(L, "const char *");
 	assert(CTID_CONST_CHAR_PTR != 0);
+	rc = luaL_cdef(L, "struct tt_uuid {"
+				  "uint32_t time_low;"
+				  "uint16_t time_mid;"
+				  "uint16_t time_hi_and_version;"
+				  "uint8_t clock_seq_hi_and_reserved;"
+				  "uint8_t clock_seq_low;"
+				  "uint8_t node[6];"
+			  "};");
+	CTID_UUID = luaL_ctypeid(L, "struct tt_uuid");
+	assert(CTID_UUID != 0);
 	return 0;
 }
diff --git a/src/lua/utils.h b/src/lua/utils.h
index 0b3672769..4bc041796 100644
--- a/src/lua/utils.h
+++ b/src/lua/utils.h
@@ -61,6 +61,7 @@ extern "C" {
 
 struct lua_State;
 struct ibuf;
+struct tt_uuid;
 
 /**
  * Single global lua_State shared by core and modules.
@@ -71,6 +72,9 @@ struct ibuf;
 extern struct lua_State *tarantool_L;
 extern struct ibuf *tarantool_lua_ibuf;
 
+struct tt_uuid *
+luaL_pushuuid(struct lua_State *L);
+
 /** \cond public */
 
 /**
@@ -320,6 +324,7 @@ struct luaL_field {
 		/* Array or map. */
 		uint32_t size;
 		decimal_t *decval;
+		struct tt_uuid *uuidval;
 	};
 	enum mp_type type;
 	/* subtypes of MP_EXT */
diff --git a/src/lua/uuid.lua b/src/lua/uuid.lua
index f8418cf4d..5d19a4408 100644
--- a/src/lua/uuid.lua
+++ b/src/lua/uuid.lua
@@ -5,15 +5,6 @@ local static_alloc = require('buffer').static_alloc
 local builtin = ffi.C
 
 ffi.cdef[[
-struct tt_uuid {
-    uint32_t time_low;
-    uint16_t time_mid;
-    uint16_t time_hi_and_version;
-    uint8_t clock_seq_hi_and_reserved;
-    uint8_t clock_seq_low;
-    uint8_t node[6];
-};
-
 void
 tt_uuid_create(struct tt_uuid *uu);
 int
diff --git a/test/app-tap/lua/serializer_test.lua b/test/app-tap/lua/serializer_test.lua
index 47edac621..2a668f898 100644
--- a/test/app-tap/lua/serializer_test.lua
+++ b/test/app-tap/lua/serializer_test.lua
@@ -204,6 +204,13 @@ local function test_decimal(test, s)
     rt(test, s, decimal.new('-1234567891234567890.0987654321987654321'), 'cdata')
 end
 
+local function test_uuid(test, s)
+    local uuid = require('uuid')
+    test:plan(2)
+
+    rt(test, s, uuid.new(), 'cdata')
+end
+
 local function test_boolean(test, s)
     test:plan(4)
 
@@ -505,6 +512,7 @@ return {
     test_table = test_table;
     test_ucdata = test_ucdata;
     test_decimal = test_decimal;
+    test_uuid = test_uuid;
     test_depth = test_depth;
     test_decode_buffer = test_decode_buffer;
 }
diff --git a/test/app-tap/msgpackffi.test.lua b/test/app-tap/msgpackffi.test.lua
index 994402d15..0ee5f5edc 100755
--- a/test/app-tap/msgpackffi.test.lua
+++ b/test/app-tap/msgpackffi.test.lua
@@ -118,11 +118,12 @@ end
 
 tap.test("msgpackffi", function(test)
     local serializer = require('msgpackffi')
-    test:plan(11)
+    test:plan(12)
     test:test("unsigned", common.test_unsigned, serializer)
     test:test("signed", common.test_signed, serializer)
     test:test("double", common.test_double, serializer)
     test:test("decimal", common.test_decimal, serializer)
+    test:test("uuid", common.test_uuid, serializer)
     test:test("boolean", common.test_boolean, serializer)
     test:test("string", common.test_string, serializer)
     test:test("nil", common.test_nil, serializer)
diff --git a/test/app/msgpack.result b/test/app/msgpack.result
index 4b5aec784..ddf06fc9d 100644
--- a/test/app/msgpack.result
+++ b/test/app/msgpack.result
@@ -293,3 +293,24 @@ msgpack.decode(msgpack.encode(e)) == e
 ---
 - true
 ...
+--
+-- gh-4268: msgpack encode/decode UUID
+--
+uuid = require('uuid')
+---
+...
+fail = nil
+---
+...
+for i = 1,10 do\
+    local a = uuid.new()\
+    if msgpack.decode(msgpack.encode(a)) ~= a then\
+        fail = a\
+    end\
+end
+---
+...
+fail
+---
+- null
+...
diff --git a/test/app/msgpack.test.lua b/test/app/msgpack.test.lua
index 9224d870a..17e05df5c 100644
--- a/test/app/msgpack.test.lua
+++ b/test/app/msgpack.test.lua
@@ -99,3 +99,16 @@ msgpack.decode(msgpack.encode(b)) == b
 msgpack.decode(msgpack.encode(c)) == c
 msgpack.decode(msgpack.encode(d)) == d
 msgpack.decode(msgpack.encode(e)) == e
+
+--
+-- gh-4268: msgpack encode/decode UUID
+--
+uuid = require('uuid')
+fail = nil
+for i = 1,10 do\
+    local a = uuid.new()\
+    if msgpack.decode(msgpack.encode(a)) ~= a then\
+        fail = a\
+    end\
+end
+fail
diff --git a/test/app/uuid.result b/test/app/uuid.result
index 0713614c6..751865e5f 100644
--- a/test/app/uuid.result
+++ b/test/app/uuid.result
@@ -2,6 +2,13 @@
 uuid = require('uuid')
 ---
 ...
+test_run = require('test_run').new()
+---
+...
+test_run:cmd("push filter ".."'\\.lua.*:[0-9]+: ' to '.lua '")
+---
+- true
+...
 --
 -- RFC4122 compliance
 --
@@ -106,7 +113,7 @@ uu.node[5]
 -- invalid values
 uuid.fromstr(nil)
 ---
-- error: 'builtin/uuid.lua:47: fromstr(str)'
+- error: 'builtin/uuid.lua fromstr(str)'
 ...
 uuid.fromstr('')
 ---
@@ -268,3 +275,7 @@ uu = nil
 uuid = nil
 ---
 ...
+test_run:cmd("clear filter")
+---
+- true
+...
diff --git a/test/app/uuid.test.lua b/test/app/uuid.test.lua
index ecb0cc3fe..ac125cddc 100644
--- a/test/app/uuid.test.lua
+++ b/test/app/uuid.test.lua
@@ -1,6 +1,9 @@
 -- box.uuid
 uuid = require('uuid')
 
+test_run = require('test_run').new()
+test_run:cmd("push filter ".."'\\.lua.*:[0-9]+: ' to '.lua '")
+
 --
 -- RFC4122 compliance
 --
@@ -96,3 +99,5 @@ uu.str()
 
 uu = nil
 uuid = nil
+
+test_run:cmd("clear filter")
diff --git a/test/box/tuple.result b/test/box/tuple.result
index a499aa43a..eb60a5645 100644
--- a/test/box/tuple.result
+++ b/test/box/tuple.result
@@ -1490,6 +1490,87 @@ box.tuple.is(box.tuple.new({1}))
 ---
 - true
 ...
+--
+-- gh-4268 UUID in tuple
+--
+uuid = require("uuid")
+---
+...
+-- Fixed randomly generated uuids to avoid problems with test
+-- output comparison.
+a = uuid.fromstr("c8f0fa1f-da29-438c-a040-393f1126ad39")
+---
+...
+b = uuid.fromstr("83eb4959-3de6-49fb-8890-6fb4423dd186")
+---
+...
+t = box.tuple.new(a, 2, b, "string")
+---
+...
+state, val = t:next()
+---
+...
+state
+---
+- 1
+...
+val == a
+---
+- true
+...
+state, val = t:next(state)
+---
+...
+state
+---
+- 2
+...
+val
+---
+- 2
+...
+state, val = t:next(state)
+---
+...
+state
+---
+- 3
+...
+val == b
+---
+- true
+...
+t:slice(1)
+---
+- 2
+- 83eb4959-3de6-49fb-8890-6fb4423dd186
+- string
+...
+t:slice(-1)
+---
+- string
+...
+t:slice(-2)
+---
+- 83eb4959-3de6-49fb-8890-6fb4423dd186
+- string
+...
+msgpack.decode(msgpack.encode(t))
+---
+- [c8f0fa1f-da29-438c-a040-393f1126ad39, 2, 83eb4959-3de6-49fb-8890-6fb4423dd186,
+  'string']
+- 46
+...
+msgpackffi.decode(msgpackffi.encode(t))
+---
+- [c8f0fa1f-da29-438c-a040-393f1126ad39, 2, 83eb4959-3de6-49fb-8890-6fb4423dd186,
+  'string']
+- 46
+...
+t:bsize()
+---
+- 45
+...
 msgpack.cfg({encode_max_depth = max_depth, encode_deep_as_nil = deep_as_nil})
 ---
 ...
diff --git a/test/box/tuple.test.lua b/test/box/tuple.test.lua
index b83fca5cd..4201e9860 100644
--- a/test/box/tuple.test.lua
+++ b/test/box/tuple.test.lua
@@ -510,4 +510,29 @@ box.tuple.is('1')
 box.tuple.is(box.tuple.new())
 box.tuple.is(box.tuple.new({1}))
 
+--
+-- gh-4268 UUID in tuple
+--
+uuid = require("uuid")
+-- Fixed randomly generated uuids to avoid problems with test
+-- output comparison.
+a = uuid.fromstr("c8f0fa1f-da29-438c-a040-393f1126ad39")
+b = uuid.fromstr("83eb4959-3de6-49fb-8890-6fb4423dd186")
+t = box.tuple.new(a, 2, b, "string")
+state, val = t:next()
+state
+val == a
+state, val = t:next(state)
+state
+val
+state, val = t:next(state)
+state
+val == b
+t:slice(1)
+t:slice(-1)
+t:slice(-2)
+msgpack.decode(msgpack.encode(t))
+msgpackffi.decode(msgpackffi.encode(t))
+t:bsize()
+
 msgpack.cfg({encode_max_depth = max_depth, encode_deep_as_nil = deep_as_nil})
diff --git a/test/unit/uuid.c b/test/unit/uuid.c
index c43d93b4f..b51d13cb8 100644
--- a/test/unit/uuid.c
+++ b/test/unit/uuid.c
@@ -1,5 +1,7 @@
 #include "unit.h"
 #include "uuid/tt_uuid.h"
+#include "uuid/mp_uuid.h"
+#include "core/random.h"
 #include <string.h>
 
 static void
@@ -27,10 +29,29 @@ uuid_test(struct tt_uuid a, struct tt_uuid b, int expected_result)
            "%s %s %s", a_str, sign, b_str);
 }
 
+static void
+mp_uuid_test()
+{
+        plan(4);
+        char buf[18];
+        char *data = buf;
+        const char *data1 = buf;
+        struct tt_uuid uu, ret;
+        random_init();
+        tt_uuid_create(&uu);
+        char *end = mp_encode_uuid(data, &uu);
+        is(end - data, mp_sizeof_uuid(), "mp_sizeof_uuid() == encoded length");
+        struct tt_uuid *rc = mp_decode_uuid(&data1, &ret);
+        is(rc, &ret, "mp_decode_uuid() return code");
+        is(data1, end, "mp_sizeof_uuid() == decoded length");
+        is(tt_uuid_compare(&uu, &ret), 0, "mp_decode_uuid(mp_encode_uuid(uu)) == uu");
+        check_plan();
+}
+
 int
 main(void)
 {
-        plan(2);
+        plan(3);
 
         uuid_test(
                 (struct tt_uuid){.time_low = 1712399963,
@@ -63,5 +84,7 @@ main(void)
                                 .node = "v\025Oo9I"},
                 -1);
 
+        mp_uuid_test();
+
         return check_plan();
 }
diff --git a/test/unit/uuid.result b/test/unit/uuid.result
index 40ccce759..50a1140c5 100644
--- a/test/unit/uuid.result
+++ b/test/unit/uuid.result
@@ -1,3 +1,9 @@
-1..2
+1..3
 ok 1 - 6611265b-8852-4832-af8b-4164d52c62eb > 186ebbf7-cf97-4e2e-8b1b-76154f6f3949
 ok 2 - 075b4148-8fb0-2e7f-af50-4164d52c62eb < 1fbc929f-5da8-28c5-8b36-76154f6f3949
+    1..4
+    ok 1 - mp_sizeof_uuid() == encoded length
+    ok 2 - mp_decode_uuid() return code
+    ok 3 - mp_sizeof_uuid() == decoded length
+    ok 4 - mp_decode_uuid(mp_encode_uuid(uu)) == uu
+ok 3 - subtests
diff --git a/third_party/lua-cjson/lua_cjson.c b/third_party/lua-cjson/lua_cjson.c
index 26e566a6f..6e1793a59 100644
--- a/third_party/lua-cjson/lua_cjson.c
+++ b/third_party/lua-cjson/lua_cjson.c
@@ -48,6 +48,9 @@
 #include "strbuf.h"
 
 #include "lua/utils.h"
+#include "lib/core/mp_extension_types.h" /* MP_DECIMAL, MP_UUID */
+#include "lib/core/tt_static.h"
+#include "lib/uuid/tt_uuid.h" /* tt_uuid_to_string(), UUID_STR_LEN */
 
 #define DEFAULT_ENCODE_KEEP_BUFFER 1
 
@@ -421,15 +424,21 @@ static void json_append_data(lua_State *l, struct luaL_serializer *cfg,
     json_append_array(l, cfg, current_depth + 1, json, field.size);
     return;
     case MP_EXT:
-	switch (field.ext_type) {
-	case MP_DECIMAL:
-	{
-	    const char *str = decimal_to_string(field.decval);
-	    return json_append_string(cfg, json, str, strlen(str));
-	}
-	default:
-	    assert(false);
-	}
+        switch (field.ext_type) {
+        case MP_DECIMAL:
+        {
+            const char *str = decimal_to_string(field.decval);
+            return json_append_string(cfg, json, str, strlen(str));
+        }
+        case MP_UUID:
+        {
+            char *str = tt_static_buf();
+            tt_uuid_to_string(field.uuidval, str);
+            return json_append_string(cfg, json, str, UUID_STR_LEN);
+        }
+        default:
+            assert(false);
+        }
     }
 }
 
diff --git a/third_party/lua-yaml/lyaml.cc b/third_party/lua-yaml/lyaml.cc
index af4f2f5d5..411c56f71 100644
--- a/third_party/lua-yaml/lyaml.cc
+++ b/third_party/lua-yaml/lyaml.cc
@@ -50,6 +50,9 @@ extern "C" {
 } /* extern "C" */
 #include "lua/utils.h"
 #include "lib/core/decimal.h"
+#include "lib/core/tt_static.h"
+#include "lib/core/mp_extension_types.h" /* MP_DECIMAL, MP_UUID */
+#include "lib/uuid/tt_uuid.h" /* tt_uuid_to_string(), UUID_STR_LEN */
 
 #define LUAYAML_TAG_PREFIX "tag:yaml.org,2002:"
 
@@ -697,10 +700,18 @@ static int dump_node(struct lua_yaml_dumper *dumper)
       switch (field.ext_type) {
       case MP_DECIMAL:
          str = decimal_to_string(field.decval);
-	 len = strlen(str);
-	 break;
+         len = strlen(str);
+         break;
+      case MP_UUID:
+      {
+         char *buf = tt_static_buf();
+         tt_uuid_to_string(field.uuidval, buf);
+         str = buf;
+         len = UUID_STR_LEN;
+         break;
+      }
       default:
-	 assert(0); /* checked by luaL_checkfield() */
+         assert(0); /* checked by luaL_checkfield() */
       }
       break;
     }
-- 
2.21.1 (Apple Git-122.3)

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Tarantool-patches] [PATCH v2 4/4] box: introduce indices by UUID
  2020-04-09 23:50 [Tarantool-patches] [PATCH v2 0/4] introduce indices over UUID Serge Petrenko
                   ` (2 preceding siblings ...)
  2020-04-09 23:50 ` [Tarantool-patches] [PATCH v2 3/4] box: add MsgPack encoding/decoding for UUID Serge Petrenko
@ 2020-04-09 23:50 ` Serge Petrenko
  2020-04-10 16:56   ` Vladislav Shpilevoy
  2020-04-10 12:27 ` [Tarantool-patches] [PATCH v2 0/4] introduce indices over UUID Serge Petrenko
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 14+ messages in thread
From: Serge Petrenko @ 2020-04-09 23:50 UTC (permalink / raw)
  To: v.shpilevoy; +Cc: tarantool-patches

It is now possible to create an index over UUID values, returned by
`uuid.new()`.

Closes #4268
Closes #2916

@TarantoolBot document
Title: Document uuid field type.

There's a new field type -- UUID, it accepts values returned by
`uuid.new()`.

The index may be either unique or non-unique, nullable or non-nullable,
and may be a primary key.

The values in an index are ordered lexicographically by their string
representation.

To create an index over a uuid field for space `test`, say:
```
box.space.test:create_index("pk", {parts={1, 'uuid'}})
```
Now you may insert uuids into the space:
```
tarantool> box.space.test:insert{uuid.new()}
---
- [e631fdcc-0e8a-4d2f-83fd-b0ce6762b13f]
...

tarantool> box.space.test:insert{uuid.fromstr('64d22e4d-ac92-4a23-899a-e59f34af5479')}
---
- [64d22e4d-ac92-4a23-899a-e59f34af5479]
...

tarantool> box.space.test:select{}
---
- - [64d22e4d-ac92-4a23-899a-e59f34af5479]
  - [e631fdcc-0e8a-4d2f-83fd-b0ce6762b13f]
...

```
---
 src/box/field_def.c       | 32 +++++++------
 src/box/field_def.h       |  1 +
 src/box/tuple_compare.cc  | 59 ++++++++++++++++++++++++
 test/engine/ddl.result    | 97 ++++++++++++++++++++++++++++++++++++++-
 test/engine/ddl.test.lua  | 42 ++++++++++++++++-
 test/engine/uuid.result   | 55 ++++++++++++++++++++++
 test/engine/uuid.test.lua | 27 +++++++++++
 7 files changed, 298 insertions(+), 15 deletions(-)
 create mode 100644 test/engine/uuid.result
 create mode 100644 test/engine/uuid.test.lua

diff --git a/src/box/field_def.c b/src/box/field_def.c
index fde4e5a00..82a2493fa 100644
--- a/src/box/field_def.c
+++ b/src/box/field_def.c
@@ -33,6 +33,8 @@
 #include "trivia/util.h"
 #include "key_def.h"
 #include "mp_extension_types.h"
+#include "lib/uuid/mp_uuid.h"
+#include "uuid/tt_uuid.h"
 
 const char *mp_type_strs[] = {
 	/* .MP_NIL    = */ "nil",
@@ -67,6 +69,7 @@ const uint32_t field_mp_type[] = {
 		(1U << MP_FLOAT) | (1U << MP_DOUBLE) | (1U << MP_STR) |
 		(1U << MP_BIN) | (1U << MP_BOOL),
 	/* [FIELD_TYPE_DECIMAL]  =  */ 0, /* only MP_DECIMAL is supported */
+	/* [FIELD_TYPE_UUID]     =  */ 0, /* only MP_UUID is supported */
 	/* [FIELD_TYPE_ARRAY]    =  */ 1U << MP_ARRAY,
 	/* [FIELD_TYPE_MAP]      =  */ (1U << MP_MAP),
 };
@@ -82,6 +85,7 @@ const uint32_t field_ext_type[] = {
 	/* [FIELD_TYPE_VARBINARY] = */ 0,
 	/* [FIELD_TYPE_SCALAR]    = */ 1U << MP_DECIMAL,
 	/* [FIELD_TYPE_DECIMAL]   = */ 1U << MP_DECIMAL,
+	/* [FIELD_TYPE_UUID]      = */ 1U << MP_UUID,
 	/* [FIELD_TYPE_ARRAY]     = */ 0,
 	/* [FIELD_TYPE_MAP]       = */ 0,
 };
@@ -97,6 +101,7 @@ const char *field_type_strs[] = {
 	/* [FIELD_TYPE_VARBINARY] = */"varbinary",
 	/* [FIELD_TYPE_SCALAR]   = */ "scalar",
 	/* [FIELD_TYPE_DECIMAL]  = */ "decimal",
+	/* [FIELD_TYPE_UUID]     = */ "uuid",
 	/* [FIELD_TYPE_ARRAY]    = */ "array",
 	/* [FIELD_TYPE_MAP]      = */ "map",
 };
@@ -123,19 +128,20 @@ field_type_by_name_wrapper(const char *str, uint32_t len)
  * values can be stored in the j type.
  */
 static const bool field_type_compatibility[] = {
-	   /*   ANY   UNSIGNED  STRING   NUMBER  DOUBLE  INTEGER  BOOLEAN VARBINARY SCALAR  DECIMAL  ARRAY    MAP  */
-/*   ANY    */ true,   false,   false,   false,   false,   false,   false,   false,  false,  false,  false,   false,
-/* UNSIGNED */ true,   true,    false,   true,    false,   true,    false,   false,  true,   false,  false,   false,
-/*  STRING  */ true,   false,   true,    false,   false,   false,   false,   false,  true,   false,  false,   false,
-/*  NUMBER  */ true,   false,   false,   true,    false,   false,   false,   false,  true,   false,  false,   false,
-/*  DOUBLE  */ true,   false,   false,   true,    true,    false,   false,   false,  true,   false,  false,   false,
-/*  INTEGER */ true,   false,   false,   true,    false,   true,    false,   false,  true,   false,  false,   false,
-/*  BOOLEAN */ true,   false,   false,   false,   false,   false,   true,    false,  true,   false,  false,   false,
-/* VARBINARY*/ true,   false,   false,   false,   false,   false,   false,   true,   true,   false,  false,   false,
-/*  SCALAR  */ true,   false,   false,   false,   false,   false,   false,   false,  true,   false,  false,   false,
-/*  DECIMAL */ true,   false,   false,   true,    false,   false,   false,   false,  true,   true,   false,   false,
-/*   ARRAY  */ true,   false,   false,   false,   false,   false,   false,   false,  false,  false,  true,    false,
-/*    MAP   */ true,   false,   false,   false,   false,   false,   false,   false,  false,  false,  false,   true,
+	   /*   ANY   UNSIGNED  STRING   NUMBER  DOUBLE  INTEGER  BOOLEAN VARBINARY SCALAR  DECIMAL   UUID    ARRAY    MAP  */
+/*   ANY    */ true,   false,   false,   false,   false,   false,   false,   false,  false,  false,  false,   false,   false,
+/* UNSIGNED */ true,   true,    false,   true,    false,   true,    false,   false,  true,   false,  false,   false,   false,
+/*  STRING  */ true,   false,   true,    false,   false,   false,   false,   false,  true,   false,  false,   false,   false,
+/*  NUMBER  */ true,   false,   false,   true,    false,   false,   false,   false,  true,   false,  false,   false,   false,
+/*  DOUBLE  */ true,   false,   false,   true,    true,    false,   false,   false,  true,   false,  false,   false,   false,
+/*  INTEGER */ true,   false,   false,   true,    false,   true,    false,   false,  true,   false,  false,   false,   false,
+/*  BOOLEAN */ true,   false,   false,   false,   false,   false,   true,    false,  true,   false,  false,   false,   false,
+/* VARBINARY*/ true,   false,   false,   false,   false,   false,   false,   true,   true,   false,  false,   false,   false,
+/*  SCALAR  */ true,   false,   false,   false,   false,   false,   false,   false,  true,   false,  false,   false,   false,
+/*  DECIMAL */ true,   false,   false,   true,    false,   false,   false,   false,  true,   true,   false,   false,   false,
+/*   UUID   */ true,   false,   false,   false,   false,   false,   false,   false,  false,  false,  true,    false,   false,
+/*   ARRAY  */ true,   false,   false,   false,   false,   false,   false,   false,  false,  false,  false,   true,    false,
+/*    MAP   */ true,   false,   false,   false,   false,   false,   false,   false,  false,  false,  false,   false,   true,
 };
 
 bool
diff --git a/src/box/field_def.h b/src/box/field_def.h
index 8e82369f1..c5cfe5e86 100644
--- a/src/box/field_def.h
+++ b/src/box/field_def.h
@@ -60,6 +60,7 @@ enum field_type {
 	FIELD_TYPE_VARBINARY,
 	FIELD_TYPE_SCALAR,
 	FIELD_TYPE_DECIMAL,
+	FIELD_TYPE_UUID,
 	FIELD_TYPE_ARRAY,
 	FIELD_TYPE_MAP,
 	field_type_MAX
diff --git a/src/box/tuple_compare.cc b/src/box/tuple_compare.cc
index 3f8a0ce24..a47f7ac6d 100644
--- a/src/box/tuple_compare.cc
+++ b/src/box/tuple_compare.cc
@@ -35,6 +35,7 @@
 #include <math.h>
 #include "lib/core/decimal.h"
 #include "lib/core/mp_decimal.h"
+#include "lib/uuid/mp_uuid.h"
 #include "lib/core/mp_extension_types.h"
 
 /* {{{ tuple_compare */
@@ -74,6 +75,7 @@ enum mp_class {
 	MP_CLASS_NUMBER,
 	MP_CLASS_STR,
 	MP_CLASS_BIN,
+	MP_CLASS_UUID,
 	MP_CLASS_ARRAY,
 	MP_CLASS_MAP,
 	mp_class_max,
@@ -96,6 +98,7 @@ static enum mp_class mp_classes[] = {
 static enum mp_class mp_ext_classes[] = {
 	/* .MP_UNKNOWN_EXTENSION = */ mp_class_max, /* unsupported */
 	/* .MP_DECIMAL		 = */ MP_CLASS_NUMBER,
+	/* .MP_UUID		 = */ MP_CLASS_UUID,
 };
 
 static enum mp_class
@@ -110,6 +113,7 @@ mp_extension_class(const char *data)
 	assert(mp_typeof(*data) == MP_EXT);
 	int8_t type;
 	mp_decode_extl(&data, &type);
+	assert(type >= 0 && type < mp_extension_type_MAX);
 	return mp_ext_classes[type];
 }
 
@@ -378,6 +382,25 @@ mp_compare_bin(const char *field_a, const char *field_b)
 	return COMPARE_RESULT(size_a, size_b);
 }
 
+static inline int
+mp_compare_uuid(const char *field_a, const char *field_b)
+{
+	const char *str_a, *str_b;
+	int8_t type;
+	uint32_t len;
+	str_a = mp_decode_ext(&field_a, &type, &len);
+	assert(type == MP_UUID && len == UUID_PACKED_LEN);
+	str_b = mp_decode_ext(&field_b, &type, &len);
+	assert(type == MP_UUID && len == UUID_PACKED_LEN);
+	/*
+	 * Packed uuid fields are in the right order for
+	 * comparison and are big-endian, so memcmp is
+	 * the same as tt_uuid_compare() and lets us
+	 * spare 2 mp_uuid_unpack() calls.
+	 */
+	return memcmp(str_a, str_b, UUID_PACKED_LEN);
+}
+
 typedef int (*mp_compare_f)(const char *, const char *);
 static mp_compare_f mp_class_comparators[] = {
 	/* .MP_CLASS_NIL    = */ NULL,
@@ -385,6 +408,7 @@ static mp_compare_f mp_class_comparators[] = {
 	/* .MP_CLASS_NUMBER = */ mp_compare_number,
 	/* .MP_CLASS_STR    = */ mp_compare_str,
 	/* .MP_CLASS_BIN    = */ mp_compare_bin,
+	/* .MP_CLASS_UUID   = */ NULL,
 	/* .MP_CLASS_ARRAY  = */ NULL,
 	/* .MP_CLASS_MAP    = */ NULL,
 };
@@ -463,6 +487,8 @@ tuple_compare_field(const char *field_a, const char *field_b,
 		       mp_compare_scalar(field_a, field_b);
 	case FIELD_TYPE_DECIMAL:
 		return mp_compare_decimal(field_a, field_b);
+	case FIELD_TYPE_UUID:
+		return mp_compare_uuid(field_a, field_b);
 	default:
 		unreachable();
 		return 0;
@@ -501,6 +527,8 @@ tuple_compare_field_with_type(const char *field_a, enum mp_type a_type,
 	case FIELD_TYPE_DECIMAL:
 		return mp_compare_number_with_type(field_a, a_type,
 						   field_b, b_type);
+	case FIELD_TYPE_UUID:
+		return mp_compare_uuid(field_a, field_b);
 	default:
 		unreachable();
 		return 0;
@@ -1578,6 +1606,21 @@ hint_decimal(decimal_t *dec)
 	return hint_create(MP_CLASS_NUMBER, val);
 }
 
+static inline hint_t
+hint_uuid_raw(const char *data)
+{
+	/*
+	 * Packed UUID fields are big-endian and are stored in the
+	 * order allowing lexicographical comparison, so the first
+	 * 8 bytes of the packed representation constitute a big
+	 * endian unsigned integer. Use it as a hint.
+	 */
+	uint64_t val = mp_load_u64(&data);
+	/* Make space for class representation. */
+	val >>= HINT_CLASS_BITS;
+	return hint_create(MP_CLASS_UUID, val);
+}
+
 static inline uint64_t
 hint_str_raw(const char *s, uint32_t len)
 {
@@ -1698,6 +1741,17 @@ field_hint_decimal(const char *field)
 	}
 }
 
+static inline hint_t
+field_hint_uuid(const char *field)
+{
+	assert(mp_typeof(*field) == MP_EXT);
+	int8_t type;
+	uint32_t len;
+	const char *data = mp_decode_ext(&field, &type, &len);
+	assert(type == MP_UUID && len == UUID_PACKED_LEN);
+	return hint_uuid_raw(data);
+}
+
 static inline hint_t
 field_hint_string(const char *field, struct coll *coll)
 {
@@ -1782,6 +1836,8 @@ field_hint(const char *field, struct coll *coll)
 		return field_hint_scalar(field, coll);
 	case FIELD_TYPE_DECIMAL:
 		return field_hint_decimal(field);
+	case FIELD_TYPE_UUID:
+		return field_hint_uuid(field);
 	default:
 		unreachable();
 	}
@@ -1893,6 +1949,9 @@ key_def_set_hint_func(struct key_def *def)
 	case FIELD_TYPE_DECIMAL:
 		key_def_set_hint_func<FIELD_TYPE_DECIMAL>(def);
 		break;
+	case FIELD_TYPE_UUID:
+		key_def_set_hint_func<FIELD_TYPE_UUID>(def);
+		break;
 	default:
 		/* Invalid key definition. */
 		def->key_hint = NULL;
diff --git a/test/engine/ddl.result b/test/engine/ddl.result
index 67b22ed9e..b7c04aafe 100644
--- a/test/engine/ddl.result
+++ b/test/engine/ddl.result
@@ -1037,6 +1037,9 @@ s:drop()
 decimal = require('decimal')
 ---
 ...
+uuid = require('uuid')
+---
+...
 -- Ensure that vinyl correctly process field count change.
 s = box.schema.space.create('test', {engine = engine, field_count = 2})
 ---
@@ -1098,13 +1101,16 @@ format[10] = {name = 'field10', type = 'map'}
 format[11] = {name = 'field11', type = 'decimal'}
 ---
 ...
+format[12] = {name = 'field12', type = 'uuid'}
+---
+...
 s = box.schema.space.create('test', {engine = engine, format = format})
 ---
 ...
 pk = s:create_index('pk')
 ---
 ...
-t = s:replace{1, {2}, 3, '4', 5.5, -6, true, -8, {9, 9}, {val = 10}, decimal.new(-11.11)}
+t = s:replace{1, {2}, 3, '4', 5.5, -6, true, -8, {9, 9}, {val = 10}, decimal.new(-11.11), uuid.new()}
 ---
 ...
 inspector:cmd("setopt delimiter ';'")
@@ -1171,6 +1177,11 @@ fail_format_change(3, 'decimal')
 ---
 - 'Tuple field 3 type does not match one required by operation: expected decimal'
 ...
+-- unsigned --X--> uuid
+fail_format_change(3, 'uuid')
+---
+- 'Tuple field 3 type does not match one required by operation: expected uuid'
+...
 -- string -----> any
 ok_format_change(4, 'any')
 ---
@@ -1189,6 +1200,11 @@ fail_format_change(4, 'decimal')
 ---
 - 'Tuple field 4 type does not match one required by operation: expected decimal'
 ...
+-- string --X--> uuid
+fail_format_change(4, 'uuid')
+---
+- 'Tuple field 4 type does not match one required by operation: expected uuid'
+...
 -- number -----> any
 ok_format_change(5, 'any')
 ---
@@ -1207,6 +1223,11 @@ fail_format_change(5, 'decimal')
 ---
 - 'Tuple field 5 type does not match one required by operation: expected decimal'
 ...
+-- number --X--> uuid
+fail_format_change(5, 'uuid')
+---
+- 'Tuple field 5 type does not match one required by operation: expected uuid'
+...
 -- integer -----> any
 ok_format_change(6, 'any')
 ---
@@ -1229,6 +1250,11 @@ fail_format_change(6, 'decimal')
 ---
 - 'Tuple field 6 type does not match one required by operation: expected decimal'
 ...
+-- integer --X--> uuid
+fail_format_change(6, 'uuid')
+---
+- 'Tuple field 6 type does not match one required by operation: expected uuid'
+...
 -- boolean -----> any
 ok_format_change(7, 'any')
 ---
@@ -1247,6 +1273,11 @@ fail_format_change(7, 'decimal')
 ---
 - 'Tuple field 7 type does not match one required by operation: expected decimal'
 ...
+-- boolean --X--> uuid
+fail_format_change(7, 'uuid')
+---
+- 'Tuple field 7 type does not match one required by operation: expected uuid'
+...
 -- scalar -----> any
 ok_format_change(8, 'any')
 ---
@@ -1261,6 +1292,11 @@ fail_format_change(8, 'decimal')
 ---
 - 'Tuple field 8 type does not match one required by operation: expected decimal'
 ...
+-- scalar --X--> uuid
+fail_format_change(8, 'uuid')
+---
+- 'Tuple field 8 type does not match one required by operation: expected uuid'
+...
 -- array -----> any
 ok_format_change(9, 'any')
 ---
@@ -1275,6 +1311,11 @@ fail_format_change(9, 'decimal')
 ---
 - 'Tuple field 9 type does not match one required by operation: expected decimal'
 ...
+-- array --X--> uuid
+fail_format_change(9, 'uuid')
+---
+- 'Tuple field 9 type does not match one required by operation: expected uuid'
+...
 -- map -----> any
 ok_format_change(10, 'any')
 ---
@@ -1289,6 +1330,11 @@ fail_format_change(10, 'decimal')
 ---
 - 'Tuple field 10 type does not match one required by operation: expected decimal'
 ...
+-- map --X--> uuid
+fail_format_change(10, 'uuid')
+---
+- 'Tuple field 10 type does not match one required by operation: expected uuid'
+...
 -- decimal ----> any
 ok_format_change(11, 'any')
 ---
@@ -1326,6 +1372,55 @@ fail_format_change(11, 'array')
 ---
 - 'Tuple field 11 type does not match one required by operation: expected array'
 ...
+-- decimal --X--> uuid
+fail_format_change(11, 'uuid')
+---
+- 'Tuple field 11 type does not match one required by operation: expected uuid'
+...
+-- uuid ----> any
+ok_format_change(12, 'any')
+---
+...
+-- uuid --X--> number
+fail_format_change(12, 'number')
+---
+- 'Tuple field 12 type does not match one required by operation: expected number'
+...
+-- uuid --X--> scalar
+fail_format_change(12, 'scalar')
+---
+- 'Tuple field 12 type does not match one required by operation: expected scalar'
+...
+-- uuid --X--> string
+fail_format_change(12, 'string')
+---
+- 'Tuple field 12 type does not match one required by operation: expected string'
+...
+-- uuid --X--> integer
+fail_format_change(12, 'integer')
+---
+- 'Tuple field 12 type does not match one required by operation: expected integer'
+...
+-- uuid --X--> unsigned
+fail_format_change(12, 'unsigned')
+---
+- 'Tuple field 12 type does not match one required by operation: expected unsigned'
+...
+-- uuid --X--> map
+fail_format_change(12, 'map')
+---
+- 'Tuple field 12 type does not match one required by operation: expected map'
+...
+-- uuid --X--> array
+fail_format_change(12, 'array')
+---
+- 'Tuple field 12 type does not match one required by operation: expected array'
+...
+-- uuid --X--> decimal
+fail_format_change(12, 'decimal')
+---
+- 'Tuple field 12 type does not match one required by operation: expected decimal'
+...
 s:drop()
 ---
 ...
diff --git a/test/engine/ddl.test.lua b/test/engine/ddl.test.lua
index e761966d7..7d408807f 100644
--- a/test/engine/ddl.test.lua
+++ b/test/engine/ddl.test.lua
@@ -356,6 +356,7 @@ s:drop()
 --
 
 decimal = require('decimal')
+uuid = require('uuid')
 
 -- Ensure that vinyl correctly process field count change.
 s = box.schema.space.create('test', {engine = engine, field_count = 2})
@@ -379,10 +380,11 @@ format[8] = {name = 'field8', type = 'scalar'}
 format[9] = {name = 'field9', type = 'array'}
 format[10] = {name = 'field10', type = 'map'}
 format[11] = {name = 'field11', type = 'decimal'}
+format[12] = {name = 'field12', type = 'uuid'}
 
 s = box.schema.space.create('test', {engine = engine, format = format})
 pk = s:create_index('pk')
-t = s:replace{1, {2}, 3, '4', 5.5, -6, true, -8, {9, 9}, {val = 10}, decimal.new(-11.11)}
+t = s:replace{1, {2}, 3, '4', 5.5, -6, true, -8, {9, 9}, {val = 10}, decimal.new(-11.11), uuid.new()}
 
 inspector:cmd("setopt delimiter ';'")
 function fail_format_change(fieldno, new_type)
@@ -421,6 +423,8 @@ ok_format_change(3, 'scalar')
 fail_format_change(3, 'map')
 -- unsigned --X--> decimal
 fail_format_change(3, 'decimal')
+-- unsigned --X--> uuid
+fail_format_change(3, 'uuid')
 
 -- string -----> any
 ok_format_change(4, 'any')
@@ -430,6 +434,8 @@ ok_format_change(4, 'scalar')
 fail_format_change(4, 'boolean')
 -- string --X--> decimal
 fail_format_change(4, 'decimal')
+-- string --X--> uuid
+fail_format_change(4, 'uuid')
 
 -- number -----> any
 ok_format_change(5, 'any')
@@ -439,6 +445,8 @@ ok_format_change(5, 'scalar')
 fail_format_change(5, 'integer')
 -- number --X--> decimal
 fail_format_change(5, 'decimal')
+-- number --X--> uuid
+fail_format_change(5, 'uuid')
 
 -- integer -----> any
 ok_format_change(6, 'any')
@@ -450,6 +458,8 @@ ok_format_change(6, 'scalar')
 fail_format_change(6, 'unsigned')
 -- integer --X--> decimal
 fail_format_change(6, 'decimal')
+-- integer --X--> uuid
+fail_format_change(6, 'uuid')
 
 -- boolean -----> any
 ok_format_change(7, 'any')
@@ -459,6 +469,8 @@ ok_format_change(7, 'scalar')
 fail_format_change(7, 'string')
 -- boolead --X--> decimal
 fail_format_change(7, 'decimal')
+-- boolean --X--> uuid
+fail_format_change(7, 'uuid')
 
 -- scalar -----> any
 ok_format_change(8, 'any')
@@ -466,6 +478,8 @@ ok_format_change(8, 'any')
 fail_format_change(8, 'unsigned')
 -- scalar --X--> decimal
 fail_format_change(8, 'decimal')
+-- scalar --X--> uuid
+fail_format_change(8, 'uuid')
 
 -- array -----> any
 ok_format_change(9, 'any')
@@ -473,6 +487,8 @@ ok_format_change(9, 'any')
 fail_format_change(9, 'scalar')
 -- arary --X--> decimal
 fail_format_change(9, 'decimal')
+-- array --X--> uuid
+fail_format_change(9, 'uuid')
 
 -- map -----> any
 ok_format_change(10, 'any')
@@ -480,6 +496,8 @@ ok_format_change(10, 'any')
 fail_format_change(10, 'scalar')
 -- map --X--> decimal
 fail_format_change(10, 'decimal')
+-- map --X--> uuid
+fail_format_change(10, 'uuid')
 
 -- decimal ----> any
 ok_format_change(11, 'any')
@@ -497,6 +515,28 @@ fail_format_change(11, 'unsigned')
 fail_format_change(11, 'map')
 -- decimal --X--> array
 fail_format_change(11, 'array')
+-- decimal --X--> uuid
+fail_format_change(11, 'uuid')
+
+-- uuid ----> any
+ok_format_change(12, 'any')
+-- uuid --X--> number
+fail_format_change(12, 'number')
+-- uuid --X--> scalar
+fail_format_change(12, 'scalar')
+-- uuid --X--> string
+fail_format_change(12, 'string')
+-- uuid --X--> integer
+fail_format_change(12, 'integer')
+-- uuid --X--> unsigned
+fail_format_change(12, 'unsigned')
+-- uuid --X--> map
+fail_format_change(12, 'map')
+-- uuid --X--> array
+fail_format_change(12, 'array')
+-- uuid --X--> decimal
+fail_format_change(12, 'decimal')
+
 s:drop()
 
 -- Check new fields adding.
diff --git a/test/engine/uuid.result b/test/engine/uuid.result
new file mode 100644
index 000000000..c4c186e92
--- /dev/null
+++ b/test/engine/uuid.result
@@ -0,0 +1,55 @@
+-- test-run result file version 2
+env = require('test_run')
+ | ---
+ | ...
+test_run = env.new()
+ | ---
+ | ...
+engine = test_run:get_cfg('engine')
+ | ---
+ | ...
+
+uuid = require('uuid')
+ | ---
+ | ...
+ffi = require('ffi')
+ | ---
+ | ...
+
+-- check uuid indices
+_ = box.schema.space.create('test', {engine=engine})
+ | ---
+ | ...
+_ = box.space.test:create_index('pk', {parts={1,'uuid'}})
+ | ---
+ | ...
+
+for i = 1,16 do\
+    box.space.test:insert{uuid.new()}\
+end
+ | ---
+ | ...
+
+a = box.space.test:select{}
+ | ---
+ | ...
+err = nil
+ | ---
+ | ...
+for i = 1, #a - 1 do\
+    if tostring(a[i][1]) >= tostring(a[i+1][1]) then\
+        err = {a[i][1], a[i+1][1]}\
+        break\
+    end\
+end
+ | ---
+ | ...
+
+err
+ | ---
+ | - null
+ | ...
+
+box.space.test:drop()
+ | ---
+ | ...
diff --git a/test/engine/uuid.test.lua b/test/engine/uuid.test.lua
new file mode 100644
index 000000000..f34795ce4
--- /dev/null
+++ b/test/engine/uuid.test.lua
@@ -0,0 +1,27 @@
+env = require('test_run')
+test_run = env.new()
+engine = test_run:get_cfg('engine')
+
+uuid = require('uuid')
+ffi = require('ffi')
+
+-- check uuid indices
+_ = box.schema.space.create('test', {engine=engine})
+_ = box.space.test:create_index('pk', {parts={1,'uuid'}})
+
+for i = 1,16 do\
+    box.space.test:insert{uuid.new()}\
+end
+
+a = box.space.test:select{}
+err = nil
+for i = 1, #a - 1 do\
+    if tostring(a[i][1]) >= tostring(a[i+1][1]) then\
+        err = {a[i][1], a[i+1][1]}\
+        break\
+    end\
+end
+
+err
+
+box.space.test:drop()
-- 
2.21.1 (Apple Git-122.3)

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 0/4] introduce indices over UUID
  2020-04-09 23:50 [Tarantool-patches] [PATCH v2 0/4] introduce indices over UUID Serge Petrenko
                   ` (3 preceding siblings ...)
  2020-04-09 23:50 ` [Tarantool-patches] [PATCH v2 4/4] box: introduce indices by UUID Serge Petrenko
@ 2020-04-10 12:27 ` Serge Petrenko
  2020-04-11 18:01 ` Vladislav Shpilevoy
  2020-04-13 13:52 ` Kirill Yukhin
  6 siblings, 0 replies; 14+ messages in thread
From: Serge Petrenko @ 2020-04-10 12:27 UTC (permalink / raw)
  To: Vladislav Shpilevoy; +Cc: tarantool-patches

@ChangeLog
  - add ability to encode/decode
    uuids to MsgPack (#4268, #2916)
  - introduce field and index type UUID (#4268, #2916)

--
Serge Petrenko
sergepetrenko@tarantool.org




> 10 апр. 2020 г., в 02:50, Serge Petrenko <sergepetrenko@tarantool.org> написал(а):
> 
> https://github.com/tarantool/tarantool/issues/4268
> https://github.com/tarantool/tarantool/tree/sp/gh-4268-uuid-type
> 
> Changes in v2:
>  - disallow to insert strings and binstrings
>    to uuid fields.
>  - move mp_uuid  files to uuid lib
>  - extract mpstream to a separate lib
>  - review fixes as per review from Vlad
> 
> Serge Petrenko (4):
>  refactoring: extract mpstream into a separate library
>  uuid: expose tt_uuid_validate method
>  box: add MsgPack encoding/decoding for UUID
>  box: introduce indices by UUID
> 
> extra/exports                         |  3 +
> src/CMakeLists.txt                    |  2 +-
> src/box/CMakeLists.txt                |  2 +-
> src/box/field_def.c                   | 32 +++++----
> src/box/field_def.h                   |  1 +
> src/box/lua/call.c                    |  2 +-
> src/box/lua/misc.cc                   |  2 +-
> src/box/lua/net_box.c                 |  2 +-
> src/box/lua/tuple.c                   |  2 +-
> src/box/sql.c                         |  3 +-
> src/box/sql/func.c                    |  2 +-
> src/box/sql/vdbe.c                    |  2 +-
> src/box/sql/vdbemem.c                 |  2 +-
> src/box/tuple_compare.cc              | 59 ++++++++++++++++
> src/box/xrow.c                        |  2 +-
> src/lib/CMakeLists.txt                |  1 +
> src/lib/core/CMakeLists.txt           |  1 -
> src/lib/core/mp_extension_types.h     |  2 +
> src/lib/mpstream/CMakeLists.txt       |  2 +
> src/lib/{core => mpstream}/mpstream.c | 13 +++-
> src/lib/{core => mpstream}/mpstream.h |  5 ++
> src/lib/msgpuck                       |  2 +-
> src/lib/uuid/CMakeLists.txt           |  2 +-
> src/lib/uuid/mp_uuid.c                | 98 +++++++++++++++++++++++++++
> src/lib/uuid/mp_uuid.h                | 90 ++++++++++++++++++++++++
> src/lib/uuid/tt_uuid.c                |  3 +
> src/lib/uuid/tt_uuid.h                | 16 +++--
> src/lua/msgpack.c                     | 29 ++++++--
> src/lua/msgpackffi.lua                | 14 ++++
> src/lua/utils.c                       | 20 ++++++
> src/lua/utils.h                       |  5 ++
> src/lua/uuid.lua                      |  9 ---
> test/app-tap/lua/serializer_test.lua  |  8 +++
> test/app-tap/msgpackffi.test.lua      |  3 +-
> test/app/msgpack.result               | 21 ++++++
> test/app/msgpack.test.lua             | 13 ++++
> test/app/uuid.result                  | 13 +++-
> test/app/uuid.test.lua                |  5 ++
> test/box/tuple.result                 | 81 ++++++++++++++++++++++
> test/box/tuple.test.lua               | 25 +++++++
> test/engine/ddl.result                | 97 +++++++++++++++++++++++++-
> test/engine/ddl.test.lua              | 42 +++++++++++-
> test/engine/uuid.result               | 55 +++++++++++++++
> test/engine/uuid.test.lua             | 27 ++++++++
> test/unit/uuid.c                      | 25 ++++++-
> test/unit/uuid.result                 |  8 ++-
> third_party/lua-cjson/lua_cjson.c     | 27 +++++---
> third_party/lua-yaml/lyaml.cc         | 17 ++++-
> 48 files changed, 829 insertions(+), 68 deletions(-)
> create mode 100644 src/lib/mpstream/CMakeLists.txt
> rename src/lib/{core => mpstream}/mpstream.c (95%)
> rename src/lib/{core => mpstream}/mpstream.h (97%)
> create mode 100644 src/lib/uuid/mp_uuid.c
> create mode 100644 src/lib/uuid/mp_uuid.h
> create mode 100644 test/engine/uuid.result
> create mode 100644 test/engine/uuid.test.lua
> 
> -- 
> 2.21.1 (Apple Git-122.3)
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 4/4] box: introduce indices by UUID
  2020-04-09 23:50 ` [Tarantool-patches] [PATCH v2 4/4] box: introduce indices by UUID Serge Petrenko
@ 2020-04-10 16:56   ` Vladislav Shpilevoy
  2020-04-11 14:14     ` Serge Petrenko
  0 siblings, 1 reply; 14+ messages in thread
From: Vladislav Shpilevoy @ 2020-04-10 16:56 UTC (permalink / raw)
  To: Serge Petrenko; +Cc: tarantool-patches

Thanks for the patch!

The patchset is almost perfect, just a few nits are left.
See 2 of them below.

> diff --git a/src/box/tuple_compare.cc b/src/box/tuple_compare.cc
> index 3f8a0ce24..a47f7ac6d 100644
> --- a/src/box/tuple_compare.cc
> +++ b/src/box/tuple_compare.cc
> @@ -378,6 +382,25 @@ mp_compare_bin(const char *field_a, const char *field_b)
>  	return COMPARE_RESULT(size_a, size_b);
>  }
>  
> +static inline int
> +mp_compare_uuid(const char *field_a, const char *field_b)
> +{
> +	const char *str_a, *str_b;
> +	int8_t type;
> +	uint32_t len;
> +	str_a = mp_decode_ext(&field_a, &type, &len);
> +	assert(type == MP_UUID && len == UUID_PACKED_LEN);
> +	str_b = mp_decode_ext(&field_b, &type, &len);
> +	assert(type == MP_UUID && len == UUID_PACKED_LEN);

1. I would either do field_a += 2, field_b += 2; or just
memcmp(field_a, field_b), because the same prefix won't
affect the result. Up to you. +2 is the fastest solution I
think.

+2 version could be even moved to mp_uuid.h as something like
mp_strip_uuid_header() or mp_decode_ext_uuidl() (similar to
mp_decode_strl()). Point is we eliminate lots of instructions
and switch-case mp_decode_extl().

> +	/*
> +	 * Packed uuid fields are in the right order for
> +	 * comparison and are big-endian, so memcmp is
> +	 * the same as tt_uuid_compare() and lets us
> +	 * spare 2 mp_uuid_unpack() calls.
> +	 */
> +	return memcmp(str_a, str_b, UUID_PACKED_LEN);
> +}> diff --git a/test/engine/uuid.result b/test/engine/uuid.result
> new file mode 100644
> index 000000000..c4c186e92
> --- /dev/null
> +++ b/test/engine/uuid.result
> @@ -0,0 +1,55 @@
> +-- test-run result file version 2
> +env = require('test_run')
> + | ---
> + | ...
> +test_run = env.new()
> + | ---
> + | ...
> +engine = test_run:get_cfg('engine')
> + | ---
> + | ...
> +
> +uuid = require('uuid')
> + | ---
> + | ...
> +ffi = require('ffi')
> + | ---
> + | ...
> +
> +-- check uuid indices

2. Lets mention the ticket here, and

    check -> Check
    indices -> indices.

> +_ = box.schema.space.create('test', {engine=engine})
> + | ---
> + | ...
> +_ = box.space.test:create_index('pk', {parts={1,'uuid'}})
> + | ---
> + | ...

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 1/4] refactoring: extract mpstream into a separate library
  2020-04-09 23:50 ` [Tarantool-patches] [PATCH v2 1/4] refactoring: extract mpstream into a separate library Serge Petrenko
@ 2020-04-10 16:56   ` Vladislav Shpilevoy
  2020-04-11 13:12     ` Serge Petrenko
  0 siblings, 1 reply; 14+ messages in thread
From: Vladislav Shpilevoy @ 2020-04-10 16:56 UTC (permalink / raw)
  To: Serge Petrenko; +Cc: tarantool-patches

Thanks for the patch!

> diff --git a/src/lib/core/mpstream.c b/src/lib/mpstream/mpstream.c
> similarity index 99%
> rename from src/lib/core/mpstream.c
> rename to src/lib/mpstream/mpstream.c
> index 2be1797d0..a737212c1 100644
> --- a/src/lib/core/mpstream.c
> +++ b/src/lib/mpstream/mpstream.c
> @@ -33,7 +33,7 @@
>  #include <assert.h>
>  #include <stdint.h>
>  #include "msgpuck.h"
> -#include "mp_decimal.h"
> +#include "core/mp_decimal.h"

You can keep it as is, anyway core/ is added to -I, so
all files there are visible without core/ prefix. In all
next patches too.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 3/4] box: add MsgPack encoding/decoding for UUID
  2020-04-09 23:50 ` [Tarantool-patches] [PATCH v2 3/4] box: add MsgPack encoding/decoding for UUID Serge Petrenko
@ 2020-04-10 16:56   ` Vladislav Shpilevoy
  2020-04-11 14:14     ` Serge Petrenko
  0 siblings, 1 reply; 14+ messages in thread
From: Vladislav Shpilevoy @ 2020-04-10 16:56 UTC (permalink / raw)
  To: Serge Petrenko; +Cc: tarantool-patches

Thanks for the patch!

See 7 comments below.

> diff --git a/src/lib/uuid/mp_uuid.c b/src/lib/uuid/mp_uuid.c
> new file mode 100644
> index 000000000..7acfbc797
> --- /dev/null
> +++ b/src/lib/uuid/mp_uuid.c
> @@ -0,0 +1,98 @@
> +
> +#include "mp_uuid.h"
> +#include "msgpuck.h"
> +#include "mp_extension_types.h"
> +#include "lib/uuid/tt_uuid.h"

1. Lib/, as well as core/, can be omitted. That paths anyway
are in -I.

> +
> +inline uint32_t
> +mp_sizeof_uuid(void)
> +{
> +	return mp_sizeof_ext(UUID_PACKED_LEN);
> +}
> diff --git a/src/lib/uuid/mp_uuid.h b/src/lib/uuid/mp_uuid.h
> new file mode 100644
> index 000000000..430cb96d2
> --- /dev/null
> +++ b/src/lib/uuid/mp_uuid.h
> @@ -0,0 +1,90 @@
> +
> +#include <stdint.h>
> +
> +#if defined(__cplusplus)
> +extern "C" {
> +#endif /* defined(__cplusplus) */
> +
> +struct tt_uuid;
> +
> +#define UUID_PACKED_LEN sizeof(struct tt_uuid)

2. Maybe better make it enum. When you do it via the macros, you
workaround the necessity to make include tt_uuid.h, but the macros
anyway can't be actually used without this include. So it is ok
to add the include here + change that to macros.

> +
> +/**
> + * \brief Return the number of bytes an encoded uuid value takes.
> + */

3. I would better use @ than \. The latter is used in the old code
only.

> +uint32_t
> +mp_sizeof_uuid(void);
> +
> diff --git a/src/lua/msgpack.c b/src/lua/msgpack.c
> index 73ed3ece6..e4fb0cf43 100644
> --- a/src/lua/msgpack.c
> +++ b/src/lua/msgpack.c
> @@ -43,6 +43,7 @@
>  
>  #include "lua/decimal.h" /* lua_pushdecimal() */
>  #include "lib/core/decimal.h" /* decimal_unpack() */
> +#include "lib/uuid/mp_uuid.h" /* mp_decode_uuid() */

4. lib/ can be omitted. Don't know why they are used in other
includes.

diag.h is the most used header from core/, and we never write
core/diag.h.

> diff --git a/src/lua/utils.c b/src/lua/utils.c
> index 54d18ac89..bd6bfb008 100644
> --- a/src/lua/utils.c
> +++ b/src/lua/utils.c
> @@ -1286,5 +1296,15 @@ tarantool_lua_utils_init(struct lua_State *L)
>  	assert(CTID_CHAR_PTR != 0);
>  	CTID_CONST_CHAR_PTR = luaL_ctypeid(L, "const char *");
>  	assert(CTID_CONST_CHAR_PTR != 0);
> +	rc = luaL_cdef(L, "struct tt_uuid {"
> +				  "uint32_t time_low;"
> +				  "uint16_t time_mid;"
> +				  "uint16_t time_hi_and_version;"
> +				  "uint8_t clock_seq_hi_and_reserved;"
> +				  "uint8_t clock_seq_low;"
> +				  "uint8_t node[6];"
> +			  "};");

5. It is worth adding assert(rc == 0). Otherwise you can omit 'rc = '
at all.

> +	CTID_UUID = luaL_ctypeid(L, "struct tt_uuid");
> +	assert(CTID_UUID != 0);
>  	return 0;
>  }
> diff --git a/third_party/lua-yaml/lyaml.cc b/third_party/lua-yaml/lyaml.cc
> index af4f2f5d5..411c56f71 100644
> --- a/third_party/lua-yaml/lyaml.cc
> +++ b/third_party/lua-yaml/lyaml.cc
> @@ -50,6 +50,9 @@ extern "C" {
>  } /* extern "C" */
>  #include "lua/utils.h"
>  #include "lib/core/decimal.h"
> +#include "lib/core/tt_static.h"
> +#include "lib/core/mp_extension_types.h" /* MP_DECIMAL, MP_UUID */
> +#include "lib/uuid/tt_uuid.h" /* tt_uuid_to_string(), UUID_STR_LEN */

6. lib/ and core/ can be omitted.

>  #define LUAYAML_TAG_PREFIX "tag:yaml.org,2002:"
>  
> @@ -697,10 +700,18 @@ static int dump_node(struct lua_yaml_dumper *dumper)
>        switch (field.ext_type) {
>        case MP_DECIMAL:
>           str = decimal_to_string(field.decval);
> -	 len = strlen(str);
> -	 break;
> +         len = strlen(str);
> +         break;
> +      case MP_UUID:
> +      {
> +         char *buf = tt_static_buf();
> +         tt_uuid_to_string(field.uuidval, buf);
> +         str = buf;
> +         len = UUID_STR_LEN;
> +         break;
> +      }

7. Consider the diff:

====================
diff --git a/third_party/lua-yaml/lyaml.cc b/third_party/lua-yaml/lyaml.cc
index 411c56f71..29dbe7211 100644
--- a/third_party/lua-yaml/lyaml.cc
+++ b/third_party/lua-yaml/lyaml.cc
@@ -703,13 +703,9 @@ static int dump_node(struct lua_yaml_dumper *dumper)
          len = strlen(str);
          break;
       case MP_UUID:
-      {
-         char *buf = tt_static_buf();
-         tt_uuid_to_string(field.uuidval, buf);
-         str = buf;
+         str = tt_uuid_str(field.uuidval);
          len = UUID_STR_LEN;
          break;
-      }
       default:
          assert(0); /* checked by luaL_checkfield() */
       }
====================

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 1/4] refactoring: extract mpstream into a separate library
  2020-04-10 16:56   ` Vladislav Shpilevoy
@ 2020-04-11 13:12     ` Serge Petrenko
  0 siblings, 0 replies; 14+ messages in thread
From: Serge Petrenko @ 2020-04-11 13:12 UTC (permalink / raw)
  To: Vladislav Shpilevoy; +Cc: tarantool-patches



> 10 апр. 2020 г., в 19:56, Vladislav Shpilevoy <v.shpilevoy@tarantool.org> написал(а):
> 
> Thanks for the patch!

Thanks for the review!

> 
>> diff --git a/src/lib/core/mpstream.c b/src/lib/mpstream/mpstream.c
>> similarity index 99%
>> rename from src/lib/core/mpstream.c
>> rename to src/lib/mpstream/mpstream.c
>> index 2be1797d0..a737212c1 100644
>> --- a/src/lib/core/mpstream.c
>> +++ b/src/lib/mpstream/mpstream.c
>> @@ -33,7 +33,7 @@
>> #include <assert.h>
>> #include <stdint.h>
>> #include "msgpuck.h"
>> -#include "mp_decimal.h"
>> +#include "core/mp_decimal.h"
> 
> You can keep it as is, anyway core/ is added to -I, so
> all files there are visible without core/ prefix. In all
> next patches too.

Indeed, thanks!

diff --git a/src/lib/mpstream/mpstream.c b/src/lib/mpstream/mpstream.c
index a737212c1..2be1797d0 100644
--- a/src/lib/mpstream/mpstream.c
+++ b/src/lib/mpstream/mpstream.c
@@ -33,7 +33,7 @@
 #include <assert.h>
 #include <stdint.h>
 #include "msgpuck.h"
-#include "core/mp_decimal.h"
+#include "mp_decimal.h"
 
 void
 mpstream_reserve_slow(struct mpstream *stream, size_t size)

--
Serge Petrenko
sergepetrenko@tarantool.org

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 3/4] box: add MsgPack encoding/decoding for UUID
  2020-04-10 16:56   ` Vladislav Shpilevoy
@ 2020-04-11 14:14     ` Serge Petrenko
  0 siblings, 0 replies; 14+ messages in thread
From: Serge Petrenko @ 2020-04-11 14:14 UTC (permalink / raw)
  To: Vladislav Shpilevoy; +Cc: tarantool-patches


> 10 апр. 2020 г., в 19:56, Vladislav Shpilevoy <v.shpilevoy@tarantool.org> написал(а):
> 
> Thanks for the patch!

Hi! Thanks for the review!

> 
> See 7 comments below.
> 
>> diff --git a/src/lib/uuid/mp_uuid.c b/src/lib/uuid/mp_uuid.c
>> new file mode 100644
>> index 000000000..7acfbc797
>> --- /dev/null
>> +++ b/src/lib/uuid/mp_uuid.c
>> @@ -0,0 +1,98 @@
>> +
>> +#include "mp_uuid.h"
>> +#include "msgpuck.h"
>> +#include "mp_extension_types.h"
>> +#include "lib/uuid/tt_uuid.h"
> 
> 1. Lib/, as well as core/, can be omitted. That paths anyway
> are in -I.

Ok, thanks.

> 
>> +
>> +inline uint32_t
>> +mp_sizeof_uuid(void)
>> +{
>> +	return mp_sizeof_ext(UUID_PACKED_LEN);
>> +}
>> diff --git a/src/lib/uuid/mp_uuid.h b/src/lib/uuid/mp_uuid.h
>> new file mode 100644
>> index 000000000..430cb96d2
>> --- /dev/null
>> +++ b/src/lib/uuid/mp_uuid.h
>> @@ -0,0 +1,90 @@
>> +
>> +#include <stdint.h>
>> +
>> +#if defined(__cplusplus)
>> +extern "C" {
>> +#endif /* defined(__cplusplus) */
>> +
>> +struct tt_uuid;
>> +
>> +#define UUID_PACKED_LEN sizeof(struct tt_uuid)
> 
> 2. Maybe better make it enum. When you do it via the macros, you
> workaround the necessity to make include tt_uuid.h, but the macros
> anyway can't be actually used without this include. So it is ok
> to add the include here + change that to macros.

Ok.

> 
>> +
>> +/**
>> + * \brief Return the number of bytes an encoded uuid value takes.
>> + */
> 
> 3. I would better use @ than \. The latter is used in the old code
> only.

Ok.

> 
>> +uint32_t
>> +mp_sizeof_uuid(void);
>> +
>> diff --git a/src/lua/msgpack.c b/src/lua/msgpack.c
>> index 73ed3ece6..e4fb0cf43 100644
>> --- a/src/lua/msgpack.c
>> +++ b/src/lua/msgpack.c
>> @@ -43,6 +43,7 @@
>> 
>> #include "lua/decimal.h" /* lua_pushdecimal() */
>> #include "lib/core/decimal.h" /* decimal_unpack() */
>> +#include "lib/uuid/mp_uuid.h" /* mp_decode_uuid() */
> 
> 4. lib/ can be omitted. Don't know why they are used in other
> includes.
> 
> diag.h is the most used header from core/, and we never write
> core/diag.h.

I see, ok.

> 
>> diff --git a/src/lua/utils.c b/src/lua/utils.c
>> index 54d18ac89..bd6bfb008 100644
>> --- a/src/lua/utils.c
>> +++ b/src/lua/utils.c
>> @@ -1286,5 +1296,15 @@ tarantool_lua_utils_init(struct lua_State *L)
>> 	assert(CTID_CHAR_PTR != 0);
>> 	CTID_CONST_CHAR_PTR = luaL_ctypeid(L, "const char *");
>> 	assert(CTID_CONST_CHAR_PTR != 0);
>> +	rc = luaL_cdef(L, "struct tt_uuid {"
>> +				  "uint32_t time_low;"
>> +				  "uint16_t time_mid;"
>> +				  "uint16_t time_hi_and_version;"
>> +				  "uint8_t clock_seq_hi_and_reserved;"
>> +				  "uint8_t clock_seq_low;"
>> +				  "uint8_t node[6];"
>> +			  "};");
> 
> 5. It is worth adding assert(rc == 0). Otherwise you can omit 'rc = '
> at all.

Yep, I missed it somehow. Thanks.

> 
>> +	CTID_UUID = luaL_ctypeid(L, "struct tt_uuid");
>> +	assert(CTID_UUID != 0);
>> 	return 0;
>> }
>> diff --git a/third_party/lua-yaml/lyaml.cc b/third_party/lua-yaml/lyaml.cc
>> index af4f2f5d5..411c56f71 100644
>> --- a/third_party/lua-yaml/lyaml.cc
>> +++ b/third_party/lua-yaml/lyaml.cc
>> @@ -50,6 +50,9 @@ extern "C" {
>> } /* extern "C" */
>> #include "lua/utils.h"
>> #include "lib/core/decimal.h"
>> +#include "lib/core/tt_static.h"
>> +#include "lib/core/mp_extension_types.h" /* MP_DECIMAL, MP_UUID */
>> +#include "lib/uuid/tt_uuid.h" /* tt_uuid_to_string(), UUID_STR_LEN */
> 
> 6. lib/ and core/ can be omitted.

Done.

> 
>> #define LUAYAML_TAG_PREFIX "tag:yaml.org,2002:"
>> 
>> @@ -697,10 +700,18 @@ static int dump_node(struct lua_yaml_dumper *dumper)
>>       switch (field.ext_type) {
>>       case MP_DECIMAL:
>>          str = decimal_to_string(field.decval);
>> -	 len = strlen(str);
>> -	 break;
>> +         len = strlen(str);
>> +         break;
>> +      case MP_UUID:
>> +      {
>> +         char *buf = tt_static_buf();
>> +         tt_uuid_to_string(field.uuidval, buf);
>> +         str = buf;
>> +         len = UUID_STR_LEN;
>> +         break;
>> +      }
> 7. Consider the diff:
> 
> ====================
> diff --git a/third_party/lua-yaml/lyaml.cc b/third_party/lua-yaml/lyaml.cc
> index 411c56f71..29dbe7211 100644
> --- a/third_party/lua-yaml/lyaml.cc
> +++ b/third_party/lua-yaml/lyaml.cc
> @@ -703,13 +703,9 @@ static int dump_node(struct lua_yaml_dumper *dumper)
>          len = strlen(str);
>          break;
>       case MP_UUID:
> -      {
> -         char *buf = tt_static_buf();
> -         tt_uuid_to_string(field.uuidval, buf);
> -         str = buf;
> +         str = tt_uuid_str(field.uuidval);
>          len = UUID_STR_LEN;
>          break;
> -      }
>       default:
>          assert(0); /* checked by luaL_checkfield() */
>       }
> ====================

Thanks! Also applied to lua-cjson.

Here’s the diff:

diff --git a/src/lib/uuid/mp_uuid.c b/src/lib/uuid/mp_uuid.c
index 7acfbc797..1a9daf6d1 100644
--- a/src/lib/uuid/mp_uuid.c
+++ b/src/lib/uuid/mp_uuid.c
@@ -32,7 +32,6 @@
 #include "mp_uuid.h"
 #include "msgpuck.h"
 #include "mp_extension_types.h"
-#include "lib/uuid/tt_uuid.h"
 
 inline uint32_t
 mp_sizeof_uuid(void)
diff --git a/src/lib/uuid/mp_uuid.h b/src/lib/uuid/mp_uuid.h
index 430cb96d2..fdc39f7ef 100644
--- a/src/lib/uuid/mp_uuid.h
+++ b/src/lib/uuid/mp_uuid.h
@@ -32,17 +32,17 @@
  */
 
 #include <stdint.h>
+#include "tt_uuid.h"
 
 #if defined(__cplusplus)
 extern "C" {
 #endif /* defined(__cplusplus) */
 
-struct tt_uuid;
 
-#define UUID_PACKED_LEN sizeof(struct tt_uuid)
+enum {UUID_PACKED_LEN = sizeof(struct tt_uuid)};
 
 /**
- * \brief Return the number of bytes an encoded uuid value takes.
+ * @brief Return the number of bytes an encoded uuid value takes.
  */
 uint32_t
 mp_sizeof_uuid(void);
@@ -52,35 +52,35 @@ mp_sizeof_uuid(void);
  * with mp_decode_extl() instead of mp_decode_uuid() when multiple
  * extension types are possible.
  *
- * \param data A buffer.
- * \param len Length returned by mp_decode_extl, has to be equal
+ * @param data A buffer.
+ * @param len Length returned by mp_decode_extl, has to be equal
  *            to sizeof(struct tt_uuid), otherwise an error is
  *            returned.
- * \param[out] uuid Uuid to be decoded.
- * \return A pointer to the decoded uuid.
+ * @param[out] uuid Uuid to be decoded.
+ * @return A pointer to the decoded uuid.
  *         NULL in case of an error.
- * \post *data = *data + sizeof(struct tt_uuid).
+ * @post *data = *data + sizeof(struct tt_uuid).
  */
 struct tt_uuid *
 uuid_unpack(const char **data, uint32_t len, struct tt_uuid *uuid);
 
 /**
- * \brief Decode a uuid from MsgPack \a data.
- * \param data A buffer.
- * \param[out] uuid Uuid to be decoded.
- * \return A pointer to the decoded uuid.
+ * @brief Decode a uuid from MsgPack @a data.
+ * @param data A buffer.
+ * @param[out] uuid Uuid to be decoded.
+ * @return A pointer to the decoded uuid.
  *         NULL in case of an error.
- * \post *data = *data + mp_sizeof_uuid().
+ * @post *data = *data + mp_sizeof_uuid().
  */
 struct tt_uuid *
 mp_decode_uuid(const char **data, struct tt_uuid *uuid);
 
 /**
- * \brief Encode a uuid.
- * \param data A buffer.
- * \param uuid A uuid to encode.
+ * @brief Encode a uuid.
+ * @param data A buffer.
+ * @param uuid A uuid to encode.
  *
- * \return \a data + mp_sizeof_uuid()
+ * @return @a data + mp_sizeof_uuid()
  */
 char *
 mp_encode_uuid(char *data, const struct tt_uuid *uuid);
diff --git a/src/lua/utils.c b/src/lua/utils.c
index bd6bfb008..667365fdc 100644
--- a/src/lua/utils.c
+++ b/src/lua/utils.c
@@ -1287,7 +1287,6 @@ tarantool_lua_utils_init(struct lua_State *L)
 
 	int rc = luaL_cdef(L, "struct ibuf;");
 	assert(rc == 0);
-	(void) rc;
 	CTID_STRUCT_IBUF = luaL_ctypeid(L, "struct ibuf");
 	assert(CTID_STRUCT_IBUF != 0);
 	CTID_STRUCT_IBUF_PTR = luaL_ctypeid(L, "struct ibuf *");
@@ -1304,6 +1303,8 @@ tarantool_lua_utils_init(struct lua_State *L)
 				  "uint8_t clock_seq_low;"
 				  "uint8_t node[6];"
 			  "};");
+	assert(rc == 0);
+	(void) rc;
 	CTID_UUID = luaL_ctypeid(L, "struct tt_uuid");
 	assert(CTID_UUID != 0);
 	return 0;
diff --git a/third_party/lua-cjson/lua_cjson.c b/third_party/lua-cjson/lua_cjson.c
index 6e1793a59..d4b89ce0d 100644
--- a/third_party/lua-cjson/lua_cjson.c
+++ b/third_party/lua-cjson/lua_cjson.c
@@ -48,9 +48,9 @@
 #include "strbuf.h"
 
 #include "lua/utils.h"
-#include "lib/core/mp_extension_types.h" /* MP_DECIMAL, MP_UUID */
-#include "lib/core/tt_static.h"
-#include "lib/uuid/tt_uuid.h" /* tt_uuid_to_string(), UUID_STR_LEN */
+#include "mp_extension_types.h" /* MP_DECIMAL, MP_UUID */
+#include "tt_static.h"
+#include "uuid/tt_uuid.h" /* tt_uuid_to_string(), UUID_STR_LEN */
 
 #define DEFAULT_ENCODE_KEEP_BUFFER 1
 
@@ -431,11 +431,8 @@ static void json_append_data(lua_State *l, struct luaL_serializer *cfg,
             return json_append_string(cfg, json, str, strlen(str));
         }
         case MP_UUID:
-        {
-            char *str = tt_static_buf();
-            tt_uuid_to_string(field.uuidval, str);
-            return json_append_string(cfg, json, str, UUID_STR_LEN);
-        }
+            return json_append_string(cfg, json, tt_uuid_str(field.uuidval),
+                                      UUID_STR_LEN);
         default:
             assert(false);
         }
diff --git a/third_party/lua-yaml/lyaml.cc b/third_party/lua-yaml/lyaml.cc
index 411c56f71..9c3a4a646 100644
--- a/third_party/lua-yaml/lyaml.cc
+++ b/third_party/lua-yaml/lyaml.cc
@@ -50,9 +50,9 @@ extern "C" {
 } /* extern "C" */
 #include "lua/utils.h"
 #include "lib/core/decimal.h"
-#include "lib/core/tt_static.h"
-#include "lib/core/mp_extension_types.h" /* MP_DECIMAL, MP_UUID */
-#include "lib/uuid/tt_uuid.h" /* tt_uuid_to_string(), UUID_STR_LEN */
+#include "tt_static.h"
+#include "mp_extension_types.h" /* MP_DECIMAL, MP_UUID */
+#include "uuid/tt_uuid.h" /* tt_uuid_to_string(), UUID_STR_LEN */
 
 #define LUAYAML_TAG_PREFIX "tag:yaml.org,2002:"
 
@@ -703,13 +703,9 @@ static int dump_node(struct lua_yaml_dumper *dumper)
          len = strlen(str);
          break;
       case MP_UUID:
-      {
-         char *buf = tt_static_buf();
-         tt_uuid_to_string(field.uuidval, buf);
-         str = buf;
+         str = tt_uuid_str(field.uuidval);
          len = UUID_STR_LEN;
          break;
-      }
       default:
          assert(0); /* checked by luaL_checkfield() */
       }



--
Serge Petrenko
sergepetrenko@tarantool.org

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 4/4] box: introduce indices by UUID
  2020-04-10 16:56   ` Vladislav Shpilevoy
@ 2020-04-11 14:14     ` Serge Petrenko
  0 siblings, 0 replies; 14+ messages in thread
From: Serge Petrenko @ 2020-04-11 14:14 UTC (permalink / raw)
  To: Vladislav Shpilevoy; +Cc: tarantool-patches


> 10 апр. 2020 г., в 19:56, Vladislav Shpilevoy <v.shpilevoy@tarantool.org> написал(а):
> 
> Thanks for the patch!
> 

Hi! Thanks for the review!

> The patchset is almost perfect, just a few nits are left.
> See 2 of them below.
> 
>> diff --git a/src/box/tuple_compare.cc b/src/box/tuple_compare.cc
>> index 3f8a0ce24..a47f7ac6d 100644
>> --- a/src/box/tuple_compare.cc
>> +++ b/src/box/tuple_compare.cc
>> @@ -378,6 +382,25 @@ mp_compare_bin(const char *field_a, const char *field_b)
>> 	return COMPARE_RESULT(size_a, size_b);
>> }
>> 
>> +static inline int
>> +mp_compare_uuid(const char *field_a, const char *field_b)
>> +{
>> +	const char *str_a, *str_b;
>> +	int8_t type;
>> +	uint32_t len;
>> +	str_a = mp_decode_ext(&field_a, &type, &len);
>> +	assert(type == MP_UUID && len == UUID_PACKED_LEN);
>> +	str_b = mp_decode_ext(&field_b, &type, &len);
>> +	assert(type == MP_UUID && len == UUID_PACKED_LEN);
> 
> 1. I would either do field_a += 2, field_b += 2; or just
> memcmp(field_a, field_b), because the same prefix won't
> affect the result. Up to you. +2 is the fastest solution I
> think.
> 
> +2 version could be even moved to mp_uuid.h as something like
> mp_strip_uuid_header() or mp_decode_ext_uuidl() (similar to
> mp_decode_strl()). Point is we eliminate lots of instructions
> and switch-case mp_decode_extl().

Lets just do field_a + 2, field_b + 2.

> 
>> +	/*
>> +	 * Packed uuid fields are in the right order for
>> +	 * comparison and are big-endian, so memcmp is
>> +	 * the same as tt_uuid_compare() and lets us
>> +	 * spare 2 mp_uuid_unpack() calls.
>> +	 */
>> +	return memcmp(str_a, str_b, UUID_PACKED_LEN);
>> +}> diff --git a/test/engine/uuid.result b/test/engine/uuid.result
>> new file mode 100644
>> index 000000000..c4c186e92
>> --- /dev/null
>> +++ b/test/engine/uuid.result
>> @@ -0,0 +1,55 @@
>> +-- test-run result file version 2
>> +env = require('test_run')
>> + | ---
>> + | ...
>> +test_run = env.new()
>> + | ---
>> + | ...
>> +engine = test_run:get_cfg('engine')
>> + | ---
>> + | ...
>> +
>> +uuid = require('uuid')
>> + | ---
>> + | ...
>> +ffi = require('ffi')
>> + | ---
>> + | ...
>> +
>> +-- check uuid indices
> 
> 2. Lets mention the ticket here, and
> 
>    check -> Check
>    indices -> indices.

Ok.

> 
>> +_ = box.schema.space.create('test', {engine=engine})
>> + | ---
>> + | ...
>> +_ = box.space.test:create_index('pk', {parts={1,'uuid'}})
>> + | ---
>> + | ...


diff --git a/src/box/field_def.c b/src/box/field_def.c
index 82a2493fa..213e91699 100644
--- a/src/box/field_def.c
+++ b/src/box/field_def.c
@@ -33,7 +33,7 @@
 #include "trivia/util.h"
 #include "key_def.h"
 #include "mp_extension_types.h"
-#include "lib/uuid/mp_uuid.h"
+#include "uuid/mp_uuid.h"
 #include "uuid/tt_uuid.h"
 
 const char *mp_type_strs[] = {
diff --git a/src/box/tuple_compare.cc b/src/box/tuple_compare.cc
index a47f7ac6d..bc01fe068 100644
--- a/src/box/tuple_compare.cc
+++ b/src/box/tuple_compare.cc
@@ -35,7 +35,7 @@
 #include <math.h>
 #include "lib/core/decimal.h"
 #include "lib/core/mp_decimal.h"
-#include "lib/uuid/mp_uuid.h"
+#include "uuid/mp_uuid.h"
 #include "lib/core/mp_extension_types.h"
 
 /* {{{ tuple_compare */
@@ -385,20 +385,14 @@ mp_compare_bin(const char *field_a, const char *field_b)
 static inline int
 mp_compare_uuid(const char *field_a, const char *field_b)
 {
-	const char *str_a, *str_b;
-	int8_t type;
-	uint32_t len;
-	str_a = mp_decode_ext(&field_a, &type, &len);
-	assert(type == MP_UUID && len == UUID_PACKED_LEN);
-	str_b = mp_decode_ext(&field_b, &type, &len);
-	assert(type == MP_UUID && len == UUID_PACKED_LEN);
 	/*
 	 * Packed uuid fields are in the right order for
 	 * comparison and are big-endian, so memcmp is
 	 * the same as tt_uuid_compare() and lets us
 	 * spare 2 mp_uuid_unpack() calls.
+	 * "field_a + 2" to skip the uuid header.
 	 */
-	return memcmp(str_a, str_b, UUID_PACKED_LEN);
+	return memcmp(field_a + 2, field_b + 2, UUID_PACKED_LEN);
 }
 
 typedef int (*mp_compare_f)(const char *, const char *);
diff --git a/test/engine/uuid.test.lua b/test/engine/uuid.test.lua
index f34795ce4..34e74e68b 100644
--- a/test/engine/uuid.test.lua
+++ b/test/engine/uuid.test.lua
@@ -5,7 +5,7 @@ engine = test_run:get_cfg('engine')
 uuid = require('uuid')
 ffi = require('ffi')
 
--- check uuid indices
+-- Check uuid indices (gh-4268).
 _ = box.schema.space.create('test', {engine=engine})
 _ = box.space.test:create_index('pk', {parts={1,'uuid'}})
 


--
Serge Petrenko
sergepetrenko@tarantool.org

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 0/4] introduce indices over UUID
  2020-04-09 23:50 [Tarantool-patches] [PATCH v2 0/4] introduce indices over UUID Serge Petrenko
                   ` (4 preceding siblings ...)
  2020-04-10 12:27 ` [Tarantool-patches] [PATCH v2 0/4] introduce indices over UUID Serge Petrenko
@ 2020-04-11 18:01 ` Vladislav Shpilevoy
  2020-04-13 13:52 ` Kirill Yukhin
  6 siblings, 0 replies; 14+ messages in thread
From: Vladislav Shpilevoy @ 2020-04-11 18:01 UTC (permalink / raw)
  To: Serge Petrenko; +Cc: tarantool-patches

Thanks for the patchset!

LGTM.

I don't know whether a second review is needed. Feel
free to send to anybody else or ping Kirill right
away.

On 10/04/2020 01:50, Serge Petrenko wrote:
> https://github.com/tarantool/tarantool/issues/4268
> https://github.com/tarantool/tarantool/tree/sp/gh-4268-uuid-type
> 
> Changes in v2:
>   - disallow to insert strings and binstrings
>     to uuid fields.
>   - move mp_uuid  files to uuid lib
>   - extract mpstream to a separate lib
>   - review fixes as per review from Vlad
> 
> Serge Petrenko (4):
>   refactoring: extract mpstream into a separate library
>   uuid: expose tt_uuid_validate method
>   box: add MsgPack encoding/decoding for UUID
>   box: introduce indices by UUID
> 
>  extra/exports                         |  3 +
>  src/CMakeLists.txt                    |  2 +-
>  src/box/CMakeLists.txt                |  2 +-
>  src/box/field_def.c                   | 32 +++++----
>  src/box/field_def.h                   |  1 +
>  src/box/lua/call.c                    |  2 +-
>  src/box/lua/misc.cc                   |  2 +-
>  src/box/lua/net_box.c                 |  2 +-
>  src/box/lua/tuple.c                   |  2 +-
>  src/box/sql.c                         |  3 +-
>  src/box/sql/func.c                    |  2 +-
>  src/box/sql/vdbe.c                    |  2 +-
>  src/box/sql/vdbemem.c                 |  2 +-
>  src/box/tuple_compare.cc              | 59 ++++++++++++++++
>  src/box/xrow.c                        |  2 +-
>  src/lib/CMakeLists.txt                |  1 +
>  src/lib/core/CMakeLists.txt           |  1 -
>  src/lib/core/mp_extension_types.h     |  2 +
>  src/lib/mpstream/CMakeLists.txt       |  2 +
>  src/lib/{core => mpstream}/mpstream.c | 13 +++-
>  src/lib/{core => mpstream}/mpstream.h |  5 ++
>  src/lib/msgpuck                       |  2 +-
>  src/lib/uuid/CMakeLists.txt           |  2 +-
>  src/lib/uuid/mp_uuid.c                | 98 +++++++++++++++++++++++++++
>  src/lib/uuid/mp_uuid.h                | 90 ++++++++++++++++++++++++
>  src/lib/uuid/tt_uuid.c                |  3 +
>  src/lib/uuid/tt_uuid.h                | 16 +++--
>  src/lua/msgpack.c                     | 29 ++++++--
>  src/lua/msgpackffi.lua                | 14 ++++
>  src/lua/utils.c                       | 20 ++++++
>  src/lua/utils.h                       |  5 ++
>  src/lua/uuid.lua                      |  9 ---
>  test/app-tap/lua/serializer_test.lua  |  8 +++
>  test/app-tap/msgpackffi.test.lua      |  3 +-
>  test/app/msgpack.result               | 21 ++++++
>  test/app/msgpack.test.lua             | 13 ++++
>  test/app/uuid.result                  | 13 +++-
>  test/app/uuid.test.lua                |  5 ++
>  test/box/tuple.result                 | 81 ++++++++++++++++++++++
>  test/box/tuple.test.lua               | 25 +++++++
>  test/engine/ddl.result                | 97 +++++++++++++++++++++++++-
>  test/engine/ddl.test.lua              | 42 +++++++++++-
>  test/engine/uuid.result               | 55 +++++++++++++++
>  test/engine/uuid.test.lua             | 27 ++++++++
>  test/unit/uuid.c                      | 25 ++++++-
>  test/unit/uuid.result                 |  8 ++-
>  third_party/lua-cjson/lua_cjson.c     | 27 +++++---
>  third_party/lua-yaml/lyaml.cc         | 17 ++++-
>  48 files changed, 829 insertions(+), 68 deletions(-)
>  create mode 100644 src/lib/mpstream/CMakeLists.txt
>  rename src/lib/{core => mpstream}/mpstream.c (95%)
>  rename src/lib/{core => mpstream}/mpstream.h (97%)
>  create mode 100644 src/lib/uuid/mp_uuid.c
>  create mode 100644 src/lib/uuid/mp_uuid.h
>  create mode 100644 test/engine/uuid.result
>  create mode 100644 test/engine/uuid.test.lua
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Tarantool-patches] [PATCH v2 0/4] introduce indices over UUID
  2020-04-09 23:50 [Tarantool-patches] [PATCH v2 0/4] introduce indices over UUID Serge Petrenko
                   ` (5 preceding siblings ...)
  2020-04-11 18:01 ` Vladislav Shpilevoy
@ 2020-04-13 13:52 ` Kirill Yukhin
  6 siblings, 0 replies; 14+ messages in thread
From: Kirill Yukhin @ 2020-04-13 13:52 UTC (permalink / raw)
  To: Serge Petrenko; +Cc: tarantool-patches, v.shpilevoy

Hello,

On 10 Apr 02:50, Serge Petrenko wrote:
> https://github.com/tarantool/tarantool/issues/4268
> https://github.com/tarantool/tarantool/tree/sp/gh-4268-uuid-type
> 
> Changes in v2:
>   - disallow to insert strings and binstrings
>     to uuid fields.
>   - move mp_uuid  files to uuid lib
>   - extract mpstream to a separate lib
>   - review fixes as per review from Vlad
> 
> Serge Petrenko (4):
>   refactoring: extract mpstream into a separate library
>   uuid: expose tt_uuid_validate method
>   box: add MsgPack encoding/decoding for UUID
>   box: introduce indices by UUID

I've checked your patch into master.

--
Regards, Kirill Yukhin

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2020-04-13 13:52 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-09 23:50 [Tarantool-patches] [PATCH v2 0/4] introduce indices over UUID Serge Petrenko
2020-04-09 23:50 ` [Tarantool-patches] [PATCH v2 1/4] refactoring: extract mpstream into a separate library Serge Petrenko
2020-04-10 16:56   ` Vladislav Shpilevoy
2020-04-11 13:12     ` Serge Petrenko
2020-04-09 23:50 ` [Tarantool-patches] [PATCH v2 2/4] uuid: expose tt_uuid_validate method Serge Petrenko
2020-04-09 23:50 ` [Tarantool-patches] [PATCH v2 3/4] box: add MsgPack encoding/decoding for UUID Serge Petrenko
2020-04-10 16:56   ` Vladislav Shpilevoy
2020-04-11 14:14     ` Serge Petrenko
2020-04-09 23:50 ` [Tarantool-patches] [PATCH v2 4/4] box: introduce indices by UUID Serge Petrenko
2020-04-10 16:56   ` Vladislav Shpilevoy
2020-04-11 14:14     ` Serge Petrenko
2020-04-10 12:27 ` [Tarantool-patches] [PATCH v2 0/4] introduce indices over UUID Serge Petrenko
2020-04-11 18:01 ` Vladislav Shpilevoy
2020-04-13 13:52 ` Kirill Yukhin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox