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 927796ECE3; Thu, 25 Nov 2021 15:54:37 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 927796ECE3 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1637844877; bh=wqBm5Ytbmj7S3bOMaKjQg7adXDe72vUsi7erzpxgbJY=; h=To:Cc:Date:Subject:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:From; b=pHnRZJWKc2ouGHnrfjCF79wWPYhqN79nv+95Aioy/t4yOp5AYBIDwrRQtPMPSPTa1 tWxC1uSzXazH+9+jtNDlrv6GTYpooavRzNeCWLnHzV7uWrDHgCabWsG20s883fJcT9 AD5ZuFMrT/yFbOdRP0K9mv7CQlXfVT32TYEMfAcc= Received: from smtpng1.i.mail.ru (smtpng1.i.mail.ru [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 258616ECE3 for ; Thu, 25 Nov 2021 15:54:36 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 258616ECE3 Received: by smtpng1.m.smailru.net with esmtpa (envelope-from ) id 1mqEGp-0003F4-A4; Thu, 25 Nov 2021 15:54:35 +0300 To: v.shpilevoy@tarantool.org Cc: tarantool-patches@dev.tarantool.org Date: Thu, 25 Nov 2021 15:54:35 +0300 Message-Id: X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-7564579A: 646B95376F6C166E X-77F55803: 4F1203BC0FB41BD9FE0487E502468146B8787A579DD4BF53754E468A758266C2182A05F5380850402A08D35232CB19A073D6245D1EE983AAC54B3D4091F3D2C319BE90F11B61AF88 X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE7081BBE264C6D7F42EA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F790063736901D4B68B3D4FF8638F802B75D45FF36EB9D2243A4F8B5A6FCA7DBDB1FC311F39EFFDF887939037866D6147AF826D816A0D3080EC340CEA5106A847301906C117882F4460429724CE54428C33FAD305F5C1EE8F4F765FCAA867293B0326636D2E47CDBA5A96583BD4B6F7A4D31EC0BC014FD901B82EE079FA2833FD35BB23D27C277FBC8AE2E8BAA867293B0326636D2E47CDBA5A96583BA9C0B312567BB231DD303D21008E298D5E8D9A59859A8B6B372FE9A2E580EFC725E5C173C3A84C315AF0D0D4FC4FA3D35872C767BF85DA2F004C90652538430E4A6367B16DE6309 X-C1DE0DAB: C20DE7B7AB408E4181F030C43753B8186998911F362727C414F749A5E30D975CFDB0F733DE27E9130F985D9971F05F009412DE4B19E44D8B9C2B6934AE262D3EE7EAB7254005DCED7ECBB8B029842A501E0A4E2319210D9B64D260DF9561598F01A9E91200F654B01098AAFFB0A1231D8E8E86DC7131B365E7726E8460B7C23C X-C8649E89: 4E36BF7865823D7055A7F0CF078B5EC49A30900B95165D34A783A638E01A3CDE2BF10B8A80DF7A8292352ACF516B3D91ACE92D9D6EE9A4346159F3264E9F6B751D7E09C32AA3244C12BCB3DDE829C1D60118FBF351A460B47101BF96129E4011729B2BEF169E0186 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojycNqkYkaYUJpWnPHESkWbQ== X-Mailru-Sender: 689FA8AB762F7393C37E3C1AEC41BA5DC39D4F07319D314BE171F4FC7D6AD63583D72C36FC87018B9F80AB2734326CD2FB559BB5D741EB96352A0ABBE4FDA4210A04DAD6CC59E33667EA787935ED9F1B X-Mras: Ok Subject: [Tarantool-patches] [PATCH v1 1/1] sql: introduce binding for ARRAY 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" After this patch, ARRAY values can be used as bind variables. However, due to the current syntax for binding in Lua, the only possible way is to use ARRAY values as the named bind variable. Part of #4762 --- https://github.com/tarantool/tarantool/issues/4762 https://github.com/tarantool/tarantool/tree/imeevma/gh-4762-bindings-for-array src/box/bind.c | 7 +++---- src/box/lua/execute.c | 32 +++++++++++++++++++++++++++----- src/box/sql/sqlInt.h | 3 +++ src/box/sql/vdbeapi.c | 8 ++++++++ test/sql-tap/array.test.lua | 25 ++++++++++++++++++++++++- test/sql/bind.result | 7 ------- test/sql/bind.test.lua | 2 -- 7 files changed, 65 insertions(+), 19 deletions(-) diff --git a/src/box/bind.c b/src/box/bind.c index e75e36283..af9f9eac5 100644 --- a/src/box/bind.c +++ b/src/box/bind.c @@ -99,15 +99,12 @@ sql_bind_decode(struct sql_bind *bind, int i, const char **packet) case MP_BIN: bind->s = mp_decode_bin(packet, &bind->bytes); break; + case MP_ARRAY: case MP_EXT: bind->s = *packet; mp_next(packet); bind->bytes = *packet - bind->s; break; - case MP_ARRAY: - diag_set(ClientError, ER_SQL_BIND_TYPE, "ARRAY", - sql_bind_name(bind)); - return -1; case MP_MAP: diag_set(ClientError, ER_SQL_BIND_TYPE, "MAP", sql_bind_name(bind)); @@ -190,6 +187,8 @@ sql_bind_column(struct sql_stmt *stmt, const struct sql_bind *p, return sql_bind_null(stmt, pos); case MP_BIN: return sql_bind_bin_static(stmt, pos, p->s, p->bytes); + case MP_ARRAY: + return sql_bind_array_static(stmt, pos, p->s, p->bytes); case MP_EXT: assert(p->ext_type == MP_UUID || p->ext_type == MP_DECIMAL); if (p->ext_type == MP_UUID) diff --git a/src/box/lua/execute.c b/src/box/lua/execute.c index 18a45a5d5..71d4d7fae 100644 --- a/src/box/lua/execute.c +++ b/src/box/lua/execute.c @@ -8,6 +8,8 @@ #include "box/bind.h" #include "box/sql_stmt_cache.h" #include "box/schema.h" +#include "mpstream/mpstream.h" +#include "box/sql/vdbeInt.h" /** * Serialize a description of the prepared statement. @@ -331,6 +333,8 @@ lua_sql_bind_decode(struct lua_State *L, struct sql_bind *bind, int idx, int i) } if (luaL_tofield(L, luaL_msgpack_default, -1, &field) < 0) return -1; + bind->type = field.type; + bind->ext_type = field.ext_type; switch (field.type) { case MP_UINT: bind->u64 = field.ival; @@ -382,10 +386,30 @@ lua_sql_bind_decode(struct lua_State *L, struct sql_bind *bind, int idx, int i) diag_set(ClientError, ER_SQL_BIND_TYPE, "USERDATA", sql_bind_name(bind)); return -1; - case MP_ARRAY: - diag_set(ClientError, ER_SQL_BIND_TYPE, "ARRAY", - sql_bind_name(bind)); + case MP_ARRAY: { + size_t used = region_used(region); + struct mpstream stream; + bool is_error = false; + mpstream_init(&stream, region, region_reserve_cb, + region_alloc_cb, set_encode_error, &is_error); + lua_pushvalue(L, -1); + luamp_encode_r(L, luaL_msgpack_default, &stream, &field, 0); + lua_pop(L, 1); + mpstream_flush(&stream); + if (is_error) { + region_truncate(region, used); + diag_set(OutOfMemory, stream.pos - stream.buf, + "mpstream_flush", "stream"); + return -1; + } + bind->bytes = region_used(region) - used; + bind->s = region_join(region, bind->bytes); + if (bind->s != NULL) + break; + region_truncate(region, used); + diag_set(OutOfMemory, bind->bytes, "region_join", "bind->s"); return -1; + } case MP_MAP: diag_set(ClientError, ER_SQL_BIND_TYPE, "MAP", sql_bind_name(bind)); @@ -393,8 +417,6 @@ lua_sql_bind_decode(struct lua_State *L, struct sql_bind *bind, int idx, int i) default: unreachable(); } - bind->type = field.type; - bind->ext_type = field.ext_type; lua_pop(L, lua_gettop(L) - idx); return 0; } diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h index dcd71e5bd..716110edc 100644 --- a/src/box/sql/sqlInt.h +++ b/src/box/sql/sqlInt.h @@ -556,6 +556,9 @@ sql_bind_str_static(sql_stmt *stmt, int i, const char *str, uint32_t len); int sql_bind_bin_static(sql_stmt *stmt, int i, const char *str, uint32_t size); +int +sql_bind_array_static(sql_stmt *stmt, int i, const char *str, uint32_t size); + int sql_bind_uuid(struct sql_stmt *stmt, int i, const struct tt_uuid *uuid); diff --git a/src/box/sql/vdbeapi.c b/src/box/sql/vdbeapi.c index 3894bb943..7349d6ece 100644 --- a/src/box/sql/vdbeapi.c +++ b/src/box/sql/vdbeapi.c @@ -524,6 +524,14 @@ sql_bind_bin_static(sql_stmt *stmt, int i, const char *str, uint32_t size) return sql_bind_type(vdbe, i, "text"); } +int +sql_bind_array_static(sql_stmt *stmt, int i, const char *str, uint32_t size) +{ + struct Vdbe *vdbe = (struct Vdbe *)stmt; + mem_set_array_static(&vdbe->aVar[i - 1], (char *)str, size); + return sql_bind_type(vdbe, i, "array"); +} + int sql_bind_uuid(struct sql_stmt *stmt, int i, const struct tt_uuid *uuid) { diff --git a/test/sql-tap/array.test.lua b/test/sql-tap/array.test.lua index 752cb24f2..ef8e763a5 100755 --- a/test/sql-tap/array.test.lua +++ b/test/sql-tap/array.test.lua @@ -1,6 +1,6 @@ #!/usr/bin/env tarantool local test = require("sqltester") -test:plan(110) +test:plan(112) box.schema.func.create('A1', { language = 'Lua', @@ -979,6 +979,29 @@ test:do_catchsql_test( 1, "Failed to execute SQL statement: wrong arguments for function ZEROBLOB()" }) +-- Make sure that ARRAY values can be used as bound variable. +test:do_test( + "builtins-13.1", + function() + local res = box.execute([[SELECT #a;]], {{['#a'] = {1, 2, 3}}}) + return {res.rows[1][1]} + end, { + {1, 2, 3} + }) + +local remote = require('net.box') +box.cfg{listen = os.getenv('LISTEN')} +local cn = remote.connect(box.cfg.listen) +test:do_test( + "builtins-13.2", + function() + local res = cn:execute([[SELECT #a;]], {{['#a'] = {1, 2, 3}}}) + return {res.rows[1][1]} + end, { + {1, 2, 3} + }) +cn:close() + box.execute([[DROP TABLE t1;]]) box.execute([[DROP TABLE t;]]) diff --git a/test/sql/bind.result b/test/sql/bind.result index cb0302885..f269056e2 100644 --- a/test/sql/bind.result +++ b/test/sql/bind.result @@ -249,13 +249,6 @@ execute('SELECT ? AS big_uint', {0xefffffffffffffff}) - [17293822569102704640] ... -- Bind incorrect parameters. -ok, err = pcall(execute, 'SELECT ?', { {1, 2, 3} }) ---- -... -ok ---- -- false -... parameters = {} --- ... diff --git a/test/sql/bind.test.lua b/test/sql/bind.test.lua index 2ced7775a..4ad227d95 100644 --- a/test/sql/bind.test.lua +++ b/test/sql/bind.test.lua @@ -82,8 +82,6 @@ execute(sql, parameters) -- suitable method in its bind API. execute('SELECT ? AS big_uint', {0xefffffffffffffff}) -- Bind incorrect parameters. -ok, err = pcall(execute, 'SELECT ?', { {1, 2, 3} }) -ok parameters = {} parameters[1] = {} parameters[1][100] = 200 -- 2.25.1