[Tarantool-patches] [PATCH V3 5/7] error: add session setting for error type marshaling
Leonid Vasiliev
lvasiliev at tarantool.org
Wed Apr 15 12:32:00 MSK 2020
Errors are encoded as a string when serialized to MessagePack to
be sent over IProto or when just saved into a buffer via Lua
modules msgpackffi and msgpack.
That is not very useful on client-side, because most of the error
metadata is lost: code, type, trace - everything except the
message.
Next commits are going to dedicate a new MP_EXT type to error
objects so as everything could be encoded, and on client side it
would be possible to restore types.
But this is a breaking change in case some users use old
connectors when work with newer Tarantool instances. So to smooth
the upgrade there is a new session setting -
'error_marshaling_enabled'.
By default it is false. When it is true, all fibers of the given
session will serialize error objects as MP_EXT.
Co-authored-by: Vladislav Shpilevoy<v.shpilevoy at tarantool.org>
Needed for #4398
---
src/box/lua/call.c | 33 ++++++++++++++---------
src/box/lua/execute.c | 2 +-
src/box/lua/tuple.c | 12 ++++-----
src/box/session.cc | 5 +++-
src/box/session.h | 5 ++--
src/box/session_settings.c | 56 ++++++++++++++++++++++++++++++++++++++++
src/box/session_settings.h | 1 +
src/box/sql/func.c | 4 ++-
src/lua/msgpack.c | 25 +++++++++---------
src/lua/msgpack.h | 8 +++---
src/lua/utils.c | 11 +++++---
src/lua/utils.h | 8 ++++--
src/serializer_opts.h | 44 +++++++++++++++++++++++++++++++
test/box/session_settings.result | 3 ++-
14 files changed, 172 insertions(+), 45 deletions(-)
create mode 100644 src/serializer_opts.h
diff --git a/src/box/lua/call.c b/src/box/lua/call.c
index 1d29494..91e291c 100644
--- a/src/box/lua/call.c
+++ b/src/box/lua/call.c
@@ -46,6 +46,7 @@
#include "small/obuf.h"
#include "trivia/util.h"
#include "mpstream/mpstream.h"
+#include "box/session.h"
/**
* A helper to find a Lua function by name and put it
@@ -174,7 +175,7 @@ luamp_encode_call_16(lua_State *L, struct luaL_serializer *cfg,
*/
for (int i = 1; i <= nrets; ++i) {
struct luaL_field field;
- if (luaL_tofield(L, cfg, i, &field) < 0)
+ if (luaL_tofield(L, cfg, NULL, i, &field) < 0)
return luaT_error(L);
struct tuple *tuple;
if (field.type == MP_EXT &&
@@ -188,11 +189,11 @@ luamp_encode_call_16(lua_State *L, struct luaL_serializer *cfg,
*/
lua_pushvalue(L, i);
mpstream_encode_array(stream, 1);
- luamp_encode_r(L, cfg, stream, &field, 0);
+ luamp_encode_r(L, cfg, NULL, stream, &field, 0);
lua_pop(L, 1);
} else {
/* `return ..., array, ...` */
- luamp_encode(L, cfg, stream, i);
+ luamp_encode(L, cfg, NULL, stream, i);
}
}
return nrets;
@@ -203,7 +204,7 @@ luamp_encode_call_16(lua_State *L, struct luaL_serializer *cfg,
* Inspect the first result
*/
struct luaL_field root;
- if (luaL_tofield(L, cfg, 1, &root) < 0)
+ if (luaL_tofield(L, cfg, NULL, 1, &root) < 0)
return luaT_error(L);
struct tuple *tuple;
if (root.type == MP_EXT && (tuple = luaT_istuple(L, 1)) != NULL) {
@@ -217,7 +218,7 @@ luamp_encode_call_16(lua_State *L, struct luaL_serializer *cfg,
*/
mpstream_encode_array(stream, 1);
assert(lua_gettop(L) == 1);
- luamp_encode_r(L, cfg, stream, &root, 0);
+ luamp_encode_r(L, cfg, NULL, stream, &root, 0);
return 1;
}
@@ -233,7 +234,7 @@ luamp_encode_call_16(lua_State *L, struct luaL_serializer *cfg,
for (uint32_t t = 1; t <= root.size; t++) {
lua_rawgeti(L, 1, t);
struct luaL_field field;
- if (luaL_tofield(L, cfg, -1, &field) < 0)
+ if (luaL_tofield(L, cfg, NULL, -1, &field) < 0)
return luaT_error(L);
if (field.type == MP_EXT && (tuple = luaT_istuple(L, -1))) {
tuple_to_mpstream(tuple, stream);
@@ -249,13 +250,13 @@ luamp_encode_call_16(lua_State *L, struct luaL_serializer *cfg,
* Encode the first field of tuple using
* existing information from luaL_tofield
*/
- luamp_encode_r(L, cfg, stream, &field, 0);
+ luamp_encode_r(L, cfg, NULL, stream, &field, 0);
lua_pop(L, 1);
assert(lua_gettop(L) == 1);
/* Encode remaining fields as usual */
for (uint32_t f = 2; f <= root.size; f++) {
lua_rawgeti(L, 1, f);
- luamp_encode(L, cfg, stream, -1);
+ luamp_encode(L, cfg, NULL, stream, -1);
lua_pop(L, 1);
}
return 1;
@@ -265,10 +266,10 @@ luamp_encode_call_16(lua_State *L, struct luaL_serializer *cfg,
* { tuple/array, ..., { scalar }, ... }`
*/
mpstream_encode_array(stream, 1);
- luamp_encode_r(L, cfg, stream, &field, 0);
+ luamp_encode_r(L, cfg, NULL, stream, &field, 0);
} else {
/* `return { tuple/array, ..., tuple/array, ... }` */
- luamp_encode_r(L, cfg, stream, &field, 0);
+ luamp_encode_r(L, cfg, NULL, stream, &field, 0);
}
lua_pop(L, 1);
assert(lua_gettop(L) == 1);
@@ -379,6 +380,11 @@ execute_lua_eval(lua_State *L)
struct encode_lua_ctx {
struct port_lua *port;
struct mpstream *stream;
+ /*
+ * Lua serializer additional options.
+ * Used for sets the session specific serialization options.
+ */
+ struct serializer_opts *serializer_opts;
};
static int
@@ -393,8 +399,10 @@ encode_lua_call(lua_State *L)
*/
struct luaL_serializer *cfg = luaL_msgpack_default;
int size = lua_gettop(ctx->port->L);
- for (int i = 1; i <= size; ++i)
- luamp_encode(ctx->port->L, cfg, ctx->stream, i);
+ for (int i = 1; i <= size; ++i) {
+ luamp_encode(ctx->port->L, cfg, ctx->serializer_opts,
+ ctx->stream, i);
+ }
ctx->port->size = size;
mpstream_flush(ctx->stream);
return 0;
@@ -429,6 +437,7 @@ port_lua_do_dump(struct port *base, struct mpstream *stream,
struct encode_lua_ctx ctx;
ctx.port = port;
ctx.stream = stream;
+ ctx.serializer_opts = ¤t_session()->meta.serializer_opts;
struct lua_State *L = tarantool_L;
int top = lua_gettop(L);
if (lua_cpcall(L, handler, &ctx) != 0) {
diff --git a/src/box/lua/execute.c b/src/box/lua/execute.c
index b4843b2..b5db3c9 100644
--- a/src/box/lua/execute.c
+++ b/src/box/lua/execute.c
@@ -328,7 +328,7 @@ lua_sql_bind_decode(struct lua_State *L, struct sql_bind *bind, int idx, int i)
bind->name = NULL;
bind->name_len = 0;
}
- if (luaL_tofield(L, luaL_msgpack_default, -1, &field) < 0)
+ if (luaL_tofield(L, luaL_msgpack_default, NULL, -1, &field) < 0)
return -1;
switch (field.type) {
case MP_UINT:
diff --git a/src/box/lua/tuple.c b/src/box/lua/tuple.c
index 4b0701e..aba906d 100644
--- a/src/box/lua/tuple.c
+++ b/src/box/lua/tuple.c
@@ -120,7 +120,7 @@ luaT_tuple_new(struct lua_State *L, int idx, box_tuple_format_t *format)
int argc = lua_gettop(L);
mpstream_encode_array(&stream, argc);
for (int k = 1; k <= argc; ++k) {
- luamp_encode(L, luaL_msgpack_default, &stream, k);
+ luamp_encode(L, luaL_msgpack_default, NULL, &stream, k);
}
} else {
/* Create the tuple from a Lua table. */
@@ -252,18 +252,18 @@ luamp_convert_key(struct lua_State *L, struct luaL_serializer *cfg,
return tuple_to_mpstream(tuple, stream);
struct luaL_field field;
- if (luaL_tofield(L, cfg, index, &field) < 0)
+ if (luaL_tofield(L, cfg, NULL, index, &field) < 0)
luaT_error(L);
if (field.type == MP_ARRAY) {
lua_pushvalue(L, index);
- luamp_encode_r(L, cfg, stream, &field, 0);
+ luamp_encode_r(L, cfg, NULL, stream, &field, 0);
lua_pop(L, 1);
} else if (field.type == MP_NIL) {
mpstream_encode_array(stream, 0);
} else {
mpstream_encode_array(stream, 1);
lua_pushvalue(L, index);
- luamp_encode_r(L, cfg, stream, &field, 0);
+ luamp_encode_r(L, cfg, NULL, stream, &field, 0);
lua_pop(L, 1);
}
}
@@ -275,7 +275,7 @@ luamp_encode_tuple(struct lua_State *L, struct luaL_serializer *cfg,
struct tuple *tuple = luaT_istuple(L, index);
if (tuple != NULL) {
return tuple_to_mpstream(tuple, stream);
- } else if (luamp_encode(L, cfg, stream, index) != MP_ARRAY) {
+ } else if (luamp_encode(L, cfg, NULL, stream, index) != MP_ARRAY) {
diag_set(ClientError, ER_TUPLE_NOT_ARRAY);
luaT_error(L);
}
@@ -435,7 +435,7 @@ lbox_tuple_transform(struct lua_State *L)
mpstream_encode_array(&stream, 3);
mpstream_encode_str(&stream, "!");
mpstream_encode_uint(&stream, offset);
- luamp_encode(L, luaL_msgpack_default, &stream, i);
+ luamp_encode(L, luaL_msgpack_default, NULL, &stream, i);
}
mpstream_flush(&stream);
diff --git a/src/box/session.cc b/src/box/session.cc
index b557eed..08a1092 100644
--- a/src/box/session.cc
+++ b/src/box/session.cc
@@ -275,6 +275,9 @@ session_find(uint64_t sid)
mh_i64ptr_node(session_registry, k)->val;
}
+extern "C" void
+session_settings_init(void);
+
void
session_init()
{
@@ -283,7 +286,7 @@ session_init()
panic("out of memory");
mempool_create(&session_pool, &cord()->slabc, sizeof(struct session));
credentials_create(&admin_credentials, admin_user);
- sql_session_settings_init();
+ session_settings_init();
}
void
diff --git a/src/box/session.h b/src/box/session.h
index 8693799..500a88b 100644
--- a/src/box/session.h
+++ b/src/box/session.h
@@ -36,13 +36,12 @@
#include "fiber.h"
#include "user.h"
#include "authentication.h"
+#include "serializer_opts.h"
#if defined(__cplusplus)
extern "C" {
#endif /* defined(__cplusplus) */
-extern void sql_session_settings_init();
-
struct port;
struct session_vtab;
@@ -90,6 +89,8 @@ struct session_meta {
};
/** Console output format. */
enum output_format output_format;
+ /** Session-specific serialization options. */
+ struct serializer_opts serializer_opts;
};
/**
diff --git a/src/box/session_settings.c b/src/box/session_settings.c
index 79c4b8d..dbbbf24 100644
--- a/src/box/session_settings.c
+++ b/src/box/session_settings.c
@@ -42,6 +42,7 @@ struct session_setting session_settings[SESSION_SETTING_COUNT] = {};
/** Corresponding names of session settings. */
const char *session_setting_strs[SESSION_SETTING_COUNT] = {
+ "error_marshaling_enabled",
"sql_default_engine",
"sql_defer_foreign_keys",
"sql_full_column_names",
@@ -449,3 +450,58 @@ session_setting_find(const char *name) {
else
return -1;
}
+
+/* Module independent session settings. */
+
+static void
+session_setting_error_marshaling_enabled_get(int id, const char **mp_pair,
+ const char **mp_pair_end)
+{
+ assert(id == SESSION_SETTING_ERROR_MARSHALING_ENABLED);
+ struct session *session = current_session();
+ const char *name = session_setting_strs[id];
+ size_t name_len = strlen(name);
+ bool value = session->meta.serializer_opts.error_marshaling_enabled;
+ size_t size = mp_sizeof_array(2) + mp_sizeof_str(name_len) +
+ mp_sizeof_bool(value);
+
+ char *pos = (char*)static_alloc(size);
+ assert(pos != NULL);
+ char *pos_end = mp_encode_array(pos, 2);
+ pos_end = mp_encode_str(pos_end, name, name_len);
+ pos_end = mp_encode_bool(pos_end, value);
+ *mp_pair = pos;
+ *mp_pair_end = pos_end;
+}
+
+static int
+session_setting_error_marshaling_enabled_set(int id, const char *mp_value)
+{
+ assert(id == SESSION_SETTING_ERROR_MARSHALING_ENABLED);
+ enum mp_type mtype = mp_typeof(*mp_value);
+ enum field_type stype = session_settings[id].field_type;
+ if (mtype != MP_BOOL) {
+ diag_set(ClientError, ER_SESSION_SETTING_INVALID_VALUE,
+ session_setting_strs[id], field_type_strs[stype]);
+ return -1;
+ }
+ struct session *session = current_session();
+ session->meta.serializer_opts.error_marshaling_enabled =
+ mp_decode_bool(&mp_value);
+ return 0;
+}
+
+extern void
+sql_session_settings_init();
+
+void
+session_settings_init(void)
+{
+ struct session_setting *s =
+ &session_settings[SESSION_SETTING_ERROR_MARSHALING_ENABLED];
+ s->field_type = FIELD_TYPE_BOOLEAN;
+ s->get = session_setting_error_marshaling_enabled_get;
+ s->set = session_setting_error_marshaling_enabled_set;
+
+ sql_session_settings_init();
+}
diff --git a/src/box/session_settings.h b/src/box/session_settings.h
index e2adc52..6560b8c 100644
--- a/src/box/session_settings.h
+++ b/src/box/session_settings.h
@@ -42,6 +42,7 @@
* space iterator will not be sorted properly.
*/
enum {
+ SESSION_SETTING_ERROR_MARSHALING_ENABLED,
SESSION_SETTING_SQL_BEGIN,
SESSION_SETTING_SQL_DEFAULT_ENGINE = SESSION_SETTING_SQL_BEGIN,
SESSION_SETTING_SQL_DEFER_FOREIGN_KEYS,
diff --git a/src/box/sql/func.c b/src/box/sql/func.c
index e3a6e88..3768372 100644
--- a/src/box/sql/func.c
+++ b/src/box/sql/func.c
@@ -257,8 +257,10 @@ port_lua_get_vdbemem(struct port *base, uint32_t *size)
return NULL;
for (int i = 0; i < argc; i++) {
struct luaL_field field;
- if (luaL_tofield(L, luaL_msgpack_default, -1 - i, &field) < 0)
+ if (luaL_tofield(L, luaL_msgpack_default,
+ NULL, -1 - i, &field) < 0) {
goto error;
+ }
switch (field.type) {
case MP_BOOL:
mem_set_bool(&val[i], field.bval);
diff --git a/src/lua/msgpack.c b/src/lua/msgpack.c
index e4fb0cf..b14361f 100644
--- a/src/lua/msgpack.c
+++ b/src/lua/msgpack.c
@@ -109,8 +109,8 @@ luamp_set_decode_extension(luamp_decode_extension_f handler)
enum mp_type
luamp_encode_r(struct lua_State *L, struct luaL_serializer *cfg,
- struct mpstream *stream, struct luaL_field *field,
- int level)
+ struct serializer_opts *opts, struct mpstream *stream,
+ struct luaL_field *field, int level)
{
int top = lua_gettop(L);
enum mp_type type;
@@ -155,13 +155,13 @@ restart: /* used by MP_EXT of unidentified subtype */
lua_pushnil(L); /* first key */
while (lua_next(L, top) != 0) {
lua_pushvalue(L, -2); /* push a copy of key to top */
- if (luaL_tofield(L, cfg, lua_gettop(L), field) < 0)
+ if (luaL_tofield(L, cfg, opts, lua_gettop(L), field) < 0)
return luaT_error(L);
- luamp_encode_r(L, cfg, stream, field, level + 1);
+ luamp_encode_r(L, cfg, opts, stream, field, level + 1);
lua_pop(L, 1); /* pop a copy of key */
- if (luaL_tofield(L, cfg, lua_gettop(L), field) < 0)
+ if (luaL_tofield(L, cfg, opts, lua_gettop(L), field) < 0)
return luaT_error(L);
- luamp_encode_r(L, cfg, stream, field, level + 1);
+ luamp_encode_r(L, cfg, opts, stream, field, level + 1);
lua_pop(L, 1); /* pop value */
}
assert(lua_gettop(L) == top);
@@ -180,9 +180,9 @@ restart: /* used by MP_EXT of unidentified subtype */
mpstream_encode_array(stream, size);
for (uint32_t i = 0; i < size; i++) {
lua_rawgeti(L, top, i + 1);
- if (luaL_tofield(L, cfg, top + 1, field) < 0)
+ if (luaL_tofield(L, cfg, opts, top + 1, field) < 0)
return luaT_error(L);
- luamp_encode_r(L, cfg, stream, field, level + 1);
+ luamp_encode_r(L, cfg, opts, stream, field, level + 1);
lua_pop(L, 1);
}
assert(lua_gettop(L) == top);
@@ -213,7 +213,8 @@ restart: /* used by MP_EXT of unidentified subtype */
enum mp_type
luamp_encode(struct lua_State *L, struct luaL_serializer *cfg,
- struct mpstream *stream, int index)
+ struct serializer_opts *opts, struct mpstream *stream,
+ int index)
{
int top = lua_gettop(L);
if (index < 0)
@@ -225,9 +226,9 @@ luamp_encode(struct lua_State *L, struct luaL_serializer *cfg,
}
struct luaL_field field;
- if (luaL_tofield(L, cfg, lua_gettop(L), &field) < 0)
+ if (luaL_tofield(L, cfg, opts, lua_gettop(L), &field) < 0)
return luaT_error(L);
- enum mp_type top_type = luamp_encode_r(L, cfg, stream, &field, 0);
+ enum mp_type top_type = luamp_encode_r(L, cfg, opts, stream, &field, 0);
if (!on_top) {
lua_remove(L, top + 1); /* remove a value copy */
@@ -369,7 +370,7 @@ lua_msgpack_encode(lua_State *L)
mpstream_init(&stream, buf, ibuf_reserve_cb, ibuf_alloc_cb,
luamp_error, L);
- luamp_encode(L, cfg, &stream, 1);
+ luamp_encode(L, cfg, NULL, &stream, 1);
mpstream_flush(&stream);
if (index > 1) {
diff --git a/src/lua/msgpack.h b/src/lua/msgpack.h
index d0ade30..279e056 100644
--- a/src/lua/msgpack.h
+++ b/src/lua/msgpack.h
@@ -43,6 +43,7 @@ extern "C" {
struct luaL_serializer;
struct mpstream;
+struct serializer_opts;
/**
* Default instance of msgpack serializer (msgpack = require('msgpack')).
@@ -63,12 +64,13 @@ enum { LUAMP_ALLOC_FACTOR = 256 };
/* low-level function needed for execute_lua_call() */
enum mp_type
luamp_encode_r(struct lua_State *L, struct luaL_serializer *cfg,
- struct mpstream *stream, struct luaL_field *field,
- int level);
+ struct serializer_opts *opts, struct mpstream *stream,
+ struct luaL_field *field, int level);
enum mp_type
luamp_encode(struct lua_State *L, struct luaL_serializer *cfg,
- struct mpstream *stream, int index);
+ struct serializer_opts *opts, struct mpstream *stream,
+ int index);
void
luamp_decode(struct lua_State *L, struct luaL_serializer *cfg,
diff --git a/src/lua/utils.c b/src/lua/utils.c
index 667365f..bd320f3 100644
--- a/src/lua/utils.c
+++ b/src/lua/utils.c
@@ -452,7 +452,7 @@ lua_field_inspect_ucdata(struct lua_State *L, struct luaL_serializer *cfg,
lua_pcall(L, 1, 1, 0);
/* replace obj with the unpacked value */
lua_replace(L, idx);
- if (luaL_tofield(L, cfg, idx, field) < 0)
+ if (luaL_tofield(L, cfg, NULL, idx, field) < 0)
luaT_error(L);
} /* else ignore lua_gettable exceptions */
lua_settop(L, top); /* remove temporary objects */
@@ -515,7 +515,7 @@ lua_field_try_serialize(struct lua_State *L)
/* copy object itself */
lua_pushvalue(L, 1);
lua_call(L, 1, 1);
- s->is_error = (luaL_tofield(L, cfg, -1, field) != 0);
+ s->is_error = (luaL_tofield(L, cfg, NULL, -1, field) != 0);
s->is_value_returned = true;
return 1;
}
@@ -641,14 +641,17 @@ lua_field_tostring(struct lua_State *L, struct luaL_serializer *cfg, int idx,
lua_call(L, 1, 1);
lua_replace(L, idx);
lua_settop(L, top);
- if (luaL_tofield(L, cfg, idx, field) < 0)
+ if (luaL_tofield(L, cfg, NULL, idx, field) < 0)
luaT_error(L);
}
int
-luaL_tofield(struct lua_State *L, struct luaL_serializer *cfg, int index,
+luaL_tofield(struct lua_State *L, struct luaL_serializer *cfg,
+ struct serializer_opts *opts, int index,
struct luaL_field *field)
{
+ /* opts will be used for encode MP_ERROR in the future */
+ (void)opts;
if (index < 0)
index = lua_gettop(L) + index + 1;
diff --git a/src/lua/utils.h b/src/lua/utils.h
index 4bc0417..cf9ef76 100644
--- a/src/lua/utils.h
+++ b/src/lua/utils.h
@@ -59,6 +59,8 @@ extern "C" {
#include "lib/core/mp_extension_types.h"
#include "lib/core/decimal.h" /* decimal_t */
+#include "serializer_opts.h"
+
struct lua_State;
struct ibuf;
struct tt_uuid;
@@ -366,6 +368,7 @@ struct luaL_field {
*
* @param L stack
* @param cfg configuration
+ * @param serializer_opts the Lua serializer additional options
* @param index stack index
* @param field conversion result
*
@@ -373,7 +376,8 @@ struct luaL_field {
* @retval -1 Error.
*/
int
-luaL_tofield(struct lua_State *L, struct luaL_serializer *cfg, int index,
+luaL_tofield(struct lua_State *L, struct luaL_serializer *cfg,
+ struct serializer_opts *opts, int index,
struct luaL_field *field);
/**
@@ -412,7 +416,7 @@ static inline void
luaL_checkfield(struct lua_State *L, struct luaL_serializer *cfg, int idx,
struct luaL_field *field)
{
- if (luaL_tofield(L, cfg, idx, field) < 0)
+ if (luaL_tofield(L, cfg, NULL, idx, field) < 0)
luaT_error(L);
if (field->type != MP_EXT || field->ext_type != MP_UNKNOWN_EXTENSION)
return;
diff --git a/src/serializer_opts.h b/src/serializer_opts.h
new file mode 100644
index 0000000..9e2c15e
--- /dev/null
+++ b/src/serializer_opts.h
@@ -0,0 +1,44 @@
+#pragma once
+/*
+ * Copyright 2010-2020, Tarantool AUTHORS, please see AUTHORS file.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/**
+ * Serializer options which can regulate how to serialize
+ * something in scope of one session.
+ */
+struct serializer_opts {
+ /**
+ * When enabled, error objects get their own MP_EXT
+ * MessagePack type and therefore can be type-safely
+ * transmitted over the network.
+ */
+ bool error_marshaling_enabled;
+};
diff --git a/test/box/session_settings.result b/test/box/session_settings.result
index ea6302d..149cc4b 100644
--- a/test/box/session_settings.result
+++ b/test/box/session_settings.result
@@ -52,7 +52,8 @@ s:replace({'sql_defer_foreign_keys', true})
--
s:select()
| ---
- | - - ['sql_default_engine', 'memtx']
+ | - - ['error_marshaling_enabled', false]
+ | - ['sql_default_engine', 'memtx']
| - ['sql_defer_foreign_keys', false]
| - ['sql_full_column_names', false]
| - ['sql_full_metadata', false]
--
2.7.4
More information about the Tarantool-patches
mailing list