[tarantool-patches] [PATCH v3 3/5] refactoring: replace exceptions in most alter.cc functions
Ilya Kosarev
i.kosarev at tarantool.org
Wed Sep 11 16:05:17 MSK 2019
Non-trigger functions from alter.cc are refactored.
Their usages are updated.
---
src/box/alter.cc | 974 ++++++++++++++++++++++++++++-------------------
1 file changed, 587 insertions(+), 387 deletions(-)
diff --git a/src/box/alter.cc b/src/box/alter.cc
index 0a9cc5751..8cc59ef5f 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,12 +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(cr->uid);
if (user == NULL)
- diag_raise();
+ return -1;
const char *object_name;
const char *pname;
if (access & PRIV_U) {
@@ -113,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)
@@ -142,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,
- space_name, "sequence field must be a part of "
- "the index");
+ 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,
- space_name, "sequence cannot be used with "
- "a non-integer key");
+ diag_set(ClientError, ER_MODIFY_INDEX, index_def->name,
+ space_name, "sequence cannot be used with "
+ "a non-integer key");
+ return -1;
}
+ return 0;
}
/**
@@ -159,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[] =
@@ -175,9 +178,9 @@ index_def_check_tuple(struct tuple *tuple)
goto err;
mp_next(&data);
}
- return;
+ return 0;
-err:
+ err:
char got[DIAG_ERRMSG_MAX];
char *p = got, *e = got + sizeof(got);
data = field_start;
@@ -186,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,
- "space id (unsigned), index id (unsigned), name (string), "\
+ 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,
- BOX_INDEX_FIELD_OPTS, "distance must be either "\
+ 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,
- BOX_INDEX_FIELD_OPTS,
- "page_size must be greater than 0 and "
- "less than or equal to range_size");
+ 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,
- BOX_INDEX_FIELD_OPTS,
- "run_count_per_level must be greater than 0");
+ 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,
- BOX_INDEX_FIELD_OPTS,
- "run_size_ratio must be greater than 1");
+ 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,
- BOX_INDEX_FIELD_OPTS,
- "bloom_fpr must be greater than 0 and "
- "less than or equal to 1");
+ 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;
}
/**
@@ -238,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,
- "referenced function doesn't satisfy "
- "functional index function constraints");
+ diag_set(ClientError, ER_WRONG_INDEX_OPTIONS, 0,
+ "referenced function doesn't satisfy "
+ "functional index function constraints");
+ return -1;
}
+ return 0;
}
/**
@@ -265,57 +277,72 @@ 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,
- &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);
+ const char *name = tuple_field_str(tuple, BOX_INDEX_FIELD_NAME,
+ &name_len);
+ 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,
- tt_cstr(name, BOX_INVALID_NAME_MAX),
- space_name(space), "index name is too long");
+ 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);
+ malloc(sizeof(*part_def) * part_count);
if (part_def == NULL) {
- tnt_raise(OutOfMemory, sizeof(*part_def) * part_count,
- "malloc", "key_part_def");
+ diag_set(OutOfMemory, sizeof(*part_def) * part_count,
+ "malloc", "key_part_def");
+ return NULL;
}
auto key_def_guard = make_scoped_guard([&] {
- free(part_def);
- if (key_def != NULL)
- key_def_delete(key_def);
+ free(part_def);
+ if (key_def != NULL)
+ key_def_delete(key_def);
});
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
@@ -333,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,
- space->sequence_path,
- space->sequence_path != NULL ?
- strlen(space->sequence_path) : 0,
- space_name(space));
+ 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)) != 0)
+ return NULL;
index_def_guard.is_active = false;
return index_def;
}
@@ -350,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",
- "sql");
+ diag_set(OutOfMemory, strlen(opts->sql) + 1, "strdup",
+ "sql");
+ return -1;
}
opts->sql = sql;
}
+ return 0;
}
/**
@@ -382,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),
- tt_sprintf("field %d is not map",
- fieldno + TUPLE_INDEX_BASE));
+ 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;
@@ -398,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,
- tt_cstr(space_name, name_len),
- tt_sprintf("field %d format is not map"\
+ 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));
+ fieldno + TUPLE_INDEX_BASE));
+ return -1;
}
uint32_t key_len;
const char *key = mp_decode_str(data, &key_len);
@@ -410,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)
@@ -418,48 +451,55 @@ field_def_decode(struct field_def *field, const char **data,
}
if (is_action_missing) {
field->nullable_action = field->is_nullable ?
- ON_CONFLICT_ACTION_NONE
- : ON_CONFLICT_ACTION_DEFAULT;
+ ON_CONFLICT_ACTION_NONE
+ : ON_CONFLICT_ACTION_DEFAULT;
}
if (field->name == NULL) {
- tnt_raise(ClientError, errcode, tt_cstr(space_name, name_len),
- tt_sprintf("field %d name is not specified",
- fieldno + TUPLE_INDEX_BASE));
+ 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),
- tt_sprintf("field %d name is too long",
- fieldno + TUPLE_INDEX_BASE));
+ 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),
- tt_sprintf("field %d has unknown field type",
- fieldno + TUPLE_INDEX_BASE));
+ 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),
- tt_sprintf("field %d has unknown field on conflict "
- "nullable action",
- fieldno + TUPLE_INDEX_BASE));
+ 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)
+ ON_CONFLICT_ACTION_NONE)
|| (!field->is_nullable
&& field->nullable_action != ON_CONFLICT_ACTION_NONE))) {
- tnt_raise(ClientError, errcode, tt_cstr(space_name, name_len),
- tt_sprintf("field %d has conflicting nullability and "
- "nullable action properties", fieldno +
- TUPLE_INDEX_BASE));
+ 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),
- tt_sprintf("collation is reasonable only for "
- "string, scalar and any fields"));
+ 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;
@@ -467,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;
}
/**
@@ -481,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
@@ -502,14 +549,16 @@ space_format_decode(const char *data, uint32_t *out_count,
*/
memset(region_defs, 0, size);
auto fields_guard = make_scoped_guard([=] {
- space_def_destroy_fields(region_defs, count, false);
+ 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;
}
/**
@@ -552,8 +601,6 @@ space_def_new_from_tuple(struct tuple *tuple, uint32_t errcode,
"space engine name is too long");
}
identifier_check_xc(engine_name, engine_name_len);
- struct field_def *fields;
- uint32_t field_count;
/* Check space opts. */
const char *space_opts =
tuple_field_with_type_xc(tuple, BOX_SPACE_FIELD_OPTS,
@@ -562,37 +609,50 @@ space_def_new_from_tuple(struct tuple *tuple, uint32_t errcode,
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);
+ 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);
+ 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),
- "exact_field_count must be either 0 or >= "\
+ 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,
- int2str(opts.group_id));
+ 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,
- engine_name, engine_name_len, &opts, fields,
- field_count);
+ 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;
}
@@ -627,25 +687,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;
}
/* }}} */
@@ -753,11 +829,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
@@ -1914,17 +1999,18 @@ on_replace_dd_space(struct trigger * /* trigger */, void *event)
*/
uint32_t old_id;
if (tuple_field_u32(old_tuple ? old_tuple : new_tuple,
- BOX_SPACE_FIELD_ID, &old_id) != 0)
+ 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);
/**
@@ -1955,7 +2041,7 @@ on_replace_dd_space(struct trigger * /* trigger */, void *event)
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)
return -1;
auto select_guard = make_scoped_guard([=] {
@@ -1971,7 +2057,7 @@ on_replace_dd_space(struct trigger * /* trigger */, void *event)
update_view_references(select, -1, false,
&disappeared_space);
diag_set(ClientError, ER_NO_SUCH_SPACE,
- disappeared_space);
+ disappeared_space);
return -1;
}
struct trigger *on_commit_view =
@@ -1989,13 +2075,14 @@ on_replace_dd_space(struct trigger * /* trigger */, void *event)
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) {
diag_set(ClientError, ER_DROP_SPACE,
- space_name(old_space),
- "the space has indexes");
+ space_name(old_space),
+ "the space has indexes");
return -1;
}
bool out;
@@ -2008,14 +2095,18 @@ on_replace_dd_space(struct trigger * /* trigger */, void *event)
"the space has grants");
return -1;
}
- if (space_has_data(BOX_TRUNCATE_ID, 0, old_space->def->id))
- tnt_raise(ClientError, ER_DROP_SPACE,
- space_name(old_space),
- "the space has truncate record");
+ 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) {
diag_set(ClientError, ER_DROP_SPACE,
- space_name(old_space),
- "other views depend on this space");
+ space_name(old_space),
+ "other views depend on this space");
return -1;
}
/*
@@ -2027,14 +2118,14 @@ on_replace_dd_space(struct trigger * /* trigger */, void *event)
*/
if (!rlist_empty(&old_space->child_fk_constraint)) {
diag_set(ClientError, ER_DROP_SPACE,
- space_name(old_space),
- "the space has foreign key constraints");
+ space_name(old_space),
+ "the space has foreign key constraints");
return -1;
}
if (!rlist_empty(&old_space->ck_constraint)) {
diag_set(ClientError, ER_DROP_SPACE,
- space_name(old_space),
- "the space has check constraints");
+ space_name(old_space),
+ "the space has check constraints");
return -1;
}
/**
@@ -2085,37 +2176,37 @@ on_replace_dd_space(struct trigger * /* trigger */, void *event)
}
} 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))
+ 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");
+ space_name(old_space),
+ "space id is immutable");
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");
+ space_name(old_space),
+ "can not change space engine");
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");
+ space_name(old_space),
+ "replication group is immutable");
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");
+ 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 &&
@@ -2131,8 +2222,9 @@ on_replace_dd_space(struct trigger * /* trigger */, void *event)
* 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
@@ -2238,14 +2330,15 @@ on_replace_dd_index(struct trigger * /* trigger */, void *event)
struct space *old_space = space_cache_find_xc(id);
if (old_space->def->opts.is_view) {
diag_set(ClientError, ER_ALTER_SPACE, space_name(old_space),
- "can not add index on a view");
+ "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);
/*
@@ -2257,7 +2350,7 @@ on_replace_dd_index(struct trigger * /* trigger */, void *event)
*/
if (space_is_system(old_space)) {
diag_set(ClientError, ER_LAST_DROP,
- space_name(old_space));
+ space_name(old_space));
return -1;
}
/*
@@ -2265,7 +2358,7 @@ on_replace_dd_index(struct trigger * /* trigger */, void *event)
*/
if (old_space->index_count > 1) {
diag_set(ClientError, ER_DROP_PRIMARY_KEY,
- space_name(old_space));
+ space_name(old_space));
return -1;
}
/*
@@ -2273,9 +2366,9 @@ on_replace_dd_index(struct trigger * /* trigger */, void *event)
*/
if (old_space->sequence != NULL) {
diag_set(ClientError, ER_ALTER_SPACE,
- space_name(old_space),
- "can not drop primary key while "
- "space sequence exists");
+ space_name(old_space),
+ "can not drop primary key while "
+ "space sequence exists");
return -1;
}
}
@@ -2286,14 +2379,15 @@ on_replace_dd_index(struct trigger * /* trigger */, void *event)
* a primary key.
*/
diag_set(ClientError, ER_ALTER_SPACE,
- space_name(old_space),
- "can not add a secondary key before primary");
+ 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:
@@ -2311,8 +2405,8 @@ on_replace_dd_index(struct trigger * /* trigger */, void *event)
if (index_is_used_by_fk_constraint(&old_space->parent_fk_constraint,
iid)) {
diag_set(ClientError, ER_ALTER_SPACE,
- space_name(old_space),
- "can not drop a referenced index");
+ space_name(old_space),
+ "can not drop a referenced index");
return -1;
}
alter_space_move_indexes(alter, 0, iid);
@@ -2324,6 +2418,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);
}
@@ -2331,6 +2427,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); });
/*
@@ -2457,19 +2555,19 @@ on_replace_dd_truncate(struct trigger * /* trigger */, void *event)
*/
if (space_is_system(old_space)) {
diag_set(ClientError, ER_TRUNCATE_SYSTEM_SPACE,
- space_name(old_space));
+ space_name(old_space));
return -1;
}
/*
* Check if a write privilege was given, raise an error if not.
*/
- access_check_space_xc(old_space, PRIV_W);
-
+ if (access_check_space(old_space, PRIV_W) != 0)
+ 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); });
/*
* Modify the WAL header to prohibit
* replication of local & temporary
@@ -2497,7 +2595,7 @@ on_replace_dd_truncate(struct trigger * /* trigger */, void *event)
/* {{{ 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,
@@ -2508,18 +2606,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;
}
/**
@@ -2527,7 +2633,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);
@@ -2539,13 +2645,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,
- user->name, "invalid password format, "
- "use box.schema.user.passwd() to reset password");
+ 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++) {
@@ -2562,19 +2669,23 @@ 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,
- user->name, "invalid user password");
+ 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);
+ /** Guest user is permitted to have empty 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 *
@@ -2631,6 +2742,8 @@ user_def_new_from_tuple(struct tuple *tuple)
"authentication data can not be set for a "\
"role");
user_def_fill_auth_data(user, auth_data);
+ if (user_def_fill_auth_data(user, auth_data) != 0)
+ return NULL;
}
def_guard.is_active = false;
return user;
@@ -2652,6 +2765,8 @@ 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);
@@ -2672,13 +2787,16 @@ on_replace_dd_user(struct trigger * /* trigger */, void *event)
uint32_t uid;
if (tuple_field_u32(old_tuple ? old_tuple : new_tuple,
- BOX_USER_FIELD_ID, &uid) != 0)
+ 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);
def_guard.is_active = false;
@@ -2688,23 +2806,29 @@ on_replace_dd_user(struct trigger * /* trigger */, void *event)
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) {
diag_set(ClientError, ER_DROP_USER,
- old_user->def->name,
- "the user or the role is a system");
+ 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 =
@@ -2720,8 +2844,11 @@ 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;
@@ -2799,14 +2926,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); });
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,
- tt_cstr(name, name_len), "function id is too big");
+ 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);
@@ -2972,14 +3102,18 @@ on_replace_dd_func(struct trigger * /* trigger */, void *event)
uint32_t fid;
if (tuple_field_u32(old_tuple ? old_tuple : new_tuple,
- BOX_FUNC_FIELD_ID, &fid) != 0)
+ 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)
@@ -3000,8 +3134,9 @@ on_replace_dd_func(struct trigger * /* trigger */, void *event)
* 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. */
bool out;
if (schema_find_grants("function", old_func->def->fid, &out) != 0) {
@@ -3013,11 +3148,13 @@ on_replace_dd_func(struct trigger * /* trigger */, void *event)
"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,
- (unsigned) old_func->def->uid,
- "function has references");
+ 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;
}
/* Can't' drop a builtin function. */
if (old_func->def->language == FUNC_LANGUAGE_SQL_BUILTIN) {
@@ -3043,8 +3180,8 @@ on_replace_dd_func(struct trigger * /* trigger */, void *event)
*/
struct func_def *old_def = NULL, *new_def = NULL;
auto guard = make_scoped_guard([=] {
- free(old_def);
- free(new_def);
+ free(old_def);
+ free(new_def);
});
old_def = func_def_new_from_tuple(old_tuple);
new_def = func_def_new_from_tuple(new_tuple);
@@ -3052,7 +3189,7 @@ on_replace_dd_func(struct trigger * /* trigger */, void *event)
return -1;
if (func_def_cmp(new_def, old_def) != 0) {
diag_set(ClientError, ER_UNSUPPORTED, "function",
- "alter");
+ "alter");
return -1;
}
}
@@ -3060,7 +3197,7 @@ on_replace_dd_func(struct trigger * /* trigger */, void *event)
}
/** 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));
@@ -3142,6 +3279,7 @@ coll_id_def_new_from_tuple(struct tuple *tuple, struct coll_id_def *def)
"ICU wrong numeric_collation option setting, "
"expected ON | OFF");
}
+ return 0;
}
/** Delete the new collation identifier. */
@@ -3214,14 +3352,15 @@ on_replace_dd_collation(struct trigger * /* trigger */, void *event)
*/
if (old_id == COLL_NONE) {
diag_set(ClientError, ER_DROP_COLLATION, "none",
- "system collation");
+ "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
@@ -3239,9 +3378,11 @@ on_replace_dd_collation(struct trigger * /* trigger */, void *event)
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)
return -1;
@@ -3326,21 +3467,23 @@ 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(priv->grantor_id);
if (grantor == NULL)
- diag_raise();
+ 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,
- int2str(priv->grantee_id));
+ 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) {
@@ -3453,33 +3596,39 @@ priv_def_check(struct priv_def *priv, enum priv_type priv_type)
tnt_raise(ClientError, ER_GRANT,
"the grant tuple has no privileges");
}
+ 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. */
@@ -3492,7 +3641,8 @@ revoke_priv(struct trigger *trigger, void *event)
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;
}
@@ -3505,7 +3655,8 @@ modify_priv(struct trigger *trigger, void *event)
struct priv_def priv;
if (priv_def_create_from_tuple(&priv, tuple) != 0)
return -1;
- grant_or_revoke(&priv);
+ if (grant_or_revoke(&priv) != 0)
+ return -1;
return 0;
}
@@ -3525,8 +3676,10 @@ on_replace_dd_priv(struct trigger * /* trigger */, void *event)
if (new_tuple != NULL && old_tuple == NULL) { /* grant */
if (priv_def_create_from_tuple(&priv, new_tuple) != 0)
return -1;
- priv_def_check(&priv, PRIV_GRANT);
- grant_or_revoke(&priv);
+ 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)
@@ -3536,9 +3689,11 @@ on_replace_dd_priv(struct trigger * /* trigger */, void *event)
assert(old_tuple);
if (priv_def_create_from_tuple(&priv, old_tuple) != 0)
return -1;
- priv_def_check(&priv, PRIV_REVOKE);
+ 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)
@@ -3547,8 +3702,10 @@ on_replace_dd_priv(struct trigger * /* trigger */, void *event)
} else { /* modify */
if (priv_def_create_from_tuple(&priv, new_tuple) != 0)
return -1;
- priv_def_check(&priv, PRIV_GRANT);
- grant_or_revoke(&priv);
+ 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)
@@ -3579,7 +3736,7 @@ on_replace_dd_schema(struct trigger * /* trigger */, void *event)
struct tuple *old_tuple = stmt->old_tuple;
struct tuple *new_tuple = stmt->new_tuple;
const char *key = tuple_field_cstr(new_tuple ? new_tuple : old_tuple,
- BOX_SCHEMA_FIELD_KEY);
+ BOX_SCHEMA_FIELD_KEY);
if (key == NULL)
return -1;
if (strcmp(key, "cluster") == 0) {
@@ -3676,11 +3833,11 @@ on_replace_dd_cluster(struct trigger *trigger, void *event)
if (replica_check_id(replica_id) != 0)
return -1;
if (tuple_field_uuid(new_tuple, BOX_CLUSTER_FIELD_UUID,
- &replica_uuid) != 0)
+ &replica_uuid) != 0)
return -1;
if (tt_uuid_is_nil(&replica_uuid)) {
diag_set(ClientError, ER_INVALID_UUID,
- tt_uuid_str(&replica_uuid));
+ tt_uuid_str(&replica_uuid));
return -1;
}
if (old_tuple != NULL) {
@@ -3691,12 +3848,12 @@ on_replace_dd_cluster(struct trigger *trigger, void *event)
*/
tt_uuid old_uuid;
if (tuple_field_uuid(old_tuple, BOX_CLUSTER_FIELD_UUID,
- &old_uuid) != 0)
+ &old_uuid) != 0)
return -1;
if (!tt_uuid_is_equal(&replica_uuid, &old_uuid)) {
diag_set(ClientError, ER_UNSUPPORTED,
- "Space _cluster",
- "updates of instance uuid");
+ "Space _cluster",
+ "updates of instance uuid");
return -1;
}
} else {
@@ -3846,8 +4003,11 @@ 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);
if (on_rollback == NULL)
@@ -3864,21 +4024,30 @@ on_replace_dd_sequence(struct trigger * /* trigger */, void *event)
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 (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))
- tnt_raise(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 (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");
+ 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");
+ seq->def->name, "the sequence has grants");
return -1;
}
struct trigger *on_commit =
@@ -3893,10 +4062,13 @@ on_replace_dd_sequence(struct trigger * /* trigger */, void *event)
} 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 =
@@ -3953,7 +4125,7 @@ on_replace_dd_sequence_data(struct trigger * /* trigger */, void *event)
if (new_tuple != NULL) { /* INSERT, UPDATE */
int64_t value;
if (tuple_field_i64(new_tuple, BOX_SEQUENCE_DATA_FIELD_VALUE,
- &value) != 0)
+ &value) != 0)
return -1;
if (sequence_set(seq, value) != 0)
return -1;
@@ -3979,11 +4151,14 @@ on_replace_dd_sequence_data(struct trigger * /* trigger */, void *event)
* 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;
@@ -3991,26 +4166,32 @@ 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,
- "malloc", "sequence path");
+ 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. */
@@ -4033,7 +4214,9 @@ set_space_sequence(struct trigger *trigger, void * /* event */)
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;
@@ -4081,7 +4264,7 @@ on_replace_dd_space_sequence(struct trigger * /* trigger */, void *event)
return -1;
bool is_generated;
if (tuple_field_bool(tuple, BOX_SPACE_SEQUENCE_FIELD_IS_GENERATED,
- &is_generated) != 0)
+ &is_generated) != 0)
return -1;
struct space *space = space_cache_find(space_id);
if (space == NULL)
@@ -4096,34 +4279,39 @@ 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);
+ free(sequence_path);
});
if (seq->is_generated) {
diag_set(ClientError, ER_ALTER_SPACE,
- space_name(space),
- "can not attach generated sequence");
+ space_name(space),
+ "can not attach generated sequence");
return -1;
}
struct trigger *on_rollback;
@@ -4245,15 +4433,15 @@ on_replace_dd_trigger(struct trigger * /* trigger */, void *event)
/* DROP trigger. */
uint32_t trigger_name_len;
const char *trigger_name_src = tuple_field_str(old_tuple,
- BOX_TRIGGER_FIELD_NAME, &trigger_name_len);
+ 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)
+ &space_id) != 0)
return -1;
char *trigger_name = (char *)region_alloc(&fiber()->gc,
- trigger_name_len + 1);
+ trigger_name_len + 1);
if (trigger_name == NULL)
return -1;
memcpy(trigger_name, trigger_name_src, trigger_name_len);
@@ -4272,16 +4460,17 @@ on_replace_dd_trigger(struct trigger * /* trigger */, void *event)
/* INSERT, REPLACE trigger. */
uint32_t trigger_name_len;
const char *trigger_name_src = tuple_field_str(new_tuple,
- BOX_TRIGGER_FIELD_NAME, &trigger_name_len);
+ 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);
+ 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)
@@ -4296,18 +4485,18 @@ on_replace_dd_trigger(struct trigger * /* trigger */, void *event)
memcmp(trigger_name_src, trigger_name,
trigger_name_len) != 0) {
diag_set(ClientError, ER_SQL_EXECUTE,
- "trigger name does not match extracted "
- "from SQL");
+ "trigger name does not match extracted "
+ "from SQL");
return -1;
}
uint32_t space_id;
if (tuple_field_u32(new_tuple,BOX_TRIGGER_FIELD_SPACE_ID,
- &space_id) != 0)
+ &space_id) != 0)
return -1;
if (space_id != sql_trigger_space_id(new_trigger)) {
diag_set(ClientError, ER_SQL_EXECUTE,
- "trigger space_id does not match the value "
- "resolved on AST building from SQL");
+ "trigger space_id does not match the value "
+ "resolved on AST building from SQL");
return -1;
}
@@ -4406,12 +4595,15 @@ fk_constraint_def_new_from_tuple(struct tuple *tuple, uint32_t errcode)
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",
- "struct fk_constraint_def");
+ 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);
@@ -4593,7 +4785,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;
@@ -4606,8 +4798,8 @@ fk_constraint_check_dup_links(struct fk_constraint_def *fk_def)
goto error;
field_mask |= parent_field;
}
- return;
-slow_check:
+ 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;
for (uint32_t j = i + 1; j < fk_def->field_count; ++j) {
@@ -4615,10 +4807,11 @@ slow_check:
goto error;
}
}
- return;
-error:
- tnt_raise(ClientError, ER_CREATE_FK_CONSTRAINT, fk_def->name,
- "referenced fields can not contain duplicates");
+ return 0;
+ error:
+ 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. */
@@ -4649,8 +4842,8 @@ on_replace_dd_fk_constraint(struct trigger * /* trigger*/, void *event)
space_cache_find_xc(fk_def->parent_id);
if (parent_space->def->opts.is_view) {
diag_set(ClientError, ER_CREATE_FK_CONSTRAINT,
- fk_def->name,
- "referenced space can't be VIEW");
+ fk_def->name,
+ "referenced space can't be VIEW");
return -1;
}
/*
@@ -4663,8 +4856,8 @@ 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) {
diag_set(ClientError, ER_CREATE_FK_CONSTRAINT,
- fk_def->name,
- "referencing space must be empty");
+ fk_def->name,
+ "referencing space must be empty");
return -1;
}
/* Check types of referenced fields. */
@@ -4685,17 +4878,18 @@ on_replace_dd_fk_constraint(struct trigger * /* trigger*/, void *event)
if (! field_type1_contains_type2(parent_field->type,
child_field->type)) {
diag_set(ClientError, ER_CREATE_FK_CONSTRAINT,
- fk_def->name, "field type mismatch");
+ fk_def->name, "field type mismatch");
return -1;
}
if (child_field->coll_id != parent_field->coll_id) {
diag_set(ClientError, ER_CREATE_FK_CONSTRAINT,
- fk_def->name,
- "field collation mismatch");
+ 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
@@ -4725,15 +4919,15 @@ on_replace_dd_fk_constraint(struct trigger * /* trigger*/, void *event)
}
if (fk_index == NULL) {
diag_set(ClientError, ER_CREATE_FK_CONSTRAINT,
- fk_def->name, "referenced fields don't "
- "compose unique index");
+ 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) {
diag_set(OutOfMemory, sizeof(*fk),
- "malloc", "struct fk_constraint");
+ "malloc", "struct fk_constraint");
return -1;
}
auto fk_guard = make_scoped_guard([=] { free(fk); });
@@ -4786,7 +4980,9 @@ on_replace_dd_fk_constraint(struct trigger * /* trigger*/, void *event)
/* Drop foreign key. */
struct fk_constraint_def *fk_def =
fk_constraint_def_new_from_tuple(old_tuple,
- ER_DROP_FK_CONSTRAINT);
+ 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);
@@ -4910,7 +5106,7 @@ on_replace_ck_constraint_rollback(struct trigger *trigger, void * /* event */)
struct space *space = space_by_id(ck->def->space_id);
assert(space != NULL);
struct ck_constraint *new_ck = space_ck_constraint_by_name(space,
- ck->def->name, strlen(ck->def->name));
+ ck->def->name, strlen(ck->def->name));
assert(new_ck != NULL);
rlist_del_entry(new_ck, link);
rlist_add_entry(&space->ck_constraint, ck, link);
@@ -4939,18 +5135,20 @@ on_replace_dd_ck_constraint(struct trigger * /* trigger*/, void *event)
if (new_tuple != NULL) {
bool is_deferred;
if (tuple_field_bool(new_tuple,
- BOX_CK_CONSTRAINT_FIELD_DEFERRED, &is_deferred) != 0)
+ BOX_CK_CONSTRAINT_FIELD_DEFERRED, &is_deferred) != 0)
return -1;
if (is_deferred) {
diag_set(ClientError, ER_UNSUPPORTED, "Tarantool",
- "deferred ck constraints");
+ "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);
+ ck_constraint_def_delete(ck_def);
});
/*
* FIXME: Ck constraint creation on non-empty
@@ -4959,7 +5157,7 @@ on_replace_dd_ck_constraint(struct trigger * /* trigger*/, void *event)
struct index *pk = space_index(space, 0);
if (pk != NULL && index_size(pk) > 0) {
diag_set(ClientError, ER_CREATE_CK_CONSTRAINT,
- ck_def->name,
+ ck_def->name,
"referencing space must be empty");
return -1;
}
@@ -4969,7 +5167,7 @@ on_replace_dd_ck_constraint(struct trigger * /* trigger*/, void *event)
return -1;
ck_def_guard.is_active = false;
auto ck_guard = make_scoped_guard([=] {
- ck_constraint_delete(new_ck_constraint);
+ ck_constraint_delete(new_ck_constraint);
});
const char *name = new_ck_constraint->def->name;
struct ck_constraint *old_ck_constraint =
@@ -4977,7 +5175,7 @@ on_replace_dd_ck_constraint(struct trigger * /* trigger*/, void *event)
if (old_ck_constraint != NULL)
rlist_del_entry(old_ck_constraint, link);
if (space_add_ck_constraint(space, new_ck_constraint) != 0) {
- return -1;
+ return -1;
}
ck_guard.is_active = false;
if (old_tuple != NULL) {
@@ -4994,7 +5192,7 @@ on_replace_dd_ck_constraint(struct trigger * /* trigger*/, void *event)
/* Drop check constraint. */
uint32_t name_len;
const char *name = tuple_field_str(old_tuple,
- BOX_CK_CONSTRAINT_FIELD_NAME, &name_len);
+ BOX_CK_CONSTRAINT_FIELD_NAME, &name_len);
if (name == NULL)
return -1;
struct ck_constraint *old_ck_constraint =
@@ -5033,10 +5231,10 @@ on_replace_dd_func_index(struct trigger *trigger, void *event)
uint32_t index_id;
uint32_t fid;
if (tuple_field_u32(new_tuple,BOX_FUNC_INDEX_FIELD_SPACE_ID,
- &space_id) != 0)
+ &space_id) != 0)
return -1;
if (tuple_field_u32(new_tuple,BOX_FUNC_INDEX_FIELD_INDEX_ID,
- &index_id) != 0)
+ &index_id) != 0)
return -1;
if (tuple_field_u32(new_tuple,BOX_FUNC_INDEX_FUNCTION_ID, &fid) != 0)
return -1;
@@ -5065,7 +5263,7 @@ on_replace_dd_func_index(struct trigger *trigger, void *event)
&space_id) != 0)
return -1;
if (tuple_field_u32(old_tuple,BOX_FUNC_INDEX_FIELD_INDEX_ID,
- &index_id) != 0)
+ &index_id) != 0)
return -1;
space = space_cache_find(space_id);
if (space == NULL)
@@ -5088,6 +5286,8 @@ on_replace_dd_func_index(struct trigger *trigger, void *event)
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);
--
2.17.1
More information about the Tarantool-patches
mailing list