diff --git a/src/box/bind.c b/src/box/bind.c
index af9f9eac54c491e16f142f786e27eaf6b381ecb0..441c9f46fff062b64fd54f9749cc94ee87d81c43 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 71d4d7faed03e0f475de4ba3322b0e551da09135..b3f81d709fb962f877302295551ac7eb2dbf1c1e 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 716110edc69b58c1fb7babf0023819da81be5c98..0db16b293c593c84ad878fcecfed4976c5fa61c1 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 3ea155d17bce81119f44e7a7351cb74432675e49..060846572f4769b05b9e9c109d421d91e54649ab 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 1afbb2b1de600157645a7d66b1e3bc1b8fb48519..8cdbb16629b3235fba61218d94319bd44efb5f53 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 f269056e22c98715baaf1ccdfddd0c45f436a89d..e738a91cda8f80ccc0ddfda469a813bdaa47ca0d 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.
 --