Tarantool development patches archive
 help / color / mirror / Atom feed
* [Tarantool-patches] [PATCH v1 1/1] sql: introduce binding for MAP
@ 2021-11-26  7:48 Mergen Imeev via Tarantool-patches
  2021-12-02 23:06 ` Vladislav Shpilevoy via Tarantool-patches
  0 siblings, 1 reply; 4+ messages in thread
From: Mergen Imeev via Tarantool-patches @ 2021-11-26  7:48 UTC (permalink / raw)
  To: v.shpilevoy; +Cc: tarantool-patches

After this patch, MAP values can be used as bind variables. However, due
to the current syntax for binding in Lua, the only possible way is to
use MAP values as the named bind variable.

Part of #4763
---
https://github.com/tarantool/tarantool/issues/4763
https://github.com/tarantool/tarantool/tree/imeevma/gh-4763-bindings-for-map

 src/box/bind.c            |  7 +++----
 src/box/lua/execute.c     |  5 +----
 src/box/sql/sqlInt.h      |  3 +++
 src/box/sql/vdbeapi.c     |  8 ++++++++
 test/sql-tap/map.test.lua | 25 ++++++++++++++++++++++++-
 test/sql/bind.result      |  6 +++++-
 6 files changed, 44 insertions(+), 10 deletions(-)

diff --git a/src/box/bind.c b/src/box/bind.c
index af9f9eac5..441c9f46f 100644
--- a/src/box/bind.c
+++ b/src/box/bind.c
@@ -100,15 +100,12 @@ sql_bind_decode(struct sql_bind *bind, int i, const char **packet)
 		bind->s = mp_decode_bin(packet, &bind->bytes);
 		break;
 	case MP_ARRAY:
+	case MP_MAP:
 	case MP_EXT:
 		bind->s = *packet;
 		mp_next(packet);
 		bind->bytes = *packet - bind->s;
 		break;
-	case MP_MAP:
-		diag_set(ClientError, ER_SQL_BIND_TYPE, "MAP",
-			 sql_bind_name(bind));
-		return -1;
 	default:
 		unreachable();
 	}
@@ -189,6 +186,8 @@ sql_bind_column(struct sql_stmt *stmt, const struct sql_bind *p,
 		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_MAP:
+		return sql_bind_map_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 71d4d7fae..b3f81d709 100644
--- a/src/box/lua/execute.c
+++ b/src/box/lua/execute.c
@@ -386,6 +386,7 @@ 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_MAP:
 	case MP_ARRAY: {
 		size_t used = region_used(region);
 		struct mpstream stream;
@@ -410,10 +411,6 @@ lua_sql_bind_decode(struct lua_State *L, struct sql_bind *bind, int idx, int i)
 		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));
-		return -1;
 	default:
 		unreachable();
 	}
diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h
index 716110edc..0db16b293 100644
--- a/src/box/sql/sqlInt.h
+++ b/src/box/sql/sqlInt.h
@@ -559,6 +559,9 @@ 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_map_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 7349d6ece..74f1a0f7b 100644
--- a/src/box/sql/vdbeapi.c
+++ b/src/box/sql/vdbeapi.c
@@ -532,6 +532,14 @@ sql_bind_array_static(sql_stmt *stmt, int i, const char *str, uint32_t size)
 	return sql_bind_type(vdbe, i, "array");
 }
 
+int
+sql_bind_map_static(sql_stmt *stmt, int i, const char *str, uint32_t size)
+{
+	struct Vdbe *vdbe = (struct Vdbe *)stmt;
+	mem_set_map_static(&vdbe->aVar[i - 1], (char *)str, size);
+	return sql_bind_type(vdbe, i, "map");
+}
+
 int
 sql_bind_uuid(struct sql_stmt *stmt, int i, const struct tt_uuid *uuid)
 {
diff --git a/test/sql-tap/map.test.lua b/test/sql-tap/map.test.lua
index 1afbb2b1d..8cdbb1662 100755
--- a/test/sql-tap/map.test.lua
+++ b/test/sql-tap/map.test.lua
@@ -1,6 +1,6 @@
 #!/usr/bin/env tarantool
 local test = require("sqltester")
-test:plan(110)
+test:plan(112)
 
 box.schema.func.create('M1', {
     language = 'Lua',
@@ -982,6 +982,29 @@ test:do_catchsql_test(
         1, "Failed to execute SQL statement: wrong arguments for function ZEROBLOB()"
     })
 
+-- Make sure that MAP values can be used as a bound variable.
+test:do_test(
+    "builtins-13.1",
+    function()
+        local res = box.execute([[SELECT #a;]], {{['#a'] = {abc = 2, [1] = 3}}})
+        return {res.rows[1][1]}
+    end, {
+        {abc = 2, [1] = 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'] = {abc = 2, [1] = 3}}})
+        return {res.rows[1][1]}
+    end, {
+        {abc = 2, [1] = 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 f269056e2..e738a91cd 100644
--- a/test/sql/bind.result
+++ b/test/sql/bind.result
@@ -276,7 +276,11 @@ parameters[1][':value'] = {kek = 300}
 ...
 execute('SELECT :value', parameters)
 ---
-- error: Bind value type MAP for parameter ':value' is not supported
+- metadata:
+  - name: COLUMN_1
+    type: map
+  rows:
+  - [{'kek': 300}]
 ...
 -- gh-3810: bind values of integer in range up to 2^64 - 1.
 --
-- 
2.25.1


^ permalink raw reply	[flat|nested] 4+ messages in thread
* [Tarantool-patches] [PATCH v1 1/1] sql: introduce binding for MAP
@ 2021-12-15 10:58 Mergen Imeev via Tarantool-patches
  2021-12-16 15:01 ` Kirill Yukhin via Tarantool-patches
  0 siblings, 1 reply; 4+ messages in thread
From: Mergen Imeev via Tarantool-patches @ 2021-12-15 10:58 UTC (permalink / raw)
  To: kyukhin; +Cc: tarantool-patches

After this patch, MAP values can be used as bind variables. However, due
to the current syntax for binding in Lua, the only possible way is to
use MAP values as the named bind variable.

Part of #4763
---
https://github.com/tarantool/tarantool/issues/4763
https://github.com/tarantool/tarantool/tree/imeevma/gh-4763-bindings-for-map

 src/box/bind.c            |  7 +++----
 src/box/lua/execute.c     |  5 +----
 src/box/sql/sqlInt.h      |  3 +++
 src/box/sql/vdbeapi.c     |  8 ++++++++
 test/sql-tap/map.test.lua | 25 ++++++++++++++++++++++++-
 test/sql/bind.result      |  6 +++++-
 6 files changed, 44 insertions(+), 10 deletions(-)

diff --git a/src/box/bind.c b/src/box/bind.c
index af9f9eac5..441c9f46f 100644
--- a/src/box/bind.c
+++ b/src/box/bind.c
@@ -100,15 +100,12 @@ sql_bind_decode(struct sql_bind *bind, int i, const char **packet)
 		bind->s = mp_decode_bin(packet, &bind->bytes);
 		break;
 	case MP_ARRAY:
+	case MP_MAP:
 	case MP_EXT:
 		bind->s = *packet;
 		mp_next(packet);
 		bind->bytes = *packet - bind->s;
 		break;
-	case MP_MAP:
-		diag_set(ClientError, ER_SQL_BIND_TYPE, "MAP",
-			 sql_bind_name(bind));
-		return -1;
 	default:
 		unreachable();
 	}
@@ -189,6 +186,8 @@ sql_bind_column(struct sql_stmt *stmt, const struct sql_bind *p,
 		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_MAP:
+		return sql_bind_map_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 71d4d7fae..b3f81d709 100644
--- a/src/box/lua/execute.c
+++ b/src/box/lua/execute.c
@@ -386,6 +386,7 @@ 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_MAP:
 	case MP_ARRAY: {
 		size_t used = region_used(region);
 		struct mpstream stream;
@@ -410,10 +411,6 @@ lua_sql_bind_decode(struct lua_State *L, struct sql_bind *bind, int idx, int i)
 		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));
-		return -1;
 	default:
 		unreachable();
 	}
diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h
index 716110edc..0db16b293 100644
--- a/src/box/sql/sqlInt.h
+++ b/src/box/sql/sqlInt.h
@@ -559,6 +559,9 @@ 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_map_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 3ea155d17..060846572 100644
--- a/src/box/sql/vdbeapi.c
+++ b/src/box/sql/vdbeapi.c
@@ -532,6 +532,14 @@ sql_bind_array_static(sql_stmt *stmt, int i, const char *str, uint32_t size)
 	return sql_bind_type(vdbe, i, "array");
 }
 
+int
+sql_bind_map_static(sql_stmt *stmt, int i, const char *str, uint32_t size)
+{
+	struct Vdbe *vdbe = (struct Vdbe *)stmt;
+	mem_set_map_static(&vdbe->aVar[i - 1], (char *)str, size);
+	return sql_bind_type(vdbe, i, "map");
+}
+
 int
 sql_bind_uuid(struct sql_stmt *stmt, int i, const struct tt_uuid *uuid)
 {
diff --git a/test/sql-tap/map.test.lua b/test/sql-tap/map.test.lua
index 1afbb2b1d..8cdbb1662 100755
--- a/test/sql-tap/map.test.lua
+++ b/test/sql-tap/map.test.lua
@@ -1,6 +1,6 @@
 #!/usr/bin/env tarantool
 local test = require("sqltester")
-test:plan(110)
+test:plan(112)
 
 box.schema.func.create('M1', {
     language = 'Lua',
@@ -982,6 +982,29 @@ test:do_catchsql_test(
         1, "Failed to execute SQL statement: wrong arguments for function ZEROBLOB()"
     })
 
+-- Make sure that MAP values can be used as a bound variable.
+test:do_test(
+    "builtins-13.1",
+    function()
+        local res = box.execute([[SELECT #a;]], {{['#a'] = {abc = 2, [1] = 3}}})
+        return {res.rows[1][1]}
+    end, {
+        {abc = 2, [1] = 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'] = {abc = 2, [1] = 3}}})
+        return {res.rows[1][1]}
+    end, {
+        {abc = 2, [1] = 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 f269056e2..e738a91cd 100644
--- a/test/sql/bind.result
+++ b/test/sql/bind.result
@@ -276,7 +276,11 @@ parameters[1][':value'] = {kek = 300}
 ...
 execute('SELECT :value', parameters)
 ---
-- error: Bind value type MAP for parameter ':value' is not supported
+- metadata:
+  - name: COLUMN_1
+    type: map
+  rows:
+  - [{'kek': 300}]
 ...
 -- gh-3810: bind values of integer in range up to 2^64 - 1.
 --
-- 
2.25.1


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

end of thread, other threads:[~2021-12-16 15:01 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-26  7:48 [Tarantool-patches] [PATCH v1 1/1] sql: introduce binding for MAP Mergen Imeev via Tarantool-patches
2021-12-02 23:06 ` Vladislav Shpilevoy via Tarantool-patches
2021-12-15 10:58 Mergen Imeev via Tarantool-patches
2021-12-16 15:01 ` Kirill Yukhin via Tarantool-patches

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