From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org>
To: tarantool-patches@freelists.org
Cc: alexander.turenko@tarantool.org
Subject: [tarantool-patches] [PATCH v2 1/5] alter: fix assertion in collations alter
Date: Sun, 29 Apr 2018 01:45:09 +0300 [thread overview]
Message-ID: <506613bb9ee89cbfe764baaedd9b3bf35851204b.1524955403.git.v.shpilevoy@tarantool.org> (raw)
In-Reply-To: <cover.1524955403.git.v.shpilevoy@tarantool.org>
In-Reply-To: <cover.1524955403.git.v.shpilevoy@tarantool.org>
Forbid collations update - it leads to an assertion in collation
cache about unavailability to correctly replace collations.
Refactor collations deletion and insertion.
Besides, collation update potentially changes indexing order with
no actual indexes rebuilding.
---
src/box/alter.cc | 115 ++++++++++++++++++++++++++------------------------
test/box/ddl.result | 10 +++++
test/box/ddl.test.lua | 3 ++
3 files changed, 74 insertions(+), 54 deletions(-)
diff --git a/src/box/alter.cc b/src/box/alter.cc
index 77b03e680..be2ccc061 100644
--- a/src/box/alter.cc
+++ b/src/box/alter.cc
@@ -2376,19 +2376,31 @@ coll_cache_rollback(struct trigger *trigger, void *event)
struct txn_stmt *stmt = txn_last_stmt((struct txn*) event);
struct tuple *new_tuple = stmt->new_tuple;
- if (new_tuple != NULL) {
+ if (new_tuple == NULL && old_coll != NULL) {
+ /* Rollback DELETE. */
+ if (coll_by_id(old_coll->id) == old_coll) {
+ /*
+ * Nothing to do - the tx had been failed
+ * before old collation deletion.
+ */
+ return;
+ }
+ struct coll *replaced;
+ if (coll_cache_replace(old_coll, &replaced) != 0) {
+ panic("Out of memory on insertion into collation "\
+ "cache");
+ }
+ assert(replaced == NULL);
+ } else {
+ assert(new_tuple != NULL && old_coll == NULL);
uint32_t new_id = tuple_field_u32_xc(new_tuple,
BOX_COLLATION_FIELD_ID);
struct coll *new_coll = coll_by_id(new_id);
- coll_cache_delete(new_coll);
- coll_delete(new_coll);
- }
-
- if (old_coll != NULL) {
- struct coll *replaced;
- int rc = coll_cache_replace(old_coll, &replaced);
- assert(rc == 0 && replaced == NULL);
- (void)rc;
+ /* Can be NULL, if failed before cache update. */
+ if (new_coll != NULL) {
+ coll_cache_delete(new_coll);
+ coll_delete(new_coll);
+ }
}
}
@@ -2412,59 +2424,54 @@ on_replace_dd_collation(struct trigger * /* trigger */, void *event)
struct tuple *old_tuple = stmt->old_tuple;
struct tuple *new_tuple = stmt->new_tuple;
txn_check_singlestatement_xc(txn, "Space _collation");
- struct coll *old_coll = NULL;
- if (old_tuple != NULL) {
+ if (new_tuple == NULL && old_tuple != NULL) {
+ /* DELETE */
/* TODO: Check that no index uses the collation */
- uint32_t old_id = tuple_field_u32_xc(old_tuple,
- BOX_COLLATION_FIELD_ID);
- old_coll = coll_by_id(old_id);
+ int32_t old_id = tuple_field_u32_xc(old_tuple,
+ BOX_COLLATION_FIELD_ID);
+ struct coll *old_coll = coll_by_id(old_id);
assert(old_coll != NULL);
access_check_ddl(old_coll->name, old_coll->owner_id,
- SC_COLLATION,
- new_tuple == NULL ? PRIV_D: PRIV_A,
- false);
-
- struct trigger *on_commit =
- txn_alter_trigger_new(coll_cache_delete_coll, old_coll);
- txn_on_commit(txn, on_commit);
- }
-
- if (new_tuple == NULL) {
- /* Simple DELETE */
- assert(old_tuple != NULL);
- coll_cache_delete(old_coll);
-
+ SC_COLLATION, PRIV_D, false);
+ /*
+ * Set on_rollback before deletion from the cache.
+ * Else rollback setting can fail and the
+ * collation will be lost.
+ */
struct trigger *on_rollback =
txn_alter_trigger_new(coll_cache_rollback, old_coll);
txn_on_rollback(txn, on_rollback);
- return;
- }
-
- struct coll_def new_def;
- coll_def_new_from_tuple(new_tuple, &new_def);
- access_check_ddl(new_def.name, new_def.owner_id, SC_COLLATION,
- old_tuple == NULL ? PRIV_C : PRIV_A, false);
- struct coll *new_coll = coll_new(&new_def);
- if (new_coll == NULL)
- diag_raise();
- auto def_guard = make_scoped_guard([=] { coll_delete(new_coll); });
-
- struct coll *replaced;
- if (coll_cache_replace(new_coll, &replaced) != 0)
- diag_raise();
- if (replaced == NULL && old_coll != NULL) {
+ coll_cache_delete(old_coll);
+ struct trigger *on_commit =
+ txn_alter_trigger_new(coll_cache_delete_coll, old_coll);
+ txn_on_commit(txn, on_commit);
+ } else if (new_tuple != NULL && old_tuple == NULL) {
+ /* INSERT */
+ struct coll_def new_def;
+ coll_def_new_from_tuple(new_tuple, &new_def);
+ access_check_ddl(new_def.name, new_def.owner_id, SC_COLLATION,
+ PRIV_C, false);
/*
- * ID of a collation was changed.
- * Remove collation by old ID.
+ * Set on_rollback before the collation is
+ * inserted into the cache. Else if the trigger
+ * creation fails the collation will not be
+ * deleted on abort.
*/
- coll_cache_delete(old_coll);
+ struct trigger *on_rollback =
+ txn_alter_trigger_new(coll_cache_rollback, NULL);
+ txn_on_rollback(txn, on_rollback);
+ struct coll *new_coll = coll_new(&new_def);
+ if (new_coll == NULL)
+ diag_raise();
+ struct coll *replaced;
+ if (coll_cache_replace(new_coll, &replaced) != 0)
+ diag_raise();
+ assert(replaced == NULL);
+ } else {
+ /* UPDATE */
+ assert(new_tuple != NULL && old_tuple != NULL);
+ tnt_raise(ClientError, ER_UNSUPPORTED, "collation", "alter");
}
-
- struct trigger *on_rollback =
- txn_alter_trigger_new(coll_cache_rollback, old_coll);
- txn_on_rollback(txn, on_rollback);
-
- def_guard.is_active = false;
}
/**
diff --git a/test/box/ddl.result b/test/box/ddl.result
index 0eef37992..87b9581c6 100644
--- a/test/box/ddl.result
+++ b/test/box/ddl.result
@@ -289,6 +289,16 @@ box.internal.collation.create('test', 'ICU', 'ru_RU', {strength='primary'}) --ok
box.internal.collation.drop('test') --ok
---
...
+c = box.space._collation:get{1}:totable()
+---
+...
+c[2] = 'unicode_test'
+---
+...
+box.space._collation:replace(c)
+---
+- error: collation does not support alter
+...
box.begin() box.internal.collation.create('test2', 'ICU', 'ru_RU')
---
- error: Space _collation does not support multi-statement transactions
diff --git a/test/box/ddl.test.lua b/test/box/ddl.test.lua
index 820fe7d4d..a1502ae13 100644
--- a/test/box/ddl.test.lua
+++ b/test/box/ddl.test.lua
@@ -127,6 +127,9 @@ box.internal.collation.create('test', 'ICU', 'ru_RU', {strength=2}) --ok
box.internal.collation.drop('test') --ok
box.internal.collation.create('test', 'ICU', 'ru_RU', {strength='primary'}) --ok
box.internal.collation.drop('test') --ok
+c = box.space._collation:get{1}:totable()
+c[2] = 'unicode_test'
+box.space._collation:replace(c)
box.begin() box.internal.collation.create('test2', 'ICU', 'ru_RU')
box.rollback()
--
2.15.1 (Apple Git-101)
next prev parent reply other threads:[~2018-04-28 22:45 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-04-28 22:45 [tarantool-patches] [PATCH v2 0/5] Expose ICU into Lua Vladislav Shpilevoy
2018-04-28 22:45 ` Vladislav Shpilevoy [this message]
2018-04-28 22:45 ` [tarantool-patches] [PATCH v2 2/5] Move struct on_access_denied_ctx into error.h Vladislav Shpilevoy
2018-05-04 11:06 ` [tarantool-patches] " Alexander Turenko
2018-05-04 12:05 ` Vladislav Shpilevoy
2018-04-28 22:45 ` [tarantool-patches] [PATCH v2 3/5] Merge box_error, stat and collations into core library Vladislav Shpilevoy
2018-05-04 11:36 ` [tarantool-patches] " Alexander Turenko
2018-05-04 12:05 ` Vladislav Shpilevoy
2018-05-08 13:18 ` Konstantin Osipov
2018-05-10 21:06 ` Vladislav Shpilevoy
2018-04-28 22:45 ` [tarantool-patches] [PATCH v2 4/5] Always store built-in collations in the cache Vladislav Shpilevoy
2018-05-08 13:20 ` [tarantool-patches] " Konstantin Osipov
2018-04-28 22:45 ` [tarantool-patches] [PATCH v2 5/5] lua: introduce utf8 built-in globaly visible module Vladislav Shpilevoy
2018-05-04 22:33 ` [tarantool-patches] " Alexander Turenko
2018-05-04 23:32 ` Vladislav Shpilevoy
2018-05-05 0:18 ` Alexander Turenko
2018-05-05 0:24 ` Vladislav Shpilevoy
2018-05-05 0:38 ` Alexander Turenko
2018-05-05 0:45 ` Vladislav Shpilevoy
2018-05-08 13:21 ` Konstantin Osipov
2018-05-05 0:19 ` [tarantool-patches] Re: [PATCH v2 0/5] Expose ICU into Lua Alexander Turenko
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=506613bb9ee89cbfe764baaedd9b3bf35851204b.1524955403.git.v.shpilevoy@tarantool.org \
--to=v.shpilevoy@tarantool.org \
--cc=alexander.turenko@tarantool.org \
--cc=tarantool-patches@freelists.org \
--subject='Re: [tarantool-patches] [PATCH v2 1/5] alter: fix assertion in collations alter' \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox