diff --git a/src/box/sophia_engine.cc b/src/box/sophia_engine.cc index d3e612ffbdc709d423667e66307bd7040af45a8c..d7c39d97235360104fdccc476994cf5e39ec5067 100644 --- a/src/box/sophia_engine.cc +++ b/src/box/sophia_engine.cc @@ -97,9 +97,17 @@ struct tuple * SophiaSpace::executeReplace(struct txn *txn, struct space *space, struct request *request) { + SophiaIndex *index = (SophiaIndex *)index_find(space, 0); + space_validate_tuple_raw(space, request->tuple); tuple_field_count_validate(space->format, request->tuple); + int size = request->tuple_end - request->tuple; + const char *key = + tuple_field_raw(request->tuple, size, + index->key_def->parts[0].fieldno); + primary_key_validate(index->key_def, key, index->key_def->part_count); + /* Switch from INSERT to REPLACE during recovery. * * Database might hold newer key version than currenly @@ -111,8 +119,6 @@ SophiaSpace::executeReplace(struct txn *txn, struct space *space, if (engine->recovery_complete) mode = DUP_INSERT; } - SophiaIndex *index = - (SophiaIndex *)index_find(space, 0); index->replace_or_insert(request->tuple, request->tuple_end, mode); txn_commit_stmt(txn); return NULL; diff --git a/test/sophia/constraint.result b/test/sophia/constraint.result new file mode 100644 index 0000000000000000000000000000000000000000..9dabea6c03f931b68dcfc5dfd0aa2ec1536ac7fc --- /dev/null +++ b/test/sophia/constraint.result @@ -0,0 +1,76 @@ +-- key type validations (str, num) +space = box.schema.space.create('test', { engine = 'sophia' }) +--- +... +index = space:create_index('primary', { type = 'tree', parts = {1, 'str'} }) +--- +... +space:insert{1} +--- +- error: 'Supplied key type of part 0 does not match index part type: expected STR' +... +space:replace{1} +--- +- error: 'Supplied key type of part 0 does not match index part type: expected STR' +... +space:delete{1} +--- +- error: 'Supplied key type of part 0 does not match index part type: expected STR' +... +space:update(1, {{'=', 1, 101}}) +--- +- error: 'Supplied key type of part 0 does not match index part type: expected STR' +... +space:upsert(1, {{'+', 1, 10}}, {0}) +--- +- error: 'Supplied key type of part 0 does not match index part type: expected STR' +... +space:get{1} +--- +- error: 'Supplied key type of part 0 does not match index part type: expected STR' +... +index:pairs(1, {iterator = 'GE'}) +--- +- error: 'Supplied key type of part 0 does not match index part type: expected STR' +... +space:drop() +--- +... +-- key type validations (num, str) +space = box.schema.space.create('test', { engine = 'sophia' }) +--- +... +index = space:create_index('primary', { type = 'tree', parts = {1, 'num'} }) +--- +... +space:insert{'A'} +--- +- error: 'Supplied key type of part 0 does not match index part type: expected NUM' +... +space:replace{'A'} +--- +- error: 'Supplied key type of part 0 does not match index part type: expected NUM' +... +space:delete{'A'} +--- +- error: 'Supplied key type of part 0 does not match index part type: expected NUM' +... +space:update('A', {{'=', 1, 101}}) +--- +- error: 'Supplied key type of part 0 does not match index part type: expected NUM' +... +space:upsert('A', {{'+', 1, 10}}, {0}) +--- +- error: 'Supplied key type of part 0 does not match index part type: expected NUM' +... +space:get{'A'} +--- +- error: 'Supplied key type of part 0 does not match index part type: expected NUM' +... +index:pairs('A', {iterator = 'GE'}) +--- +- error: 'Supplied key type of part 0 does not match index part type: expected NUM' +... +space:drop() +--- +... diff --git a/test/sophia/constraint.test.lua b/test/sophia/constraint.test.lua new file mode 100644 index 0000000000000000000000000000000000000000..216b325a8ef4a98287bdf2d4ec874e26384d7567 --- /dev/null +++ b/test/sophia/constraint.test.lua @@ -0,0 +1,24 @@ + +-- key type validations (str, num) +space = box.schema.space.create('test', { engine = 'sophia' }) +index = space:create_index('primary', { type = 'tree', parts = {1, 'str'} }) +space:insert{1} +space:replace{1} +space:delete{1} +space:update(1, {{'=', 1, 101}}) +space:upsert(1, {{'+', 1, 10}}, {0}) +space:get{1} +index:pairs(1, {iterator = 'GE'}) +space:drop() + +-- key type validations (num, str) +space = box.schema.space.create('test', { engine = 'sophia' }) +index = space:create_index('primary', { type = 'tree', parts = {1, 'num'} }) +space:insert{'A'} +space:replace{'A'} +space:delete{'A'} +space:update('A', {{'=', 1, 101}}) +space:upsert('A', {{'+', 1, 10}}, {0}) +space:get{'A'} +index:pairs('A', {iterator = 'GE'}) +space:drop() diff --git a/test/sophia/gh.result b/test/sophia/gh.result index 3e46a144a956a327c8cbd57ea92bcaff2d0c11d3..7c8f9e5139886713b29cd69372b7d9acc2db9b8d 100644 --- a/test/sophia/gh.result +++ b/test/sophia/gh.result @@ -136,3 +136,17 @@ s.index.primary:alter({parts={1,'NUM'}}) s:drop() --- ... +-- gh-1008: assertion if insert of wrong type +s = box.schema.space.create('t', {engine='sophia'}) +--- +... +i = s:create_index('primary',{parts={1, 'STR'}}) +--- +... +box.space.t:insert{1,'A'} +--- +- error: 'Supplied key type of part 0 does not match index part type: expected STR' +... +s:drop() +--- +... diff --git a/test/sophia/gh.test.lua b/test/sophia/gh.test.lua index 3ef3f0b1a036df7f031763a9446bbf8d004fd9fb..d820e911215d479395b0a52cf96c5b9cf13d7aab 100644 --- a/test/sophia/gh.test.lua +++ b/test/sophia/gh.test.lua @@ -56,3 +56,10 @@ i = s:create_index('primary',{}) s:insert{5} s.index.primary:alter({parts={1,'NUM'}}) s:drop() + + +-- gh-1008: assertion if insert of wrong type +s = box.schema.space.create('t', {engine='sophia'}) +i = s:create_index('primary',{parts={1, 'STR'}}) +box.space.t:insert{1,'A'} +s:drop()