From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTP id 64E6320626 for ; Thu, 15 Aug 2019 02:09:54 -0400 (EDT) Received: from turing.freelists.org ([127.0.0.1]) by localhost (turing.freelists.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Z65U_PzoTCrB for ; Thu, 15 Aug 2019 02:09:54 -0400 (EDT) Received: from smtp54.i.mail.ru (smtp54.i.mail.ru [217.69.128.34]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTPS id 2758A25DE4 for ; Thu, 15 Aug 2019 02:09:50 -0400 (EDT) Received: by smtp54.i.mail.ru with esmtpa (envelope-from ) id 1hy8xH-0005dF-7i for tarantool-patches@freelists.org; Thu, 15 Aug 2019 09:09:48 +0300 From: =?utf-8?B?0JPQtdC+0YDQs9C40Lkg0JrQuNGA0LjRh9C10L3QutC+?= Subject: [tarantool-patches] Re: [PATCH] triggers: remove exceptions Date: Thu, 15 Aug 2019 09:09:46 +0300 Message-ID: <31962388.LeSfngyRPH@localhost> In-Reply-To: <20190808183057.16684-1-i.kosarev@tarantool.org> References: <20190808183057.16684-1-i.kosarev@tarantool.org> MIME-Version: 1.0 Content-Type: multipart/signed; boundary="nextPart3169611.W46JsgntyF"; micalg="pgp-sha256"; protocol="application/pgp-signature" Sender: tarantool-patches-bounce@freelists.org Errors-to: tarantool-patches-bounce@freelists.org Reply-To: tarantool-patches@freelists.org List-Help: List-Unsubscribe: List-software: Ecartis version 1.0.0 List-Id: tarantool-patches List-Subscribe: List-Owner: List-post: List-Archive: To: tarantool-patches@freelists.org --nextPart3169611.W46JsgntyF Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" On Thursday, August 8, 2019 9:30:57 PM MSK Ilya Kosarev wrote: > Triggers don't throw exceptions any more. Now they have > return codes to report errors. > > Closes #4247 Thanks for the patch. This diff is to big, please consider splitting it to smaller ones. Also there are some comments which should be adjusted after refactoring. > --- > Branch: > https://github.com/tarantool/tarantool/tree/i.kosarev/gh-4247-remove-except > ions-from-triggers Issue: https://github.com/tarantool/tarantool/issues/4247 > > src/box/alter.cc | 2398 +++++++++++++++++++++++------------ > src/box/applier.cc | 18 +- > src/box/ck_constraint.c | 9 +- > src/box/ck_constraint.h | 2 +- > src/box/identifier.h | 10 - > src/box/iproto.cc | 3 +- > src/box/lua/call.c | 5 +- > src/box/lua/sequence.c | 3 +- > src/box/lua/space.cc | 3 +- > src/box/memtx_space.c | 17 +- > src/box/relay.cc | 5 +- > src/box/replication.cc | 101 +- > src/box/replication.h | 2 +- > src/box/schema.cc | 28 +- > src/box/schema.h | 13 +- > src/box/sequence.h | 9 - > src/box/session.cc | 3 +- > src/box/tuple.h | 10 - > src/box/txn.c | 10 +- > src/box/user.cc | 9 +- > src/box/user.h | 14 +- > src/box/vinyl.c | 44 +- > src/lib/core/fiber.c | 3 +- > src/lib/core/trigger.cc | 22 +- > src/lib/core/trigger.h | 2 +- > src/lua/trigger.c | 7 +- > src/main.cc | 3 +- > test/unit/cbus.c | 3 +- > test/unit/swim.c | 6 +- > test/unit/swim_test_utils.c | 3 +- > 30 files changed, 1745 insertions(+), 1020 deletions(-) > > diff --git a/src/box/alter.cc b/src/box/alter.cc > index 4f2e34bf0..923cc19cd 100644 > --- a/src/box/alter.cc > +++ b/src/box/alter.cc > @@ -60,7 +60,7 @@ > > /* {{{ Auxiliary functions and methods. */ > > -static void > +static int > access_check_ddl(const char *name, uint32_t object_id, uint32_t owner_uid, > enum schema_object_type type, enum priv_type priv_type) > { > @@ -71,7 +71,7 @@ access_check_ddl(const char *name, uint32_t object_id, > uint32_t owner_uid, ~has_access); > bool is_owner = owner_uid == cr->uid || cr->uid == ADMIN; > if (access == 0) > - return; /* Access granted. */ > + return 0; /* Access granted. */ > /* Check for specific entity access. */ > struct access *object = entity_access_get(type); > if (object) { > @@ -87,7 +87,7 @@ access_check_ddl(const char *name, uint32_t object_id, > uint32_t owner_uid, * CREATE privilege is required. > */ > if (access == 0 || (is_owner && !(access & (PRIV_U | PRIV_C)))) > - return; /* Access granted. */ > + return 0; /* Access granted. */ > /* > * USAGE can be granted only globally. > */ > @@ -97,10 +97,12 @@ access_check_ddl(const char *name, uint32_t object_id, > uint32_t owner_uid, if (object != NULL) > access &= ~object[cr->auth_token].effective; > if (access == 0) > - return; /* Access granted. */ > + return 0; /* Access granted. */ > } > /* Create a meaningful error message. */ > - struct user *user = user_find_xc(cr->uid); > + struct user *user = user_find(cr->uid); > + if (user == NULL) > + return -1; > const char *object_name; > const char *pname; > if (access & PRIV_U) { > @@ -111,15 +113,15 @@ access_check_ddl(const char *name, uint32_t object_id, > uint32_t owner_uid, object_name = schema_object_name(type); > pname = priv_name(access); > } > - tnt_raise(AccessDeniedError, pname, object_name, name, > - user->def->name); > + diag_set(AccessDeniedError, pname, object_name, name, user->def- >name); > + return -1; > } > > /** > * Throw an exception if the given index definition > * is incompatible with a sequence. > */ > -static void > +static int > index_def_check_sequence(struct index_def *index_def, uint32_t > sequence_fieldno, const char *sequence_path, uint32_t sequence_path_len, > const char *space_name) > @@ -140,16 +142,19 @@ index_def_check_sequence(struct index_def *index_def, > uint32_t sequence_fieldno, } > } > if (sequence_part == NULL) { > - tnt_raise(ClientError, ER_MODIFY_INDEX, index_def- >name, > + diag_set(ClientError, ER_MODIFY_INDEX, index_def->name, > space_name, "sequence field must be a part of " > "the index"); > + return -1; > } > enum field_type type = sequence_part->type; > if (type != FIELD_TYPE_UNSIGNED && type != FIELD_TYPE_INTEGER) { > - tnt_raise(ClientError, ER_MODIFY_INDEX, index_def- >name, > + diag_set(ClientError, ER_MODIFY_INDEX, index_def->name, > space_name, "sequence cannot be used with " > "a non-integer key"); > + return -1; > } > + return 0; > } > > /** > @@ -157,7 +162,7 @@ index_def_check_sequence(struct index_def *index_def, > uint32_t sequence_fieldno, * Checks tuple (of _index space) and throws a > nice error if it is invalid * Checks only types of fields and their count! > */ > -static void > +static int > index_def_check_tuple(struct tuple *tuple) > { > const mp_type common_template[] = > @@ -173,7 +178,7 @@ index_def_check_tuple(struct tuple *tuple) > goto err; > mp_next(&data); > } > - return; > + return 0; > > err: > char got[DIAG_ERRMSG_MAX]; > @@ -184,51 +189,58 @@ err: > mp_next(&data); > p += snprintf(p, e - p, i ? ", %s" : "%s", mp_type_strs[type]); > } > - tnt_raise(ClientError, ER_WRONG_INDEX_RECORD, got, > + diag_set(ClientError, ER_WRONG_INDEX_RECORD, got, > "space id (unsigned), index id (unsigned), name (string), "\ > "type (string), options (map), parts (array)"); > + return -1; > } > > /** > * Fill index_opts structure from opts field in tuple of space _index > * Throw an error is unrecognized option. > */ > -static void > +static int > index_opts_decode(struct index_opts *opts, const char *map, > struct region *region) > { > index_opts_create(opts); > if (opts_decode(opts, index_opts_reg, &map, ER_WRONG_INDEX_OPTIONS, > BOX_INDEX_FIELD_OPTS, region) != 0) > - diag_raise(); > + return -1; > if (opts->distance == rtree_index_distance_type_MAX) { > - tnt_raise(ClientError, ER_WRONG_INDEX_OPTIONS, > + diag_set(ClientError, ER_WRONG_INDEX_OPTIONS, > BOX_INDEX_FIELD_OPTS, "distance must be either "\ > "'euclid' or 'manhattan'"); > + return -1; > } > if (opts->page_size <= 0 || (opts->range_size > 0 && > opts->page_size > opts- >range_size)) { > - tnt_raise(ClientError, ER_WRONG_INDEX_OPTIONS, > + diag_set(ClientError, ER_WRONG_INDEX_OPTIONS, > BOX_INDEX_FIELD_OPTS, > "page_size must be greater than 0 and " > "less than or equal to range_size"); > + return -1; > } > if (opts->run_count_per_level <= 0) { > - tnt_raise(ClientError, ER_WRONG_INDEX_OPTIONS, > + diag_set(ClientError, ER_WRONG_INDEX_OPTIONS, > BOX_INDEX_FIELD_OPTS, > "run_count_per_level must be greater than 0"); > + return -1; > } > if (opts->run_size_ratio <= 1) { > - tnt_raise(ClientError, ER_WRONG_INDEX_OPTIONS, > + diag_set(ClientError, ER_WRONG_INDEX_OPTIONS, > BOX_INDEX_FIELD_OPTS, > "run_size_ratio must be greater than 1"); > + return -1; > } > if (opts->bloom_fpr <= 0 || opts->bloom_fpr > 1) { > - tnt_raise(ClientError, ER_WRONG_INDEX_OPTIONS, > + diag_set(ClientError, ER_WRONG_INDEX_OPTIONS, > BOX_INDEX_FIELD_OPTS, > "bloom_fpr must be greater than 0 and " > "less than or equal to 1"); > + return -1; > } > + return 0; > } > > /** > @@ -236,16 +248,18 @@ index_opts_decode(struct index_opts *opts, const char > *map, * only a deterministic persistent Lua function may be used in > * functional index for now. > */ > -static void > +static int > func_index_check_func(struct func *func) { > assert(func != NULL); > if (func->def->language != FUNC_LANGUAGE_LUA || > func->def->body == NULL || !func->def->is_deterministic || > !func->def->is_sandboxed) { > - tnt_raise(ClientError, ER_WRONG_INDEX_OPTIONS, 0, > + diag_set(ClientError, ER_WRONG_INDEX_OPTIONS, 0, > "referenced function doesn't satisfy " > "functional index function constraints"); > + return -1; > } > + return 0; > } > > /** > @@ -263,35 +277,48 @@ func_index_check_func(struct func *func) { > static struct index_def * > index_def_new_from_tuple(struct tuple *tuple, struct space *space) > { > - index_def_check_tuple(tuple); > + if (index_def_check_tuple(tuple) != 0) > + return NULL; > > struct index_opts opts; > - uint32_t id = tuple_field_u32_xc(tuple, BOX_INDEX_FIELD_SPACE_ID); > - uint32_t index_id = tuple_field_u32_xc(tuple, BOX_INDEX_FIELD_ID); > - enum index_type type = > - STR2ENUM(index_type, tuple_field_cstr_xc(tuple, > - BOX_INDEX_FIELD_TYPE)); > + uint32_t id; > + if (tuple_field_u32(tuple, BOX_INDEX_FIELD_SPACE_ID, &id) != 0) > + return NULL; > + uint32_t index_id; > + if (tuple_field_u32(tuple, BOX_INDEX_FIELD_ID, &index_id) != 0) > + return NULL; > + const char *out = tuple_field_cstr(tuple, BOX_INDEX_FIELD_TYPE); > + if (out == NULL) > + return NULL; > + enum index_type type = STR2ENUM(index_type, out); > uint32_t name_len; > - const char *name = tuple_field_str_xc(tuple, BOX_INDEX_FIELD_NAME, > + const char *name = tuple_field_str(tuple, BOX_INDEX_FIELD_NAME, > &name_len); > - const char *opts_field = > - tuple_field_with_type_xc(tuple, BOX_INDEX_FIELD_OPTS, > - MP_MAP); > - index_opts_decode(&opts, opts_field, &fiber()->gc); > + if (name == NULL) > + return NULL; > + const char *opts_field = tuple_field_with_type(tuple, > + BOX_INDEX_FIELD_OPTS, MP_MAP); > + if (opts_field == NULL) > + return NULL; > + if (index_opts_decode(&opts, opts_field, &fiber()->gc) != 0) > + return NULL; > const char *parts = tuple_field(tuple, BOX_INDEX_FIELD_PARTS); > uint32_t part_count = mp_decode_array(&parts); > if (name_len > BOX_NAME_MAX) { > - tnt_raise(ClientError, ER_MODIFY_INDEX, > + diag_set(ClientError, ER_MODIFY_INDEX, > tt_cstr(name, BOX_INVALID_NAME_MAX), > space_name(space), "index name is too long"); > + return NULL; > } > - identifier_check_xc(name, name_len); > + if (identifier_check(name, name_len) != 0) > + return NULL; > struct key_def *key_def = NULL; > struct key_part_def *part_def = (struct key_part_def *) > malloc(sizeof(*part_def) * part_count); > if (part_def == NULL) { > - tnt_raise(OutOfMemory, sizeof(*part_def) * part_count, > + diag_set(OutOfMemory, sizeof(*part_def) * part_count, > "malloc", "key_part_def"); > + return NULL; > } > auto key_def_guard = make_scoped_guard([&] { > free(part_def); > @@ -301,19 +328,21 @@ index_def_new_from_tuple(struct tuple *tuple, struct > space *space) if (key_def_decode_parts(part_def, part_count, &parts, > space->def->fields, > space->def->field_count, &fiber()- >gc) != 0) > - diag_raise(); > + return NULL; > bool for_func_index = opts.func_id > 0; > key_def = key_def_new(part_def, part_count, for_func_index); > if (key_def == NULL) > - diag_raise(); > + return NULL; > struct index_def *index_def = > index_def_new(id, index_id, name, name_len, type, > &opts, key_def, space_index_key_def(space, 0)); > if (index_def == NULL) > - diag_raise(); > + return NULL; > auto index_def_guard = make_scoped_guard([=] { > index_def_delete(index_def); }); - index_def_check_xc(index_def, > space_name(space)); > - space_check_index_def_xc(space, index_def); > + if (!index_def_is_valid(index_def, space_name(space))) > + return NULL; > + if (space_check_index_def(space, index_def) != 0) > + return NULL; > /* > * In case of functional index definition, resolve a > * function pointer to perform a complete index build > @@ -331,15 +360,17 @@ index_def_new_from_tuple(struct tuple *tuple, struct > space *space) */ > struct func *func = NULL; > if (for_func_index && (func = func_by_id(opts.func_id)) != NULL) { > - func_index_check_func(func); > + if (func_index_check_func(func) != 0) > + return NULL; > index_def_set_func(index_def, func); > } > if (index_def->iid == 0 && space->sequence != NULL) > - index_def_check_sequence(index_def, space- >sequence_fieldno, > + if (index_def_check_sequence(index_def, space- >sequence_fieldno, > space->sequence_path, > space->sequence_path != NULL ? > strlen(space- >sequence_path) : 0, > - space_name(space)); > + space_name(space)) != 0) > + return NULL; > index_def_guard.is_active = false; > return index_def; > } > @@ -348,23 +379,25 @@ index_def_new_from_tuple(struct tuple *tuple, struct > space *space) * Fill space opts from the msgpack stream (MP_MAP field in > the > * tuple). > */ > -static void > +static int > space_opts_decode(struct space_opts *opts, const char *map, > struct region *region) > { > space_opts_create(opts); > if (opts_decode(opts, space_opts_reg, &map, ER_WRONG_SPACE_OPTIONS, > BOX_SPACE_FIELD_OPTS, region) != 0) > - diag_raise(); > + return -1; > if (opts->sql != NULL) { > char *sql = strdup(opts->sql); > if (sql == NULL) { > opts->sql = NULL; > - tnt_raise(OutOfMemory, strlen(opts->sql) + 1, "strdup", > + diag_set(OutOfMemory, strlen(opts->sql) + 1, "strdup", > "sql"); > + return -1; > } > opts->sql = sql; > } > + return 0; > } > > /** > @@ -380,15 +413,16 @@ space_opts_decode(struct space_opts *opts, const char > *map, * @param fieldno Field number to decode. Used in error messages. * > @param region Region to allocate field name. > */ > -static void > +static int > field_def_decode(struct field_def *field, const char **data, > const char *space_name, uint32_t name_len, > uint32_t errcode, uint32_t fieldno, struct region *region) > { > if (mp_typeof(**data) != MP_MAP) { > - tnt_raise(ClientError, errcode, tt_cstr(space_name, name_len), > + diag_set(ClientError, errcode, tt_cstr(space_name, name_len), > tt_sprintf("field %d is not map", > fieldno + TUPLE_INDEX_BASE)); > + return -1; > } > int count = mp_decode_map(data); > *field = field_def_default; > @@ -396,11 +430,12 @@ field_def_decode(struct field_def *field, const char > **data, uint32_t action_literal_len = strlen("nullable_action"); > for (int i = 0; i < count; ++i) { > if (mp_typeof(**data) != MP_STR) { > - tnt_raise(ClientError, errcode, > + diag_set(ClientError, errcode, > tt_cstr(space_name, name_len), > tt_sprintf("field %d format is not map"\ > " with string keys", > fieldno + TUPLE_INDEX_BASE)); > + return -1; > } > uint32_t key_len; > const char *key = mp_decode_str(data, &key_len); > @@ -408,7 +443,7 @@ field_def_decode(struct field_def *field, const char > **data, ER_WRONG_SPACE_FORMAT, > fieldno + TUPLE_INDEX_BASE, region, > true) != 0) > - diag_raise(); > + return -1; > if (is_action_missing && > key_len == action_literal_len && > memcmp(key, "nullable_action", action_literal_len) == 0) > @@ -420,44 +455,51 @@ field_def_decode(struct field_def *field, const char > **data, > : ON_CONFLICT_ACTION_DEFAULT; > > } > if (field->name == NULL) { > - tnt_raise(ClientError, errcode, tt_cstr(space_name, name_len), > + diag_set(ClientError, errcode, tt_cstr(space_name, name_len), > tt_sprintf("field %d name is not specified", > fieldno + TUPLE_INDEX_BASE)); > + return -1; > } > size_t field_name_len = strlen(field->name); > if (field_name_len > BOX_NAME_MAX) { > - tnt_raise(ClientError, errcode, tt_cstr(space_name, name_len), > + diag_set(ClientError, errcode, tt_cstr(space_name, name_len), > tt_sprintf("field %d name is too long", > fieldno + TUPLE_INDEX_BASE)); > + return -1; > } > - identifier_check_xc(field->name, field_name_len); > + if (identifier_check(field->name, field_name_len) != 0) > + return -1; > if (field->type == field_type_MAX) { > - tnt_raise(ClientError, errcode, tt_cstr(space_name, name_len), > + diag_set(ClientError, errcode, tt_cstr(space_name, name_len), > tt_sprintf("field %d has unknown field type", > fieldno + TUPLE_INDEX_BASE)); > + return -1; > } > if (field->nullable_action == on_conflict_action_MAX) { > - tnt_raise(ClientError, errcode, tt_cstr(space_name, name_len), > + diag_set(ClientError, errcode, tt_cstr(space_name, name_len), > tt_sprintf("field %d has unknown field on conflict " > "nullable action", > fieldno + TUPLE_INDEX_BASE)); > + return -1; > } > if (!((field->is_nullable && field->nullable_action == > ON_CONFLICT_ACTION_NONE) > > || (!field->is_nullable > > && field->nullable_action != ON_CONFLICT_ACTION_NONE))) { > - tnt_raise(ClientError, errcode, tt_cstr(space_name, name_len), > + diag_set(ClientError, errcode, tt_cstr(space_name, name_len), > tt_sprintf("field %d has conflicting nullability and " > "nullable action properties", fieldno + > TUPLE_INDEX_BASE)); > + return -1; > } > if (field->coll_id != COLL_NONE && > field->type != FIELD_TYPE_STRING && > field->type != FIELD_TYPE_SCALAR && > field->type != FIELD_TYPE_ANY) { > - tnt_raise(ClientError, errcode, tt_cstr(space_name, name_len), > + diag_set(ClientError, errcode, tt_cstr(space_name, name_len), > tt_sprintf("collation is reasonable only for " > "string, scalar and any fields")); > + return -1; > } > > const char *dv = field->default_value; > @@ -465,8 +507,9 @@ field_def_decode(struct field_def *field, const char > **data, field->default_value_expr = sql_expr_compile(sql_get(), dv, > strlen(dv)); > if (field->default_value_expr == NULL) > - diag_raise(); > + return -1; > } > + return 0; > } > > /** > @@ -479,20 +522,26 @@ field_def_decode(struct field_def *field, const char > **data, * > * @retval Array of fields. > */ > -static struct field_def * > +static int > space_format_decode(const char *data, uint32_t *out_count, > const char *space_name, uint32_t name_len, > - uint32_t errcode, struct region *region) > + uint32_t errcode, struct region *region, struct field_def **fields) > { > /* Type is checked by _space format. */ > assert(mp_typeof(*data) == MP_ARRAY); > uint32_t count = mp_decode_array(&data); > *out_count = count; > - if (count == 0) > - return NULL; > + if (count == 0) { > + *fields = NULL; > + return 0; > + } > size_t size = count * sizeof(struct field_def); > struct field_def *region_defs = > - (struct field_def *) region_alloc_xc(region, size); > + (struct field_def *) region_alloc(region, size); > + if (region_defs == NULL) { > + diag_set(OutOfMemory, size, "region", "new slab"); > + return -1; > + } > /* > * Nullify to prevent a case when decoding will fail in > * the middle and space_def_destroy_fields() below will > @@ -503,11 +552,13 @@ space_format_decode(const char *data, uint32_t > *out_count, space_def_destroy_fields(region_defs, count, false); > }); > for (uint32_t i = 0; i < count; ++i) { > - field_def_decode(®ion_defs[i], &data, space_name, name_len, > - errcode, i, region); > + if (field_def_decode(®ion_defs[i], &data, space_name, name_len, > + errcode, i, region) != 0) > + return -1; > } > fields_guard.is_active = false; > - return region_defs; > + *fields = region_defs; > + return 0; > } > > /** > @@ -518,79 +569,108 @@ space_def_new_from_tuple(struct tuple *tuple, > uint32_t errcode, struct region *region) > { > uint32_t name_len; > - const char *name = > - tuple_field_str_xc(tuple, BOX_SPACE_FIELD_NAME, &name_len); > - if (name_len > BOX_NAME_MAX) > - tnt_raise(ClientError, errcode, > - tt_cstr(name, BOX_INVALID_NAME_MAX), > - "space name is too long"); > - identifier_check_xc(name, name_len); > - uint32_t id = tuple_field_u32_xc(tuple, BOX_SPACE_FIELD_ID); > + const char *name = tuple_field_str(tuple, BOX_SPACE_FIELD_NAME, > + &name_len); > + if (name == NULL) > + return NULL; > + if (name_len > BOX_NAME_MAX) { > + diag_set(ClientError, errcode, > + tt_cstr(name, BOX_INVALID_NAME_MAX), > + "space name is too long"); > + return NULL; > + } > + if (identifier_check(name, name_len) != 0) > + return NULL; > + uint32_t id; > + if (tuple_field_u32(tuple, BOX_SPACE_FIELD_ID, &id) != 0) > + return NULL; > if (id > BOX_SPACE_MAX) { > - tnt_raise(ClientError, errcode, tt_cstr(name, name_len), > + diag_set(ClientError, errcode, tt_cstr(name, name_len), > "space id is too big"); > + return NULL; > } > if (id == 0) { > - tnt_raise(ClientError, errcode, tt_cstr(name, name_len), > + diag_set(ClientError, errcode, tt_cstr(name, name_len), > "space id 0 is reserved"); > + return NULL; > } > - uint32_t uid = tuple_field_u32_xc(tuple, BOX_SPACE_FIELD_UID); > - uint32_t exact_field_count = > - tuple_field_u32_xc(tuple, BOX_SPACE_FIELD_FIELD_COUNT); > + uint32_t uid; > + if (tuple_field_u32(tuple, BOX_SPACE_FIELD_UID, &uid) != 0) > + return NULL; > + uint32_t exact_field_count; > + if (tuple_field_u32(tuple, BOX_SPACE_FIELD_FIELD_COUNT, > + &exact_field_count) != 0) > + return NULL; > uint32_t engine_name_len; > - const char *engine_name = > - tuple_field_str_xc(tuple, BOX_SPACE_FIELD_ENGINE, > - &engine_name_len); > + const char *engine_name = tuple_field_str(tuple, > + BOX_SPACE_FIELD_ENGINE, &engine_name_len); > + if (engine_name == NULL) > + return NULL; > /* > * Engines are compiled-in so their names are known in > * advance to be shorter than names of other identifiers. > */ > if (engine_name_len > ENGINE_NAME_MAX) { > - tnt_raise(ClientError, errcode, tt_cstr(name, name_len), > + diag_set(ClientError, errcode, tt_cstr(name, name_len), > "space engine name is too long"); > + return NULL; > } > - identifier_check_xc(engine_name, engine_name_len); > - struct field_def *fields; > - uint32_t field_count; > + if (identifier_check(engine_name, engine_name_len) != 0) > + return NULL; > /* Check space opts. */ > - const char *space_opts = > - tuple_field_with_type_xc(tuple, BOX_SPACE_FIELD_OPTS, > - MP_MAP); > + const char *space_opts = tuple_field_with_type(tuple, > + BOX_SPACE_FIELD_OPTS, MP_MAP); > + if (space_opts == NULL) > + return NULL; > /* Check space format */ > - const char *format = > - tuple_field_with_type_xc(tuple, BOX_SPACE_FIELD_FORMAT, > - MP_ARRAY); > - fields = space_format_decode(format, &field_count, name, > - name_len, errcode, region); > + const char *format = tuple_field_with_type(tuple, > + BOX_SPACE_FIELD_FORMAT, MP_ARRAY); > + if (format == NULL) > + return NULL; > + struct field_def *fields = NULL; > + uint32_t field_count; > + if (space_format_decode(format, &field_count, name, > + name_len, errcode, region, &fields) != 0) > + return NULL; > auto fields_guard = make_scoped_guard([=] { > space_def_destroy_fields(fields, field_count, false); > }); > if (exact_field_count != 0 && > exact_field_count < field_count) { > - tnt_raise(ClientError, errcode, tt_cstr(name, name_len), > + diag_set(ClientError, errcode, tt_cstr(name, name_len), > "exact_field_count must be either 0 or >= "\ > "formatted field count"); > + return NULL; > } > struct space_opts opts; > - space_opts_decode(&opts, space_opts, region); > + if (space_opts_decode(&opts, space_opts, region) != 0) > + return NULL; > /* > * Currently, only predefined replication groups > * are supported. > */ > if (opts.group_id != GROUP_DEFAULT && > opts.group_id != GROUP_LOCAL) { > - tnt_raise(ClientError, ER_NO_SUCH_GROUP, > + diag_set(ClientError, ER_NO_SUCH_GROUP, > int2str(opts.group_id)); > + return NULL; > + } > + if (opts.is_view && opts.sql == NULL) { > + diag_set(ClientError, ER_VIEW_MISSING_SQL); > + return NULL; > } > - if (opts.is_view && opts.sql == NULL) > - tnt_raise(ClientError, ER_VIEW_MISSING_SQL); > struct space_def *def = > - space_def_new_xc(id, uid, exact_field_count, name, name_len, > + space_def_new(id, uid, exact_field_count, name, name_len, > engine_name, engine_name_len, &opts, fields, > field_count); > + if (def == NULL) > + return NULL; > auto def_guard = make_scoped_guard([=] { space_def_delete(def); }); > - struct engine *engine = engine_find_xc(def->engine_name); > - engine_check_space_def_xc(engine, def); > + struct engine *engine = engine_find(def->engine_name); > + if (engine == NULL) > + return NULL; > + if (engine_check_space_def(engine, def) != 0) > + return NULL; > def_guard.is_active = false; > return def; > } > @@ -625,25 +705,41 @@ space_swap_fk_constraints(struct space *new_space, > struct space *old_space) * True if the space has records identified by key > 'uid'. > * Uses 'iid' index. > */ > -bool > -space_has_data(uint32_t id, uint32_t iid, uint32_t uid) > +int > +space_has_data(uint32_t id, uint32_t iid, uint32_t uid, bool *out) > { > struct space *space = space_by_id(id); > - if (space == NULL) > - return false; > + if (space == NULL) { > + *out = false; > + return 0; > + } > > - if (space_index(space, iid) == NULL) > - return false; > + if (space_index(space, iid) == NULL) { > + *out = false; > + return 0; > + } > + > + if (!space_is_memtx(space)) { > + diag_set(ClientError, ER_UNSUPPORTED, > + space->engine->name, "system data"); > + return -1; > + } > + struct index *index = index_find(space, iid); > + if (index == NULL) > + return -1; > > - struct index *index = index_find_system_xc(space, iid); > char key[6]; > assert(mp_sizeof_uint(BOX_SYSTEM_ID_MIN) <= sizeof(key)); > mp_encode_uint(key, uid); > - struct iterator *it = index_create_iterator_xc(index, ITER_EQ, key, 1); > + struct iterator *it = index_create_iterator(index, ITER_EQ, key, 1); > + if (it == NULL) > + return -1; > IteratorGuard iter_guard(it); > - if (iterator_next_xc(it) != NULL) > - return true; > - return false; > + struct tuple *tuple; > + if (iterator_next(it, &tuple) != 0) > + return -1; > + *out = (tuple != NULL); > + return 0; > } > > /* }}} */ > @@ -707,8 +803,15 @@ public: > static struct trigger * > txn_alter_trigger_new(trigger_f run, void *data) > { > + size_t size = sizeof(struct trigger); > struct trigger *trigger = (struct trigger *) > - region_calloc_object_xc(&in_txn()->region, struct trigger); > + region_aligned_alloc(&in_txn()->region, size, > + alignof(struct trigger)); > + if (trigger == NULL) { > + diag_set(OutOfMemory, size, "region", "new slab"); > + return NULL; > + } > + trigger = (struct trigger *)memset(trigger, 0, size); > trigger->run = run; > trigger->data = data; > trigger->destroy = NULL; > @@ -751,11 +854,20 @@ static struct alter_space * > alter_space_new(struct space *old_space) > { > struct txn *txn = in_txn(); > - struct alter_space *alter = region_calloc_object_xc(&txn->region, > - struct alter_space); > + size_t size = sizeof(struct alter_space); > + struct alter_space *alter = (struct alter_space *) > + region_aligned_alloc(&in_txn()->region, size, > + alignof(struct alter_space)); > + if (alter == NULL) { > + diag_set(OutOfMemory, size, "region", "new slab"); > + return NULL; > + } > + alter = (struct alter_space *)memset(alter, 0, size); > rlist_create(&alter->ops); > alter->old_space = old_space; > - alter->space_def = space_def_dup_xc(alter->old_space->def); > + alter->space_def = space_def_dup(alter->old_space->def); > + if (alter->space_def == NULL) > + return NULL; > if (old_space->format != NULL) > alter->new_min_field_count = old_space->format- >min_field_count; > else > @@ -858,7 +970,7 @@ struct mh_i32_t *AlterSpaceLock::registry; > * of the dropped indexes. > * Replace the old space with a new one in the space cache. > */ > -static void > +static int > alter_space_commit(struct trigger *trigger, void *event) > { > struct txn *txn = (struct txn *) event; > @@ -877,8 +989,13 @@ alter_space_commit(struct trigger *trigger, void > *event) * indexes into their new places. > */ > class AlterSpaceOp *op; > - rlist_foreach_entry(op, &alter->ops, link) > - op->commit(alter, signature); > + try { > + rlist_foreach_entry(op, &alter->ops, link) { > + op->commit(alter, signature); > + } > + } catch (Exception *e) { > + return -1; > + } > > alter->new_space = NULL; /* for alter_space_delete(). */ > /* > @@ -888,6 +1005,7 @@ alter_space_commit(struct trigger *trigger, void > *event) space_delete(alter->old_space); > alter->old_space = NULL; > alter_space_delete(alter); > + return 0; > } > > /** > @@ -898,14 +1016,18 @@ alter_space_commit(struct trigger *trigger, void > *event) * Keep in mind that we may end up here in case of > * alter_space_commit() failure (unlikely) > */ > -static void > +static int > alter_space_rollback(struct trigger *trigger, void * /* event */) > { > struct alter_space *alter = (struct alter_space *) trigger->data; > /* Rollback alter ops */ > class AlterSpaceOp *op; > - rlist_foreach_entry(op, &alter->ops, link) { > - op->rollback(alter); > + try { > + rlist_foreach_entry(op, &alter->ops, link) { > + op->rollback(alter); > + } > + } catch (Exception *e) { > + return -1; > } > /* Rebuild index maps once for all indexes. */ > space_fill_index_map(alter->old_space); > @@ -917,6 +1039,7 @@ alter_space_rollback(struct trigger *trigger, void * /* > event */) space_swap_fk_constraints(alter->new_space, alter->old_space); > space_cache_replace(alter->new_space, alter->old_space); > alter_space_delete(alter); > + return 0; > } > > /** > @@ -968,6 +1091,8 @@ alter_space_do(struct txn_stmt *stmt, struct > alter_space *alter) struct trigger *on_commit, *on_rollback; > on_commit = txn_alter_trigger_new(alter_space_commit, alter); > on_rollback = txn_alter_trigger_new(alter_space_rollback, alter); > + if (on_commit == NULL || on_rollback == NULL) > + diag_raise(); > > /* Create a definition of the new space. */ > space_dump_def(alter->old_space, &alter->key_list); > @@ -1644,12 +1769,13 @@ MoveCkConstraints::rollback(struct alter_space > *alter) /** > * Delete the space. It is already removed from the space cache. > */ > -static void > +static int > on_drop_space_commit(struct trigger *trigger, void *event) > { > (void) event; > struct space *space = (struct space *)trigger->data; > space_delete(space); > + return 0; > } > > /** > @@ -1657,12 +1783,13 @@ on_drop_space_commit(struct trigger *trigger, void > *event) * of all other events happened after the space was removed were > * reverted by the cascading rollback. > */ > -static void > +static int > on_drop_space_rollback(struct trigger *trigger, void *event) > { > (void) event; > struct space *space = (struct space *)trigger->data; > space_cache_replace(NULL, space); > + return 0; > } > > /** > @@ -1672,13 +1799,14 @@ on_drop_space_rollback(struct trigger *trigger, void > *event) * By the time the space is removed, it should be empty: we > * rely on cascading rollback. > */ > -static void > +static int > on_create_space_rollback(struct trigger *trigger, void *event) > { > (void) event; > struct space *space = (struct space *)trigger->data; > space_cache_replace(space, NULL); > space_delete(space); > + return 0; > } > > /** > @@ -1780,12 +1908,13 @@ update_view_references(struct Select *select, int > update_value, * Trigger which is fired to commit creation of new SQL view. > * Its purpose is to release memory of SELECT. > */ > -static void > +static int > on_create_view_commit(struct trigger *trigger, void *event) > { > (void) event; > struct Select *select = (struct Select *)trigger->data; > sql_select_delete(sql_get(), select); > + return 0; > } > > /** > @@ -1793,13 +1922,15 @@ on_create_view_commit(struct trigger *trigger, void > *event) * Decrements view reference counters of dependent spaces and > * releases memory for SELECT. > */ > -static void > +static int > on_create_view_rollback(struct trigger *trigger, void *event) > { > (void) event; > struct Select *select = (struct Select *)trigger->data; > - update_view_references(select, -1, true, NULL); > + if (update_view_references(select, -1, true, NULL) != 0) > + return -1; > sql_select_delete(sql_get(), select); > + return 0; > } > > /** > @@ -1807,12 +1938,13 @@ on_create_view_rollback(struct trigger *trigger, > void *event) * Its purpose is to decrement view reference counters of > * dependent spaces and release memory for SELECT. > */ > -static void > +static int > on_drop_view_commit(struct trigger *trigger, void *event) > { > (void) event; > struct Select *select = (struct Select *)trigger->data; > sql_select_delete(sql_get(), select); > + return 0; > } > > /** > @@ -1820,13 +1952,15 @@ on_drop_view_commit(struct trigger *trigger, void > *event) * Release memory for struct SELECT compiled in > * on_replace_dd_space trigger. > */ > -static void > +static int > on_drop_view_rollback(struct trigger *trigger, void *event) > { > (void) event; > struct Select *select = (struct Select *)trigger->data; > - update_view_references(select, 1, true, NULL); > + if (update_view_references(select, 1, true, NULL) != 0) > + return -1; > sql_select_delete(sql_get(), select); > + return 0; > } > > /** > @@ -1879,7 +2013,7 @@ on_drop_view_rollback(struct trigger *trigger, void > *event) * dynamic space configuration such a check would be particularly * > clumsy, so it is simply not done. > */ > -static void > +static int > on_replace_dd_space(struct trigger * /* trigger */, void *event) > { > struct txn *txn = (struct txn *) event; > @@ -1901,19 +2035,25 @@ on_replace_dd_space(struct trigger * /* trigger */, > void *event) * old_tuple ID field, if old_tuple is set, since UPDATE > * may have changed space id. > */ > - uint32_t old_id = tuple_field_u32_xc(old_tuple ? old_tuple : new_tuple, > - BOX_SPACE_FIELD_ID); > + uint32_t old_id; > + if (tuple_field_u32(old_tuple ? old_tuple : new_tuple, > + BOX_SPACE_FIELD_ID, &old_id) != 0) > + return -1; > struct space *old_space = space_by_id(old_id); > if (new_tuple != NULL && old_space == NULL) { /* INSERT */ > - struct space_def *def = > - space_def_new_from_tuple(new_tuple, ER_CREATE_SPACE, > - region); > - auto def_guard = > - make_scoped_guard([=] { space_def_delete(def); }); > - access_check_ddl(def->name, def->id, def->uid, SC_SPACE, > - PRIV_C); > + struct space_def *def = space_def_new_from_tuple(new_tuple, > + ER_CREATE_SPACE, region); > + if (def == NULL) > + return -1; > + auto def_guard = make_scoped_guard([=] { space_def_delete(def); }); > + if (access_check_ddl(def->name, def->id, def->uid, SC_SPACE, > + PRIV_C) != 0) > + return -1; > RLIST_HEAD(empty_list); > - struct space *space = space_new_xc(def, &empty_list); > + struct space *space; > + space = space_new(def, &empty_list); > + if (space == NULL) > + return -1; > /** > * The new space must be inserted in the space > * cache right away to achieve linearisable > @@ -1937,14 +2077,16 @@ on_replace_dd_space(struct trigger * /* trigger */, > void *event) */ > struct trigger *on_rollback = > txn_alter_trigger_new(on_create_space_rollback, space); > + if (on_rollback == NULL) > + return -1; > txn_stmt_on_rollback(stmt, on_rollback); > if (def->opts.is_view) { > struct Select *select = sql_view_compile(sql_get(), > - def->opts.sql); > + def->opts.sql); > if (select == NULL) > - diag_raise(); > + return -1; > auto select_guard = make_scoped_guard([=] { > - sql_select_delete(sql_get(), select); > + sql_select_delete(sql_get(), select); > }); > const char *disappeared_space; > if (update_view_references(select, 1, false, > @@ -1955,41 +2097,58 @@ on_replace_dd_space(struct trigger * /* trigger */, > void *event) */ > update_view_references(select, -1, false, > &disappeared_space); > - tnt_raise(ClientError, ER_NO_SUCH_SPACE, > + diag_set(ClientError, ER_NO_SUCH_SPACE, > disappeared_space); > + return -1; > } > struct trigger *on_commit_view = > txn_alter_trigger_new(on_create_view_commit, > select); > + if (on_commit_view == NULL) > + return -1; > txn_stmt_on_commit(stmt, on_commit_view); > struct trigger *on_rollback_view = > txn_alter_trigger_new(on_create_view_rollback, > select); > + if (on_rollback_view == NULL) > + return -1; > txn_stmt_on_rollback(stmt, on_rollback_view); > select_guard.is_active = false; > } > } else if (new_tuple == NULL) { /* DELETE */ > - access_check_ddl(old_space->def->name, old_space->def- >id, > - old_space->def->uid, SC_SPACE, PRIV_D); > + if (access_check_ddl(old_space->def->name, old_space- >def->id, > + old_space->def->uid, SC_SPACE, PRIV_D) != 0) > + return -1; > /* Verify that the space is empty (has no indexes) */ > if (old_space->index_count) { > - tnt_raise(ClientError, ER_DROP_SPACE, > + diag_set(ClientError, ER_DROP_SPACE, > space_name(old_space), > "the space has indexes"); > + return -1; > } > - if (schema_find_grants("space", old_space->def->id)) { > - tnt_raise(ClientError, ER_DROP_SPACE, > - space_name(old_space), > - "the space has grants"); > + bool out; > + if (schema_find_grants("space", old_space->def->id, &out) != 0) { > + return -1; > } > - if (space_has_data(BOX_TRUNCATE_ID, 0, old_space->def- >id)) > - tnt_raise(ClientError, ER_DROP_SPACE, > + if (out) { > + diag_set(ClientError, ER_DROP_SPACE, > + space_name(old_space), > + "the space has grants"); > + return -1; > + } > + if (space_has_data(BOX_TRUNCATE_ID, 0, old_space->def- >id, &out) != 0) > + return -1; > + if (out) { > + diag_set(ClientError, ER_DROP_SPACE, > space_name(old_space), > "the space has truncate record"); > + return -1; > + } > if (old_space->def->view_ref_count > 0) { > - tnt_raise(ClientError, ER_DROP_SPACE, > + diag_set(ClientError, ER_DROP_SPACE, > space_name(old_space), > "other views depend on this space"); > + return -1; > } > /* > * No need to check existence of parent keys, > @@ -1998,15 +2157,17 @@ on_replace_dd_space(struct trigger * /* trigger */, > void *event) * one referenced index which can't be dropped > * before constraint itself. > */ > - if (! rlist_empty(&old_space->child_fk_constraint)) { > - tnt_raise(ClientError, ER_DROP_SPACE, > + if (!rlist_empty(&old_space->child_fk_constraint)) { > + diag_set(ClientError, ER_DROP_SPACE, > space_name(old_space), > "the space has foreign key constraints"); > + return -1; > } > if (!rlist_empty(&old_space->ck_constraint)) { > - tnt_raise(ClientError, ER_DROP_SPACE, > + diag_set(ClientError, ER_DROP_SPACE, > space_name(old_space), > "the space has check constraints"); > + return -1; > } > /** > * The space must be deleted from the space > @@ -2022,69 +2183,88 @@ on_replace_dd_space(struct trigger * /* trigger */, > void *event) ++schema_version; > struct trigger *on_commit = > txn_alter_trigger_new(on_drop_space_commit, old_space); > + if (on_commit == NULL) > + return -1; > txn_stmt_on_commit(stmt, on_commit); > struct trigger *on_rollback = > txn_alter_trigger_new(on_drop_space_rollback, old_space); > + if (on_rollback == NULL) > + return -1; > txn_stmt_on_rollback(stmt, on_rollback); > if (old_space->def->opts.is_view) { > - struct Select *select = > - sql_view_compile(sql_get(), > - old_space- >def->opts.sql); > + struct Select *select = sql_view_compile(sql_get(), > + old_space- >def->opts.sql); > if (select == NULL) > - diag_raise(); > + return -1; > auto select_guard = make_scoped_guard([=] { > - sql_select_delete(sql_get(), select); > + sql_select_delete(sql_get(), select); > }); > struct trigger *on_commit_view = > txn_alter_trigger_new(on_drop_view_commit, > select); > + if (on_commit_view == NULL) > + return -1; > txn_stmt_on_commit(stmt, on_commit_view); > struct trigger *on_rollback_view = > txn_alter_trigger_new(on_drop_view_rollback, > select); > + if (on_rollback_view == NULL) > + return -1; > txn_stmt_on_rollback(stmt, on_rollback_view); > update_view_references(select, -1, true, NULL); > select_guard.is_active = false; > } > } else { /* UPDATE, REPLACE */ > assert(old_space != NULL && new_tuple != NULL); > - struct space_def *def = > - space_def_new_from_tuple(new_tuple, ER_ALTER_SPACE, > - region); > - auto def_guard = > - make_scoped_guard([=] { space_def_delete(def); }); > - access_check_ddl(def->name, def->id, def->uid, SC_SPACE, > - PRIV_A); > - if (def->id != space_id(old_space)) > - tnt_raise(ClientError, ER_ALTER_SPACE, > + struct space_def *def = space_def_new_from_tuple(new_tuple, > + ER_ALTER_SPACE, region); > + if (def == NULL) > + return -1; > + auto def_guard = make_scoped_guard([=] { space_def_delete(def); }); > + if (access_check_ddl(def->name, def->id, def->uid, SC_SPACE, > + PRIV_A) != 0) > + return -1; > + if (def->id != space_id(old_space)) { > + diag_set(ClientError, ER_ALTER_SPACE, > space_name(old_space), > "space id is immutable"); > - if (strcmp(def->engine_name, old_space->def- >engine_name) != 0) > - tnt_raise(ClientError, ER_ALTER_SPACE, > + return -1; > + } > + if (strcmp(def->engine_name, old_space->def- >engine_name) != 0) { > + diag_set(ClientError, ER_ALTER_SPACE, > space_name(old_space), > "can not change space engine"); > - if (def->opts.group_id != space_group_id(old_space)) > - tnt_raise(ClientError, ER_ALTER_SPACE, > + return -1; > + } > + if (def->opts.group_id != space_group_id(old_space)) { > + diag_set(ClientError, ER_ALTER_SPACE, > space_name(old_space), > "replication group is immutable"); > - if (def->opts.is_view != old_space->def->opts.is_view) > - tnt_raise(ClientError, ER_ALTER_SPACE, > + return -1; > + } > + if (def->opts.is_view != old_space->def->opts.is_view) { > + diag_set(ClientError, ER_ALTER_SPACE, > space_name(old_space), > "can not convert a space to " > "a view and vice versa"); > + return -1; > + } > if (strcmp(def->name, old_space->def->name) != 0 && > - old_space->def->view_ref_count > 0) > - tnt_raise(ClientError, ER_ALTER_SPACE, > - space_name(old_space), > - "can not rename space which is referenced by " > - "view"); > + old_space->def->view_ref_count > 0) { > + diag_set(ClientError, ER_ALTER_SPACE, > + space_name(old_space), > + "can not rename space which is referenced by " > + "view"); > + return -1; > + } > /* > * Allow change of space properties, but do it > * in WAL-error-safe mode. > */ > struct alter_space *alter = alter_space_new(old_space); > - auto alter_guard = > - make_scoped_guard([=] {alter_space_delete(alter);}); > + if (alter == NULL) > + return -1; > + auto alter_guard = make_scoped_guard([=] { alter_space_delete(alter); }); > /* > * Calculate a new min_field_count. It can be > * changed by resetting space:format(), if an old > @@ -2095,8 +2275,11 @@ on_replace_dd_space(struct trigger * /* trigger */, > void *event) */ > struct key_def **keys; > size_t bsize = old_space->index_count * sizeof(keys[0]); > - keys = (struct key_def **) region_alloc_xc(&fiber()->gc, > - bsize); > + keys = (struct key_def **) region_alloc(&fiber()->gc, bsize); > + if (keys == NULL) { > + diag_set(OutOfMemory, bsize, "region", "new slab"); > + return -1; > + } > for (uint32_t i = 0; i < old_space->index_count; ++i) > keys[i] = old_space->index[i]->def->key_def; > alter->new_min_field_count = > @@ -2112,9 +2295,14 @@ on_replace_dd_space(struct trigger * /* trigger */, > void *event) alter_space_move_indexes(alter, 0, old_space->index_id_max + > 1); /* Remember to update schema_version. */ > (void) new UpdateSchemaVersion(alter); > - alter_space_do(stmt, alter); > + try { > + alter_space_do(stmt, alter); > + } catch (Exception *e) { > + return -1; > + } > alter_guard.is_active = false; > } > + return 0; > } > > /** > @@ -2175,27 +2363,34 @@ index_is_used_by_fk_constraint(struct rlist > *fk_list, uint32_t iid) * for offsets is relinquished to the slab > allocator as tuples > * are modified. > */ > -static void > +static int > on_replace_dd_index(struct trigger * /* trigger */, void *event) > { > struct txn *txn = (struct txn *) event; > struct txn_stmt *stmt = txn_current_stmt(txn); > struct tuple *old_tuple = stmt->old_tuple; > struct tuple *new_tuple = stmt->new_tuple; > - uint32_t id = tuple_field_u32_xc(old_tuple ? old_tuple : new_tuple, > - BOX_INDEX_FIELD_SPACE_ID); > - uint32_t iid = tuple_field_u32_xc(old_tuple ? old_tuple : new_tuple, > - BOX_INDEX_FIELD_ID); > - struct space *old_space = space_cache_find_xc(id); > + uint32_t id, iid; > + if (tuple_field_u32(old_tuple ? old_tuple : new_tuple, > + BOX_INDEX_FIELD_SPACE_ID, &id) != 0) > + return -1; > + if (tuple_field_u32(old_tuple ? old_tuple : new_tuple, > + BOX_INDEX_FIELD_ID, &iid) != 0) > + return -1; > + struct space *old_space = space_cache_find(id); > + if (old_space == NULL) > + return -1; > if (old_space->def->opts.is_view) { > - tnt_raise(ClientError, ER_ALTER_SPACE, space_name(old_space), > + diag_set(ClientError, ER_ALTER_SPACE, space_name(old_space), > "can not add index on a view"); > + return -1; > } > enum priv_type priv_type = new_tuple ? PRIV_C : PRIV_D; > if (old_tuple && new_tuple) > priv_type = PRIV_A; > - access_check_ddl(old_space->def->name, old_space->def->id, > - old_space->def->uid, SC_SPACE, priv_type); > + if (access_check_ddl(old_space->def->name, old_space->def->id, > + old_space->def->uid, SC_SPACE, priv_type) != 0) > + return -1; > struct index *old_index = space_index(old_space, iid); > > /* > @@ -2205,24 +2400,28 @@ on_replace_dd_index(struct trigger * /* trigger */, > void *event) /* > * Dropping the primary key in a system space: off limits. > */ > - if (space_is_system(old_space)) > - tnt_raise(ClientError, ER_LAST_DROP, > + if (space_is_system(old_space)) { > + diag_set(ClientError, ER_LAST_DROP, > space_name(old_space)); > + return -1; > + } > /* > * Can't drop primary key before secondary keys. > */ > if (old_space->index_count > 1) { > - tnt_raise(ClientError, ER_DROP_PRIMARY_KEY, > + diag_set(ClientError, ER_DROP_PRIMARY_KEY, > space_name(old_space)); > + return -1; > } > /* > * Can't drop primary key before space sequence. > */ > if (old_space->sequence != NULL) { > - tnt_raise(ClientError, ER_ALTER_SPACE, > + diag_set(ClientError, ER_ALTER_SPACE, > space_name(old_space), > "can not drop primary key while " > "space sequence exists"); > + return -1; > } > } > > @@ -2231,14 +2430,16 @@ on_replace_dd_index(struct trigger * /* trigger */, > void *event) * A secondary index can not be created without > * a primary key. > */ > - tnt_raise(ClientError, ER_ALTER_SPACE, > + diag_set(ClientError, ER_ALTER_SPACE, > space_name(old_space), > "can not add a secondary key before primary"); > + return -1; > } > > struct alter_space *alter = alter_space_new(old_space); > - auto scoped_guard = > - make_scoped_guard([=] { alter_space_delete(alter); }); > + if (alter == NULL) > + return -1; > + auto scoped_guard = make_scoped_guard([=] { alter_space_delete(alter); }); > > /* > * Handle the following 4 cases: > @@ -2255,9 +2456,10 @@ on_replace_dd_index(struct trigger * /* trigger */, > void *event) */ > if (index_is_used_by_fk_constraint(&old_space- >parent_fk_constraint, > iid)) { > - tnt_raise(ClientError, ER_ALTER_SPACE, > + diag_set(ClientError, ER_ALTER_SPACE, > space_name(old_space), > "can not drop a referenced index"); > + return -1; > } > alter_space_move_indexes(alter, 0, iid); > (void) new DropIndex(alter, old_index); > @@ -2268,6 +2470,8 @@ on_replace_dd_index(struct trigger * /* trigger */, > void *event) CreateIndex *create_index = new CreateIndex(alter); > create_index->new_index_def = > index_def_new_from_tuple(new_tuple, old_space); > + if (create_index->new_index_def == NULL) > + return -1; > index_def_update_optionality(create_index- >new_index_def, > alter- >new_min_field_count); > } > @@ -2275,6 +2479,8 @@ on_replace_dd_index(struct trigger * /* trigger */, > void *event) if (old_index != NULL && new_tuple != NULL) { > struct index_def *index_def; > index_def = index_def_new_from_tuple(new_tuple, old_space); > + if (index_def == NULL) > + return -1; > auto index_def_guard = > make_scoped_guard([=] { index_def_delete(index_def); }); > /* > @@ -2295,10 +2501,12 @@ on_replace_dd_index(struct trigger * /* trigger */, > void *event) */ > struct key_def **keys; > size_t bsize = old_space->index_count * sizeof(keys[0]); > - keys = (struct key_def **) region_alloc_xc(&fiber()->gc, > - bsize); > - for (uint32_t i = 0, j = 0; i < old_space->index_count; > - ++i) { > + keys = (struct key_def **) region_alloc(&fiber()->gc, bsize); > + if (keys == NULL) { > + diag_set(OutOfMemory, bsize, "region", "new slab"); > + return -1; > + } > + for (uint32_t i = 0, j = 0; i < old_space->index_count; ++i) { > struct index_def *d = old_space->index[i]- >def; > if (d->iid != index_def->iid) > keys[j++] = d->key_def; > @@ -2321,9 +2529,10 @@ on_replace_dd_index(struct trigger * /* trigger */, > void *event) index_def)) { > if (index_is_used_by_fk_constraint(&old_space->parent_fk_constraint, > iid)) { > - tnt_raise(ClientError, ER_ALTER_SPACE, > - space_name(old_space), > - "can not alter a referenced index"); > + diag_set(ClientError, ER_ALTER_SPACE, > + space_name(old_space), > + "can not alter a referenced index"); > + return -1; > } > /* > * Operation demands an index rebuild. > @@ -2350,8 +2559,13 @@ on_replace_dd_index(struct trigger * /* trigger */, > void *event) (void) new MoveCkConstraints(alter); > /* Add an op to update schema_version on commit. */ > (void) new UpdateSchemaVersion(alter); > - alter_space_do(stmt, alter); > + try { > + alter_space_do(stmt, alter); > + } catch (Exception *e) { > + return -1; > + } > scoped_guard.is_active = false; > + return 0; > } > > /** > @@ -2365,7 +2579,7 @@ on_replace_dd_index(struct trigger * /* trigger */, > void *event) * This is OK, because a WAL write error implies cascading > * rollback of all transactions following this one. > */ > -static void > +static int > on_replace_dd_truncate(struct trigger * /* trigger */, void *event) > { > struct txn *txn = (struct txn *) event; > @@ -2374,19 +2588,22 @@ on_replace_dd_truncate(struct trigger * /* trigger > */, void *event) > > if (new_tuple == NULL) { > /* Space drop - nothing to do. */ > - return; > + return 0; > } > > - uint32_t space_id = > - tuple_field_u32_xc(new_tuple, BOX_TRUNCATE_FIELD_SPACE_ID); > - struct space *old_space = space_cache_find_xc(space_id); > + uint32_t space_id; > + if (tuple_field_u32(new_tuple, BOX_TRUNCATE_FIELD_SPACE_ID, &space_id) != > 0) + return -1; > + struct space *old_space = space_cache_find(space_id); > + if (old_space == NULL) > + return -1; > > if (stmt->row->type == IPROTO_INSERT) { > /* > * Space creation during initial recovery - > * nothing to do. > */ > - return; > + return 0; > } > > /* > @@ -2394,19 +2611,22 @@ on_replace_dd_truncate(struct trigger * /* trigger > */, void *event) * with internal objects. Since space truncation doesn't > * invoke triggers, we don't permit it for system spaces. > */ > - if (space_is_system(old_space)) > - tnt_raise(ClientError, ER_TRUNCATE_SYSTEM_SPACE, > + if (space_is_system(old_space)) { > + diag_set(ClientError, ER_TRUNCATE_SYSTEM_SPACE, > space_name(old_space)); > + return -1; > + } > > + struct alter_space *alter; > /* > * Check if a write privilege was given, raise an error if not. > */ > - access_check_space_xc(old_space, PRIV_W); > - > - struct alter_space *alter = alter_space_new(old_space); > - auto scoped_guard = > - make_scoped_guard([=] { alter_space_delete(alter); }); > - > + if (access_check_space(old_space, PRIV_W) != 0) > + return -1; > + alter = alter_space_new(old_space); > + if (alter == NULL) > + return -1; > + auto scoped_guard = make_scoped_guard([=] { alter_space_delete(alter); }); > /* > * Modify the WAL header to prohibit > * replication of local & temporary > @@ -2426,14 +2646,19 @@ on_replace_dd_truncate(struct trigger * /* trigger > */, void *event) } > > (void) new MoveCkConstraints(alter); > - alter_space_do(stmt, alter); > + try { > + alter_space_do(stmt, alter); > + } catch (Exception *e) { > + return -1; > + } > scoped_guard.is_active = false; > + return 0; > } > > /* {{{ access control */ > > bool > -user_has_data(struct user *user) > +user_has_data(struct user *user, bool *has_data) > { > uint32_t uid = user->def->uid; > uint32_t spaces[] = { BOX_SPACE_ID, BOX_FUNC_ID, BOX_SEQUENCE_ID, > @@ -2444,18 +2669,26 @@ user_has_data(struct user *user) > */ > uint32_t indexes[] = { 1, 1, 1, 1, 0 }; > uint32_t count = sizeof(spaces)/sizeof(*spaces); > + bool out; > for (uint32_t i = 0; i < count; i++) { > - if (space_has_data(spaces[i], indexes[i], uid)) > - return true; > + if (space_has_data(spaces[i], indexes[i], uid, &out) != 0) > + return -1; > + if (out) { > + *has_data = true; > + return 0; > + } > + } > + if (! user_map_is_empty(&user->users)) { > + *has_data = true; > + return 0; > } > - if (! user_map_is_empty(&user->users)) > - return true; > /* > * If there was a role, the previous check would have > * returned true. > */ > assert(user_map_is_empty(&user->roles)); > - return false; > + *has_data = false; > + return 0; > } > > /** > @@ -2463,7 +2696,7 @@ user_has_data(struct user *user) > * defined, but for now we only support chap-sha1. Get > * password of chap-sha1 from the _user space. > */ > -void > +int > user_def_fill_auth_data(struct user_def *user, const char *auth_data) > { > uint8_t type = mp_typeof(*auth_data); > @@ -2475,13 +2708,14 @@ user_def_fill_auth_data(struct user_def *user, const > char *auth_data) * table may well be encoded as an msgpack array. > * Treat as no data. > */ > - return; > + return 0; > } > if (mp_typeof(*auth_data) != MP_MAP) { > /** Prevent users from making silly mistakes */ > - tnt_raise(ClientError, ER_CREATE_USER, > + diag_set(ClientError, ER_CREATE_USER, > user->name, "invalid password format, " > "use box.schema.user.passwd() to reset password"); > + return -1; > } > uint32_t mech_count = mp_decode_map(&auth_data); > for (uint32_t i = 0; i < mech_count; i++) { > @@ -2498,50 +2732,65 @@ user_def_fill_auth_data(struct user_def *user, const > char *auth_data) } > const char *hash2_base64 = mp_decode_str(&auth_data, &len); > if (len != 0 && len != SCRAMBLE_BASE64_SIZE) { > - tnt_raise(ClientError, ER_CREATE_USER, > + diag_set(ClientError, ER_CREATE_USER, > user->name, "invalid user password"); > + return -1; > } > if (user->uid == GUEST) { > /** Guest user is permitted to have empty password */ > - if (strncmp(hash2_base64, CHAP_SHA1_EMPTY_PASSWORD, len)) > - tnt_raise(ClientError, ER_GUEST_USER_PASSWORD); > + if (strncmp(hash2_base64, CHAP_SHA1_EMPTY_PASSWORD, len)) { > + diag_set(ClientError, ER_GUEST_USER_PASSWORD); > + return -1; > + } > } > > base64_decode(hash2_base64, len, user->hash2, > sizeof(user->hash2)); > break; > } > + return 0; > } > > static struct user_def * > user_def_new_from_tuple(struct tuple *tuple) > { > uint32_t name_len; > - const char *name = tuple_field_str_xc(tuple, BOX_USER_FIELD_NAME, > - &name_len); > + const char *name = tuple_field_str(tuple, BOX_USER_FIELD_NAME, > + &name_len); > + if (name == NULL) > + return NULL; > if (name_len > BOX_NAME_MAX) { > - tnt_raise(ClientError, ER_CREATE_USER, > + diag_set(ClientError, ER_CREATE_USER, > tt_cstr(name, BOX_INVALID_NAME_MAX), > "user name is too long"); > + return NULL; > } > size_t size = user_def_sizeof(name_len); > /* Use calloc: in case user password is empty, fill it with \0 */ > struct user_def *user = (struct user_def *) malloc(size); > - if (user == NULL) > - tnt_raise(OutOfMemory, size, "malloc", "user"); > + if (user == NULL) { > + diag_set(OutOfMemory, size, "malloc", "user"); > + return NULL; > + } > auto def_guard = make_scoped_guard([=] { free(user); }); > - user->uid = tuple_field_u32_xc(tuple, BOX_USER_FIELD_ID); > - user->owner = tuple_field_u32_xc(tuple, BOX_USER_FIELD_UID); > - const char *user_type = > - tuple_field_cstr_xc(tuple, BOX_USER_FIELD_TYPE); > - user->type= schema_object_type(user_type); > + const char *user_type; > + if (tuple_field_u32(tuple, BOX_USER_FIELD_ID, &(user->uid)) != 0) > + return NULL; > + if (tuple_field_u32(tuple, BOX_USER_FIELD_UID, &(user->owner)) != 0) > + return NULL; > + user_type = tuple_field_cstr(tuple, BOX_USER_FIELD_TYPE); > + if (user_type == NULL) > + return NULL; > + user->type = schema_object_type(user_type); > memcpy(user->name, name, name_len); > user->name[name_len] = 0; > if (user->type != SC_ROLE && user->type != SC_USER) { > - tnt_raise(ClientError, ER_CREATE_USER, > + diag_set(ClientError, ER_CREATE_USER, > user->name, "unknown user type"); > + return NULL; > } > - identifier_check_xc(user->name, name_len); > + if (identifier_check(user->name, name_len) != 0) > + return NULL; > /* > * AUTH_DATA field in _user space should contain > * chap-sha1 -> base64_encode(sha1(sha1(password), 0). > @@ -2562,39 +2811,52 @@ user_def_new_from_tuple(struct tuple *tuple) > } else { > is_auth_empty = false; > } > - if (!is_auth_empty && user->type == SC_ROLE) > - tnt_raise(ClientError, ER_CREATE_ROLE, user- >name, > - "authentication data can not be set for a "\ > + if (!is_auth_empty && user->type == SC_ROLE) { > + diag_set(ClientError, ER_CREATE_ROLE, user- >name, > + "authentication data can not be set for a "\ > "role"); > - user_def_fill_auth_data(user, auth_data); > + return NULL; > + } > + if (user_def_fill_auth_data(user, auth_data) != 0) > + return NULL; > } > def_guard.is_active = false; > return user; > } > > -static void > +static int > user_cache_remove_user(struct trigger *trigger, void * /* event */) > { > struct tuple *tuple = (struct tuple *)trigger->data; > - uint32_t uid = tuple_field_u32_xc(tuple, BOX_USER_FIELD_ID); > + uint32_t uid; > + if (tuple_field_u32(tuple, BOX_USER_FIELD_ID, &uid) != 0) > + return -1; > user_cache_delete(uid); > + return 0; > } > > -static void > +static int > user_cache_alter_user(struct trigger *trigger, void * /* event */) > { > struct tuple *tuple = (struct tuple *)trigger->data; > struct user_def *user = user_def_new_from_tuple(tuple); > + if (user == NULL) > + return -1; > auto def_guard = make_scoped_guard([=] { free(user); }); > /* Can throw if, e.g. too many users. */ > - user_cache_replace(user); > + try { > + user_cache_replace(user); > + } catch (Exception *e) { > + return -1; > + } > def_guard.is_active = false; > + return 0; > } > > /** > * A trigger invoked on replace in the user table. > */ > -static void > +static int > on_replace_dd_user(struct trigger * /* trigger */, void *event) > { > struct txn *txn = (struct txn *) event; > @@ -2602,40 +2864,60 @@ on_replace_dd_user(struct trigger * /* trigger */, > void *event) struct tuple *old_tuple = stmt->old_tuple; > struct tuple *new_tuple = stmt->new_tuple; > > - uint32_t uid = tuple_field_u32_xc(old_tuple ? old_tuple : new_tuple, > - BOX_USER_FIELD_ID); > + uint32_t uid; > + if (tuple_field_u32(old_tuple ? old_tuple : new_tuple, > + BOX_USER_FIELD_ID, &uid) != 0) > + return -1; > struct user *old_user = user_by_id(uid); > if (new_tuple != NULL && old_user == NULL) { /* INSERT */ > struct user_def *user = user_def_new_from_tuple(new_tuple); > - access_check_ddl(user->name, user->uid, user->owner, user->type, > - PRIV_C); > + if (user == NULL) > + return -1; > + if (access_check_ddl(user->name, user->uid, user->owner, user->type, > + PRIV_C) != 0) > + return -1; > auto def_guard = make_scoped_guard([=] { free(user); }); > - (void) user_cache_replace(user); > + try { > + (void) user_cache_replace(user); > + } catch (Exception *e) { > + return -1; > + } > def_guard.is_active = false; > struct trigger *on_rollback = > txn_alter_trigger_new(user_cache_remove_user, new_tuple); > + if (on_rollback == NULL) > + return -1; > txn_stmt_on_rollback(stmt, on_rollback); > } else if (new_tuple == NULL) { /* DELETE */ > - access_check_ddl(old_user->def->name, old_user->def- >uid, > - old_user->def->owner, old_user- >def->type, > - PRIV_D); > + if (access_check_ddl(old_user->def->name, old_user->def- >uid, > + old_user->def->owner, old_user->def->type, > + PRIV_D) != 0) > + return -1; > /* Can't drop guest or super user */ > if (uid <= (uint32_t) BOX_SYSTEM_USER_ID_MAX || uid == SUPER) { > - tnt_raise(ClientError, ER_DROP_USER, > + diag_set(ClientError, ER_DROP_USER, > old_user->def->name, > "the user or the role is a system"); > + return -1; > } > /* > * Can only delete user if it has no spaces, > * no functions and no grants. > */ > - if (user_has_data(old_user)) { > - tnt_raise(ClientError, ER_DROP_USER, > - old_user->def->name, "the user has objects"); > + bool has_data; > + if (user_has_data(old_user, &has_data) != 0) { > + return -1; > + } > + if (has_data) { > + diag_set(ClientError, ER_DROP_USER, > + old_user->def->name, "the user has objects"); > + return -1; > } > user_cache_delete(uid); > struct trigger *on_rollback = > txn_alter_trigger_new(user_cache_alter_user, old_tuple); > + if (on_rollback == NULL) > + return -1; > txn_stmt_on_rollback(stmt, on_rollback); > } else { /* UPDATE, REPLACE */ > assert(old_user != NULL && new_tuple != NULL); > @@ -2645,15 +2927,25 @@ on_replace_dd_user(struct trigger * /* trigger */, > void *event) * correct. > */ > struct user_def *user = user_def_new_from_tuple(new_tuple); > - access_check_ddl(user->name, user->uid, user->uid, > - old_user->def->type, PRIV_A); > + if (user == NULL) > + return -1; > + if (access_check_ddl(user->name, user->uid, user->uid, > + old_user->def->type, PRIV_A) != 0) > + return -1; > auto def_guard = make_scoped_guard([=] { free(user); }); > - user_cache_replace(user); > - def_guard.is_active = false; > + try { > + user_cache_replace(user); > + } catch (Exception *e) { > + return -1; > + } > + def_guard.is_active = false; > struct trigger *on_rollback = > txn_alter_trigger_new(user_cache_alter_user, old_tuple); > + if (on_rollback == NULL) > + return -1; > txn_stmt_on_rollback(stmt, on_rollback); > } > + return 0; > } > > /** > @@ -2663,11 +2955,12 @@ on_replace_dd_user(struct trigger * /* trigger */, > void *event) * @param[out] fid Function identifier. > * @param[out] uid Owner identifier. > */ > -static inline void > +static inline int > func_def_get_ids_from_tuple(struct tuple *tuple, uint32_t *fid, uint32_t > *uid) { > - *fid = tuple_field_u32_xc(tuple, BOX_FUNC_FIELD_ID); > - *uid = tuple_field_u32_xc(tuple, BOX_FUNC_FIELD_UID); > + if (tuple_field_u32(tuple, BOX_FUNC_FIELD_ID, fid) != 0) > + return -1; > + return tuple_field_u32(tuple, BOX_FUNC_FIELD_UID, uid); > } > > /** Create a function definition from tuple. */ > @@ -2677,38 +2970,53 @@ func_def_new_from_tuple(struct tuple *tuple) > uint32_t field_count = tuple_field_count(tuple); > uint32_t name_len, body_len, comment_len; > const char *name, *body, *comment; > - name = tuple_field_str_xc(tuple, BOX_FUNC_FIELD_NAME, &name_len); > + name = tuple_field_str(tuple, BOX_FUNC_FIELD_NAME, &name_len); > + if (name == NULL) > + return NULL; > if (name_len > BOX_NAME_MAX) { > - tnt_raise(ClientError, ER_CREATE_FUNCTION, > + diag_set(ClientError, ER_CREATE_FUNCTION, > tt_cstr(name, BOX_INVALID_NAME_MAX), > "function name is too long"); > + return NULL; > } > - identifier_check_xc(name, name_len); > + if (identifier_check(name, name_len) != 0) > + return NULL; > if (field_count > BOX_FUNC_FIELD_BODY) { > - body = tuple_field_str_xc(tuple, BOX_FUNC_FIELD_BODY, > - &body_len); > - comment = tuple_field_str_xc(tuple, BOX_FUNC_FIELD_COMMENT, > + body = tuple_field_str(tuple, BOX_FUNC_FIELD_BODY, &body_len); > + if (body == NULL) > + return NULL; > + comment = tuple_field_str(tuple, BOX_FUNC_FIELD_COMMENT, > &comment_len); > + if (comment == NULL) > + return NULL; > uint32_t len; > - const char *routine_type = tuple_field_str_xc(tuple, > + const char *routine_type = tuple_field_str(tuple, > BOX_FUNC_FIELD_ROUTINE_TYPE, &len); > + if (routine_type == NULL) > + return NULL; > if (len != strlen("function") || > strncasecmp(routine_type, "function", len) != 0) { > - tnt_raise(ClientError, ER_CREATE_FUNCTION, name, > + diag_set(ClientError, ER_CREATE_FUNCTION, name, > "unsupported routine_type value"); > + return NULL; > } > - const char *sql_data_access = tuple_field_str_xc(tuple, > + const char *sql_data_access = tuple_field_str(tuple, > BOX_FUNC_FIELD_SQL_DATA_ACCESS, &len); > + if (sql_data_access == NULL) > + return NULL; > if (len != strlen("none") || > strncasecmp(sql_data_access, "none", len) != 0) { > - tnt_raise(ClientError, ER_CREATE_FUNCTION, name, > + diag_set(ClientError, ER_CREATE_FUNCTION, name, > "unsupported sql_data_access value"); > + return NULL; > } > - bool is_null_call = tuple_field_bool_xc(tuple, > - BOX_FUNC_FIELD_IS_NULL_CALL); > + bool is_null_call; > + if (tuple_field_bool(tuple, BOX_FUNC_FIELD_IS_NULL_CALL, &is_null_call) > != 0) + return NULL; > if (is_null_call != true) { > - tnt_raise(ClientError, ER_CREATE_FUNCTION, name, > + diag_set(ClientError, ER_CREATE_FUNCTION, name, > "unsupported is_null_call value"); > + return NULL; > } > } else { > body = NULL; > @@ -2720,13 +3028,17 @@ func_def_new_from_tuple(struct tuple *tuple) > uint32_t def_sz = func_def_sizeof(name_len, body_len, comment_len, > &body_offset, &comment_offset); > struct func_def *def = (struct func_def *) malloc(def_sz); > - if (def == NULL) > - tnt_raise(OutOfMemory, def_sz, "malloc", "def"); > + if (def == NULL) { > + diag_set(OutOfMemory, def_sz, "malloc", "def"); > + return NULL; > + } > auto def_guard = make_scoped_guard([=] { free(def); }); > - func_def_get_ids_from_tuple(tuple, &def->fid, &def->uid); > + if (func_def_get_ids_from_tuple(tuple, &def->fid, &def->uid) != 0) > + return NULL; > if (def->fid > BOX_FUNCTION_MAX) { > - tnt_raise(ClientError, ER_CREATE_FUNCTION, > + diag_set(ClientError, ER_CREATE_FUNCTION, > tt_cstr(name, name_len), "function id is too big"); > + return NULL; > } > func_opts_create(&def->opts); > memcpy(def->name, name, name_len); > @@ -2746,47 +3058,59 @@ func_def_new_from_tuple(struct tuple *tuple) > } else { > def->comment = NULL; > } > - if (field_count > BOX_FUNC_FIELD_SETUID) > - def->setuid = tuple_field_u32_xc(tuple, BOX_FUNC_FIELD_SETUID); > - else > + if (field_count > BOX_FUNC_FIELD_SETUID) { > + uint32_t out; > + if (tuple_field_u32(tuple, BOX_FUNC_FIELD_SETUID, &out) ! = 0) > + return NULL; > + def->setuid = out; > + } else { > def->setuid = false; > + } > if (field_count > BOX_FUNC_FIELD_LANGUAGE) { > const char *language = > - tuple_field_cstr_xc(tuple, BOX_FUNC_FIELD_LANGUAGE); > + tuple_field_cstr(tuple, BOX_FUNC_FIELD_LANGUAGE); > + if (language == NULL) > + return NULL; > def->language = STR2ENUM(func_language, language); > if (def->language == func_language_MAX || > def->language == FUNC_LANGUAGE_SQL) { > - tnt_raise(ClientError, ER_FUNCTION_LANGUAGE, > + diag_set(ClientError, ER_FUNCTION_LANGUAGE, > language, def->name); > + return NULL; > } > } else { > /* Lua is the default. */ > def->language = FUNC_LANGUAGE_LUA; > } > if (field_count > BOX_FUNC_FIELD_BODY) { > - def->is_deterministic = > - tuple_field_bool_xc(tuple, > - BOX_FUNC_FIELD_IS_DETERMINISTIC); > - def->is_sandboxed = > - tuple_field_bool_xc(tuple, > - BOX_FUNC_FIELD_IS_SANDBOXED); > + if (tuple_field_bool(tuple,BOX_FUNC_FIELD_IS_DETERMINISTIC, > + &(def->is_deterministic)) != 0) > + return NULL; > + if (tuple_field_bool(tuple,BOX_FUNC_FIELD_IS_SANDBOXED, > + &(def->is_sandboxed)) != 0) > + return NULL; > const char *returns = > - tuple_field_cstr_xc(tuple, BOX_FUNC_FIELD_RETURNS); > + tuple_field_cstr(tuple, BOX_FUNC_FIELD_RETURNS); > + if (returns == NULL) > + return NULL; > def->returns = STR2ENUM(field_type, returns); > if (def->returns == field_type_MAX) { > - tnt_raise(ClientError, ER_CREATE_FUNCTION, > + diag_set(ClientError, ER_CREATE_FUNCTION, > def->name, "invalid returns value"); > + return NULL; > } > def->exports.all = 0; > - const char *exports = > - tuple_field_with_type_xc(tuple, BOX_FUNC_FIELD_EXPORTS, > - MP_ARRAY); > + const char *exports = tuple_field_with_type(tuple, > + BOX_FUNC_FIELD_EXPORTS, MP_ARRAY); > + if (exports == NULL) > + return NULL; > uint32_t cnt = mp_decode_array(&exports); > for (uint32_t i = 0; i < cnt; i++) { > if (mp_typeof(*exports) != MP_STR) { > - tnt_raise(ClientError, ER_FIELD_TYPE, > + diag_set(ClientError, ER_FIELD_TYPE, > int2str(BOX_FUNC_FIELD_EXPORTS + 1), > mp_type_strs[MP_STR]); > + return NULL; > } > uint32_t len; > const char *str = mp_decode_str(&exports, &len); > @@ -2798,32 +3122,39 @@ func_def_new_from_tuple(struct tuple *tuple) > def->exports.sql = true; > break; > default: > - tnt_raise(ClientError, ER_CREATE_FUNCTION, > + diag_set(ClientError, ER_CREATE_FUNCTION, > def->name, "invalid exports value"); > + return NULL; > } > } > const char *aggregate = > - tuple_field_cstr_xc(tuple, BOX_FUNC_FIELD_AGGREGATE); > + tuple_field_cstr(tuple, BOX_FUNC_FIELD_AGGREGATE); > + if (aggregate == NULL) > + return NULL; > def->aggregate = STR2ENUM(func_aggregate, aggregate); > if (def->aggregate == func_aggregate_MAX) { > - tnt_raise(ClientError, ER_CREATE_FUNCTION, > + diag_set(ClientError, ER_CREATE_FUNCTION, > def->name, "invalid aggregate value"); > + return NULL; > } > - const char *param_list = > - tuple_field_with_type_xc(tuple, > + const char *param_list = tuple_field_with_type(tuple, > BOX_FUNC_FIELD_PARAM_LIST, MP_ARRAY); > + if (param_list == NULL) > + return NULL; > uint32_t argc = mp_decode_array(¶m_list); > for (uint32_t i = 0; i < argc; i++) { > if (mp_typeof(*param_list) != MP_STR) { > - tnt_raise(ClientError, ER_FIELD_TYPE, > + diag_set(ClientError, ER_FIELD_TYPE, > int2str(BOX_FUNC_FIELD_PARAM_LIST + 1), > mp_type_strs[MP_STR]); > + return NULL; > } > uint32_t len; > const char *str = mp_decode_str(¶m_list, &len); > if (STRN2ENUM(field_type, str, len) == field_type_MAX) { > - tnt_raise(ClientError, ER_CREATE_FUNCTION, > + diag_set(ClientError, ER_CREATE_FUNCTION, > def->name, "invalid argument type"); > + return NULL; > } > } > def->param_count = argc; > @@ -2831,7 +3162,7 @@ func_def_new_from_tuple(struct tuple *tuple) > if (opts_decode(&def->opts, func_opts_reg, &opts, > ER_WRONG_SPACE_OPTIONS, BOX_FUNC_FIELD_OPTS, > NULL) != 0) > - diag_raise(); > + return NULL; > } else { > def->is_deterministic = false; > def->is_sandboxed = false; > @@ -2843,43 +3174,48 @@ func_def_new_from_tuple(struct tuple *tuple) > def->param_count = 0; > } > if (func_def_check(def) != 0) > - diag_raise(); > + return NULL; > def_guard.is_active = false; > return def; > } > > -static void > +static int > on_create_func_rollback(struct trigger *trigger, void * /* event */) > { > /* Remove the new function from the cache and delete it. */ > struct func *func = (struct func *)trigger->data; > func_cache_delete(func->def->fid); > - trigger_run_xc(&on_alter_func, func); > + if (trigger_run(&on_alter_func, func) != 0) > + return -1; > func_delete(func); > + return 0; > } > > -static void > +static int > on_drop_func_commit(struct trigger *trigger, void * /* event */) > { > /* Delete the old function. */ > struct func *func = (struct func *)trigger->data; > func_delete(func); > + return 0; > } > > -static void > +static int > on_drop_func_rollback(struct trigger *trigger, void * /* event */) > { > /* Insert the old function back into the cache. */ > struct func *func = (struct func *)trigger->data; > func_cache_insert(func); > - trigger_run_xc(&on_alter_func, func); > + if (trigger_run(&on_alter_func, func) != 0) > + return -1; > + return 0; > } > > /** > * A trigger invoked on replace in a space containing > * functions on which there were defined any grants. > */ > -static void > +static int > on_replace_dd_func(struct trigger * /* trigger */, void *event) > { > struct txn *txn = (struct txn *) event; > @@ -2887,53 +3223,74 @@ on_replace_dd_func(struct trigger * /* trigger */, > void *event) struct tuple *old_tuple = stmt->old_tuple; > struct tuple *new_tuple = stmt->new_tuple; > > - uint32_t fid = tuple_field_u32_xc(old_tuple ? old_tuple : new_tuple, > - BOX_FUNC_FIELD_ID); > + uint32_t fid; > + if (tuple_field_u32(old_tuple ? old_tuple : new_tuple, > + BOX_FUNC_FIELD_ID, &fid) != 0) > + return -1; > struct func *old_func = func_by_id(fid); > if (new_tuple != NULL && old_func == NULL) { /* INSERT */ > - struct func_def *def = func_def_new_from_tuple(new_tuple); > + struct func_def *def; > + def = func_def_new_from_tuple(new_tuple); > + if (def == NULL) > + return -1; > auto def_guard = make_scoped_guard([=] { free(def); }); > - access_check_ddl(def->name, def->fid, def->uid, SC_FUNCTION, > - PRIV_C); > + if (access_check_ddl(def->name, def->fid, def->uid, SC_FUNCTION, > + PRIV_C) != 0) > + return -1; > struct trigger *on_rollback = > txn_alter_trigger_new(on_create_func_rollback, NULL); > + if (on_rollback == NULL) > + return -1; > struct func *func = func_new(def); > if (func == NULL) > - diag_raise(); > + return -1; > def_guard.is_active = false; > func_cache_insert(func); > on_rollback->data = func; > txn_stmt_on_rollback(stmt, on_rollback); > - trigger_run_xc(&on_alter_func, func); > + if (trigger_run(&on_alter_func, func) != 0) > + return -1; > } else if (new_tuple == NULL) { /* DELETE */ > uint32_t uid; > - func_def_get_ids_from_tuple(old_tuple, &fid, &uid); > + if (func_def_get_ids_from_tuple(old_tuple, &fid, &uid) != 0) > + return -1; > /* > * Can only delete func if you're the one > * who created it or a superuser. > */ > - access_check_ddl(old_func->def->name, fid, uid, SC_FUNCTION, > - PRIV_D); > + if (access_check_ddl(old_func->def->name, fid, uid, SC_FUNCTION, > + PRIV_D) != 0) > + return -1; > /* Can only delete func if it has no grants. */ > - if (schema_find_grants("function", old_func->def->fid)) { > - tnt_raise(ClientError, ER_DROP_FUNCTION, > - (unsigned) old_func->def->uid, > - "function has grants"); > + bool out; > + if (schema_find_grants("function", old_func->def->fid, &out) != 0) { > + return -1; > + } > + if (out) { > + diag_set(ClientError, ER_DROP_FUNCTION, > + (unsigned) old_func->def->uid, > + "function has grants"); > + return -1; > } > - if (old_func != NULL && > - space_has_data(BOX_FUNC_INDEX_ID, 1, old_func->def- >fid)) { > - tnt_raise(ClientError, ER_DROP_FUNCTION, > + if (space_has_data(BOX_FUNC_INDEX_ID, 1, old_func->def- >fid, &out) != 0) > + return -1; > + if (old_func != NULL && out) { > + diag_set(ClientError, ER_DROP_FUNCTION, > (unsigned) old_func->def->uid, > "function has references"); > + return -1; > } > struct trigger *on_commit = > txn_alter_trigger_new(on_drop_func_commit, old_func); > struct trigger *on_rollback = > txn_alter_trigger_new(on_drop_func_rollback, old_func); > + if (on_commit == NULL || on_rollback == NULL) > + return -1; > func_cache_delete(old_func->def->fid); > txn_stmt_on_commit(stmt, on_commit); > txn_stmt_on_rollback(stmt, on_rollback); > - trigger_run_xc(&on_alter_func, old_func); > + if (trigger_run(&on_alter_func, old_func) != 0) > + return -1; > } else { /* UPDATE, REPLACE */ > assert(new_tuple != NULL && old_tuple != NULL); > /** > @@ -2947,120 +3304,152 @@ on_replace_dd_func(struct trigger * /* trigger */, > void *event) }); > old_def = func_def_new_from_tuple(old_tuple); > new_def = func_def_new_from_tuple(new_tuple); > + if (old_def == NULL || new_def == NULL) > + return -1; > if (func_def_cmp(new_def, old_def) != 0) { > - tnt_raise(ClientError, ER_UNSUPPORTED, "function", > + diag_set(ClientError, ER_UNSUPPORTED, "function", > "alter"); > + return -1; > } > } > + return 0; > } > > /** Create a collation identifier definition from tuple. */ > -void > +int > coll_id_def_new_from_tuple(struct tuple *tuple, struct coll_id_def *def) > { > memset(def, 0, sizeof(*def)); > uint32_t name_len, locale_len, type_len; > - def->id = tuple_field_u32_xc(tuple, BOX_COLLATION_FIELD_ID); > - def->name = tuple_field_str_xc(tuple, BOX_COLLATION_FIELD_NAME, > &name_len); + if (tuple_field_u32(tuple, BOX_COLLATION_FIELD_ID, > &(def->id)) != 0) + return -1; > + def->name = tuple_field_str(tuple, BOX_COLLATION_FIELD_NAME, &name_len); > + if (def->name == NULL) > + return -1; > def->name_len = name_len; > - if (name_len > BOX_NAME_MAX) > - tnt_raise(ClientError, ER_CANT_CREATE_COLLATION, > - "collation name is too long"); > - identifier_check_xc(def->name, name_len); > - > - def->owner_id = tuple_field_u32_xc(tuple, BOX_COLLATION_FIELD_UID); > - struct coll_def *base = &def->base; > - const char *type = tuple_field_str_xc(tuple, BOX_COLLATION_FIELD_TYPE, > - &type_len); > + if (name_len > BOX_NAME_MAX) { > + diag_set(ClientError, ER_CANT_CREATE_COLLATION, > + "collation name is too long"); > + return -1; > + } > + struct coll_def *base; > + const char *type; > + if (identifier_check(def->name, name_len) != 0) > + return -1; > + if (tuple_field_u32(tuple, BOX_COLLATION_FIELD_UID, &(def- >owner_id)) != > 0) + return -1; > + base = &def->base; > + type = tuple_field_str(tuple, BOX_COLLATION_FIELD_TYPE, > + &type_len); > + if (type == NULL) > + return -1; > + > base->type = STRN2ENUM(coll_type, type, type_len); > - if (base->type == coll_type_MAX) > - tnt_raise(ClientError, ER_CANT_CREATE_COLLATION, > - "unknown collation type"); > - const char *locale = > - tuple_field_str_xc(tuple, BOX_COLLATION_FIELD_LOCALE, > - &locale_len); > - if (locale_len > COLL_LOCALE_LEN_MAX) > - tnt_raise(ClientError, ER_CANT_CREATE_COLLATION, > - "collation locale is too long"); > + if (base->type == coll_type_MAX) { > + diag_set(ClientError, ER_CANT_CREATE_COLLATION, > + "unknown collation type"); > + return -1; > + } > + const char *locale = tuple_field_str(tuple, BOX_COLLATION_FIELD_LOCALE, > + &locale_len); > + if (locale == NULL) > + return -1; > + if (locale_len > COLL_LOCALE_LEN_MAX) { > + diag_set(ClientError, ER_CANT_CREATE_COLLATION, > + "collation locale is too long"); > + return -1; > + } > + const char *options; > if (locale_len > 0) > - identifier_check_xc(locale, locale_len); > + if (identifier_check(locale, locale_len) != 0) > + return -1; > snprintf(base->locale, sizeof(base->locale), "%.*s", locale_len, > locale); > - const char *options = > - tuple_field_with_type_xc(tuple, BOX_COLLATION_FIELD_OPTIONS, > - MP_MAP); > - > + options = tuple_field_with_type(tuple, > + BOX_COLLATION_FIELD_OPTIONS,MP_MAP); > + if (options == NULL) > + return -1; > if (opts_decode(&base->icu, coll_icu_opts_reg, &options, > ER_WRONG_COLLATION_OPTIONS, > - BOX_COLLATION_FIELD_OPTIONS, NULL) != 0) > - diag_raise(); > - > + BOX_COLLATION_FIELD_OPTIONS, NULL) != 0) { > + return -1; > + } > if (base->icu.french_collation == coll_icu_on_off_MAX) { > - tnt_raise(ClientError, ER_CANT_CREATE_COLLATION, > + diag_set(ClientError, ER_CANT_CREATE_COLLATION, > "ICU wrong french_collation option setting, " > "expected ON | OFF"); > + return -1; > } > > if (base->icu.alternate_handling == coll_icu_alternate_handling_MAX) { > - tnt_raise(ClientError, ER_CANT_CREATE_COLLATION, > + diag_set(ClientError, ER_CANT_CREATE_COLLATION, > "ICU wrong alternate_handling option setting, " > "expected NON_IGNORABLE | SHIFTED"); > + return -1; > } > > if (base->icu.case_first == coll_icu_case_first_MAX) { > - tnt_raise(ClientError, ER_CANT_CREATE_COLLATION, > + diag_set(ClientError, ER_CANT_CREATE_COLLATION, > "ICU wrong case_first option setting, " > "expected OFF | UPPER_FIRST | LOWER_FIRST"); > + return -1; > } > > if (base->icu.case_level == coll_icu_on_off_MAX) { > - tnt_raise(ClientError, ER_CANT_CREATE_COLLATION, > + diag_set(ClientError, ER_CANT_CREATE_COLLATION, > "ICU wrong case_level option setting, " > "expected ON | OFF"); > + return -1; > } > > if (base->icu.normalization_mode == coll_icu_on_off_MAX) { > - tnt_raise(ClientError, ER_CANT_CREATE_COLLATION, > + diag_set(ClientError, ER_CANT_CREATE_COLLATION, > "ICU wrong normalization_mode option setting, " > "expected ON | OFF"); > + return -1; > } > > if (base->icu.strength == coll_icu_strength_MAX) { > - tnt_raise(ClientError, ER_CANT_CREATE_COLLATION, > + diag_set(ClientError, ER_CANT_CREATE_COLLATION, > "ICU wrong strength option setting, " > "expected PRIMARY | SECONDARY | " > "TERTIARY | QUATERNARY | IDENTICAL"); > + return -1; > } > > if (base->icu.numeric_collation == coll_icu_on_off_MAX) { > - tnt_raise(ClientError, ER_CANT_CREATE_COLLATION, > + diag_set(ClientError, ER_CANT_CREATE_COLLATION, > "ICU wrong numeric_collation option setting, " > "expected ON | OFF"); > + return -1; > } > + return 0; > } > > /** Delete the new collation identifier. */ > -static void > +static int > on_create_collation_rollback(struct trigger *trigger, void *event) > { > (void) event; > struct coll_id *coll_id = (struct coll_id *) trigger->data; > coll_id_cache_delete(coll_id); > coll_id_delete(coll_id); > + return 0; > } > > > /** Free a deleted collation identifier on commit. */ > -static void > +static int > on_drop_collation_commit(struct trigger *trigger, void *event) > { > (void) event; > struct coll_id *coll_id = (struct coll_id *) trigger->data; > coll_id_delete(coll_id); > + return 0; > } > > /** Put the collation identifier back on rollback. */ > -static void > +static int > on_drop_collation_rollback(struct trigger *trigger, void *event) > { > (void) event; > @@ -3069,13 +3458,14 @@ on_drop_collation_rollback(struct trigger *trigger, > void *event) if (coll_id_cache_replace(coll_id, &replaced_id) != 0) > panic("Out of memory on insertion into collation cache"); > assert(replaced_id == NULL); > + return 0; > } > > /** > * A trigger invoked on replace in a space containing > * collations that a user defined. > */ > -static void > +static int > on_replace_dd_collation(struct trigger * /* trigger */, void *event) > { > struct txn *txn = (struct txn *) event; > @@ -3088,12 +3478,16 @@ on_replace_dd_collation(struct trigger * /* trigger > */, void *event) txn_alter_trigger_new(on_drop_collation_commit, NULL); > struct trigger *on_rollback = > txn_alter_trigger_new(on_drop_collation_rollback, NULL); > + if (on_commit == NULL || on_rollback == NULL) > + return -1; > /* > * TODO: Check that no index uses the collation > * identifier. > */ > - int32_t old_id = tuple_field_u32_xc(old_tuple, > - BOX_COLLATION_FIELD_ID); > + uint32_t out; > + if (tuple_field_u32(old_tuple, BOX_COLLATION_FIELD_ID, &out) != 0) > + return -1; > + int32_t old_id = out; > /* > * Don't allow user to drop "none" collation > * since it is very special and vastly used > @@ -3101,14 +3495,16 @@ on_replace_dd_collation(struct trigger * /* trigger > */, void *event) * fact that "none" collation features id == 0. > */ > if (old_id == COLL_NONE) { > - tnt_raise(ClientError, ER_DROP_COLLATION, "none", > + diag_set(ClientError, ER_DROP_COLLATION, "none", > "system collation"); > + return -1; > } > struct coll_id *old_coll_id = coll_by_id(old_id); > assert(old_coll_id != NULL); > - access_check_ddl(old_coll_id->name, old_coll_id->id, > - old_coll_id->owner_id, SC_COLLATION, > - PRIV_D); > + if (access_check_ddl(old_coll_id->name, old_coll_id->id, > + old_coll_id->owner_id, SC_COLLATION, > + PRIV_D) != 0) > + return -1; > /* > * Set on_commit/on_rollback triggers after > * deletion from the cache to make trigger logic > @@ -3123,17 +3519,21 @@ on_replace_dd_collation(struct trigger * /* trigger > */, void *event) /* INSERT */ > struct trigger *on_rollback = > txn_alter_trigger_new(on_create_collation_rollback, NULL); > + if (on_rollback == NULL) > + return -1; > struct coll_id_def new_def; > - coll_id_def_new_from_tuple(new_tuple, &new_def); > - access_check_ddl(new_def.name, new_def.id, new_def.owner_id, > - SC_COLLATION, PRIV_C); > + if (coll_id_def_new_from_tuple(new_tuple, &new_def) != 0) > + return -1; > + if (access_check_ddl(new_def.name, new_def.id, new_def.owner_id, > + SC_COLLATION, PRIV_C) != 0) > + return -1; > struct coll_id *new_coll_id = coll_id_new(&new_def); > if (new_coll_id == NULL) > - diag_raise(); > + return -1; > struct coll_id *replaced_id; > if (coll_id_cache_replace(new_coll_id, &replaced_id) != 0) { > coll_id_delete(new_coll_id); > - diag_raise(); > + return -1; > } > assert(replaced_id == NULL); > on_rollback->data = new_coll_id; > @@ -3141,27 +3541,34 @@ on_replace_dd_collation(struct trigger * /* trigger > */, void *event) } else { > /* UPDATE */ > assert(new_tuple != NULL && old_tuple != NULL); > - tnt_raise(ClientError, ER_UNSUPPORTED, "collation", "alter"); > + diag_set(ClientError, ER_UNSUPPORTED, "collation", "alter"); > + return -1; > } > + return 0; > } > > /** > * Create a privilege definition from tuple. > */ > -void > +int > priv_def_create_from_tuple(struct priv_def *priv, struct tuple *tuple) > { > - priv->grantor_id = tuple_field_u32_xc(tuple, BOX_PRIV_FIELD_ID); > - priv->grantee_id = tuple_field_u32_xc(tuple, BOX_PRIV_FIELD_UID); > + if (tuple_field_u32(tuple, BOX_PRIV_FIELD_ID, &(priv->grantor_id)) ! = 0) > + return -1; > + if (tuple_field_u32(tuple, BOX_PRIV_FIELD_UID, &(priv->grantee_id)) != 0) > + return -1; > > const char *object_type = > - tuple_field_cstr_xc(tuple, BOX_PRIV_FIELD_OBJECT_TYPE); > + tuple_field_cstr(tuple, BOX_PRIV_FIELD_OBJECT_TYPE); > + if (object_type == NULL) > + return -1; > priv->object_type = schema_object_type(object_type); > > const char *data = tuple_field(tuple, BOX_PRIV_FIELD_OBJECT_ID); > if (data == NULL) { > - tnt_raise(ClientError, ER_NO_SUCH_FIELD_NO, > + diag_set(ClientError, ER_NO_SUCH_FIELD_NO, > BOX_PRIV_FIELD_OBJECT_ID + TUPLE_INDEX_BASE); > + return -1; > } > /* > * When granting or revoking privileges on a whole entity > @@ -3179,14 +3586,19 @@ priv_def_create_from_tuple(struct priv_def *priv, > struct tuple *tuple) } > FALLTHROUGH; > default: > - priv->object_id = tuple_field_u32_xc(tuple, > - BOX_PRIV_FIELD_OBJECT_ID); > + if (tuple_field_u32(tuple,BOX_PRIV_FIELD_OBJECT_ID, &(priv->object_id)) > != 0) + return -1; > } > if (priv->object_type == SC_UNKNOWN) { > - tnt_raise(ClientError, ER_UNKNOWN_SCHEMA_OBJECT, > + diag_set(ClientError, ER_UNKNOWN_SCHEMA_OBJECT, > object_type); > + return -1; > } > - priv->access = tuple_field_u32_xc(tuple, BOX_PRIV_FIELD_ACCESS); > + uint32_t out; > + if (tuple_field_u32(tuple, BOX_PRIV_FIELD_ACCESS, &out) != 0) > + return -1; > + priv->access = out; > + return 0; > } > > /* > @@ -3199,183 +3611,214 @@ priv_def_create_from_tuple(struct priv_def *priv, > struct tuple *tuple) * object can be changed during WAL write. > * In the future we must protect grant/revoke with a logical lock. > */ > -static void > +static int > priv_def_check(struct priv_def *priv, enum priv_type priv_type) > { > - struct user *grantor = user_find_xc(priv->grantor_id); > + struct user *grantor = user_find(priv->grantor_id); > + if (grantor == NULL) > + return -1; > /* May be a role */ > struct user *grantee = user_by_id(priv->grantee_id); > if (grantee == NULL) { > - tnt_raise(ClientError, ER_NO_SUCH_USER, > + diag_set(ClientError, ER_NO_SUCH_USER, > int2str(priv->grantee_id)); > + return -1; > } > const char *name = schema_find_name(priv->object_type, priv- >object_id); > - access_check_ddl(name, priv->object_id, grantor->def->uid, > - priv->object_type, priv_type); > + if (access_check_ddl(name, priv->object_id, grantor->def->uid, > + priv->object_type, priv_type) != 0) > + return -1; > switch (priv->object_type) { > - case SC_UNIVERSE: > - if (grantor->def->uid != ADMIN) { > - tnt_raise(AccessDeniedError, > - priv_name(priv_type), > - schema_object_name(SC_UNIVERSE), > - name, > - grantor->def->name); > - } > - break; > - case SC_SPACE: > - { > - struct space *space = space_cache_find_xc(priv- >object_id); > - if (space->def->uid != grantor->def->uid && > - grantor->def->uid != ADMIN) { > - tnt_raise(AccessDeniedError, > - priv_name(priv_type), > - schema_object_name(SC_SPACE), name, > - grantor->def->name); > - } > - break; > - } > - case SC_FUNCTION: > - { > - struct func *func = func_cache_find(priv->object_id); > - if (func->def->uid != grantor->def->uid && > - grantor->def->uid != ADMIN) { > - tnt_raise(AccessDeniedError, > - priv_name(priv_type), > - schema_object_name(SC_FUNCTION), name, > - grantor->def->name); > - } > - break; > - } > - case SC_SEQUENCE: > - { > - struct sequence *seq = sequence_cache_find(priv- >object_id); > - if (seq->def->uid != grantor->def->uid && > - grantor->def->uid != ADMIN) { > - tnt_raise(AccessDeniedError, > - priv_name(priv_type), > - schema_object_name(SC_SEQUENCE), name, > - grantor->def->name); > + case SC_UNIVERSE: > + if (grantor->def->uid != ADMIN) { > + diag_set(AccessDeniedError, > + priv_name(priv_type), > + schema_object_name(SC_UNIVERSE), > + name, > + grantor->def->name); > + return -1; > + } > + break; > + case SC_SPACE: { > + struct space *space = space_cache_find(priv- >object_id); > + if (space == NULL) > + return -1; > + if (space->def->uid != grantor->def->uid && > + grantor->def->uid != ADMIN) { > + diag_set(AccessDeniedError, > + priv_name(priv_type), > + schema_object_name(SC_SPACE), name, > + grantor->def->name); > + return -1; > + } > + break; > } > - break; > - } > - case SC_ROLE: > - { > - struct user *role = user_by_id(priv->object_id); > - if (role == NULL || role->def->type != SC_ROLE) { > - tnt_raise(ClientError, ER_NO_SUCH_ROLE, > - role ? role->def->name : > - int2str(priv->object_id)); > + case SC_FUNCTION: { > + struct func *func = func_by_id(priv- >object_id); > + if (func == NULL) { > + diag_set(ClientError, ER_NO_SUCH_FUNCTION, int2str(priv->object_id)); > + return -1; > + } > + if (func->def->uid != grantor->def->uid && > + grantor->def->uid != ADMIN) { > + diag_set(AccessDeniedError, > + priv_name(priv_type), > + schema_object_name(SC_FUNCTION), name, > + grantor->def->name); > + return -1; > + } > + break; > } > - /* > - * Only the creator of the role can grant or revoke it. > - * Everyone can grant 'PUBLIC' role. > - */ > - if (role->def->owner != grantor->def->uid && > - grantor->def->uid != ADMIN && > - (role->def->uid != PUBLIC || priv->access != PRIV_X)) { > - tnt_raise(AccessDeniedError, > - priv_name(priv_type), > - schema_object_name(SC_ROLE), name, > - grantor->def->name); > + case SC_SEQUENCE: { > + struct sequence *seq = sequence_by_id(priv- >object_id); > + if (seq == NULL) { > + diag_set(ClientError, ER_NO_SUCH_SEQUENCE, int2str(priv->object_id)); > + return -1; > + } > + if (seq->def->uid != grantor->def->uid && > + grantor->def->uid != ADMIN) { > + diag_set(AccessDeniedError, > + priv_name(priv_type), > + schema_object_name(SC_SEQUENCE), name, > + grantor->def->name); > + return -1; > + } > + break; > } > - /* Not necessary to do during revoke, but who cares. */ > - role_check(grantee, role); > - break; > - } > - case SC_USER: > - { > - struct user *user = user_by_id(priv->object_id); > - if (user == NULL || user->def->type != SC_USER) { > - tnt_raise(ClientError, ER_NO_SUCH_USER, > - user ? user->def->name : > - int2str(priv->object_id)); > + case SC_ROLE: { > + struct user *role = user_by_id(priv- >object_id); > + if (role == NULL || role->def->type != SC_ROLE) { > + diag_set(ClientError, ER_NO_SUCH_ROLE, > + role ? role->def->name : > + int2str(priv- >object_id)); > + return -1; > + } > + /* > + * Only the creator of the role can grant or revoke it. > + * Everyone can grant 'PUBLIC' role. > + */ > + if (role->def->owner != grantor->def->uid && > + grantor->def->uid != ADMIN && > + (role->def->uid != PUBLIC || priv->access != PRIV_X)) { > + diag_set(AccessDeniedError, > + priv_name(priv_type), > + schema_object_name(SC_ROLE), name, > + grantor->def->name); > + return -1; > + } > + /* Not necessary to do during revoke, but who cares. */ > + if (role_check(grantee, role) != 0) > + return -1; > + break; > } > - if (user->def->owner != grantor->def->uid && > - grantor->def->uid != ADMIN) { > - tnt_raise(AccessDeniedError, > - priv_name(priv_type), > - schema_object_name(SC_USER), name, > - grantor->def->name); > + case SC_USER: { > + struct user *user = user_by_id(priv- >object_id); > + if (user == NULL || user->def->type != SC_USER) { > + diag_set(ClientError, ER_NO_SUCH_USER, > + user ? user->def->name : > + int2str(priv- >object_id)); > + return -1; > + } > + if (user->def->owner != grantor->def->uid && > + grantor->def->uid != ADMIN) { > + diag_set(AccessDeniedError, > + priv_name(priv_type), > + schema_object_name(SC_USER), name, > + grantor->def->name); > + return -1; > + } > + break; > } > - break; > - } > - case SC_ENTITY_SPACE: > - case SC_ENTITY_FUNCTION: > - case SC_ENTITY_SEQUENCE: > - case SC_ENTITY_ROLE: > - case SC_ENTITY_USER: > - { > - /* Only admin may grant privileges on an entire entity. */ > - if (grantor->def->uid != ADMIN) { > - tnt_raise(AccessDeniedError, priv_name(priv_type), > - schema_object_name(priv- >object_type), name, > - grantor->def->name); > + case SC_ENTITY_SPACE: > + case SC_ENTITY_FUNCTION: > + case SC_ENTITY_SEQUENCE: > + case SC_ENTITY_ROLE: > + case SC_ENTITY_USER: { > + /* Only admin may grant privileges on an entire entity. */ > + if (grantor->def->uid != ADMIN) { > + diag_set(AccessDeniedError, priv_name(priv_type), > + schema_object_name(priv->object_type), name, > + grantor->def->name); > + return -1; > + } > } > - } > - default: > - break; > + default: > + break; > } > if (priv->access == 0) { > - tnt_raise(ClientError, ER_GRANT, > + diag_set(ClientError, ER_GRANT, > "the grant tuple has no privileges"); > + return -1; > } > + return 0; > } > > /** > * Update a metadata cache object with the new access > * data. > */ > -static void > +static int > grant_or_revoke(struct priv_def *priv) > { > struct user *grantee = user_by_id(priv->grantee_id); > if (grantee == NULL) > - return; > + return 0; > /* > * Grant a role to a user only when privilege type is 'execute' > * and the role is specified. > */ > - if (priv->object_type == SC_ROLE && !(priv->access & ~PRIV_X)) { > - struct user *role = user_by_id(priv->object_id); > - if (role == NULL || role->def->type != SC_ROLE) > - return; > - if (priv->access) > - role_grant(grantee, role); > - else > - role_revoke(grantee, role); > - } else { > - priv_grant(grantee, priv); > + try { > + if (priv->object_type == SC_ROLE && !(priv->access & ~PRIV_X)) { > + struct user *role = user_by_id(priv- >object_id); > + if (role == NULL || role->def->type != SC_ROLE) > + return 0; > + if (priv->access) > + role_grant(grantee, role); > + else > + role_revoke(grantee, role); > + } else { > + priv_grant(grantee, priv); > + } > + } catch (Exception *e) { > + return -1; > } > + return 0; > } > > /** A trigger called on rollback of grant. */ > -static void > +static int > revoke_priv(struct trigger *trigger, void *event) > { > (void) event; > struct tuple *tuple = (struct tuple *)trigger->data; > struct priv_def priv; > - priv_def_create_from_tuple(&priv, tuple); > + if (priv_def_create_from_tuple(&priv, tuple) != 0) > + return -1; > priv.access = 0; > - grant_or_revoke(&priv); > + if (grant_or_revoke(&priv) != 0) > + return -1; > + return 0; > } > > /** A trigger called on rollback of revoke or modify. */ > -static void > +static int > modify_priv(struct trigger *trigger, void *event) > { > (void) event; > struct tuple *tuple = (struct tuple *)trigger->data; > struct priv_def priv; > - priv_def_create_from_tuple(&priv, tuple); > - grant_or_revoke(&priv); > + if (priv_def_create_from_tuple(&priv, tuple) != 0) > + return -1; > + if (grant_or_revoke(&priv) != 0) > + return -1; > + return 0; > } > > /** > * A trigger invoked on replace in the space containing > * all granted privileges. > */ > -static void > +static int > on_replace_dd_priv(struct trigger * /* trigger */, void *event) > { > struct txn *txn = (struct txn *) event; > @@ -3385,29 +3828,45 @@ on_replace_dd_priv(struct trigger * /* trigger */, > void *event) struct priv_def priv; > > if (new_tuple != NULL && old_tuple == NULL) { /* grant */ > - priv_def_create_from_tuple(&priv, new_tuple); > - priv_def_check(&priv, PRIV_GRANT); > - grant_or_revoke(&priv); > + if (priv_def_create_from_tuple(&priv, new_tuple) != 0) > + return -1; > + if (priv_def_check(&priv, PRIV_GRANT) != 0) > + return -1; > + if (grant_or_revoke(&priv) != 0) > + return -1; > struct trigger *on_rollback = > txn_alter_trigger_new(revoke_priv, new_tuple); > + if (on_rollback == NULL) > + return -1; > txn_stmt_on_rollback(stmt, on_rollback); > } else if (new_tuple == NULL) { /* revoke */ > assert(old_tuple); > - priv_def_create_from_tuple(&priv, old_tuple); > - priv_def_check(&priv, PRIV_REVOKE); > + if (priv_def_create_from_tuple(&priv, old_tuple) != 0) > + return -1; > + if (priv_def_check(&priv, PRIV_REVOKE) != 0) > + return -1; > priv.access = 0; > - grant_or_revoke(&priv); > + if (grant_or_revoke(&priv) != 0) > + return -1; > struct trigger *on_rollback = > txn_alter_trigger_new(modify_priv, old_tuple); > + if (on_rollback == NULL) > + return -1; > txn_stmt_on_rollback(stmt, on_rollback); > } else { /* modify */ > - priv_def_create_from_tuple(&priv, new_tuple); > - priv_def_check(&priv, PRIV_GRANT); > - grant_or_revoke(&priv); > + if (priv_def_create_from_tuple(&priv, new_tuple) != 0) > + return -1; > + if (priv_def_check(&priv, PRIV_GRANT) != 0) > + return -1; > + if (grant_or_revoke(&priv) != 0) > + return -1; > struct trigger *on_rollback = > txn_alter_trigger_new(modify_priv, old_tuple); > + if (on_rollback == NULL) > + return -1; > txn_stmt_on_rollback(stmt, on_rollback); > } > + return 0; > } > > /* }}} access control */ > @@ -3423,23 +3882,29 @@ on_replace_dd_priv(struct trigger * /* trigger */, > void *event) * concern us, we can safely change the cluster id in > before-replace * event, not in after-replace event. > */ > -static void > +static int > on_replace_dd_schema(struct trigger * /* trigger */, void *event) > { > struct txn *txn = (struct txn *) event; > struct txn_stmt *stmt = txn_current_stmt(txn); > struct tuple *old_tuple = stmt->old_tuple; > struct tuple *new_tuple = stmt->new_tuple; > - const char *key = tuple_field_cstr_xc(new_tuple ? new_tuple : old_tuple, > + const char *key = tuple_field_cstr(new_tuple ? new_tuple : old_tuple, > BOX_SCHEMA_FIELD_KEY); > + if (key == NULL) > + return -1; > if (strcmp(key, "cluster") == 0) { > - if (new_tuple == NULL) > - tnt_raise(ClientError, ER_REPLICASET_UUID_IS_RO); > + if (new_tuple == NULL) { > + diag_set(ClientError, ER_REPLICASET_UUID_IS_RO); > + return -1; > + } > tt_uuid uu; > - tuple_field_uuid_xc(new_tuple, BOX_CLUSTER_FIELD_UUID, &uu); > + if (tuple_field_uuid(new_tuple, BOX_CLUSTER_FIELD_UUID, &uu) != 0) > + return -1; > REPLICASET_UUID = uu; > say_info("cluster uuid %s", tt_uuid_str(&uu)); > } > + return 0; > } > > /** > @@ -3447,14 +3912,16 @@ on_replace_dd_schema(struct trigger * /* trigger */, > void *event) * write ahead log. Update the cluster configuration cache > * with it. > */ > -static void > +static int > register_replica(struct trigger *trigger, void * /* event */) > { > struct tuple *new_tuple = (struct tuple *)trigger->data; > - > - uint32_t id = tuple_field_u32_xc(new_tuple, BOX_CLUSTER_FIELD_ID); > + uint32_t id; > + if (tuple_field_u32(new_tuple, BOX_CLUSTER_FIELD_ID, &id) != 0) > + return -1; > tt_uuid uuid; > - tuple_field_uuid_xc(new_tuple, BOX_CLUSTER_FIELD_UUID, &uuid); > + if (tuple_field_uuid(new_tuple, BOX_CLUSTER_FIELD_UUID, &uuid) != 0) > + return -1; > struct replica *replica = replica_by_uuid(&uuid); > if (replica != NULL) { > replica_set_id(replica, id); > @@ -3462,23 +3929,27 @@ register_replica(struct trigger *trigger, void * /* > event */) try { > replica = replicaset_add(id, &uuid); > /* Can't throw exceptions from on_commit trigger */ > - } catch(Exception *e) { > + } catch (Exception *e) { > panic("Can't register replica: %s", e- >errmsg); > } > } > + return 0; > } > > -static void > +static int > unregister_replica(struct trigger *trigger, void * /* event */) > { > struct tuple *old_tuple = (struct tuple *)trigger->data; > > struct tt_uuid old_uuid; > - tuple_field_uuid_xc(old_tuple, BOX_CLUSTER_FIELD_UUID, &old_uuid); > + > + if (tuple_field_uuid(old_tuple, BOX_CLUSTER_FIELD_UUID, &old_uuid) ! = 0) > + return -1; > > struct replica *replica = replica_by_uuid(&old_uuid); > assert(replica != NULL); > replica_clear_id(replica); > + return 0; > } > > /** > @@ -3499,7 +3970,7 @@ unregister_replica(struct trigger *trigger, void * /* > event */) * replica set can not by mistake join/follow another replica > * set without first being reset (emptied). > */ > -static void > +static int > on_replace_dd_cluster(struct trigger *trigger, void *event) > { > (void) trigger; > @@ -3508,16 +3979,21 @@ on_replace_dd_cluster(struct trigger *trigger, void > *event) struct tuple *old_tuple = stmt->old_tuple; > struct tuple *new_tuple = stmt->new_tuple; > if (new_tuple != NULL) { /* Insert or replace */ > - /* Check fields */ > - uint32_t replica_id = > - tuple_field_u32_xc(new_tuple, BOX_CLUSTER_FIELD_ID); > - replica_check_id(replica_id); > tt_uuid replica_uuid; > - tuple_field_uuid_xc(new_tuple, BOX_CLUSTER_FIELD_UUID, > - &replica_uuid); > - if (tt_uuid_is_nil(&replica_uuid)) > - tnt_raise(ClientError, ER_INVALID_UUID, > + /* Check fields */ > + uint32_t replica_id; > + if (tuple_field_u32(new_tuple, BOX_CLUSTER_FIELD_ID, &replica_id) != 0) > + return -1; > + if (replica_check_id(replica_id) != 0) > + return -1; > + if (tuple_field_uuid(new_tuple, BOX_CLUSTER_FIELD_UUID, > + &replica_uuid) != 0) > + return -1; > + if (tt_uuid_is_nil(&replica_uuid)) { > + diag_set(ClientError, ER_INVALID_UUID, > tt_uuid_str(&replica_uuid)); > + return -1; > + } > if (old_tuple != NULL) { > /* > * Forbid changes of UUID for a registered instance: > @@ -3525,17 +4001,21 @@ on_replace_dd_cluster(struct trigger *trigger, void > *event) * in sync with appliers and relays. > */ > tt_uuid old_uuid; > - tuple_field_uuid_xc(old_tuple, BOX_CLUSTER_FIELD_UUID, > - &old_uuid); > + if (tuple_field_uuid(old_tuple, BOX_CLUSTER_FIELD_UUID, > + &old_uuid) != 0) > + return -1; > if (!tt_uuid_is_equal(&replica_uuid, &old_uuid)) { > - tnt_raise(ClientError, ER_UNSUPPORTED, > + diag_set(ClientError, ER_UNSUPPORTED, > "Space _cluster", > "updates of instance uuid"); > + return -1; > } > } else { > struct trigger *on_commit; > on_commit = txn_alter_trigger_new(register_replica, > new_tuple); > + if (on_commit == NULL) > + return -1; > txn_stmt_on_commit(stmt, on_commit); > } > } else { > @@ -3544,15 +4024,20 @@ on_replace_dd_cluster(struct trigger *trigger, void > *event) * from _cluster. > */ > assert(old_tuple != NULL); > - uint32_t replica_id = > - tuple_field_u32_xc(old_tuple, BOX_CLUSTER_FIELD_ID); > - replica_check_id(replica_id); > + uint32_t replica_id; > + if (tuple_field_u32(old_tuple, BOX_CLUSTER_FIELD_ID, &replica_id) != 0) > + return -1; > + if (replica_check_id(replica_id) != 0) > + return -1; > > struct trigger *on_commit; > on_commit = txn_alter_trigger_new(unregister_replica, > old_tuple); > + if (on_commit == NULL) > + return -1; > txn_stmt_on_commit(stmt, on_commit); > } > + return 0; > } > > /* }}} cluster configuration */ > @@ -3564,79 +4049,105 @@ static struct sequence_def * > sequence_def_new_from_tuple(struct tuple *tuple, uint32_t errcode) > { > uint32_t name_len; > - const char *name = tuple_field_str_xc(tuple, BOX_USER_FIELD_NAME, > - &name_len); > + const char *name = tuple_field_str(tuple, BOX_USER_FIELD_NAME, > + &name_len); > + if (name == NULL) > + return NULL; > if (name_len > BOX_NAME_MAX) { > - tnt_raise(ClientError, errcode, > + diag_set(ClientError, errcode, > tt_cstr(name, BOX_INVALID_NAME_MAX), > "sequence name is too long"); > + return NULL; > } > - identifier_check_xc(name, name_len); > + if (identifier_check(name, name_len) != 0) > + return NULL; > size_t sz = sequence_def_sizeof(name_len); > struct sequence_def *def = (struct sequence_def *) malloc(sz); > - if (def == NULL) > - tnt_raise(OutOfMemory, sz, "malloc", "sequence"); > + if (def == NULL) { > + diag_set(OutOfMemory, sz, "malloc", "sequence"); > + return NULL; > + } > auto def_guard = make_scoped_guard([=] { free(def); }); > memcpy(def->name, name, name_len); > def->name[name_len] = '\0'; > - def->id = tuple_field_u32_xc(tuple, BOX_SEQUENCE_FIELD_ID); > - def->uid = tuple_field_u32_xc(tuple, BOX_SEQUENCE_FIELD_UID); > - def->step = tuple_field_i64_xc(tuple, BOX_SEQUENCE_FIELD_STEP); > - def->min = tuple_field_i64_xc(tuple, BOX_SEQUENCE_FIELD_MIN); > - def->max = tuple_field_i64_xc(tuple, BOX_SEQUENCE_FIELD_MAX); > - def->start = tuple_field_i64_xc(tuple, BOX_SEQUENCE_FIELD_START); > - def->cache = tuple_field_i64_xc(tuple, BOX_SEQUENCE_FIELD_CACHE); > - def->cycle = tuple_field_bool_xc(tuple, BOX_SEQUENCE_FIELD_CYCLE); > - if (def->step == 0) > - tnt_raise(ClientError, errcode, def->name, > - "step option must be non-zero"); > - if (def->min > def->max) > - tnt_raise(ClientError, errcode, def->name, > - "max must be greater than or equal to min"); > - if (def->start < def->min || def->start > def->max) > - tnt_raise(ClientError, errcode, def->name, > - "start must be between min and max"); > + if (tuple_field_u32(tuple, BOX_SEQUENCE_FIELD_ID, &(def->id)) != 0) > + return NULL; > + if (tuple_field_u32(tuple, BOX_SEQUENCE_FIELD_UID, &(def->uid)) != 0) > + return NULL; > + if (tuple_field_i64(tuple, BOX_SEQUENCE_FIELD_STEP, &(def->step)) != 0) > + return NULL; > + if (tuple_field_i64(tuple, BOX_SEQUENCE_FIELD_MIN, &(def->min)) != 0) > + return NULL; > + if (tuple_field_i64(tuple, BOX_SEQUENCE_FIELD_MAX, &(def->max)) != 0) > + return NULL; > + if (tuple_field_i64(tuple, BOX_SEQUENCE_FIELD_START, &(def->start)) != 0) > + return NULL; > + if (tuple_field_i64(tuple, BOX_SEQUENCE_FIELD_CACHE, &(def->cache)) != 0) > + return NULL; > + if (tuple_field_bool(tuple, BOX_SEQUENCE_FIELD_CYCLE, &(def->cycle)) != 0) > + return NULL; > + if (def->step == 0) { > + diag_set(ClientError, errcode, def->name, > + "step option must be non-zero"); > + return NULL; > + } > + if (def->min > def->max) { > + diag_set(ClientError, errcode, def->name, > + "max must be greater than or equal to min"); > + return NULL; > + } > + if (def->start < def->min || def->start > def->max) { > + diag_set(ClientError, errcode, def->name, > + "start must be between min and max"); > + return NULL; > + } > def_guard.is_active = false; > return def; > } > > -static void > +static int > on_create_sequence_rollback(struct trigger *trigger, void * /* event */) > { > /* Remove the new sequence from the cache and delete it. */ > struct sequence *seq = (struct sequence *)trigger->data; > sequence_cache_delete(seq->def->id); > - trigger_run_xc(&on_alter_sequence, seq); > + if (trigger_run(&on_alter_sequence, seq) != 0) > + return -1; > sequence_delete(seq); > + return 0; > } > > -static void > +static int > on_drop_sequence_commit(struct trigger *trigger, void * /* event */) > { > /* Delete the old sequence. */ > struct sequence *seq = (struct sequence *)trigger->data; > sequence_delete(seq); > + return 0; > } > > -static void > +static int > on_drop_sequence_rollback(struct trigger *trigger, void * /* event */) > { > /* Insert the old sequence back into the cache. */ > struct sequence *seq = (struct sequence *)trigger->data; > sequence_cache_insert(seq); > - trigger_run_xc(&on_alter_sequence, seq); > + if (trigger_run(&on_alter_sequence, seq) != 0) > + return -1; > + return 0; > } > > > -static void > +static int > on_alter_sequence_commit(struct trigger *trigger, void * /* event */) > { > /* Delete the old old sequence definition. */ > struct sequence_def *def = (struct sequence_def *)trigger->data; > free(def); > + return 0; > } > > -static void > +static int > on_alter_sequence_rollback(struct trigger *trigger, void * /* event */) > { > /* Restore the old sequence definition. */ > @@ -3645,14 +4156,16 @@ on_alter_sequence_rollback(struct trigger *trigger, > void * /* event */) assert(seq != NULL); > free(seq->def); > seq->def = def; > - trigger_run_xc(&on_alter_sequence, seq); > + if (trigger_run(&on_alter_sequence, seq) != 0) > + return -1; > + return 0; > } > > /** > * A trigger invoked on replace in space _sequence. > * Used to alter a sequence definition. > */ > -static void > +static int > on_replace_dd_sequence(struct trigger * /* trigger */, void *event) > { > struct txn *txn = (struct txn *) event; > @@ -3667,76 +4180,112 @@ on_replace_dd_sequence(struct trigger * /* trigger > */, void *event) if (old_tuple == NULL && new_tuple != NULL) { / * INSERT > */ > new_def = sequence_def_new_from_tuple(new_tuple, > ER_CREATE_SEQUENCE); > - access_check_ddl(new_def->name, new_def->id, new_def- >uid, > - SC_SEQUENCE, PRIV_C); > + if (new_def == NULL) > + return -1; > + if (access_check_ddl(new_def->name, new_def->id, new_def->uid, > + SC_SEQUENCE, PRIV_C) != 0) > + return -1; > struct trigger *on_rollback = > txn_alter_trigger_new(on_create_sequence_rollback, NULL); > - seq = sequence_new_xc(new_def); > + if (on_rollback == NULL) > + return -1; > + seq = sequence_new(new_def); > + if (seq == NULL) > + return -1; > sequence_cache_insert(seq); > on_rollback->data = seq; > txn_stmt_on_rollback(stmt, on_rollback); > } else if (old_tuple != NULL && new_tuple == NULL) { /* DELETE */ > - uint32_t id = tuple_field_u32_xc(old_tuple, > - BOX_SEQUENCE_DATA_FIELD_ID); > + uint32_t id; > + if (tuple_field_u32(old_tuple,BOX_SEQUENCE_DATA_FIELD_ID, &id) != 0) > + return -1; > seq = sequence_by_id(id); > assert(seq != NULL); > - access_check_ddl(seq->def->name, seq->def->id, seq- >def->uid, > - SC_SEQUENCE, PRIV_D); > - if (space_has_data(BOX_SEQUENCE_DATA_ID, 0, id)) > - tnt_raise(ClientError, ER_DROP_SEQUENCE, > + if (access_check_ddl(seq->def->name, seq->def->id, seq- >def->uid, > + SC_SEQUENCE, PRIV_D) != 0) > + return -1; > + bool out; > + if (space_has_data(BOX_SEQUENCE_DATA_ID, 0, id, &out) != 0) > + return -1; > + if (out) { > + diag_set(ClientError, ER_DROP_SEQUENCE, > seq->def->name, "the sequence has data"); > - if (space_has_data(BOX_SPACE_SEQUENCE_ID, 1, id)) > - tnt_raise(ClientError, ER_DROP_SEQUENCE, > - seq->def->name, "the sequence is in use"); > - if (schema_find_grants("sequence", seq->def->id)) > - tnt_raise(ClientError, ER_DROP_SEQUENCE, > + return -1; > + } > + if (space_has_data(BOX_SPACE_SEQUENCE_ID, 1, id, &out) ! = 0) > + return -1; > + if (out) { > + diag_set(ClientError, ER_DROP_SEQUENCE, > + seq->def->name, "the sequence is in use"); > + return -1; > + } > + if (schema_find_grants("sequence", seq->def->id, &out) != 0) { > + return -1; > + } > + if (out) { > + diag_set(ClientError, ER_DROP_SEQUENCE, > seq->def->name, "the sequence has grants"); > + return -1; > + } > struct trigger *on_commit = > txn_alter_trigger_new(on_drop_sequence_commit, seq); > struct trigger *on_rollback = > txn_alter_trigger_new(on_drop_sequence_rollback, seq); > + if (on_commit == NULL || on_rollback == NULL) > + return -1; > sequence_cache_delete(seq->def->id); > txn_stmt_on_commit(stmt, on_commit); > txn_stmt_on_rollback(stmt, on_rollback); > } else { /* UPDATE */ > new_def = sequence_def_new_from_tuple(new_tuple, > ER_ALTER_SEQUENCE); > + if (new_def == NULL) > + return -1; > seq = sequence_by_id(new_def->id); > assert(seq != NULL); > - access_check_ddl(seq->def->name, seq->def->id, seq- >def->uid, > - SC_SEQUENCE, PRIV_A); > + if (access_check_ddl(seq->def->name, seq->def->id, seq- >def->uid, > + SC_SEQUENCE, PRIV_A) != 0) > + return -1; > struct trigger *on_commit = > txn_alter_trigger_new(on_alter_sequence_commit, seq->def); > struct trigger *on_rollback = > txn_alter_trigger_new(on_alter_sequence_rollback, seq->def); > + if (on_commit == NULL || on_rollback == NULL) > + return -1; > seq->def = new_def; > txn_stmt_on_commit(stmt, on_commit); > txn_stmt_on_rollback(stmt, on_rollback); > } > > def_guard.is_active = false; > - trigger_run_xc(&on_alter_sequence, seq); > + if (trigger_run(&on_alter_sequence, seq) != 0) > + return -1; > + return 0; > } > > /** Restore the old sequence value on rollback. */ > -static void > +static int > on_drop_sequence_data_rollback(struct trigger *trigger, void * /* event */) > { > struct tuple *tuple = (struct tuple *)trigger->data; > - uint32_t id = tuple_field_u32_xc(tuple, BOX_SEQUENCE_DATA_FIELD_ID); > - int64_t val = tuple_field_i64_xc(tuple, BOX_SEQUENCE_DATA_FIELD_VALUE); > - > + uint32_t id; > + if (tuple_field_u32(tuple, BOX_SEQUENCE_DATA_FIELD_ID, &id) != 0) > + return -1; > + int64_t val; > + if (tuple_field_i64(tuple, BOX_SEQUENCE_DATA_FIELD_VALUE, &val) != 0) > + return -1; > struct sequence *seq = sequence_by_id(id); > assert(seq != NULL); > if (sequence_set(seq, val) != 0) > panic("Can't restore sequence value"); > + return 0; > } > > /** > * A trigger invoked on replace in space _sequence_data. > * Used to update a sequence value. > */ > -static void > +static int > on_replace_dd_sequence_data(struct trigger * /* trigger */, void *event) > { > struct txn *txn = (struct txn *) event; > @@ -3744,17 +4293,21 @@ on_replace_dd_sequence_data(struct trigger * /* > trigger */, void *event) struct tuple *old_tuple = stmt->old_tuple; > struct tuple *new_tuple = stmt->new_tuple; > > - uint32_t id = tuple_field_u32_xc(old_tuple ?: new_tuple, > - BOX_SEQUENCE_DATA_FIELD_ID); > - struct sequence *seq = sequence_cache_find(id); > + uint32_t id; > + if (tuple_field_u32(old_tuple ?: new_tuple,BOX_SEQUENCE_DATA_FIELD_ID, > + &id) != 0) > + return -1; > + struct sequence *seq = sequence_by_id(id); > if (seq == NULL) > - diag_raise(); > - if (new_tuple != NULL) { /* INSERT, UPDATE */ > - int64_t value = tuple_field_i64_xc(new_tuple, > - BOX_SEQUENCE_DATA_FIELD_VALUE); > + return -1; > + if (new_tuple != NULL) { /* INSERT, UPDATE */ > + int64_t value; > + if (tuple_field_i64(new_tuple, BOX_SEQUENCE_DATA_FIELD_VALUE, > + &value) != 0) > + return -1; > if (sequence_set(seq, value) != 0) > - diag_raise(); > - } else { /* DELETE */ > + return -1; > + } else { /* DELETE */ > /* > * A sequence isn't supposed to roll back to the old > * value if the transaction it was used in is aborted > @@ -3763,21 +4316,27 @@ on_replace_dd_sequence_data(struct trigger * /* > trigger */, void *event) * on rollback. > */ > struct trigger *on_rollback = txn_alter_trigger_new( > - on_drop_sequence_data_rollback, old_tuple); > + on_drop_sequence_data_rollback, old_tuple); > + if (on_rollback == NULL) > + return -1; > txn_stmt_on_rollback(stmt, on_rollback); > sequence_reset(seq); > } > + return 0; > } > > /** > * Extract field number and path from _space_sequence tuple. > * The path is allocated using malloc(). > */ > -static uint32_t > +static int > sequence_field_from_tuple(struct space *space, struct tuple *tuple, > - char **path_ptr) > + char **path_ptr, uint32_t *out) > { > - struct index *pk = index_find_xc(space, 0); > + struct index *pk = index_find(space, 0); > + if (pk == NULL) { > + return -1; > + } > struct key_part *part = &pk->def->key_def->parts[0]; > uint32_t fieldno = part->fieldno; > const char *path_raw = part->path; > @@ -3785,60 +4344,75 @@ sequence_field_from_tuple(struct space *space, > struct tuple *tuple, > > /* Sequence field was added in 2.2.1. */ > if (tuple_field_count(tuple) > BOX_SPACE_SEQUENCE_FIELD_FIELDNO) { > - fieldno = tuple_field_u32_xc(tuple, > - BOX_SPACE_SEQUENCE_FIELD_FIELDNO); > - path_raw = tuple_field_str_xc(tuple, > - BOX_SPACE_SEQUENCE_FIELD_PATH, &path_len); > + if (tuple_field_u32(tuple,BOX_SPACE_SEQUENCE_FIELD_FIELDNO, &fieldno) != > 0) + return -1; > + path_raw = tuple_field_str(tuple, > + BOX_SPACE_SEQUENCE_FIELD_PATH, &path_len); > + if (path_raw == NULL) > + return -1; > if (path_len == 0) > path_raw = NULL; > } > - index_def_check_sequence(pk->def, fieldno, path_raw, path_len, > - space_name(space)); > + if (index_def_check_sequence(pk->def, fieldno, path_raw, path_len, > + space_name(space)) != 0) > + return -1; > char *path = NULL; > if (path_raw != NULL) { > path = (char *)malloc(path_len + 1); > - if (path == NULL) > - tnt_raise(OutOfMemory, path_len + 1, > + if (path == NULL) { > + diag_set(OutOfMemory, path_len + 1, > "malloc", "sequence path"); > + return -1; > + } > memcpy(path, path_raw, path_len); > path[path_len] = 0; > } > *path_ptr = path; > - return fieldno; > + *out = fieldno; > + return 0; > } > > /** Attach a sequence to a space on rollback in _space_sequence. */ > -static void > +static int > set_space_sequence(struct trigger *trigger, void * /* event */) > { > struct tuple *tuple = (struct tuple *)trigger->data; > - uint32_t space_id = tuple_field_u32_xc(tuple, > - BOX_SPACE_SEQUENCE_FIELD_ID); > - uint32_t sequence_id = tuple_field_u32_xc(tuple, > - BOX_SPACE_SEQUENCE_FIELD_SEQUENCE_ID); > - bool is_generated = tuple_field_bool_xc(tuple, > - BOX_SPACE_SEQUENCE_FIELD_IS_GENERATED); > + uint32_t space_id; > + if (tuple_field_u32(tuple, BOX_SPACE_SEQUENCE_FIELD_ID, &space_id) ! = 0) > + return -1; > + uint32_t sequence_id; > + if (tuple_field_u32(tuple, BOX_SPACE_SEQUENCE_FIELD_SEQUENCE_ID, > &sequence_id) != 0) + return -1; > + bool is_generated; > + if (tuple_field_bool(tuple,BOX_SPACE_SEQUENCE_FIELD_IS_GENERATED, > + &is_generated) != 0) > + return -1; > struct space *space = space_by_id(space_id); > assert(space != NULL); > struct sequence *seq = sequence_by_id(sequence_id); > assert(seq != NULL); > char *path; > - uint32_t fieldno = sequence_field_from_tuple(space, tuple, &path); > + uint32_t fieldno; > + if (sequence_field_from_tuple(space, tuple, &path, &fieldno) != 0) > + return -1; > seq->is_generated = is_generated; > space->sequence = seq; > space->sequence_fieldno = fieldno; > free(space->sequence_path); > space->sequence_path = path; > - trigger_run_xc(&on_alter_space, space); > + if (trigger_run(&on_alter_space, space) != 0) > + return -1; > + return 0; > } > > /** Detach a sequence from a space on rollback in _space_sequence. */ > -static void > +static int > clear_space_sequence(struct trigger *trigger, void * /* event */) > { > struct tuple *tuple = (struct tuple *)trigger->data; > - uint32_t space_id = tuple_field_u32_xc(tuple, > - BOX_SPACE_SEQUENCE_FIELD_ID); > + uint32_t space_id; > + if (tuple_field_u32(tuple, BOX_SPACE_SEQUENCE_FIELD_ID, &space_id) ! = 0) > + return -1; > struct space *space = space_by_id(space_id); > assert(space != NULL); > assert(space->sequence != NULL); > @@ -3847,29 +4421,37 @@ clear_space_sequence(struct trigger *trigger, void * > /* event */) space->sequence_fieldno = 0; > free(space->sequence_path); > space->sequence_path = NULL; > - trigger_run_xc(&on_alter_space, space); > + if (trigger_run(&on_alter_space, space) != 0) > + return -1; > + return 0; > } > > /** > * A trigger invoked on replace in space _space_sequence. > * Used to update space <-> sequence mapping. > */ > -static void > +static int > on_replace_dd_space_sequence(struct trigger * /* trigger */, void *event) > { > struct txn *txn = (struct txn *) event; > struct txn_stmt *stmt = txn_current_stmt(txn); > struct tuple *tuple = stmt->new_tuple ? stmt->new_tuple : stmt- >old_tuple; > - > - uint32_t space_id = tuple_field_u32_xc(tuple, > - BOX_SPACE_SEQUENCE_FIELD_ID); > - uint32_t sequence_id = tuple_field_u32_xc(tuple, > - BOX_SPACE_SEQUENCE_FIELD_SEQUENCE_ID); > - bool is_generated = tuple_field_bool_xc(tuple, > - BOX_SPACE_SEQUENCE_FIELD_IS_GENERATED); > - > - struct space *space = space_cache_find_xc(space_id); > - struct sequence *seq = sequence_cache_find(sequence_id); > + uint32_t space_id; > + if (tuple_field_u32(tuple,BOX_SPACE_SEQUENCE_FIELD_ID, &space_id) != 0) > + return -1; > + uint32_t sequence_id; > + if (tuple_field_u32(tuple, BOX_SPACE_SEQUENCE_FIELD_SEQUENCE_ID, > &sequence_id) != 0) + return -1; > + bool is_generated; > + if (tuple_field_bool(tuple, BOX_SPACE_SEQUENCE_FIELD_IS_GENERATED, > + &is_generated) != 0) > + return -1; > + struct space *space = space_cache_find(space_id); > + if (space == NULL) > + return -1; > + struct sequence *seq = sequence_by_id(sequence_id); > + if (seq == NULL) > + return -1; > > enum priv_type priv_type = stmt->new_tuple ? PRIV_C : PRIV_D; > if (stmt->new_tuple && stmt->old_tuple) > @@ -3877,34 +4459,40 @@ on_replace_dd_space_sequence(struct trigger * /* > trigger */, void *event) > > /* Check we have the correct access type on the sequence. * */ > if (is_generated || !stmt->new_tuple) { > - access_check_ddl(seq->def->name, seq->def->id, seq- >def->uid, > - SC_SEQUENCE, priv_type); > + if (access_check_ddl(seq->def->name, seq->def->id, seq- >def->uid, > + SC_SEQUENCE, priv_type) != 0) > + return -1; > } else { > /* > * In case user wants to attach an existing sequence, > * check that it has read and write access. > */ > - access_check_ddl(seq->def->name, seq->def->id, seq- >def->uid, > - SC_SEQUENCE, PRIV_R); > - access_check_ddl(seq->def->name, seq->def->id, seq- >def->uid, > - SC_SEQUENCE, PRIV_W); > + if (access_check_ddl(seq->def->name, seq->def->id, seq- >def->uid, > + SC_SEQUENCE, PRIV_R) != 0) > + return -1; > + if (access_check_ddl(seq->def->name, seq->def->id, seq- >def->uid, > + SC_SEQUENCE, PRIV_W) != 0) > + return -1; > } > /** Check we have alter access on space. */ > - access_check_ddl(space->def->name, space->def->id, space->def- >uid, > - SC_SPACE, PRIV_A); > + if (access_check_ddl(space->def->name, space->def->id, space->def- >uid, > + SC_SPACE, PRIV_A) != 0) > + return -1; > > if (stmt->new_tuple != NULL) { /* INSERT, UPDATE */ > char *sequence_path; > uint32_t sequence_fieldno; > - sequence_fieldno = sequence_field_from_tuple(space, tuple, > - &sequence_path); > + if (sequence_field_from_tuple(space, tuple, &sequence_path, > + &sequence_fieldno) != 0) > + return -1; > auto sequence_path_guard = make_scoped_guard([=] { > free(sequence_path); > }); > if (seq->is_generated) { > - tnt_raise(ClientError, ER_ALTER_SPACE, > + diag_set(ClientError, ER_ALTER_SPACE, > space_name(space), > "can not attach generated sequence"); > + return -1; > } > struct trigger *on_rollback; > if (stmt->old_tuple != NULL) > @@ -3913,6 +4501,8 @@ on_replace_dd_space_sequence(struct trigger * /* > trigger */, void *event) else > on_rollback = txn_alter_trigger_new(clear_space_sequence, > stmt->new_tuple); > + if (on_rollback == NULL) > + return -1; > seq->is_generated = is_generated; > space->sequence = seq; > space->sequence_fieldno = sequence_fieldno; > @@ -3924,6 +4514,8 @@ on_replace_dd_space_sequence(struct trigger * /* > trigger */, void *event) struct trigger *on_rollback; > on_rollback = txn_alter_trigger_new(set_space_sequence, > stmt- >old_tuple); > + if (on_rollback == NULL) > + return -1; > assert(space->sequence == seq); > seq->is_generated = false; > space->sequence = NULL; > @@ -3932,13 +4524,15 @@ on_replace_dd_space_sequence(struct trigger * /* > trigger */, void *event) space->sequence_path = NULL; > txn_stmt_on_rollback(stmt, on_rollback); > } > - trigger_run_xc(&on_alter_space, space); > + if (trigger_run(&on_alter_space, space) != 0) > + return -1; > + return 0; > } > > /* }}} sequence */ > > /** Delete the new trigger on rollback of an INSERT statement. */ > -static void > +static int > on_create_trigger_rollback(struct trigger *trigger, void * /* event */) > { > struct sql_trigger *old_trigger = (struct sql_trigger *)trigger- >data; > @@ -3950,28 +4544,30 @@ on_create_trigger_rollback(struct trigger *trigger, > void * /* event */) assert(rc == 0); > assert(new_trigger == old_trigger); > sql_trigger_delete(sql_get(), new_trigger); > + return 0; > } > > /** Restore the old trigger on rollback of a DELETE statement. */ > -static void > +static int > on_drop_trigger_rollback(struct trigger *trigger, void * /* event */) > { > struct sql_trigger *old_trigger = (struct sql_trigger *)trigger- >data; > struct sql_trigger *new_trigger; > if (old_trigger == NULL) > - return; > + return 0; > if (sql_trigger_replace(sql_trigger_name(old_trigger), > sql_trigger_space_id(old_trigger), > old_trigger, &new_trigger) != 0) > panic("Out of memory on insertion into trigger hash"); > assert(new_trigger == NULL); > + return 0; > } > > /** > * Restore the old trigger and delete the new trigger on rollback > * of a REPLACE statement. > */ > -static void > +static int > on_replace_trigger_rollback(struct trigger *trigger, void * /* event */) > { > struct sql_trigger *old_trigger = (struct sql_trigger *)trigger- >data; > @@ -3981,24 +4577,26 @@ on_replace_trigger_rollback(struct trigger *trigger, > void * /* event */) old_trigger, &new_trigger) != 0) > panic("Out of memory on insertion into trigger hash"); > sql_trigger_delete(sql_get(), new_trigger); > + return 0; > } > > /** > * Trigger invoked on commit in the _trigger space. > * Drop useless old sql_trigger AST object if any. > */ > -static void > +static int > on_replace_trigger_commit(struct trigger *trigger, void * /* event */) > { > struct sql_trigger *old_trigger = (struct sql_trigger *)trigger- >data; > sql_trigger_delete(sql_get(), old_trigger); > + return 0; > } > > /** > * A trigger invoked on replace in a space containing > * SQL triggers. > */ > -static void > +static int > on_replace_dd_trigger(struct trigger * /* trigger */, void *event) > { > struct txn *txn = (struct txn *) event; > @@ -4009,19 +4607,24 @@ on_replace_dd_trigger(struct trigger * /* trigger > */, void *event) struct trigger *on_rollback = txn_alter_trigger_new(NULL, > NULL); struct trigger *on_commit = > txn_alter_trigger_new(on_replace_trigger_commit, NULL); > + if (on_rollback == NULL || on_commit == NULL) > + return -1; > > if (old_tuple != NULL && new_tuple == NULL) { > /* DROP trigger. */ > uint32_t trigger_name_len; > - const char *trigger_name_src = > - tuple_field_str_xc(old_tuple, BOX_TRIGGER_FIELD_NAME, > - &trigger_name_len); > - uint32_t space_id = > - tuple_field_u32_xc(old_tuple, > - BOX_TRIGGER_FIELD_SPACE_ID); > - char *trigger_name = > - (char *)region_alloc_xc(&fiber()->gc, > - trigger_name_len + 1); > + const char *trigger_name_src = tuple_field_str(old_tuple, > + BOX_TRIGGER_FIELD_NAME, &trigger_name_len); > + if (trigger_name_src == NULL) > + return -1; > + uint32_t space_id; > + if (tuple_field_u32(old_tuple,BOX_TRIGGER_FIELD_SPACE_ID, > + &space_id) != 0) > + return -1; > + char *trigger_name = (char *)region_alloc(&fiber()->gc, > + trigger_name_len + 1); > + if (trigger_name == NULL) > + return -1; > memcpy(trigger_name, trigger_name_src, trigger_name_len); > trigger_name[trigger_name_len] = 0; > > @@ -4037,21 +4640,22 @@ on_replace_dd_trigger(struct trigger * /* trigger > */, void *event) } else { > /* INSERT, REPLACE trigger. */ > uint32_t trigger_name_len; > - const char *trigger_name_src = > - tuple_field_str_xc(new_tuple, BOX_TRIGGER_FIELD_NAME, > - &trigger_name_len); > - > - const char *space_opts = > - tuple_field_with_type_xc(new_tuple, > - BOX_TRIGGER_FIELD_OPTS, > - MP_MAP); > + const char *trigger_name_src = tuple_field_str(new_tuple, > + BOX_TRIGGER_FIELD_NAME, &trigger_name_len); > + if (trigger_name_src == NULL) > + return -1; > + const char *space_opts = tuple_field_with_type(new_tuple, > + BOX_TRIGGER_FIELD_OPTS,MP_MAP); > + if (space_opts == NULL) > + return -1; > struct space_opts opts; > struct region *region = &fiber()->gc; > - space_opts_decode(&opts, space_opts, region); > + if (space_opts_decode(&opts, space_opts, region) != 0) > + return -1; > struct sql_trigger *new_trigger = > sql_trigger_compile(sql_get(), opts.sql); > if (new_trigger == NULL) > - diag_raise(); > + return -1; > > auto new_trigger_guard = make_scoped_guard([=] { > sql_trigger_delete(sql_get(), new_trigger); > @@ -4061,24 +4665,27 @@ on_replace_dd_trigger(struct trigger * /* trigger > */, void *event) if (strlen(trigger_name) != trigger_name_len || > memcmp(trigger_name_src, trigger_name, > trigger_name_len) != 0) { > - tnt_raise(ClientError, ER_SQL_EXECUTE, > + diag_set(ClientError, ER_SQL_EXECUTE, > "trigger name does not match extracted " > "from SQL"); > + return -1; > } > - uint32_t space_id = > - tuple_field_u32_xc(new_tuple, > - BOX_TRIGGER_FIELD_SPACE_ID); > + uint32_t space_id; > + if (tuple_field_u32(new_tuple,BOX_TRIGGER_FIELD_SPACE_ID, > + &space_id) != 0) > + return -1; > if (space_id != sql_trigger_space_id(new_trigger)) { > - tnt_raise(ClientError, ER_SQL_EXECUTE, > + diag_set(ClientError, ER_SQL_EXECUTE, > "trigger space_id does not match the value " > "resolved on AST building from SQL"); > + return -1; > } > > struct sql_trigger *old_trigger; > if (sql_trigger_replace(trigger_name, > sql_trigger_space_id(new_trigger), > new_trigger, &old_trigger) != 0) > - diag_raise(); > + return -1; > > on_commit->data = old_trigger; > if (old_tuple != NULL) { > @@ -4093,6 +4700,7 @@ on_replace_dd_trigger(struct trigger * /* trigger */, > void *event) > > txn_stmt_on_rollback(stmt, on_rollback); > txn_stmt_on_commit(stmt, on_commit); > + return 0; > } > > /** > @@ -4112,38 +4720,45 @@ decode_fk_links(struct tuple *tuple, uint32_t > *out_count, const char *constraint_name, uint32_t constraint_len, > uint32_t errcode) > { > - const char *parent_cols = > - tuple_field_with_type_xc(tuple, > - BOX_FK_CONSTRAINT_FIELD_PARENT_COLS, > - MP_ARRAY); > + const char *parent_cols = tuple_field_with_type(tuple, > + BOX_FK_CONSTRAINT_FIELD_PARENT_COLS, MP_ARRAY); > + if (parent_cols == NULL) > + return NULL; > uint32_t count = mp_decode_array(&parent_cols); > if (count == 0) { > - tnt_raise(ClientError, errcode, > + diag_set(ClientError, errcode, > tt_cstr(constraint_name, constraint_len), > "at least one link must be specified"); > + return NULL; > } > - const char *child_cols = > - tuple_field_with_type_xc(tuple, > - BOX_FK_CONSTRAINT_FIELD_CHILD_COLS, > - MP_ARRAY); > + const char *child_cols = tuple_field_with_type(tuple, > + BOX_FK_CONSTRAINT_FIELD_CHILD_COLS, MP_ARRAY); > + if (child_cols == NULL) > + return NULL; > if (mp_decode_array(&child_cols) != count) { > - tnt_raise(ClientError, errcode, > + diag_set(ClientError, errcode, > tt_cstr(constraint_name, constraint_len), > "number of referenced and referencing fields " > "must be the same"); > + return NULL; > } > *out_count = count; > size_t size = count * sizeof(struct field_link); > struct field_link *region_links = > - (struct field_link *) region_alloc_xc(&fiber()->gc, size); > + (struct field_link *)region_alloc(&fiber()->gc, size); > + if (region_links == NULL) { > + diag_set(OutOfMemory, size, "region", "new slab"); > + return NULL; > + } > memset(region_links, 0, size); > for (uint32_t i = 0; i < count; ++i) { > if (mp_typeof(*parent_cols) != MP_UINT || > mp_typeof(*child_cols) != MP_UINT) { > - tnt_raise(ClientError, errcode, > + diag_set(ClientError, errcode, > tt_cstr(constraint_name, constraint_len), > tt_sprintf("value of %d link is not unsigned", > i)); > + return NULL; > } > region_links[i].parent_field = mp_decode_uint(&parent_cols); > region_links[i].child_field = mp_decode_uint(&child_cols); > @@ -4156,24 +4771,29 @@ static struct fk_constraint_def * > fk_constraint_def_new_from_tuple(struct tuple *tuple, uint32_t errcode) > { > uint32_t name_len; > - const char *name = > - tuple_field_str_xc(tuple, BOX_FK_CONSTRAINT_FIELD_NAME, > - &name_len); > + const char *name = tuple_field_str(tuple, BOX_FK_CONSTRAINT_FIELD_NAME, > &name_len); + if (name == NULL) > + return NULL; > if (name_len > BOX_NAME_MAX) { > - tnt_raise(ClientError, errcode, > + diag_set(ClientError, errcode, > tt_cstr(name, BOX_INVALID_NAME_MAX), > "constraint name is too long"); > + return NULL; > } > - identifier_check_xc(name, name_len); > + if (identifier_check(name, name_len) != 0) > + return NULL; > uint32_t link_count; > struct field_link *links = decode_fk_links(tuple, &link_count, name, > name_len, errcode); > + if (links == NULL) > + return NULL; > size_t fk_def_sz = fk_constraint_def_sizeof(link_count, name_len); > struct fk_constraint_def *fk_def = > (struct fk_constraint_def *) malloc(fk_def_sz); > if (fk_def == NULL) { > - tnt_raise(OutOfMemory, fk_def_sz, "malloc", > + diag_set(OutOfMemory, fk_def_sz, "malloc", > "struct fk_constraint_def"); > + return NULL; > } > auto def_guard = make_scoped_guard([=] { free(fk_def); }); > memcpy(fk_def->name, name, name_len); > @@ -4182,37 +4802,44 @@ fk_constraint_def_new_from_tuple(struct tuple > *tuple, uint32_t errcode) name_len + 1); > memcpy(fk_def->links, links, link_count * sizeof(struct field_link)); > fk_def->field_count = link_count; > - fk_def->child_id = tuple_field_u32_xc(tuple, > - BOX_FK_CONSTRAINT_FIELD_CHILD_ID); > - fk_def->parent_id = > - tuple_field_u32_xc(tuple, BOX_FK_CONSTRAINT_FIELD_PARENT_ID); > - fk_def->is_deferred = > - tuple_field_bool_xc(tuple, BOX_FK_CONSTRAINT_FIELD_DEFERRED); > - const char *match = tuple_field_str_xc(tuple, > - BOX_FK_CONSTRAINT_FIELD_MATCH, > - &name_len); > + if (tuple_field_u32(tuple, BOX_FK_CONSTRAINT_FIELD_CHILD_ID, > + &(fk_def->child_id )) != 0) > + return NULL; > + if (tuple_field_u32(tuple, BOX_FK_CONSTRAINT_FIELD_PARENT_ID, > &(fk_def->parent_id)) != 0) + return NULL; > + if (tuple_field_bool(tuple, BOX_FK_CONSTRAINT_FIELD_DEFERRED, > &(fk_def->is_deferred)) != 0) + return NULL; > + const char *match = tuple_field_str(tuple, > + BOX_FK_CONSTRAINT_FIELD_MATCH, &name_len); > + if (match == NULL) > + return NULL; > fk_def->match = STRN2ENUM(fk_constraint_match, match, name_len); > if (fk_def->match == fk_constraint_match_MAX) { > - tnt_raise(ClientError, errcode, fk_def->name, > + diag_set(ClientError, errcode, fk_def->name, > "unknown MATCH clause"); > + return NULL; > } > - const char *on_delete_action = > - tuple_field_str_xc(tuple, BOX_FK_CONSTRAINT_FIELD_ON_DELETE, > - &name_len); > + const char *on_delete_action = tuple_field_str(tuple, > + BOX_FK_CONSTRAINT_FIELD_ON_DELETE, &name_len); > + if (on_delete_action == NULL) > + return NULL; > fk_def->on_delete = STRN2ENUM(fk_constraint_action, > on_delete_action, name_len); > if (fk_def->on_delete == fk_constraint_action_MAX) { > - tnt_raise(ClientError, errcode, fk_def->name, > + diag_set(ClientError, errcode, fk_def->name, > "unknown ON DELETE action"); > + return NULL; > } > - const char *on_update_action = > - tuple_field_str_xc(tuple, BOX_FK_CONSTRAINT_FIELD_ON_UPDATE, > - &name_len); > + const char *on_update_action = tuple_field_str(tuple, > + BOX_FK_CONSTRAINT_FIELD_ON_UPDATE, &name_len); > + if (on_update_action == NULL) > + return NULL; > fk_def->on_update = STRN2ENUM(fk_constraint_action, > on_update_action, name_len); > if (fk_def->on_update == fk_constraint_action_MAX) { > - tnt_raise(ClientError, errcode, fk_def->name, > + diag_set(ClientError, errcode, fk_def->name, > "unknown ON UPDATE action"); > + return NULL; > } > def_guard.is_active = false; > return fk_def; > @@ -4286,7 +4913,7 @@ space_reset_fk_constraint_mask(struct space *space) > * from parent's and child's lists of constraints and > * release memory. > */ > -static void > +static int > on_create_fk_constraint_rollback(struct trigger *trigger, void *event) > { > (void) event; > @@ -4296,10 +4923,11 @@ on_create_fk_constraint_rollback(struct trigger > *trigger, void *event) > space_reset_fk_constraint_mask(space_by_id(fk->def->parent_id)); > space_reset_fk_constraint_mask(space_by_id(fk->def->child_id)); > fk_constraint_delete(fk); > + return 0; > } > > /** Return old FK and release memory for the new one. */ > -static void > +static int > on_replace_fk_constraint_rollback(struct trigger *trigger, void *event) > { > (void) event; > @@ -4314,10 +4942,11 @@ on_replace_fk_constraint_rollback(struct trigger > *trigger, void *event) rlist_add_entry(&parent->parent_fk_constraint, > old_fk, in_parent_space); space_reset_fk_constraint_mask(parent); > space_reset_fk_constraint_mask(child); > + return 0; > } > > /** On rollback of drop simply return back FK to DD. */ > -static void > +static int > on_drop_fk_constraint_rollback(struct trigger *trigger, void *event) > { > (void) event; > @@ -4330,6 +4959,7 @@ on_drop_fk_constraint_rollback(struct trigger > *trigger, void *event) FIELD_LINK_CHILD); > fk_constraint_set_mask(old_fk, &parent->fk_constraint_mask, > FIELD_LINK_PARENT); > + return 0; > } > > /** > @@ -4337,11 +4967,12 @@ on_drop_fk_constraint_rollback(struct trigger > *trigger, void *event) * foreign key entry from both (parent's and child's) > lists, > * so just release memory. > */ > -static void > +static int > on_drop_or_replace_fk_constraint_commit(struct trigger *trigger, void > *event) { > (void) event; > fk_constraint_delete((struct fk_constraint *) trigger->data); > + return 0; > } > > /** > @@ -4351,7 +4982,7 @@ on_drop_or_replace_fk_constraint_commit(struct trigger > *trigger, void *event) * use bit mask. Otherwise, fall through slow check > where we > * use O(field_cont^2) simple nested cycle iterations. > */ > -static void > +static int > fk_constraint_check_dup_links(struct fk_constraint_def *fk_def) > { > uint64_t field_mask = 0; > @@ -4364,7 +4995,7 @@ fk_constraint_check_dup_links(struct fk_constraint_def > *fk_def) goto error; > field_mask |= parent_field; > } > - return; > + return 0; > slow_check: > for (uint32_t i = 0; i < fk_def->field_count; ++i) { > uint32_t parent_field = fk_def->links[i].parent_field; > @@ -4373,14 +5004,15 @@ slow_check: > goto error; > } > } > - return; > + return 0; > error: > - tnt_raise(ClientError, ER_CREATE_FK_CONSTRAINT, fk_def->name, > + diag_set(ClientError, ER_CREATE_FK_CONSTRAINT, fk_def->name, > "referenced fields can not contain duplicates"); > + return -1; > } > > /** A trigger invoked on replace in the _fk_constraint space. */ > -static void > +static int > on_replace_dd_fk_constraint(struct trigger * /* trigger*/, void *event) > { > struct txn *txn = (struct txn *) event; > @@ -4392,20 +5024,26 @@ on_replace_dd_fk_constraint(struct trigger * /* > trigger*/, void *event) struct fk_constraint_def *fk_def = > fk_constraint_def_new_from_tuple(new_tuple, > ER_CREATE_FK_CONSTRAINT); > + if (fk_def == NULL) > + return -1; > auto fk_def_guard = make_scoped_guard([=] { free(fk_def); }); > - struct space *child_space = > - space_cache_find_xc(fk_def->child_id); > + struct space *child_space = space_cache_find(fk_def- >child_id); > + if (child_space == NULL) > + return -1; > if (child_space->def->opts.is_view) { > - tnt_raise(ClientError, ER_CREATE_FK_CONSTRAINT, > + diag_set(ClientError, ER_CREATE_FK_CONSTRAINT, > fk_def->name, > "referencing space can't be VIEW"); > + return -1; > } > - struct space *parent_space = > - space_cache_find_xc(fk_def->parent_id); > + struct space *parent_space = space_cache_find(fk_def- >parent_id); > + if (parent_space == NULL) > + return -1; > if (parent_space->def->opts.is_view) { > - tnt_raise(ClientError, ER_CREATE_FK_CONSTRAINT, > + diag_set(ClientError, ER_CREATE_FK_CONSTRAINT, > fk_def->name, > "referenced space can't be VIEW"); > + return -1; > } > /* > * FIXME: until SQL triggers are completely > @@ -4416,9 +5054,10 @@ on_replace_dd_fk_constraint(struct trigger * /* > trigger*/, void *event) */ > struct index *pk = space_index(child_space, 0); > if (pk != NULL && index_size(pk) > 0) { > - tnt_raise(ClientError, ER_CREATE_FK_CONSTRAINT, > + diag_set(ClientError, ER_CREATE_FK_CONSTRAINT, > fk_def->name, > "referencing space must be empty"); > + return -1; > } > /* Check types of referenced fields. */ > for (uint32_t i = 0; i < fk_def->field_count; ++i) { > @@ -4426,9 +5065,10 @@ on_replace_dd_fk_constraint(struct trigger * /* > trigger*/, void *event) uint32_t parent_fieldno = > fk_def->links[i].parent_field; > if (child_fieldno >= child_space->def- >field_count || > parent_fieldno >= parent_space->def- >field_count) { > - tnt_raise(ClientError, ER_CREATE_FK_CONSTRAINT, > + diag_set(ClientError, ER_CREATE_FK_CONSTRAINT, > fk_def->name, "foreign key refers to " > "nonexistent field"); > + return -1; > } > struct field_def *child_field = > &child_space->def- >fields[child_fieldno]; > @@ -4436,16 +5076,19 @@ on_replace_dd_fk_constraint(struct trigger * /* > trigger*/, void *event) &parent_space->def->fields[parent_fieldno]; > if (! field_type1_contains_type2(parent_field- >type, > child_field->type)) { > - tnt_raise(ClientError, ER_CREATE_FK_CONSTRAINT, > + diag_set(ClientError, ER_CREATE_FK_CONSTRAINT, > fk_def->name, "field type mismatch"); > + return -1; > } > if (child_field->coll_id != parent_field- >coll_id) { > - tnt_raise(ClientError, ER_CREATE_FK_CONSTRAINT, > + diag_set(ClientError, ER_CREATE_FK_CONSTRAINT, > fk_def->name, > "field collation mismatch"); > + return -1; > } > } > - fk_constraint_check_dup_links(fk_def); > + if (fk_constraint_check_dup_links(fk_def) != 0) > + return -1; > /* > * Search for suitable index in parent space: > * it must be unique and consist exactly from > @@ -4464,8 +5107,8 @@ on_replace_dd_fk_constraint(struct trigger * /* > trigger*/, void *event) for (j = 0; j < fk_def->field_count; ++j) { > if (key_def_find_by_fieldno(idx- >def->key_def, > fk_def->links[j]. > - parent_field) == > - NULL) > + parent_field) == > + NULL) > break; > } > if (j != fk_def->field_count) > @@ -4474,15 +5117,17 @@ on_replace_dd_fk_constraint(struct trigger * /* > trigger*/, void *event) break; > } > if (fk_index == NULL) { > - tnt_raise(ClientError, ER_CREATE_FK_CONSTRAINT, > + diag_set(ClientError, ER_CREATE_FK_CONSTRAINT, > fk_def->name, "referenced fields don't " > "compose unique index"); > + return -1; > } > struct fk_constraint *fk = > (struct fk_constraint *) malloc(sizeof(*fk)); > if (fk == NULL) { > - tnt_raise(OutOfMemory, sizeof(*fk), > + diag_set(OutOfMemory, sizeof(*fk), > "malloc", "struct fk_constraint"); > + return -1; > } > auto fk_guard = make_scoped_guard([=] { free(fk); }); > memset(fk, 0, sizeof(*fk)); > @@ -4496,6 +5141,8 @@ on_replace_dd_fk_constraint(struct trigger * /* > trigger*/, void *event) struct trigger *on_rollback = > txn_alter_trigger_new(on_create_fk_constraint_rollback, > fk); > + if (on_rollback == NULL) > + return -1; > txn_stmt_on_rollback(stmt, on_rollback); > fk_constraint_set_mask(fk, > &parent_space- >fk_constraint_mask, > @@ -4514,10 +5161,14 @@ on_replace_dd_fk_constraint(struct trigger * /* > trigger*/, void *event) struct trigger *on_rollback = > txn_alter_trigger_new(on_replace_fk_constraint_rollback, > old_fk); > + if (on_rollback == NULL) > + return -1; > txn_stmt_on_rollback(stmt, on_rollback); > struct trigger *on_commit = > txn_alter_trigger_new(on_drop_or_replace_fk_constraint_commit, > old_fk); > + if (on_commit == NULL) > + return -1; > txn_stmt_on_commit(stmt, on_commit); > space_reset_fk_constraint_mask(child_space); > space_reset_fk_constraint_mask(parent_space); > @@ -4529,25 +5180,32 @@ on_replace_dd_fk_constraint(struct trigger * /* > trigger*/, void *event) struct fk_constraint_def *fk_def = > fk_constraint_def_new_from_tuple(old_tuple, > ER_DROP_FK_CONSTRAINT); > + if (fk_def == NULL) > + return -1; > auto fk_def_guard = make_scoped_guard([=] { free(fk_def); }); > - struct space *child_space = > - space_cache_find_xc(fk_def->child_id); > - struct space *parent_space = > - space_cache_find_xc(fk_def->parent_id); > + struct space *child_space = space_cache_find(fk_def- >child_id); > + struct space *parent_space = space_cache_find(fk_def- >parent_id); > + if (child_space == NULL or parent_space == NULL) > + return -1; > struct fk_constraint *old_fk= > fk_constraint_remove(&child_space- >child_fk_constraint, > fk_def->name); > struct trigger *on_commit = > txn_alter_trigger_new(on_drop_or_replace_fk_constraint_commit, > old_fk); > + if (on_commit == NULL) > + return -1; > txn_stmt_on_commit(stmt, on_commit); > struct trigger *on_rollback = > txn_alter_trigger_new(on_drop_fk_constraint_rollback, > old_fk); > + if (on_rollback == NULL) > + return -1; > txn_stmt_on_rollback(stmt, on_rollback); > space_reset_fk_constraint_mask(child_space); > space_reset_fk_constraint_mask(parent_space); > } > + return 0; > } > > /** Create an instance of check constraint definition by tuple. */ > @@ -4555,39 +5213,43 @@ static struct ck_constraint_def * > ck_constraint_def_new_from_tuple(struct tuple *tuple) > { > uint32_t name_len; > - const char *name = > - tuple_field_str_xc(tuple, BOX_CK_CONSTRAINT_FIELD_NAME, > - &name_len); > + const char *name = tuple_field_str(tuple, BOX_CK_CONSTRAINT_FIELD_NAME, > &name_len); + if (name == NULL) > + return NULL; > if (name_len > BOX_NAME_MAX) { > - tnt_raise(ClientError, ER_CREATE_CK_CONSTRAINT, > + diag_set(ClientError, ER_CREATE_CK_CONSTRAINT, > tt_cstr(name, BOX_INVALID_NAME_MAX), > "check constraint name is too long"); > + return NULL; > } > - identifier_check_xc(name, name_len); > - uint32_t space_id = > - tuple_field_u32_xc(tuple, BOX_CK_CONSTRAINT_FIELD_SPACE_ID); > - const char *language_str = > - tuple_field_cstr_xc(tuple, BOX_CK_CONSTRAINT_FIELD_LANGUAGE); > + if (identifier_check(name, name_len) != 0) > + return NULL; > + uint32_t space_id; > + if (tuple_field_u32(tuple, BOX_CK_CONSTRAINT_FIELD_SPACE_ID, &space_id) != > 0) + return NULL; > + const char *language_str = tuple_field_cstr(tuple, > BOX_CK_CONSTRAINT_FIELD_LANGUAGE); + if (language_str == NULL) > + return NULL; > enum ck_constraint_language language = > STR2ENUM(ck_constraint_language, language_str); > if (language == ck_constraint_language_MAX) { > - tnt_raise(ClientError, ER_FUNCTION_LANGUAGE, language_str, > + diag_set(ClientError, ER_FUNCTION_LANGUAGE, language_str, > tt_cstr(name, name_len)); > + return NULL; > } > uint32_t expr_str_len; > - const char *expr_str = > - tuple_field_str_xc(tuple, BOX_CK_CONSTRAINT_FIELD_CODE, > - &expr_str_len); > + const char *expr_str = tuple_field_str(tuple, > + BOX_CK_CONSTRAINT_FIELD_CODE, &expr_str_len); > + if (expr_str == NULL) > + return NULL; > struct ck_constraint_def *ck_def = > ck_constraint_def_new(name, name_len, expr_str, expr_str_len, > space_id, language); > - if (ck_def == NULL) > - diag_raise(); > return ck_def; > } > > /** Rollback INSERT check constraint. */ > -static void > +static int > on_create_ck_constraint_rollback(struct trigger *trigger, void * /* event > */) { > struct ck_constraint *ck = (struct ck_constraint *)trigger->data; > @@ -4598,20 +5260,23 @@ on_create_ck_constraint_rollback(struct trigger > *trigger, void * /* event */) strlen(ck->def->name)) != NULL); > space_remove_ck_constraint(space, ck); > ck_constraint_delete(ck); > - trigger_run_xc(&on_alter_space, space); > + if (trigger_run(&on_alter_space, space) != 0) > + return -1; > + return 0; > } > > /** Commit DELETE check constraint. */ > -static void > +static int > on_drop_ck_constraint_commit(struct trigger *trigger, void * /* event */) > { > struct ck_constraint *ck = (struct ck_constraint *)trigger->data; > assert(ck != NULL); > ck_constraint_delete(ck); > + return 0; > } > > /** Rollback DELETE check constraint. */ > -static void > +static int > on_drop_ck_constraint_rollback(struct trigger *trigger, void * /* event */) > { > struct ck_constraint *ck = (struct ck_constraint *)trigger->data; > @@ -4622,20 +5287,25 @@ on_drop_ck_constraint_rollback(struct trigger > *trigger, void * /* event */) strlen(ck->def->name)) == NULL); > if (space_add_ck_constraint(space, ck) != 0) > panic("Can't recover after CK constraint drop rollback"); > - trigger_run_xc(&on_alter_space, space); > + if (trigger_run(&on_alter_space, space) != 0) > + return -1; > + return 0; > } > > /** Commit REPLACE check constraint. */ > -static void > +static int > on_replace_ck_constraint_commit(struct trigger *trigger, void * /* event > */) { > struct ck_constraint *ck = (struct ck_constraint *)trigger->data; > + > if (ck != NULL) > ck_constraint_delete(ck); > + > + return 0; > } > > /** Rollback REPLACE check constraint. */ > -static void > +static int > on_replace_ck_constraint_rollback(struct trigger *trigger, void * /* event > */) { > struct ck_constraint *ck = (struct ck_constraint *)trigger->data; > @@ -4648,35 +5318,46 @@ on_replace_ck_constraint_rollback(struct trigger > *trigger, void * /* event */) rlist_del_entry(new_ck, link); > rlist_add_entry(&space->ck_constraint, ck, link); > ck_constraint_delete(new_ck); > - trigger_run_xc(&on_alter_space, space); > + if (trigger_run(&on_alter_space, space) != 0) > + return -1; > + return 0; > } > > /** A trigger invoked on replace in the _ck_constraint space. */ > -static void > +static int > on_replace_dd_ck_constraint(struct trigger * /* trigger*/, void *event) > { > struct txn *txn = (struct txn *) event; > struct txn_stmt *stmt = txn_current_stmt(txn); > struct tuple *old_tuple = stmt->old_tuple; > struct tuple *new_tuple = stmt->new_tuple; > - uint32_t space_id = > - tuple_field_u32_xc(old_tuple != NULL ? old_tuple : new_tuple, > - BOX_CK_CONSTRAINT_FIELD_SPACE_ID); > - struct space *space = space_cache_find_xc(space_id); > + uint32_t space_id; > + if (tuple_field_u32(old_tuple != NULL ? old_tuple : new_tuple, > + BOX_CK_CONSTRAINT_FIELD_SPACE_ID, &space_id) != 0) > + return -1; > + struct space *space = space_cache_find(space_id); > + if (space == NULL) > + return -1; > struct trigger *on_rollback = txn_alter_trigger_new(NULL, NULL); > struct trigger *on_commit = txn_alter_trigger_new(NULL, NULL); > + if (on_commit == NULL || on_rollback == NULL) > + return -1; > > if (new_tuple != NULL) { > - bool is_deferred = > - tuple_field_bool_xc(new_tuple, > - BOX_CK_CONSTRAINT_FIELD_DEFERRED); > + bool is_deferred; > + if (tuple_field_bool(new_tuple, > + BOX_CK_CONSTRAINT_FIELD_DEFERRED, &is_deferred) != 0) > + return -1; > if (is_deferred) { > - tnt_raise(ClientError, ER_UNSUPPORTED, "Tarantool", > + diag_set(ClientError, ER_UNSUPPORTED, "Tarantool", > "deferred ck constraints"); > + return -1; > } > /* Create or replace check constraint. */ > struct ck_constraint_def *ck_def = > ck_constraint_def_new_from_tuple(new_tuple); > + if (ck_def == NULL) > + return -1; > auto ck_def_guard = make_scoped_guard([=] { > ck_constraint_def_delete(ck_def); > }); > @@ -4686,14 +5367,15 @@ on_replace_dd_ck_constraint(struct trigger * /* > trigger*/, void *event) */ > struct index *pk = space_index(space, 0); > if (pk != NULL && index_size(pk) > 0) { > - tnt_raise(ClientError, ER_CREATE_CK_CONSTRAINT, > + diag_set(ClientError, ER_CREATE_CK_CONSTRAINT, > ck_def->name, > "referencing space must be empty"); > + return -1; > } > - struct ck_constraint *new_ck_constraint = > - ck_constraint_new(ck_def, space->def); > + struct ck_constraint *new_ck_constraint; > + new_ck_constraint = ck_constraint_new(ck_def, space- >def); > if (new_ck_constraint == NULL) > - diag_raise(); > + return -1; > ck_def_guard.is_active = false; > auto ck_guard = make_scoped_guard([=] { > ck_constraint_delete(new_ck_constraint); > @@ -4703,8 +5385,9 @@ on_replace_dd_ck_constraint(struct trigger * /* > trigger*/, void *event) space_ck_constraint_by_name(space, name, > strlen(name)); > if (old_ck_constraint != NULL) > rlist_del_entry(old_ck_constraint, link); > - if (space_add_ck_constraint(space, new_ck_constraint) ! = 0) > - diag_raise(); > + if (space_add_ck_constraint(space, new_ck_constraint) != 0) { > + return -1; > + } > ck_guard.is_active = false; > if (old_tuple != NULL) { > on_rollback->data = old_ck_constraint; > @@ -4719,10 +5402,10 @@ on_replace_dd_ck_constraint(struct trigger * /* > trigger*/, void *event) assert(new_tuple == NULL && old_tuple != NULL); > /* Drop check constraint. */ > uint32_t name_len; > - const char *name = > - tuple_field_str_xc(old_tuple, > - BOX_CK_CONSTRAINT_FIELD_NAME, > - &name_len); > + const char *name = tuple_field_str(old_tuple, > + BOX_CK_CONSTRAINT_FIELD_NAME, &name_len); > + if (name == NULL) > + return -1; > struct ck_constraint *old_ck_constraint = > space_ck_constraint_by_name(space, name, name_len); > assert(old_ck_constraint != NULL); > @@ -4736,11 +5419,14 @@ on_replace_dd_ck_constraint(struct trigger * /* > trigger*/, void *event) txn_stmt_on_rollback(stmt, on_rollback); > txn_stmt_on_commit(stmt, on_commit); > > - trigger_run_xc(&on_alter_space, space); > + if (trigger_run(&on_alter_space, space) != 0) > + return -1; > + > + return 0; > } > > /** A trigger invoked on replace in the _func_index space. */ > -static void > +static int > on_replace_dd_func_index(struct trigger *trigger, void *event) > { > (void) trigger; > @@ -4754,33 +5440,57 @@ on_replace_dd_func_index(struct trigger *trigger, > void *event) struct index *index; > struct space *space; > if (old_tuple == NULL && new_tuple != NULL) { > - uint32_t space_id = tuple_field_u32_xc(new_tuple, > - BOX_FUNC_INDEX_FIELD_SPACE_ID); > - uint32_t index_id = tuple_field_u32_xc(new_tuple, > - BOX_FUNC_INDEX_FIELD_INDEX_ID); > - uint32_t fid = tuple_field_u32_xc(new_tuple, > - BOX_FUNC_INDEX_FUNCTION_ID); > - space = space_cache_find_xc(space_id); > - index = index_find_xc(space, index_id); > - func = func_cache_find(fid); > - func_index_check_func(func); > + uint32_t space_id; > + uint32_t index_id; > + uint32_t fid; > + if (tuple_field_u32(new_tuple,BOX_FUNC_INDEX_FIELD_SPACE_ID, > + &space_id) != 0) > + return -1; > + if (tuple_field_u32(new_tuple,BOX_FUNC_INDEX_FIELD_INDEX_ID, > + &index_id) != 0) > + return -1; > + if (tuple_field_u32(new_tuple,BOX_FUNC_INDEX_FUNCTION_ID, &fid) != 0) > + return -1; > + space = space_cache_find(space_id); > + if (space == NULL) > + return -1; > + index = index_find(space, index_id); > + if (index == NULL) > + return -1; > + func = func_by_id(fid); > + if (func == NULL) { > + diag_set(ClientError, ER_NO_SUCH_FUNCTION, int2str(fid)); > + return -1; > + } > + if (func_index_check_func(func) != 0) > + return -1; > if (index->def->opts.func_id != func->def->fid) { > - tnt_raise(ClientError, ER_WRONG_INDEX_OPTIONS, 0, > + diag_set(ClientError, ER_WRONG_INDEX_OPTIONS, 0, > "Function ids defined in _index and " > "_func_index don't match"); > + return -1; > } > } else if (old_tuple != NULL && new_tuple == NULL) { > - uint32_t space_id = tuple_field_u32_xc(old_tuple, > - BOX_FUNC_INDEX_FIELD_SPACE_ID); > - uint32_t index_id = tuple_field_u32_xc(old_tuple, > - BOX_FUNC_INDEX_FIELD_INDEX_ID); > - space = space_cache_find_xc(space_id); > - index = index_find_xc(space, index_id); > + uint32_t space_id; > + uint32_t index_id; > + > + if (tuple_field_u32(old_tuple,BOX_FUNC_INDEX_FIELD_SPACE_ID, > + &space_id) != 0) > + return -1; > + if (tuple_field_u32(old_tuple,BOX_FUNC_INDEX_FIELD_INDEX_ID, > + &index_id) != 0) > + return -1; > + space = space_cache_find(space_id); > + if (space == NULL) > + return -1; > + index = index_find(space, index_id); > + if (index == NULL) > + return -1; > func = NULL; > } else { > assert(old_tuple != NULL && new_tuple != NULL); > - tnt_raise(ClientError, ER_UNSUPPORTED, > - "functional index", "alter"); > + diag_set(ClientError, ER_UNSUPPORTED, "functional index", "alter"); > + return -1; > } > > /** > @@ -4788,9 +5498,11 @@ on_replace_dd_func_index(struct trigger *trigger, > void *event) * function. Index rebuild is not required. > */ > if (index_def_get_func(index->def) == func) > - return; > + return 0; > > alter = alter_space_new(space); > + if (alter == NULL) > + return -1; > auto scoped_guard = make_scoped_guard([=] {alter_space_delete(alter);}); > alter_space_move_indexes(alter, 0, index->def->iid); > (void) new RebuildFuncIndex(alter, index->def, func); > @@ -4798,9 +5510,15 @@ on_replace_dd_func_index(struct trigger *trigger, > void *event) space->index_id_max + 1); > (void) new MoveCkConstraints(alter); > (void) new UpdateSchemaVersion(alter); > - alter_space_do(stmt, alter); > + try { > + alter_space_do(stmt, alter); > + } catch (Exception *e) { > + return -1; > + } > > scoped_guard.is_active = false; > + > + return 0; > } > > struct trigger alter_space_on_replace_space = { > diff --git a/src/box/applier.cc b/src/box/applier.cc > index cf03ea160..e770dea58 100644 > --- a/src/box/applier.cc > +++ b/src/box/applier.cc > @@ -604,7 +604,7 @@ applier_read_tx(struct applier *applier, struct stailq > *rows) next)->row.is_commit); > } > > -static void > +static int > applier_txn_rollback_cb(struct trigger *trigger, void *event) > { > (void) trigger; > @@ -615,14 +615,16 @@ applier_txn_rollback_cb(struct trigger *trigger, void > *event) trigger_run(&replicaset.applier.on_rollback, event); > /* Rollback applier vclock to the committed one. */ > vclock_copy(&replicaset.applier.vclock, &replicaset.vclock); > + return 0; > } > > -static void > +static int > applier_txn_commit_cb(struct trigger *trigger, void *event) > { > (void) trigger; > /* Broadcast the commit event across all appliers. */ > trigger_run(&replicaset.applier.on_commit, event); > + return 0; > } > > /** > @@ -738,18 +740,19 @@ fail: > /* > * A trigger to update an applier state after a replication commit. > */ > -static void > +static int > applier_on_commit(struct trigger *trigger, void *event) > { > (void) event; > struct applier *applier = (struct applier *)trigger->data; > fiber_cond_signal(&applier->writer_cond); > + return 0; > } > > /* > * A trigger to update an applier state after a replication rollback. > */ > -static void > +static int > applier_on_rollback(struct trigger *trigger, void *event) > { > (void) event; > @@ -761,6 +764,7 @@ applier_on_rollback(struct trigger *trigger, void > *event) } > /* Stop the applier fiber. */ > fiber_cancel(applier->reader); > + return 0; > } > > /** > @@ -1124,7 +1128,7 @@ struct applier_on_state { > struct fiber_cond wakeup; > }; > > -static void > +static int > applier_on_state_f(struct trigger *trigger, void *event) > { > (void) event; > @@ -1136,12 +1140,14 @@ applier_on_state_f(struct trigger *trigger, void > *event) if (applier->state != APPLIER_OFF && > applier->state != APPLIER_STOPPED && > applier->state != on_state->desired_state) > - return; > + return 0; > > /* Wake up waiter */ > fiber_cond_signal(&on_state->wakeup); > > applier_pause(applier); > + > + return 0; > } > > static inline void > diff --git a/src/box/ck_constraint.c b/src/box/ck_constraint.c > index 1cde27022..2e0fa24a5 100644 > --- a/src/box/ck_constraint.c > +++ b/src/box/ck_constraint.c > @@ -175,7 +175,7 @@ ck_constraint_program_run(struct ck_constraint > *ck_constraint, return sql_reset(ck_constraint->stmt); > } > > -void > +int > ck_constraint_on_replace_trigger(struct trigger *trigger, void *event) > { > (void) trigger; > @@ -184,7 +184,7 @@ ck_constraint_on_replace_trigger(struct trigger > *trigger, void *event) assert(stmt != NULL); > struct tuple *new_tuple = stmt->new_tuple; > if (new_tuple == NULL) > - return; > + return 0; > > struct space *space = stmt->space; > assert(space != NULL); > @@ -195,15 +195,16 @@ ck_constraint_on_replace_trigger(struct trigger > *trigger, void *event) if (field_ref == NULL) { > diag_set(OutOfMemory, field_ref_sz, "region_alloc", > "field_ref"); > - diag_raise(); > + return -1; > } > vdbe_field_ref_prepare_tuple(field_ref, new_tuple); > > struct ck_constraint *ck_constraint; > rlist_foreach_entry(ck_constraint, &space->ck_constraint, link) { > if (ck_constraint_program_run(ck_constraint, field_ref) != 0) > - diag_raise(); > + return -1; > } > + return 0; > } > > struct ck_constraint * > diff --git a/src/box/ck_constraint.h b/src/box/ck_constraint.h > index f26f77a38..6af82afe6 100644 > --- a/src/box/ck_constraint.h > +++ b/src/box/ck_constraint.h > @@ -198,7 +198,7 @@ ck_constraint_delete(struct ck_constraint > *ck_constraint); * Raises an exception when some ck constraint is > unsatisfied. > * The diag message is set. > */ > -void > +int > ck_constraint_on_replace_trigger(struct trigger *trigger, void *event); > > /** > diff --git a/src/box/identifier.h b/src/box/identifier.h > index a0ed6c10e..0d39793ba 100644 > --- a/src/box/identifier.h > +++ b/src/box/identifier.h > @@ -51,16 +51,6 @@ identifier_check(const char *str, int str_len); > #if defined(__cplusplus) > } /* extern "C" */ > > -/** > - * Throw an error if identifier is not valid. > - */ > -static inline void > -identifier_check_xc(const char *str, int str_len) > -{ > - if (identifier_check(str, str_len)) > - diag_raise(); > -} > - > #endif /* defined(__cplusplus) */ > > #endif /* TARANTOOL_BOX_IDENTIFIER_H_INCLUDED */ > diff --git a/src/box/iproto.cc b/src/box/iproto.cc > index 8f899fed8..34c8f469a 100644 > --- a/src/box/iproto.cc > +++ b/src/box/iproto.cc > @@ -1505,7 +1505,7 @@ error: > tx_reply_error(msg); > } > > -static void > +static int > tx_process_call_on_yield(struct trigger *trigger, void *event) > { > (void)event; > @@ -1513,6 +1513,7 @@ tx_process_call_on_yield(struct trigger *trigger, void > *event) TRASH(&msg->call); > tx_discard_input(msg); > trigger_clear(trigger); > + return 0; > } > > static void > diff --git a/src/box/lua/call.c b/src/box/lua/call.c > index 0ac2eb7a6..c77be6698 100644 > --- a/src/box/lua/call.c > +++ b/src/box/lua/call.c > @@ -949,17 +949,18 @@ lbox_func_delete(struct lua_State *L, struct func > *func) lua_pop(L, 2); /* box, func */ > } > > -static void > +static int > lbox_func_new_or_delete(struct trigger *trigger, void *event) > { > struct lua_State *L = (struct lua_State *) trigger->data; > struct func *func = (struct func *)event; > if (!func->def->exports.lua) > - return; > + return 0; > if (func_by_id(func->def->fid) != NULL) > lbox_func_new(L, func); > else > lbox_func_delete(L, func); > + return 0; > } > > static struct trigger on_alter_func_in_lua = { > diff --git a/src/box/lua/sequence.c b/src/box/lua/sequence.c > index bd9ec7589..bf0714c1a 100644 > --- a/src/box/lua/sequence.c > +++ b/src/box/lua/sequence.c > @@ -157,7 +157,7 @@ lbox_sequence_delete(struct lua_State *L, struct > sequence *seq) lua_pop(L, 2); /* box, sequence */ > } > > -static void > +static int > lbox_sequence_new_or_delete(struct trigger *trigger, void *event) > { > struct lua_State *L = trigger->data; > @@ -166,6 +166,7 @@ lbox_sequence_new_or_delete(struct trigger *trigger, > void *event) lbox_sequence_new(L, seq); > else > lbox_sequence_delete(L, seq); > + return 0; > } > > void > diff --git a/src/box/lua/space.cc b/src/box/lua/space.cc > index d0a7e7815..ea8294f95 100644 > --- a/src/box/lua/space.cc > +++ b/src/box/lua/space.cc > @@ -500,7 +500,7 @@ box_lua_space_delete(struct lua_State *L, uint32_t id) > lua_pop(L, 2); /* box, space */ > } > > -static void > +static int > box_lua_space_new_or_delete(struct trigger *trigger, void *event) > { > struct lua_State *L = (struct lua_State *) trigger->data; > @@ -511,6 +511,7 @@ box_lua_space_new_or_delete(struct trigger *trigger, > void *event) } else { > box_lua_space_delete(L, space->def->id); > } > + return 0; > } > > static struct trigger on_alter_space_in_lua = { > diff --git a/src/box/memtx_space.c b/src/box/memtx_space.c > index cf29cf328..862a1adcc 100644 > --- a/src/box/memtx_space.c > +++ b/src/box/memtx_space.c > @@ -864,7 +864,7 @@ struct memtx_ddl_state { > int rc; > }; > > -static void > +static int > memtx_check_on_replace(struct trigger *trigger, void *event) > { > struct txn *txn = event; > @@ -873,11 +873,11 @@ memtx_check_on_replace(struct trigger *trigger, void > *event) > > /* Nothing to check on DELETE. */ > if (stmt->new_tuple == NULL) > - return; > + return 0; > > /* We have already failed. */ > if (state->rc != 0) > - return; > + return 0; > > /* > * Only check format for already processed part of the space, > @@ -886,11 +886,12 @@ memtx_check_on_replace(struct trigger *trigger, void > *event) */ > if (tuple_compare(state->cursor, HINT_NONE, stmt->new_tuple, HINT_NONE, > state->cmp_def) < 0) > - return; > + return 0; > > state->rc = tuple_validate(state->format, stmt->new_tuple); > if (state->rc != 0) > diag_move(diag_get(), &state->diag); > + return 0; > } > > static int > @@ -987,7 +988,7 @@ memtx_init_ephemeral_space(struct space *space) > memtx_space_add_primary_key(space); > } > > -static void > +static int > memtx_build_on_replace(struct trigger *trigger, void *event) > { > struct txn *txn = event; > @@ -1002,13 +1003,13 @@ memtx_build_on_replace(struct trigger *trigger, void > *event) */ > if (tuple_compare(state->cursor, HINT_NONE, cmp_tuple, HINT_NONE, > state->cmp_def) < 0) > - return; > + return 0; > > if (stmt->new_tuple != NULL && > tuple_validate(state->format, stmt->new_tuple) != 0) { > state->rc = -1; > diag_move(diag_get(), &state->diag); > - return; > + return 0; > } > > struct tuple *delete = NULL; > @@ -1021,7 +1022,7 @@ memtx_build_on_replace(struct trigger *trigger, void > *event) if (state->rc != 0) { > diag_move(diag_get(), &state->diag); > } > - return; > + return 0; > } > > static int > diff --git a/src/box/relay.cc b/src/box/relay.cc > index efa3373f9..b99d45a15 100644 > --- a/src/box/relay.cc > +++ b/src/box/relay.cc > @@ -386,7 +386,7 @@ tx_gc_advance(struct cmsg *msg) > free(m); > } > > -static void > +static int > relay_on_close_log_f(struct trigger *trigger, void * /* event */) > { > static const struct cmsg_hop route[] = { > @@ -396,7 +396,7 @@ relay_on_close_log_f(struct trigger *trigger, void * /* > event */) struct relay_gc_msg *m = (struct relay_gc_msg > *)malloc(sizeof(*m)); if (m == NULL) { > say_warn("failed to allocate relay gc message"); > - return; > + return 0; > } > cmsg_init(&m->msg, route); > m->relay = relay; > @@ -407,6 +407,7 @@ relay_on_close_log_f(struct trigger *trigger, void * /* > event */) * sent xlog. > */ > stailq_add_tail_entry(&relay->pending_gc, m, in_pending); > + return 0; > } > > /** > diff --git a/src/box/replication.cc b/src/box/replication.cc > index 28f7acedc..abd519e86 100644 > --- a/src/box/replication.cc > +++ b/src/box/replication.cc > @@ -114,15 +114,19 @@ replication_free(void) > free(replicaset.replica_by_id); > } > > -void > +int > replica_check_id(uint32_t replica_id) > { > - if (replica_id == REPLICA_ID_NIL) > - tnt_raise(ClientError, ER_REPLICA_ID_IS_RESERVED, > + if (replica_id == REPLICA_ID_NIL) { > + diag_set(ClientError, ER_REPLICA_ID_IS_RESERVED, > (unsigned) replica_id); > - if (replica_id >= VCLOCK_MAX) > - tnt_raise(LoggedError, ER_REPLICA_MAX, > + return -1; > + } > + if (replica_id >= VCLOCK_MAX) { > + diag_set(ClientError, ER_REPLICA_MAX, > (unsigned) replica_id); > + return -1; > + } > /* > * It's okay to update the instance id while it is joining to > * a cluster as long as the id is set by the time bootstrap is > @@ -133,9 +137,12 @@ replica_check_id(uint32_t replica_id) > * case it will replay this operation during the final join > * stage. > */ > - if (!replicaset.is_joining && replica_id == instance_id) > - tnt_raise(ClientError, ER_LOCAL_INSTANCE_ID_IS_READ_ONLY, > + if (!replicaset.is_joining && replica_id == instance_id) { > + diag_set(ClientError, ER_LOCAL_INSTANCE_ID_IS_READ_ONLY, > (unsigned) replica_id); > + return -1; > + } > + return 0; > } > > /* Return true if replica doesn't have id, relay and applier */ > @@ -147,7 +154,7 @@ replica_is_orphan(struct replica *replica) > relay_get_state(replica->relay) != RELAY_FOLLOW; > } > > -static void > +static int > replica_on_applier_state_f(struct trigger *trigger, void *event); > > static struct replica * > @@ -401,48 +408,53 @@ replica_on_applier_disconnect(struct replica *replica) > replicaset.applier.loading++; > } > > -static void > +static int > replica_on_applier_state_f(struct trigger *trigger, void *event) > { > (void)event; > struct replica *replica = container_of(trigger, > struct replica, on_applier_state); > switch (replica->applier->state) { > - case APPLIER_INITIAL_JOIN: > - replicaset.is_joining = true; > - break; > - case APPLIER_JOINED: > - replicaset.is_joining = false; > - break; > - case APPLIER_CONNECTED: > - if (tt_uuid_is_nil(&replica->uuid)) > - replica_on_applier_connect(replica); > - else > - replica_on_applier_reconnect(replica); > - break; > - case APPLIER_LOADING: > - case APPLIER_DISCONNECTED: > - replica_on_applier_disconnect(replica); > - break; > - case APPLIER_FOLLOW: > - replica_on_applier_sync(replica); > - break; > - case APPLIER_OFF: > - /* > - * Connection to self, duplicate connection > - * to the same master, or the applier fiber > - * has been cancelled. Assume synced. > - */ > - replica_on_applier_sync(replica); > - break; > - case APPLIER_STOPPED: > - /* Unrecoverable error. */ > - replica_on_applier_disconnect(replica); > - break; > - default: > - break; > + case APPLIER_INITIAL_JOIN: > + replicaset.is_joining = true; > + break; > + case APPLIER_JOINED: > + replicaset.is_joining = false; > + break; > + case APPLIER_CONNECTED: > + try { > + if (tt_uuid_is_nil(&replica- >uuid)) > + replica_on_applier_connect(replica); > + else > + replica_on_applier_reconnect(replica); > + } catch (Exception *e) { > + return -1; > + } > + break; > + case APPLIER_LOADING: > + case APPLIER_DISCONNECTED: > + replica_on_applier_disconnect(replica); > + break; > + case APPLIER_FOLLOW: > + replica_on_applier_sync(replica); > + break; > + case APPLIER_OFF: > + /* > + * Connection to self, duplicate connection > + * to the same master, or the applier fiber > + * has been cancelled. Assume synced. > + */ > + replica_on_applier_sync(replica); > + break; > + case APPLIER_STOPPED: > + /* Unrecoverable error. */ > + replica_on_applier_disconnect(replica); > + break; > + default: > + break; > } > fiber_cond_signal(&replicaset.applier.cond); > + return 0; > } > > /** > @@ -575,7 +587,7 @@ struct applier_on_connect { > struct replicaset_connect_state *state; > }; > > -static void > +static int > applier_on_connect_f(struct trigger *trigger, void *event) > { > struct applier_on_connect *on_connect = container_of(trigger, > @@ -592,10 +604,11 @@ applier_on_connect_f(struct trigger *trigger, void > *event) state->connected++; > break; > default: > - return; > + return 0; > } > fiber_cond_signal(&state->wakeup); > applier_pause(applier); > + return 0; > } > > void > diff --git a/src/box/replication.h b/src/box/replication.h > index 19f283c7d..470420592 100644 > --- a/src/box/replication.h > +++ b/src/box/replication.h > @@ -352,7 +352,7 @@ replica_on_relay_stop(struct replica *replica); > #if defined(__cplusplus) > } /* extern "C" */ > > -void > +int > replica_check_id(uint32_t replica_id); > > /** > diff --git a/src/box/schema.cc b/src/box/schema.cc > index 8d8aae448..9767207e0 100644 > --- a/src/box/schema.cc > +++ b/src/box/schema.cc > @@ -599,12 +599,22 @@ func_by_name(const char *name, uint32_t name_len) > return (struct func *) mh_strnptr_node(funcs_by_name, func)->val; > } > > -bool > -schema_find_grants(const char *type, uint32_t id) > +int > +schema_find_grants(const char *type, uint32_t id, bool *out) > { > - struct space *priv = space_cache_find_xc(BOX_PRIV_ID); > + struct space *priv = space_cache_find(BOX_PRIV_ID); > + if (priv == NULL) > + return -1; > + > /** "object" index */ > - struct index *index = index_find_system_xc(priv, 2); > + if (!space_is_memtx(priv)) { > + diag_set(ClientError, ER_UNSUPPORTED, > + priv->engine->name, "system data"); > + return -1; > + } > + struct index *index = index_find(priv, 2); > + if (index == NULL) > + return -1; > /* > * +10 = max(mp_sizeof_uint32) + > * max(mp_sizeof_strl(uint32)). > @@ -612,9 +622,15 @@ schema_find_grants(const char *type, uint32_t id) > char key[GRANT_NAME_MAX + 10]; > assert(strlen(type) <= GRANT_NAME_MAX); > mp_encode_uint(mp_encode_str(key, type, strlen(type)), id); > - struct iterator *it = index_create_iterator_xc(index, ITER_EQ, key, 2); > + struct iterator *it = index_create_iterator(index, ITER_EQ, key, 2); > + if (it == NULL) > + return -1; > IteratorGuard iter_guard(it); > - return iterator_next_xc(it); > + struct tuple *tuple; > + if (iterator_next(it, &tuple) != 0) > + return -1; > + *out = (tuple != NULL); > + return 0; > } > > struct sequence * > diff --git a/src/box/schema.h b/src/box/schema.h > index f9d15b38d..88bfd74ad 100644 > --- a/src/box/schema.h > +++ b/src/box/schema.h > @@ -171,15 +171,6 @@ schema_free(); > > struct space *schema_space(uint32_t id); > > -static inline struct func * > -func_cache_find(uint32_t fid) > -{ > - struct func *func = func_by_id(fid); > - if (func == NULL) > - tnt_raise(ClientError, ER_NO_SUCH_FUNCTION, int2str(fid)); > - return func; > -} > - > > /** > * Check whether or not an object has grants on it (restrict > @@ -188,8 +179,8 @@ func_cache_find(uint32_t fid) > * @retval true object has grants > * @retval false object has no grants > */ > -bool > -schema_find_grants(const char *type, uint32_t id); > +int > +schema_find_grants(const char *type, uint32_t id, bool *out); > > /** > * A wrapper around sequence_by_id() that raises an exception > diff --git a/src/box/sequence.h b/src/box/sequence.h > index 976020a25..a164da9af 100644 > --- a/src/box/sequence.h > +++ b/src/box/sequence.h > @@ -179,15 +179,6 @@ sequence_get_value(struct sequence *seq); > #if defined(__cplusplus) > } /* extern "C" */ > > -static inline struct sequence * > -sequence_new_xc(struct sequence_def *def) > -{ > - struct sequence *seq = sequence_new(def); > - if (seq == NULL) > - diag_raise(); > - return seq; > -} > - > #endif /* defined(__cplusplus) */ > > #endif /* INCLUDES_TARANTOOL_BOX_SEQUENCE_H */ > diff --git a/src/box/session.cc b/src/box/session.cc > index 59bf226dd..d69b6572f 100644 > --- a/src/box/session.cc > +++ b/src/box/session.cc > @@ -80,7 +80,7 @@ sid_max() > return sid_max; > } > > -static void > +static int > session_on_stop(struct trigger *trigger, void * /* event */) > { > /* > @@ -91,6 +91,7 @@ session_on_stop(struct trigger *trigger, void * /* event > */) trigger_clear(trigger); > /* Destroy the session */ > session_destroy(fiber_get_session(fiber())); > + return 0; > } > > static int > diff --git a/src/box/tuple.h b/src/box/tuple.h > index 4c4050ca8..71fe2b981 100644 > --- a/src/box/tuple.h > +++ b/src/box/tuple.h > @@ -1156,16 +1156,6 @@ tuple_field_str_xc(struct tuple *tuple, uint32_t > fieldno, uint32_t *len) return ret; > } > > -/** @copydoc tuple_field_cstr() */ > -static inline const char * > -tuple_field_cstr_xc(struct tuple *tuple, uint32_t fieldno) > -{ > - const char *out = tuple_field_cstr(tuple, fieldno); > - if (out == NULL) > - diag_raise(); > - return out; > -} > - > /** @copydoc tuple_field_uuid() */ > static inline void > tuple_field_uuid_xc(struct tuple *tuple, int fieldno, struct tt_uuid *out) > diff --git a/src/box/txn.c b/src/box/txn.c > index 53ebfc053..ce0354a69 100644 > --- a/src/box/txn.c > +++ b/src/box/txn.c > @@ -40,10 +40,10 @@ double too_long_threshold; > /* Txn cache. */ > static struct stailq txn_cache = {NULL, &txn_cache.first}; > > -static void > +static int > txn_on_stop(struct trigger *trigger, void *event); > > -static void > +static int > txn_on_yield(struct trigger *trigger, void *event); > > static void > @@ -787,12 +787,13 @@ box_txn_rollback_to_savepoint(box_txn_savepoint_t > *svp) return 0; > } > > -static void > +static int > txn_on_stop(struct trigger *trigger, void *event) > { > (void) trigger; > (void) event; > txn_rollback(in_txn()); /* doesn't yield or fail */ > + return 0; > } > > /** > @@ -812,7 +813,7 @@ txn_on_stop(struct trigger *trigger, void *event) > * So much hassle to be user-friendly until we have a true > * interactive transaction support in memtx. > */ > -static void > +static int > txn_on_yield(struct trigger *trigger, void *event) > { > (void) trigger; > @@ -822,4 +823,5 @@ txn_on_yield(struct trigger *trigger, void *event) > assert(!txn_has_flag(txn, TXN_CAN_YIELD)); > txn_rollback_to_svp(txn, NULL); > txn_set_flag(txn, TXN_IS_ABORTED_BY_YIELD); > + return 0; > } > diff --git a/src/box/user.cc b/src/box/user.cc > index c46ff67d1..50614c6f2 100644 > --- a/src/box/user.cc > +++ b/src/box/user.cc > @@ -339,7 +339,8 @@ user_reload_privs(struct user *user) > struct tuple *tuple; > while ((tuple = iterator_next_xc(it)) != NULL) { > struct priv_def priv; > - priv_def_create_from_tuple(&priv, tuple); > + if (priv_def_create_from_tuple(&priv, tuple) != 0) > + diag_raise(); > /** > * Skip role grants, we're only > * interested in real objects. > @@ -559,7 +560,7 @@ user_cache_free() > > /** {{{ roles */ > > -void > +int > role_check(struct user *grantee, struct user *role) > { > /* > @@ -592,9 +593,11 @@ role_check(struct user *grantee, struct user *role) > */ > if (user_map_is_set(&transitive_closure, > role->auth_token)) { > - tnt_raise(ClientError, ER_ROLE_LOOP, > + diag_set(ClientError, ER_ROLE_LOOP, > role->def->name, grantee->def->name); > + return -1; > } > + return 0; > } > > /** > diff --git a/src/box/user.h b/src/box/user.h > index 527fb2e7c..526cd39ca 100644 > --- a/src/box/user.h > +++ b/src/box/user.h > @@ -144,16 +144,6 @@ user_cache_replace(struct user_def *user); > void > user_cache_delete(uint32_t uid); > > -/* Find a user by name. Used by authentication. */ > -static inline struct user * > -user_find_xc(uint32_t uid) > -{ > - struct user *user = user_find(uid); > - if (user == NULL) > - diag_raise(); > - return user; > -} > - > static inline struct user * > user_find_by_name_xc(const char *name, uint32_t len) > { > @@ -178,7 +168,7 @@ user_cache_free(); > * and no loop in the graph will occur when grantee gets > * a given role. > */ > -void > +int > role_check(struct user *grantee, struct user *role); > > /** > @@ -201,7 +191,7 @@ role_revoke(struct user *grantee, struct user *role); > void > priv_grant(struct user *grantee, struct priv_def *priv); > > -void > +int > priv_def_create_from_tuple(struct priv_def *priv, struct tuple *tuple); > > /* }}} */ > diff --git a/src/box/vinyl.c b/src/box/vinyl.c > index cd009c1c2..493a120f5 100644 > --- a/src/box/vinyl.c > +++ b/src/box/vinyl.c > @@ -1065,7 +1065,7 @@ struct vy_check_format_ctx { > * This is an on_replace trigger callback that checks inserted > * tuples against a new format. > */ > -static void > +static int > vy_check_format_on_replace(struct trigger *trigger, void *event) > { > struct txn *txn = event; > @@ -1073,15 +1073,16 @@ vy_check_format_on_replace(struct trigger *trigger, > void *event) struct vy_check_format_ctx *ctx = trigger->data; > > if (stmt->new_tuple == NULL) > - return; /* DELETE, nothing to do */ > + return 0; /* DELETE, nothing to do */ > > if (ctx->is_failed) > - return; /* already failed, nothing to do */ > + return 0; /* already failed, nothing to do */ > > if (tuple_validate(ctx->format, stmt->new_tuple) != 0) { > ctx->is_failed = true; > diag_move(diag_get(), &ctx->diag); > } > + return 0; > } > > static int > @@ -3736,13 +3737,14 @@ fail: > > /* {{{ Cursor */ > > -static void > +static int > vinyl_iterator_on_tx_destroy(struct trigger *trigger, void *event) > { > (void)event; > struct vinyl_iterator *it = container_of(trigger, > struct vinyl_iterator, on_tx_destroy); > it->tx = NULL; > + return 0; > } > > static int > @@ -4035,7 +4037,7 @@ struct vy_build_ctx { > * This is an on_replace trigger callback that forwards DML requests > * to the index that is currently being built. > */ > -static void > +static int > vy_build_on_replace(struct trigger *trigger, void *event) > { > struct txn *txn = event; > @@ -4046,7 +4048,7 @@ vy_build_on_replace(struct trigger *trigger, void > *event) struct vy_lsm *lsm = ctx->lsm; > > if (ctx->is_failed) > - return; /* already failed, nothing to do */ > + return 0; /* already failed, nothing to do */ > > /* Check new tuples for conformity to the new format. */ > if (stmt->new_tuple != NULL && > @@ -4083,7 +4085,7 @@ vy_build_on_replace(struct trigger *trigger, void > *event) if (rc != 0) > goto err; > } > - return; > + return 0; > err: > /* > * No need to abort the DDL request if this transaction > @@ -4093,9 +4095,10 @@ err: > * context isn't valid and so we must not modify it. > */ > if (tx->state == VINYL_TX_ABORT) > - return; > + return 0; > ctx->is_failed = true; > diag_move(diag_get(), &ctx->diag); > + return 0; > } > > /** > @@ -4488,7 +4491,7 @@ vinyl_space_build_index(struct space *src_space, > struct index *new_index, > > /* {{{ Deferred DELETE handling */ > > -static void > +static int > vy_deferred_delete_on_commit(struct trigger *trigger, void *event) > { > struct txn *txn = event; > @@ -4501,15 +4504,17 @@ vy_deferred_delete_on_commit(struct trigger > *trigger, void *event) mem->dump_lsn = txn->signature; > /* Unpin the mem pinned in vy_deferred_delete_on_replace(). */ > vy_mem_unpin(mem); > + return 0; > } > > -static void > +static int > vy_deferred_delete_on_rollback(struct trigger *trigger, void *event) > { > (void)event; > struct vy_mem *mem = trigger->data; > /* Unpin the mem pinned in vy_deferred_delete_on_replace(). */ > vy_mem_unpin(mem); > + return 0; > } > > /** > @@ -4536,7 +4541,7 @@ vy_deferred_delete_on_rollback(struct trigger > *trigger, void *event) * one of the trees got dumped while the other > didn't, we would > * mistakenly skip both statements on recovery. > */ > -static void > +static int > vy_deferred_delete_on_replace(struct trigger *trigger, void *event) > { > (void)trigger; > @@ -4546,7 +4551,7 @@ vy_deferred_delete_on_replace(struct trigger *trigger, > void *event) bool is_first_statement = txn_is_first_statement(txn); > > if (stmt->new_tuple == NULL) > - return; > + return 0; > /* > * Extract space id, LSN of the deferred DELETE statement, > * and the deleted tuple from the system space row. > @@ -4555,27 +4560,27 @@ vy_deferred_delete_on_replace(struct trigger > *trigger, void *event) tuple_rewind(&it, stmt->new_tuple); > uint32_t space_id; > if (tuple_next_u32(&it, &space_id) != 0) > - diag_raise(); > + return -1; > uint64_t lsn; > if (tuple_next_u64(&it, &lsn) != 0) > - diag_raise(); > + return -1; > const char *delete_data = tuple_next_with_type(&it, MP_ARRAY); > if (delete_data == NULL) > - diag_raise(); > + return -1; > const char *delete_data_end = delete_data; > mp_next(&delete_data_end); > > /* Look up the space. */ > struct space *space = space_cache_find(space_id); > if (space == NULL) > - diag_raise(); > + return -1; > /* > * All secondary indexes could have been dropped, in > * which case we don't need to generate deferred DELETE > * statements anymore. > */ > if (space->index_count <= 1) > - return; > + return 0; > /* > * Wait for memory quota if necessary before starting to > * process the batch (we can't yield between statements). > @@ -4589,7 +4594,7 @@ vy_deferred_delete_on_replace(struct trigger *trigger, > void *event) struct tuple *delete = vy_stmt_new_delete(pk->mem_format, > delete_data, delete_data_end); > if (delete == NULL) > - diag_raise(); > + return -1; > /* > * A deferred DELETE may be generated after new statements > * were committed for the deleted key. So we must use the > @@ -4681,7 +4686,8 @@ vy_deferred_delete_on_replace(struct trigger *trigger, > void *event) > > tuple_unref(delete); > if (rc != 0) > - diag_raise(); > + return -1; > + return 0; > } > > static struct trigger on_replace_vinyl_deferred_delete = { > diff --git a/src/lib/core/fiber.c b/src/lib/core/fiber.c > index ce90f930c..710940838 100644 > --- a/src/lib/core/fiber.c > +++ b/src/lib/core/fiber.c > @@ -1292,12 +1292,13 @@ cord_cojoin(struct cord *cord) > return cord_join(cord); > } > > -void > +int > break_ev_loop_f(struct trigger *trigger, void *event) > { > (void) trigger; > (void) event; > ev_break(loop(), EVBREAK_ALL); > + return 0; > } > > struct costart_ctx > diff --git a/src/lib/core/trigger.cc b/src/lib/core/trigger.cc > index 4a43151e1..6beb1f600 100644 > --- a/src/lib/core/trigger.cc > +++ b/src/lib/core/trigger.cc > @@ -35,25 +35,19 @@ > int > trigger_run(struct rlist *list, void *event) > { > - try { > - struct trigger *trigger, *tmp; > - rlist_foreach_entry_safe(trigger, list, link, tmp) > - trigger->run(trigger, event); > - } catch (Exception *e) { > - return -1; > - } > + struct trigger *trigger, *tmp; > + rlist_foreach_entry_safe(trigger, list, link, tmp) > + if (trigger->run(trigger, event) != 0) > + return -1; > return 0; > } > > int > trigger_run_reverse(struct rlist *list, void *event) > { > - try { > - struct trigger *trigger, *tmp; > - rlist_foreach_entry_safe_reverse(trigger, list, link, tmp) > - trigger->run(trigger, event); > - } catch (Exception *e) { > - return -1; > - } > + struct trigger *trigger, *tmp; > + rlist_foreach_entry_safe_reverse(trigger, list, link, tmp) > + if (trigger->run(trigger, event) != 0) > + return -1; > return 0; > } > diff --git a/src/lib/core/trigger.h b/src/lib/core/trigger.h > index 76fa6345d..7b500dd92 100644 > --- a/src/lib/core/trigger.h > +++ b/src/lib/core/trigger.h > @@ -40,7 +40,7 @@ extern "C" { > * on an event. > */ > struct trigger; > -typedef void (*trigger_f)(struct trigger *trigger, void *event); > +typedef int (*trigger_f)(struct trigger *trigger, void *event); > typedef void (*trigger_f0)(struct trigger *trigger); > > struct trigger > diff --git a/src/lua/trigger.c b/src/lua/trigger.c > index 4803e85c5..83718ddc3 100644 > --- a/src/lua/trigger.c > +++ b/src/lua/trigger.c > @@ -62,7 +62,7 @@ lbox_trigger_destroy(struct trigger *ptr) > free(ptr); > } > > -static void > +static int > lbox_trigger_run(struct trigger *ptr, void *event) > { > struct lbox_trigger *trigger = (struct lbox_trigger *) ptr; > @@ -97,14 +97,14 @@ lbox_trigger_run(struct trigger *ptr, void *event) > } > if (luaT_call(L, nargs, LUA_MULTRET)) { > luaL_unref(tarantool_L, LUA_REGISTRYINDEX, coro_ref); > - diag_raise(); > + return -1; > } > int nret = lua_gettop(L) - top; > if (trigger->pop_event != NULL && > trigger->pop_event(L, nret, event) != 0) { > lua_settop(L, top); > luaL_unref(tarantool_L, LUA_REGISTRYINDEX, coro_ref); > - diag_raise(); > + return -1; > } > /* > * Clear the stack after pop_event saves all > @@ -112,6 +112,7 @@ lbox_trigger_run(struct trigger *ptr, void *event) > */ > lua_settop(L, top); > luaL_unref(tarantool_L, LUA_REGISTRYINDEX, coro_ref); > + return 0; > } > > static struct lbox_trigger * > diff --git a/src/main.cc b/src/main.cc > index 5776aa41d..d40e4740a 100644 > --- a/src/main.cc > +++ b/src/main.cc > @@ -671,10 +671,11 @@ print_help(const char *program) > puts("to see online documentation, submit bugs or contribute a patch."); > } > > -static void > +static int > break_loop(struct trigger *, void *) > { > ev_break(loop(), EVBREAK_ALL); > + return 0; > } > > int > diff --git a/test/unit/cbus.c b/test/unit/cbus.c > index be930ab8f..ecf5fce72 100644 > --- a/test/unit/cbus.c > +++ b/test/unit/cbus.c > @@ -43,13 +43,14 @@ do_nothing(struct cmsg *m) > } > > /** Callback called on each flush to the main thread. */ > -static void > +static int > flush_cb(struct trigger *t, void *e) > { > (void) t; > (void) e; > ++flushed_cnt; > printf("flush event, counter = %d\n", flushed_cnt); > + return 0; > } > > /** Callback to finish the test. It breaks the main event loop. */ > diff --git a/test/unit/swim.c b/test/unit/swim.c > index 1371e7d26..bb12baf8d 100644 > --- a/test/unit/swim.c > +++ b/test/unit/swim.c > @@ -827,7 +827,7 @@ struct trigger_ctx { > struct swim_on_member_event_ctx ctx; > }; > > -static void > +static int > swim_on_member_event_save(struct trigger *t, void *event) > { > struct trigger_ctx *c = (struct trigger_ctx *) t->data; > @@ -836,9 +836,10 @@ swim_on_member_event_save(struct trigger *t, void > *event) swim_member_unref(c->ctx.member); > c->ctx = *((struct swim_on_member_event_ctx *) event); > swim_member_ref(c->ctx.member); > + return 0; > } > > -static void > +static int > swim_on_member_event_yield(struct trigger *t, void *event) > { > struct trigger_ctx *c = (struct trigger_ctx *) t->data; > @@ -846,6 +847,7 @@ swim_on_member_event_yield(struct trigger *t, void > *event) c->f = fiber(); > while (c->need_sleep) > fiber_yield(); > + return 0; > } > > static void > diff --git a/test/unit/swim_test_utils.c b/test/unit/swim_test_utils.c > index 7da82d93c..9dbd28a9f 100644 > --- a/test/unit/swim_test_utils.c > +++ b/test/unit/swim_test_utils.c > @@ -176,7 +176,7 @@ swim_cluster_id_to_uri(char *buffer, int id) > * A trigger to check correctness of event context, and ability > * to yield. > */ > -void > +int > swim_test_event_cb(struct trigger *trigger, void *event) > { > (void) trigger; > @@ -186,6 +186,7 @@ swim_test_event_cb(struct trigger *trigger, void *event) > assert((ctx->events & SWIM_EV_NEW) == 0 || > (ctx->events & SWIM_EV_DROP) == 0); > fiber_sleep(0); > + return 0; > } > > /** Create a SWIM cluster node @a n with a 0-based @a id. */ --nextPart3169611.W46JsgntyF Content-Type: application/pgp-signature; name="signature.asc" Content-Description: This is a digitally signed message part. Content-Transfer-Encoding: 7Bit -----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEFZT35EtIMRTDS5hJnoTdFFzh6LUFAl1U9yoACgkQnoTdFFzh 6LU3wAf/Uc7pAyT8uoYXCZgNE2XPQsp+rGqPMkpZThKa21VEtxcOcpsCBXbNvEQL W9RebI2kyO7JUQPvT2L9Zz2JpUgOzFI3siwP1Ch5DzIz3FQNT8/4EDBE538FZ8jk uplqUxrGMrNHMZcn4zwM22lFmewyVtalijerpvihanvxkO9zlCC45bVZtTGPRqJt PI3Gn0gNM5Lx016rDgaSuHPo/ot7z0b07tOFQL27wJAl9avU7UxGs5OaUbs6kSoS mrCfHYebdYCLDuhLNbEKEqtc1pr6Wl1ZqIf117xANu48w09DZniCGNPMSiCsxq7U 9vMh9dEahHA8vCVuBfalMmE/bIpBvA== =Mkl3 -----END PGP SIGNATURE----- --nextPart3169611.W46JsgntyF--