Tarantool development patches archive
 help / color / mirror / Atom feed
From: olegrok@tarantool.org
To: v.shpilevoy@tarantool.org, lvasiliev@tarantool.org
Cc: tarantool-patches@dev.tarantool.org
Subject: [Tarantool-patches] [PATCH] lua: introduce function for uuid comparison
Date: Wed, 11 Nov 2020 23:04:08 +0300	[thread overview]
Message-ID: <20201111200408.49148-1-olegrok@tarantool.org> (raw)

From: Oleg Babin <babinoleg@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.
To be consistent with decimal type this patch allows to compare
uuid with uuid string representation.

@TarantoolBot document Title: uuid compare

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

-- Comparison with string uuid representation supported as well

u1 > 'bbbbbbbb-bbbb-4000-b000-000000000001' -- false
u1 < 'bbbbbbbb-bbbb-4000-b000-000000000001' -- true
u1 < 'not-uuid-string' -- error

```
---
Issue: https://github.com/tarantool/tarantool/issues/5511
Branch: https://github.com/tarantool/tarantool/tree/olegrok/5511-uuid-cmp

@Changelog:
  - Allow to compare uuid values (gh-5511)

 src/exports.h          |  1 +
 src/lua/uuid.lua       | 31 +++++++++++++
 test/app/uuid.result   | 98 ++++++++++++++++++++++++++++++++++++++++++
 test/app/uuid.test.lua | 35 +++++++++++++++
 4 files changed, 165 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..0ab937877 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,38 @@ local uuid_new_str = function()
     return uuid_tostring(uuidbuf)
 end
 
+local check_uuid = function(value, index)
+    if is_uuid(value) then
+        return value
+    end
+
+    if type(value) == 'string' then
+        value = uuid_fromstr(value)
+        if value ~= nil then
+            return value
+        end
+    end
+
+    error(('incorrect value to convert to uuid as %d argument'):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..36388aed3 100644
--- a/test/app/uuid.result
+++ b/test/app/uuid.result
@@ -291,6 +291,104 @@ uuid.is_uuid(require('decimal').new('123'))
 ---
 - false
 ...
+--
+-- gh-5511: allow to compare uuid values
+--
+u1 = uuid.fromstr('aaaaaaaa-aaaa-4000-b000-000000000001')
+---
+...
+u2_str = 'bbbbbbbb-bbbb-4000-b000-000000000001'
+---
+...
+u2 = uuid.fromstr(u2_str)
+---
+...
+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 > u2_str
+---
+- false
+...
+u1 >= u2_str
+---
+- false
+...
+u1 <= u2_str
+---
+- true
+...
+u1 < u2_str
+---
+- true
+...
+u1 < 1
+---
+- error: incorrect value to convert to uuid as 2 argument
+...
+u1 <= 1
+---
+- error: incorrect value to convert to uuid as 2 argument
+...
+u1 < 'abc'
+---
+- error: incorrect value to convert to uuid as 2 argument
+...
+u1 <= 'abc'
+---
+- error: incorrect value to convert to uuid as 2 argument
+...
+1 < u1
+---
+- error: incorrect value to convert to uuid as 1 argument
+...
+1 <= u1
+---
+- error: incorrect value to convert to uuid as 1 argument
+...
+'abc' < u1
+---
+- error: incorrect value to convert to uuid as 1 argument
+...
+'abc' <= u1
+---
+- error: incorrect value to convert to 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..5a57976e1 100644
--- a/test/app/uuid.test.lua
+++ b/test/app/uuid.test.lua
@@ -108,6 +108,41 @@ 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_str = 'bbbbbbbb-bbbb-4000-b000-000000000001'
+u2 = uuid.fromstr(u2_str)
+
+u1 > u1
+u1 >= u1
+u1 <= u1
+u1 < u1
+
+u1 > u2
+u1 >= u2
+u1 <= u2
+u1 < u2
+
+u1 > u2_str
+u1 >= u2_str
+u1 <= u2_str
+u1 < u2_str
+
+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

             reply	other threads:[~2020-11-11 20:04 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-11 20:04 olegrok [this message]
2020-11-12  9:44 ` Sergey Bronnikov
2020-11-12  9:55   ` Oleg Babin
2020-11-13  6:37     ` Sergey Bronnikov
2020-11-16 21:36 ` Vladislav Shpilevoy
2020-11-17  9:11   ` Igor Munkin
2020-11-17 22:08     ` Vladislav Shpilevoy
2020-11-18  8:02   ` Oleg Babin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201111200408.49148-1-olegrok@tarantool.org \
    --to=olegrok@tarantool.org \
    --cc=lvasiliev@tarantool.org \
    --cc=tarantool-patches@dev.tarantool.org \
    --cc=v.shpilevoy@tarantool.org \
    --subject='Re: [Tarantool-patches] [PATCH] lua: introduce function for uuid comparison' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

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