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 2236724EA0 for ; Thu, 12 Sep 2019 10:00:51 -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 GXhejdebw2Qu for ; Thu, 12 Sep 2019 10:00:51 -0400 (EDT) Received: from smtpng2.m.smailru.net (smtpng2.m.smailru.net [94.100.179.3]) (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 2BC0E24E9F for ; Thu, 12 Sep 2019 10:00:48 -0400 (EDT) Date: Thu, 12 Sep 2019 17:00:45 +0300 From: Nikita Pettik Subject: [tarantool-patches] Re: [PATCH v2 1/3] box: an ability to disable CK constraints Message-ID: <20190912140044.GA97194@tarantool.org> References: <9ff97ab5cf810e52988267f150c330826d2e4910.1568275504.git.kshcherbatov@tarantool.org> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <9ff97ab5cf810e52988267f150c330826d2e4910.1568275504.git.kshcherbatov@tarantool.org> 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: Kirill Shcherbatov Cc: tarantool-patches@freelists.org On 12 Sep 11:06, Kirill Shcherbatov wrote: > @TarantoolBot document > Title: an ability to disable CK constraints > > Now it is possible to disable and enable ck constraints. > This option is not persistent. All ck constraints are enabled > by default when Tarantool is configured. Ck constraints checks > are not performed during standard recovery, but performed during > force_recovery - all conflicting tuples are skipped in case of > ck_constraint conflict. Please, add reasoning. Please, explain why do we need per constraint options? Why not disable them all at once? How to disable constraint in SQL? What is more, I'd split this patch into two: first one introduces 'is_enabled' property; second one provides check execution during force recovery. > > Example: > box.space.T6.ck_constraint.ck_unnamed_T6_1:enable(false) > box.space.T6.ck_constraint.ck_unnamed_T6_1 > - space_id: 512 > is_enabled: false > name: ck_unnamed_T6_1 > expr: a < 10 > x.space.T6:insert({11}) > -- passed > > Closes #4244 > --- > extra/exports | 1 + > src/box/ck_constraint.c | 23 +++++++- > src/box/ck_constraint.h | 19 +++++++ > src/box/lua/schema.lua | 13 +++++ > src/box/lua/space.cc | 3 ++ > src/box/memtx_engine.c | 15 ++++++ > test/sql/checks.result | 112 +++++++++++++++++++++++++++++++++++++++ > test/sql/checks.test.lua | 41 ++++++++++++++ > 8 files changed, 226 insertions(+), 1 deletion(-) > > diff --git a/extra/exports b/extra/exports > index 7b84a1452..ecc7d102b 100644 > --- a/extra/exports > +++ b/extra/exports > @@ -78,6 +78,7 @@ tarantool_exit > log_pid > space_by_id > space_run_triggers > +space_ck_constraint_enable > space_bsize > box_schema_version > > diff --git a/src/box/ck_constraint.c b/src/box/ck_constraint.c > index 1cde27022..f65715096 100644 > --- a/src/box/ck_constraint.c > +++ b/src/box/ck_constraint.c > @@ -28,6 +28,7 @@ > * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF > * SUCH DAMAGE. > */ > +#include "memtx_engine.h" > #include "box/session.h" > #include "bind.h" > #include "ck_constraint.h" > @@ -201,7 +202,8 @@ ck_constraint_on_replace_trigger(struct trigger *trigger, void *event) > > struct ck_constraint *ck_constraint; > rlist_foreach_entry(ck_constraint, &space->ck_constraint, link) { > - if (ck_constraint_program_run(ck_constraint, field_ref) != 0) > + if (ck_constraint->is_enabled && > + ck_constraint_program_run(ck_constraint, field_ref) != 0) > diag_raise(); > } > } > @@ -223,6 +225,13 @@ ck_constraint_new(struct ck_constraint_def *ck_constraint_def, > } > ck_constraint->def = NULL; > ck_constraint->stmt = NULL; > + > + struct memtx_engine *memtx = > + (struct memtx_engine *)engine_by_name("memtx"); > + assert(memtx != NULL); Wait a second, how it is supposed to work with vinyl? > + bool is_recovery = memtx->state != MEMTX_OK; Supply this code with comment. > + ck_constraint->is_enabled = !is_recovery; > + > rlist_create(&ck_constraint->link); > struct Expr *expr = > sql_expr_compile(sql_get(), ck_constraint_def->expr_str, > @@ -269,3 +278,15 @@ space_ck_constraint_by_name(struct space *space, const char *name, > } > return NULL; > } > + > +int > +space_ck_constraint_enable(struct space *space, const char *name, > + bool is_enabled) > +{ Nit: method is calles "enable", but it can also disable trigger. I'd rename it to "_set_status"/"set_state" etc > + struct ck_constraint *ck = > + space_ck_constraint_by_name(space, name, strlen(name)); > + if (ck == NULL) > + return -1; > + ck->is_enabled = is_enabled; > + return 0; > +} > diff --git a/src/box/ck_constraint.h b/src/box/ck_constraint.h > index f26f77a38..4f2a3c20e 100644 > --- a/src/box/ck_constraint.h > +++ b/src/box/ck_constraint.h > @@ -93,6 +93,12 @@ struct ck_constraint { > * message when ck condition unsatisfied. > */ > struct sql_stmt *stmt; > + /** > + * Whether the CK constraint object is enabled: the > + * checks wouldn't be performed when this flag is > + * set 'false'. -> /** * Per constraint option regulating its execution: it is disabled * (set to false) contraint won't be fired. Note that during ordinary * recovery they are turned off; during force recovery they are * enabled. */ > + */ > + bool is_enabled; > /** > * Organize check constraint structs into linked list > * with space::ck_constraint. > diff --git a/src/box/lua/space.cc b/src/box/lua/space.cc > index d0a7e7815..2c686e818 100644 > --- a/src/box/lua/space.cc > +++ b/src/box/lua/space.cc > @@ -205,6 +205,9 @@ lbox_push_ck_constraint(struct lua_State *L, struct space *space, int i) > lua_pushstring(L, ck_constraint->def->expr_str); > lua_setfield(L, -2, "expr"); > > + lua_pushboolean(L, ck_constraint->is_enabled); > + lua_setfield(L, -2, "is_enabled"); > + > lua_setfield(L, -2, ck_constraint->def->name); > } > lua_pop(L, 1); > diff --git a/src/box/memtx_engine.c b/src/box/memtx_engine.c > index f6a33282c..819571819 100644 > --- a/src/box/memtx_engine.c > +++ b/src/box/memtx_engine.c > @@ -35,6 +35,7 @@ > #include > #include > > +#include "ck_constraint.h" > #include "fiber.h" > #include "errinj.h" > #include "coio_file.h" > @@ -86,6 +87,18 @@ memtx_end_build_primary_key(struct space *space, void *param) > return 0; > } > > +static int > +space_run_ck_constraints(struct space *space, void *param) > +{ > + if (space_is_system(space)) > + return 0; > + struct ck_constraint *ck; > + rlist_foreach_entry(ck, &space->ck_constraint, link) > + ck->is_enabled = (bool)param; > + (void)trigger_run(&on_alter_space, space); > + return 0; > +} > + > /** > * Secondary indexes are built in bulk after all data is > * recovered. This function enables secondary keys on a space. > @@ -315,6 +328,8 @@ memtx_engine_end_recovery(struct engine *engine) > if (space_foreach(memtx_build_secondary_keys, memtx) != 0) > return -1; > } > + if (space_foreach(space_run_ck_constraints, (void *)true) != 0) > + unreachable(); What does this change do? Why do you need param if it is always true? Is space_is_system() check vital? > diff --git a/test/sql/checks.test.lua b/test/sql/checks.test.lua > index cde213f8b..9716647d0 100644 > --- a/test/sql/checks.test.lua > +++ b/test/sql/checks.test.lua > @@ -234,4 +234,45 @@ s2:drop() > physics_ck > physics_ck:drop() > > +-- > +-- gh-4244: An ability to disable CK constraints Nit: add an ability ... > +-- Make shure that ck constraints are turning on and of with -> sure; are turned on/off > +-- :enable configurator. > +-- > +engine = test_run:get_cfg('engine') > +box.execute('pragma sql_default_engine=\''..engine..'\'') > +box.execute("CREATE TABLE test(a INT CHECK (a < 5) primary key);"); > +box.space.TEST:insert({10}) > +box.space.TEST.ck_constraint.ck_unnamed_TEST_1:enable(false) > +box.space.TEST:insert({11}) > +box.space.TEST.ck_constraint.ck_unnamed_TEST_1:enable(true) > +box.space.TEST:insert({12}) > +-- Enshure that ck constraints are not validated during -> Ensure > +-- normal recovery. Now TEST space has a tuple {12} violating > +-- defined CK constraint. > +test_run:cmd("restart server default") > +box.space.TEST:select() > +box.space.TEST:insert({12}) > +box.execute("DROP TABLE test;") > + > +-- Enshure that ck constraints are validated during > +-- force recovery. > +test_run:cmd('create server test with script = "xlog/force_recovery.lua"') > +test_run:cmd("start server test") > +test_run:cmd("switch test") Could you make result of test be clearer? From .result file it is not obvious that check verification failed. > +engine = test_run:get_cfg('engine') > +box.execute('pragma sql_default_engine=\''..engine..'\'') > +box.execute("CREATE TABLE test(a INT CHECK (a < 10) primary key);"); > +box.space.TEST.ck_constraint.ck_unnamed_TEST_1:enable(false) > +box.space.TEST:insert({11}) > +box.space.TEST:insert({2}) > +test_run:cmd("restart server test") > +box.space.TEST:select() > +box.execute("DROP TABLE test;") > + > +test_run = require('test_run').new() > +test_run:cmd('switch default') > +test_run:cmd('stop server test') > + > test_run:cmd("clear filter")