diff --git a/src/box/iproto.cc b/src/box/iproto.cc index f313af6aec8f06654ba5d74fffa65aeb8693c9e6..f31738cb03e7e160bd98473cb7adcf489ed423c7 100644 --- a/src/box/iproto.cc +++ b/src/box/iproto.cc @@ -1780,21 +1780,24 @@ tx_process_sql(struct cmsg *m) * become out of date during yield. */ out = msg->connection->tx.p_obuf; + if (is_unprepare) { + if (iproto_reply_ok(out, msg->header.sync, schema_version) != 0) + goto error; + iproto_wpos_create(&msg->wpos, out); + return; + } struct obuf_svp header_svp; /* Prepare memory for the iproto header. */ if (iproto_prepare_header(out, &header_svp, IPROTO_HEADER_LEN) != 0) { port_destroy(&port); goto error; } - /* Nothing to dump in case of UNPREPARE request. */ - if (!is_unprepare) { - if (port_dump_msgpack(&port, out) != 0) { - port_destroy(&port); - obuf_rollback_to_svp(out, &header_svp); - goto error; - } + if (port_dump_msgpack(&port, out) != 0) { port_destroy(&port); + obuf_rollback_to_svp(out, &header_svp); + goto error; } + port_destroy(&port); iproto_reply_sql(out, &header_svp, msg->header.sync, schema_version); iproto_wpos_create(&msg->wpos, out); return; diff --git a/test/box/gh-4769-unprepare-response-body.result b/test/box/gh-4769-unprepare-response-body.result new file mode 100644 index 0000000000000000000000000000000000000000..96e234b9b1df2046eef89f3e5b590a0f2f68ab4b --- /dev/null +++ b/test/box/gh-4769-unprepare-response-body.result @@ -0,0 +1,64 @@ +-- test-run result file version 2 +net_box = require('net.box') + | --- + | ... +msgpack = require('msgpack') + | --- + | ... +urilib = require('uri') + | --- + | ... + +IPROTO_REQUEST_TYPE = 0x00 + | --- + | ... +IPROTO_PREPARE = 13 + | --- + | ... +IPROTO_SQL_TEXT = 0x40 + | --- + | ... +IPROTO_STMT_ID = 0x43 + | --- + | ... + +box.schema.user.grant('guest', 'read, write, execute', 'universe') + | --- + | ... +uri = urilib.parse(box.cfg.listen) + | --- + | ... +socket = net_box.establish_connection(uri.host, uri.service) + | --- + | ... + +header = { [IPROTO_REQUEST_TYPE] = IPROTO_PREPARE } + | --- + | ... +body = { [IPROTO_SQL_TEXT] = 'SELECT 1' } + | --- + | ... +response = iproto_request(socket, header, body) + | --- + | ... + +body = { [IPROTO_STMT_ID] = response['body'][IPROTO_STMT_ID] } + | --- + | ... +-- Decoding of the response will fail if there's no body. +response = iproto_request(socket, header, body) + | --- + | ... +response.body + | --- + | - {} + | ... + +box.schema.user.revoke('guest', 'read, write, execute', 'universe') + | --- + | ... +socket:close() + | --- + | - true + | ... + diff --git a/test/box/gh-4769-unprepare-response-body.test.lua b/test/box/gh-4769-unprepare-response-body.test.lua new file mode 100644 index 0000000000000000000000000000000000000000..9b530220191ac5748fd046e0d3c76f77c60f114b --- /dev/null +++ b/test/box/gh-4769-unprepare-response-body.test.lua @@ -0,0 +1,25 @@ +net_box = require('net.box') +msgpack = require('msgpack') +urilib = require('uri') + +IPROTO_REQUEST_TYPE = 0x00 +IPROTO_PREPARE = 13 +IPROTO_SQL_TEXT = 0x40 +IPROTO_STMT_ID = 0x43 + +box.schema.user.grant('guest', 'read, write, execute', 'universe') +uri = urilib.parse(box.cfg.listen) +socket = net_box.establish_connection(uri.host, uri.service) + +header = { [IPROTO_REQUEST_TYPE] = IPROTO_PREPARE } +body = { [IPROTO_SQL_TEXT] = 'SELECT 1' } +response = iproto_request(socket, header, body) + +body = { [IPROTO_STMT_ID] = response['body'][IPROTO_STMT_ID] } +-- Decoding of the response will fail if there's no body. +response = iproto_request(socket, header, body) +response.body + +box.schema.user.revoke('guest', 'read, write, execute', 'universe') +socket:close() +