From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from [87.239.111.99] (localhost [127.0.0.1]) by dev.tarantool.org (Postfix) with ESMTP id CC0156EC58; Thu, 27 May 2021 19:44:07 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org CC0156EC58 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1622133847; bh=AiWy0/PmbuCPsNAdN2sLpOiwuxtXsJ1wVyFLJ5EgY0o=; h=To:Cc:Date:In-Reply-To:References:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=As5qCOUp01MF9r573bjJ8LDUCNFxUQ5JMjpiGc8K9eM4rnspM4PH0FTmXzklbKTHC udpNj1aEjgppPSmM7aPLflLBo9YB4vP7rfmtab0o+j3GgrtDF2lstnJ4pkzrObfzBE 4tZFYBfeW/EbltBEQdnODkUb3uGKeorMBS7mQ6Ls= Received: from smtpng1.m.smailru.net (smtpng1.m.smailru.net [94.100.181.251]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id A16216E1D7 for ; Thu, 27 May 2021 19:43:07 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org A16216E1D7 Received: by smtpng1.m.smailru.net with esmtpa (envelope-from ) id 1lmJ6A-0004qP-R8; Thu, 27 May 2021 19:43:07 +0300 To: v.shpilevoy@tarantool.org Cc: tarantool-patches@dev.tarantool.org Date: Thu, 27 May 2021 19:43:06 +0300 Message-Id: <467b59d7949bcd38037405f29da24e491932809a.1622133397.git.imeevma@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-7564579A: 646B95376F6C166E X-77F55803: 4F1203BC0FB41BD9157EECD0FDB90B9A2D08AB5A5A51250A4DB392EDF99D404500894C459B0CD1B9EF74B91C54D827A2AA0548A92B6CD0CFE4C9BF811385D26DC1B496903CC57CC2 X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE7800ADC36C757FFF6EA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F79006377EB37407B8EEC8CE8638F802B75D45FF36EB9D2243A4F8B5A6FCA7DBDB1FC311F39EFFDF887939037866D6147AF826D8AEF7C6A4AEA62A81E2DA0C703B05406B117882F4460429724CE54428C33FAD305F5C1EE8F4F765FCAA867293B0326636D2E47CDBA5A96583BD4B6F7A4D31EC0BC014FD901B82EE079FA2833FD35BB23D27C277FBC8AE2E8BAA867293B0326636D2E47CDBA5A96583BA9C0B312567BB231DD303D21008E29813377AFFFEAFD269A417C69337E82CC2E827F84554CEF50127C277FBC8AE2E8BA83251EDC214901ED5E8D9A59859A8B62CFFCC7B69C47339089D37D7C0E48F6C5571747095F342E88FB05168BE4CE3AF X-C1DE0DAB: C20DE7B7AB408E4181F030C43753B8186998911F362727C414F749A5E30D975C7E9571940300E71A32CA48C81D364DE58247301D6572E3ED9C2B6934AE262D3EE7EAB7254005DCED7532B743992DF240BDC6A1CF3F042BAD6DF99611D93F60EFB4CA5BC574AE2910699F904B3F4130E343918A1A30D5E7FCCB5012B2E24CD356 X-C8649E89: 4E36BF7865823D7055A7F0CF078B5EC49A30900B95165D347130F804358653A6C43D54ADB66F407DE01852DB95FA5D5F32CE4C8ED3CB744345CB3EA0EE2F06D81D7E09C32AA3244CAB6BB6A416A0E892FAE59EF1F3D1FE443C6EB905E3A8056B729B2BEF169E0186 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojywAFAsvjBJgw4AD/+ba/Kg== X-Mailru-Sender: 689FA8AB762F73936BC43F508A063822B14D15C3B45786124311A25078A2F81583D72C36FC87018B9F80AB2734326CD2FB559BB5D741EB96352A0ABBE4FDA4210A04DAD6CC59E33667EA787935ED9F1B X-Mras: Ok Subject: [Tarantool-patches] [PATCH 2/2] sql: introduce SQL built-in function UUID() X-BeenThere: tarantool-patches@dev.tarantool.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Mergen Imeev via Tarantool-patches Reply-To: imeevma@tarantool.org Errors-To: tarantool-patches-bounces@dev.tarantool.org Sender: "Tarantool-patches" This patch introduces a new SQL built-in function UUID(). Closes #5886 @TarantoolBot document Title: SQL built-in function UUID() SQL built-in function UUID() takes zero or one argument. If no argument is specified, a UUID v4 is generated. If the version of the UUID to generate is specified as an argument, the function returns the new UUID of the given version. Currently only version 4 of UUID is supported. --- src/box/bootstrap.snap | Bin 5991 -> 6016 bytes src/box/lua/upgrade.lua | 19 ++++++++++++ src/box/sql/func.c | 39 +++++++++++++++++++++++++ src/box/sql/parse.y | 2 +- test/box-py/bootstrap.result | 1 + test/box/access.result | 2 +- test/box/access.test.lua | 2 +- test/box/access_bin.result | 2 +- test/box/access_bin.test.lua | 2 +- test/box/access_sysview.result | 8 ++--- test/box/function1.result | 6 ++-- test/sql-tap/uuid.test.lua | 52 ++++++++++++++++++++++++++++++++- test/wal_off/func_max.result | 8 ++--- 13 files changed, 126 insertions(+), 17 deletions(-) diff --git a/src/box/bootstrap.snap b/src/box/bootstrap.snap index c4a70297aad138d426a24ee4447af485e3597536..57374decc0f9de140772d9809a227e3ba4ce61eb 100644 diff --git a/src/box/lua/upgrade.lua b/src/box/lua/upgrade.lua index 6fba260bd..97afc0b4d 100644 --- a/src/box/lua/upgrade.lua +++ b/src/box/lua/upgrade.lua @@ -1000,6 +1000,24 @@ local function upgrade_to_2_7_1() function_access() end +-------------------------------------------------------------------------------- +-- Tarantool 2.9.1 +-------------------------------------------------------------------------------- +local function sql_builtin_function_uuid() + local _func = box.space._func + local _priv = box.space._priv + local datetime = os.date("%Y-%m-%d %H:%M:%S") + local t = _func:auto_increment({ADMIN, 'UUID', 1, 'SQL_BUILTIN', '', + 'function', {}, 'any', 'none', 'none', + false, false, true, {}, setmap({}), '', + datetime, datetime}) + _priv:replace{ADMIN, PUBLIC, 'function', t.id, box.priv.X} +end + +local function upgrade_to_2_9_1() + sql_builtin_function_uuid() +end + -------------------------------------------------------------------------------- local handlers = { @@ -1015,6 +1033,7 @@ local handlers = { {version = mkversion(2, 3, 0), func = upgrade_to_2_3_0, auto = true}, {version = mkversion(2, 3, 1), func = upgrade_to_2_3_1, auto = true}, {version = mkversion(2, 7, 1), func = upgrade_to_2_7_1, auto = true}, + {version = mkversion(2, 9, 1), func = upgrade_to_2_9_1, auto = true}, } -- Schema version of the snapshot. diff --git a/src/box/sql/func.c b/src/box/sql/func.c index 9c4480a92..f93ae867d 100644 --- a/src/box/sql/func.c +++ b/src/box/sql/func.c @@ -66,6 +66,35 @@ mem_as_bin(struct Mem *mem) return s; } +static void +sql_func_uuid(struct sql_context *ctx, int argc, struct Mem **argv) +{ + if (argc > 1) { + diag_set(ClientError, ER_FUNC_WRONG_ARG_COUNT, "UUID", + "one or zero", argc); + ctx->is_aborted = true; + return; + } + if (argc == 1) { + uint64_t version; + if (mem_get_uint(argv[0], &version) != 0) { + diag_set(ClientError, ER_SQL_TYPE_MISMATCH, + mem_str(argv[0]), "integer"); + ctx->is_aborted = true; + return; + } + if (version != 4) { + diag_set(ClientError, ER_UNSUPPORTED, "Function UUID", + "versions other than 4"); + ctx->is_aborted = true; + return; + } + } + struct tt_uuid uuid; + tt_uuid_create(&uuid); + mem_set_uuid(ctx->pOut, &uuid); +} + /* * Return the collating function associated with a function. */ @@ -2544,6 +2573,16 @@ static struct { .call = UpperICUFunc, .finalize = NULL, .export_to_sql = true, + }, { + .name = "UUID", + .param_count = -1, + .returns = FIELD_TYPE_UUID, + .aggregate = FUNC_AGGREGATE_NONE, + .is_deterministic = false, + .flags = 0, + .call = sql_func_uuid, + .finalize = NULL, + .export_to_sql = true, }, { .name = "VERSION", .param_count = 0, diff --git a/src/box/sql/parse.y b/src/box/sql/parse.y index 4c9cf475e..bd041e862 100644 --- a/src/box/sql/parse.y +++ b/src/box/sql/parse.y @@ -268,7 +268,7 @@ columnlist ::= tcons. CONFLICT DEFERRED END ENGINE FAIL IGNORE INITIALLY INSTEAD NO MATCH PLAN QUERY KEY OFFSET RAISE RELEASE REPLACE RESTRICT - RENAME CTIME_KW IF ENABLE DISABLE + RENAME CTIME_KW IF ENABLE DISABLE UUID . %wildcard ANY. diff --git a/test/box-py/bootstrap.result b/test/box-py/bootstrap.result index ed7accea3..7fd4fd64d 100644 --- a/test/box-py/bootstrap.result +++ b/test/box-py/bootstrap.result @@ -242,6 +242,7 @@ box.space._priv:select{} - [1, 2, 'function', 65, 4] - [1, 2, 'function', 66, 4] - [1, 2, 'function', 67, 4] + - [1, 2, 'function', 68, 4] - [1, 2, 'space', 276, 2] - [1, 2, 'space', 277, 1] - [1, 2, 'space', 281, 1] diff --git a/test/box/access.result b/test/box/access.result index 27e636122..1a8730f1a 100644 --- a/test/box/access.result +++ b/test/box/access.result @@ -703,7 +703,7 @@ box.schema.func.exists(1) --- - true ... -box.schema.func.exists(68) +box.schema.func.exists(69) --- - false ... diff --git a/test/box/access.test.lua b/test/box/access.test.lua index a62f87ad8..2bf772b7b 100644 --- a/test/box/access.test.lua +++ b/test/box/access.test.lua @@ -282,7 +282,7 @@ box.schema.user.exists{} box.schema.func.exists('nosuchfunc') box.schema.func.exists('guest') box.schema.func.exists(1) -box.schema.func.exists(68) +box.schema.func.exists(69) box.schema.func.exists('box.schema.user.info') box.schema.func.exists() box.schema.func.exists(nil) diff --git a/test/box/access_bin.result b/test/box/access_bin.result index c58f331d3..aeb8b3bd8 100644 --- a/test/box/access_bin.result +++ b/test/box/access_bin.result @@ -298,7 +298,7 @@ box.schema.user.grant('guest', 'execute', 'universe') function f1() return box.space._func:get(1)[4] end --- ... -function f2() return box.space._func:get(68)[4] end +function f2() return box.space._func:get(69)[4] end --- ... box.schema.func.create('f1') diff --git a/test/box/access_bin.test.lua b/test/box/access_bin.test.lua index 41d5f4245..954266858 100644 --- a/test/box/access_bin.test.lua +++ b/test/box/access_bin.test.lua @@ -112,7 +112,7 @@ test:drop() -- notice that guest can execute stuff, but can't read space _func box.schema.user.grant('guest', 'execute', 'universe') function f1() return box.space._func:get(1)[4] end -function f2() return box.space._func:get(68)[4] end +function f2() return box.space._func:get(69)[4] end box.schema.func.create('f1') box.schema.func.create('f2',{setuid=true}) c = net.connect(box.cfg.listen) diff --git a/test/box/access_sysview.result b/test/box/access_sysview.result index 6468a0709..d7a7b7534 100644 --- a/test/box/access_sysview.result +++ b/test/box/access_sysview.result @@ -258,11 +258,11 @@ box.session.su('guest') ... #box.space._vpriv:select{} --- -- 82 +- 83 ... #box.space._vfunc:select{} --- -- 67 +- 68 ... #box.space._vcollation:select{} --- @@ -290,11 +290,11 @@ box.session.su('guest') ... #box.space._vpriv:select{} --- -- 82 +- 83 ... #box.space._vfunc:select{} --- -- 67 +- 68 ... #box.space._vsequence:select{} --- diff --git a/test/box/function1.result b/test/box/function1.result index 928cd5758..0166c828f 100644 --- a/test/box/function1.result +++ b/test/box/function1.result @@ -97,7 +97,7 @@ box.func["function1.args"] exports: lua: true sql: false - id: 68 + id: 69 setuid: false is_multikey: false is_deterministic: false @@ -593,7 +593,7 @@ func exports: lua: true sql: false - id: 68 + id: 69 setuid: false is_multikey: false is_deterministic: false @@ -665,7 +665,7 @@ func exports: lua: true sql: false - id: 68 + id: 69 setuid: false is_multikey: false is_deterministic: false diff --git a/test/sql-tap/uuid.test.lua b/test/sql-tap/uuid.test.lua index 4287f0921..83fcc3d0e 100755 --- a/test/sql-tap/uuid.test.lua +++ b/test/sql-tap/uuid.test.lua @@ -3,7 +3,7 @@ local build_path = os.getenv("BUILDDIR") package.cpath = build_path..'/test/sql-tap/?.so;'..build_path..'/test/sql-tap/?.dylib;'..package.cpath local test = require("sqltester") -test:plan(139) +test:plan(145) local uuid = require("uuid") local uuid1 = uuid.fromstr("11111111-1111-1111-1111-111111111111") @@ -1266,6 +1266,56 @@ test:do_execsql_test( 3,2,1 }) +-- Check function uuid(). +test:do_execsql_test( + "uuid-16.1", + [[ + SELECT typeof(uuid()); + ]], { + "uuid" + }) + +test:do_execsql_test( + "uuid-16.2", + [[ + SELECT typeof(uuid(4)); + ]], { + "uuid" + }) + +test:do_catchsql_test( + "uuid-16.3", + [[ + SELECT uuid(1); + ]], { + 1, "Function UUID does not support versions other than 4" + }) + +test:do_catchsql_test( + "uuid-16.4", + [[ + SELECT uuid('asd'); + ]], { + 1, "Type mismatch: can not convert asd to integer" + }) + +test:do_catchsql_test( + "uuid-16.5", + [[ + SELECT uuid(4, 5); + ]], { + 1, "Wrong number of arguments is passed to UUID(): expected one or zero, got 2" + }) + +-- Make sure the uuid() function generates a new UUID each time when called. +test:do_execsql_test( + "uuid-16.6", + [[ + SELECT uuid() != uuid(); + ]], { + true + }) + test:execsql([[ DROP TRIGGER t; DROP VIEW v; diff --git a/test/wal_off/func_max.result b/test/wal_off/func_max.result index 78db38d6b..cc5bcc141 100644 --- a/test/wal_off/func_max.result +++ b/test/wal_off/func_max.result @@ -42,11 +42,11 @@ test_run:cmd("setopt delimiter ''"); ... func_limit() --- -- error: 'Failed to create function ''func31934'': function id is too big' +- error: 'Failed to create function ''func31933'': function id is too big' ... drop_limit_func() --- -- error: Function 'func31934' does not exist +- error: Function 'func31933' does not exist ... box.schema.user.create('testuser') --- @@ -62,11 +62,11 @@ session.su('testuser') ... func_limit() --- -- error: 'Failed to create function ''func31934'': function id is too big' +- error: 'Failed to create function ''func31933'': function id is too big' ... drop_limit_func() --- -- error: Function 'func31934' does not exist +- error: Function 'func31933' does not exist ... session.su('admin') --- -- 2.25.1