[Tarantool-patches] [PATCH v2 1/2] uuid: support comparison of uuid values in Lua

olegrok at tarantool.org olegrok at tarantool.org
Wed Nov 18 10:56:20 MSK 2020


From: Oleg Babin <babinoleg at mail.ru>

Since Tarantool has uuid data type sometimes we want to compare
uuid vaues as it's possible for primitive types and decimals. This
patch exports function for uuid comparison and implements le and
lt metamethods for uuid type.

Closes #5511

@TarantoolBot document
Title: uuid comparison is supported

Currently comparison between uuid values is supported.
Example:
```lua
u1 = uuid.fromstr('aaaaaaaa-aaaa-4000-b000-000000000001')
u2 = uuid.fromstr('bbbbbbbb-bbbb-4000-b000-000000000001')

u1 > u2  -- false
u1 >= u2 -- false
u1 <= u2 -- true
u1 < u2  -- true
```
---
Issue: https://github.com/tarantool/tarantool/issues/5511
Branch: https://github.com/tarantool/tarantool/tree/olegrok/5511-uuid-cmp-v2

 src/exports.h          |  1 +
 src/lua/uuid.lua       | 25 +++++++++++++
 test/app/uuid.result   | 79 ++++++++++++++++++++++++++++++++++++++++++
 test/app/uuid.test.lua | 29 ++++++++++++++++
 4 files changed, 134 insertions(+)

diff --git a/src/exports.h b/src/exports.h
index 867a027dc..ffbb84e3b 100644
--- a/src/exports.h
+++ b/src/exports.h
@@ -508,6 +508,7 @@ EXPORT(tnt_iconv_close)
 EXPORT(tnt_iconv_open)
 EXPORT(tt_uuid_bswap)
 EXPORT(tt_uuid_create)
+EXPORT(tt_uuid_compare)
 EXPORT(tt_uuid_from_string)
 EXPORT(tt_uuid_is_equal)
 EXPORT(tt_uuid_is_nil)
diff --git a/src/lua/uuid.lua b/src/lua/uuid.lua
index 42016601d..08991cfeb 100644
--- a/src/lua/uuid.lua
+++ b/src/lua/uuid.lua
@@ -19,6 +19,8 @@ bool
 tt_uuid_is_equal(const struct tt_uuid *lhs, const struct tt_uuid *rhs);
 char *
 tt_uuid_str(const struct tt_uuid *uu);
+int
+tt_uuid_compare(const struct tt_uuid *a, const struct tt_uuid *b);
 extern const struct tt_uuid uuid_nil;
 ]]
 
@@ -118,9 +120,32 @@ local uuid_new_str = function()
     return uuid_tostring(uuidbuf)
 end
 
+local check_uuid = function(value, index)
+    if is_uuid(value) then
+        return value
+    end
+
+    local err_fmt = 'incorrect value to compare with uuid as %d argument'
+    error(err_fmt:format(index), 0)
+end
+
+local uuid_cmp = function(lhs, rhs)
+    lhs = check_uuid(lhs, 1)
+    rhs = check_uuid(rhs, 2)
+    return builtin.tt_uuid_compare(lhs, rhs)
+end
+local uuid_lt = function(lhs, rhs)
+    return uuid_cmp(lhs, rhs) < 0
+end
+local uuid_le = function(lhs, rhs)
+    return uuid_cmp(lhs, rhs) <= 0
+end
+
 local uuid_mt = {
     __tostring = uuid_tostring;
     __eq = uuid_eq;
+    __lt = uuid_lt;
+    __le = uuid_le;
     __index = {
         isnil = uuid_isnil;
         bin   = uuid_tobin;    -- binary host byteorder
diff --git a/test/app/uuid.result b/test/app/uuid.result
index 9fe0e7fb4..e06331001 100644
--- a/test/app/uuid.result
+++ b/test/app/uuid.result
@@ -291,6 +291,85 @@ uuid.is_uuid(require('decimal').new('123'))
 ---
 - false
 ...
+--
+-- gh-5511: allow to compare uuid values
+--
+u1 = uuid.fromstr('aaaaaaaa-aaaa-4000-b000-000000000001')
+---
+...
+u2 = uuid.fromstr('bbbbbbbb-bbbb-4000-b000-000000000001')
+---
+...
+u1 > u1
+---
+- false
+...
+u1 >= u1
+---
+- true
+...
+u1 <= u1
+---
+- true
+...
+u1 < u1
+---
+- false
+...
+u1 > u2
+---
+- false
+...
+u1 >= u2
+---
+- false
+...
+u1 <= u2
+---
+- true
+...
+u1 < u2
+---
+- true
+...
+u1 < 1
+---
+- error: incorrect value to compare with uuid as 2 argument
+...
+u1 <= 1
+---
+- error: incorrect value to compare with uuid as 2 argument
+...
+u1 < 'abc'
+---
+- error: incorrect value to compare with uuid as 2 argument
+...
+u1 <= 'abc'
+---
+- error: incorrect value to compare with uuid as 2 argument
+...
+1 < u1
+---
+- error: incorrect value to compare with uuid as 1 argument
+...
+1 <= u1
+---
+- error: incorrect value to compare with uuid as 1 argument
+...
+'abc' < u1
+---
+- error: incorrect value to compare with uuid as 1 argument
+...
+'abc' <= u1
+---
+- error: incorrect value to compare with uuid as 1 argument
+...
+u1 = nil
+---
+...
+u2 = nil
+---
+...
 uuid = nil
 ---
 ...
diff --git a/test/app/uuid.test.lua b/test/app/uuid.test.lua
index 47a96f3c6..34ab38d35 100644
--- a/test/app/uuid.test.lua
+++ b/test/app/uuid.test.lua
@@ -108,6 +108,35 @@ uuid.is_uuid(uuid.new():str())
 uuid.is_uuid(1)
 uuid.is_uuid(require('decimal').new('123'))
 
+--
+-- gh-5511: allow to compare uuid values
+--
+
+u1 = uuid.fromstr('aaaaaaaa-aaaa-4000-b000-000000000001')
+u2 = uuid.fromstr('bbbbbbbb-bbbb-4000-b000-000000000001')
+
+u1 > u1
+u1 >= u1
+u1 <= u1
+u1 < u1
+
+u1 > u2
+u1 >= u2
+u1 <= u2
+u1 < u2
+
+u1 < 1
+u1 <= 1
+u1 < 'abc'
+u1 <= 'abc'
+1 < u1
+1 <= u1
+'abc' < u1
+'abc' <= u1
+
+u1 = nil
+u2 = nil
+
 uuid = nil
 
 test_run:cmd("clear filter")
-- 
2.29.0



More information about the Tarantool-patches mailing list