[tarantool-patches] [PATCH v2 4/5] Always store built-in collations in the cache
Vladislav Shpilevoy
v.shpilevoy at tarantool.org
Sun Apr 29 01:45:12 MSK 2018
To be able to use collations out of box.cfg it is needed to be
sure, that they are available always. Else it can break non-box
collation usage. So when a built-in collation is deleted from
_collation (for example, on box.internal.bootstrap()), it is not
deleted from the cache. When a built-in collation is inserted
into _collation, it does not touch the cache (it already contains
all built-in collations).
---
src/box/alter.cc | 14 ++++++++++++++
src/coll_cache.c | 34 ++++++++++++++++++++++++++++++++++
src/coll_def.c | 7 +++++++
src/coll_def.h | 13 +++++++++++++
4 files changed, 68 insertions(+)
diff --git a/src/box/alter.cc b/src/box/alter.cc
index be2ccc061..39fcc8de4 100644
--- a/src/box/alter.cc
+++ b/src/box/alter.cc
@@ -2429,6 +2429,13 @@ on_replace_dd_collation(struct trigger * /* trigger */, void *event)
/* TODO: Check that no index uses the collation */
int32_t old_id = tuple_field_u32_xc(old_tuple,
BOX_COLLATION_FIELD_ID);
+ if (coll_is_system(old_id)) {
+ /*
+ * Built-in collations can be deleted from
+ * _collation, but not from the cache.
+ */
+ return;
+ }
struct coll *old_coll = coll_by_id(old_id);
assert(old_coll != NULL);
access_check_ddl(old_coll->name, old_coll->owner_id,
@@ -2451,6 +2458,13 @@ on_replace_dd_collation(struct trigger * /* trigger */, void *event)
coll_def_new_from_tuple(new_tuple, &new_def);
access_check_ddl(new_def.name, new_def.owner_id, SC_COLLATION,
PRIV_C, false);
+ if (coll_is_system(new_def.id)) {
+ /*
+ * Built-in collation is in the cache
+ * already.
+ */
+ return;
+ }
/*
* Set on_rollback before the collation is
* inserted into the cache. Else if the trigger
diff --git a/src/coll_cache.c b/src/coll_cache.c
index b7eb3edb9..b7fce5aba 100644
--- a/src/coll_cache.c
+++ b/src/coll_cache.c
@@ -45,7 +45,41 @@ coll_cache_init()
"coll_cache_id");
return -1;
}
+ struct coll *replaced, *unicode_coll, *unicode_ci_coll;
+ struct coll_def def;
+ memset(&def, 0, sizeof(def));
+ def.id = COLLATION_ID_UNICODE;
+ def.owner_id = 1;
+ def.name = "unicode";
+ def.name_len = strlen(def.name);
+ def.locale = "";
+ def.type = COLL_TYPE_ICU;
+ unicode_coll = coll_new(&def);
+ if (unicode_coll == NULL)
+ goto err_unicode;
+ if (coll_cache_replace(unicode_coll, &replaced) != 0)
+ goto err_unicode_replace;
+ assert(replaced == NULL);
+
+ def.id = COLLATION_ID_UNICODE_CI;
+ def.name = "unicode_ci";
+ def.name_len = strlen(def.name);
+ def.icu.strength = COLL_ICU_STRENGTH_PRIMARY;
+ unicode_ci_coll = coll_new(&def);
+ if (unicode_ci_coll == NULL)
+ goto err_unicode_ci;
+ if (coll_cache_replace(unicode_ci_coll, &replaced) != 0)
+ goto err_unicode_ci_replace;
return 0;
+err_unicode_ci_replace:
+ coll_delete(unicode_ci_coll);
+err_unicode_ci:
+ coll_cache_delete(unicode_coll);
+err_unicode_replace:
+ coll_delete(unicode_coll);
+err_unicode:
+ mh_i32ptr_delete(coll_cache_id);
+ return -1;
}
/** Delete global hash tables. */
diff --git a/src/coll_def.c b/src/coll_def.c
index f849845b3..0a0ead9a1 100644
--- a/src/coll_def.c
+++ b/src/coll_def.c
@@ -63,6 +63,13 @@ const char *coll_icu_strength_strs[] = {
"IDENTICAL"
};
+bool
+coll_is_system(int coll_id)
+{
+ return coll_id == COLLATION_ID_UNICODE ||
+ coll_id == COLLATION_ID_UNICODE_CI;
+}
+
static int64_t
icu_on_off_from_str(const char *str, uint32_t len)
{
diff --git a/src/coll_def.h b/src/coll_def.h
index 7a1027a1e..e86c546e5 100644
--- a/src/coll_def.h
+++ b/src/coll_def.h
@@ -49,6 +49,19 @@ enum coll_type {
extern const char *coll_type_strs[];
+/** Built-in collations. */
+enum {
+ COLLATION_ID_UNICODE = 1,
+ COLLATION_ID_UNICODE_CI = 2,
+};
+
+/**
+ * Check if a collation is system by its ID. System collations can
+ * not be deleted.
+ */
+bool
+coll_is_system(int coll_id);
+
/*
* ICU collation options. See
* http://icu-project.org/apiref/icu4c/ucol_8h.html#a583fbe7fc4a850e2fcc692e766d2826c
--
2.15.1 (Apple Git-101)
More information about the Tarantool-patches
mailing list