From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from [87.239.111.99] (localhost [127.0.0.1]) by dev.tarantool.org (Postfix) with ESMTP id 5B4476EC56; Wed, 28 Jul 2021 13:37:30 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 5B4476EC56 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1627468650; bh=ZxZ9eZOaOc5kYb3OkCKjvTu8tqbjWP3z1sUGxKIdxDI=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=Js66zGJdKaMM1iwzNRlcnKucISSnTdkf/QhaDkDnJ6/z0gMstllN0KSLo3T7vueAv Cjg8j6L8TUAZFK1tMr/U/KubxOaR/qBvl2c7DlGPCNpyREgzgQKRv7x/q91BkX0I5s Tc4brU4owI19uX11VK0PpX6KNArxFmmfPDQAlHJw= Received: from smtp57.i.mail.ru (smtp57.i.mail.ru [217.69.128.37]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id EBA9C6EC6F for ; Wed, 28 Jul 2021 13:34:31 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org EBA9C6EC6F Received: by smtp57.i.mail.ru with esmtpa (envelope-from ) id 1m8gtS-0008Bz-Qq; Wed, 28 Jul 2021 13:34:31 +0300 To: v.shpilevoy@tarantool.org Date: Wed, 28 Jul 2021 13:34:08 +0300 Message-Id: <2939f293071df83ba612c431895adea49c9cb8de.1627468002.git.tsafin@tarantool.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-4EC0790: 10 X-7564579A: 78E4E2B564C1792B X-77F55803: 4F1203BC0FB41BD941C43E597735A9C34755E0A9F196FCB739C645213AB7C8E0182A05F5380850407B1830A6C1F6E75859BC1C7750BE4256B4E6135FE4B934E070E04671A415C8E0 X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE790A429F79E911BC3EA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F7900637663000D94094A5D68638F802B75D45FF36EB9D2243A4F8B5A6FCA7DBDB1FC311F39EFFDF887939037866D6147AF826D80959D12DA0BC20D130429B013ADFBC94117882F4460429724CE54428C33FAD305F5C1EE8F4F765FCF1175FABE1C0F9B6A471835C12D1D9774AD6D5ED66289B52BA9C0B312567BB23117882F44604297287769387670735209ECD01F8117BC8BEA471835C12D1D977C4224003CC836476EB9C4185024447017B076A6E789B0E975F5C1EE8F4F765FC6CB27570637ACB643AA81AA40904B5D9CF19DD082D7633A078D18283394535A93AA81AA40904B5D98AA50765F7900637F77C31F58375ACD3D81D268191BDAD3D698AB9A7B718F8C4D1B931868CE1C5781A620F70A64A45A98AA50765F79006372E808ACE2090B5E1725E5C173C3A84C3C5EA940A35A165FF2DBA43225CD8A89F83C798A30B85E16BC6EABA9B74D0DA47B5C8C57E37DE458BEDA766A37F9254B7 X-B7AD71C0: AC4F5C86D027EB782CDD5689AFBDA7A213B5FB47DCBC3458F0AFF96BAACF4158235E5A14AD4A4A4625E192CAD1D9E79DB53CE8437368708909B54329EB422496 X-C1DE0DAB: C20DE7B7AB408E4181F030C43753B8186998911F362727C414F749A5E30D975C7BEA09003D200E08C118BA1902D25C6203066D5E6564E7839C2B6934AE262D3EE7EAB7254005DCED7532B743992DF240BDC6A1CF3F042BAD6DF99611D93F60EF824747F4BD2CC0FE699F904B3F4130E343918A1A30D5E7FCCB5012B2E24CD356 X-C8649E89: 4E36BF7865823D7055A7F0CF078B5EC49A30900B95165D349FF8F8245A2FAA7BD62833F40EE101F37756B90A40045EEC92BBED55852AD94609DE212158481E5E1D7E09C32AA3244CF2804B941454AA96B6C04919B8F86546435BF7150578642F83B48618A63566E0 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojiF1u9eOpfTSztO8eX87YeA== X-Mailru-Sender: B5B6A6EBBD94DAD8C47A93838048902D54E8C5C2A129CF37ED9DB2D0E97925DF1F15E8D71F2E8E271EC9E4A2C82A33BC8C24925A86E657CE0C70AEE3C9A96FBAB3D7EE8ED63280BE112434F685709FCF0DA7A0AF5A3A8387 X-Mras: Ok Subject: [Tarantool-patches] [PATCH resend v2 06/11] box, datetime: datetime comparison for indices X-BeenThere: tarantool-patches@dev.tarantool.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Timur Safin via Tarantool-patches Reply-To: Timur Safin Cc: tarantool-patches@dev.tarantool.org Errors-To: tarantool-patches-bounces@dev.tarantool.org Sender: "Tarantool-patches" * storage hints implemented for datetime_t values; * proper comparison for indices of datetime type. Part of #5941 Part of #5946 --- src/box/field_def.c | 18 ++++++++ src/box/field_def.h | 3 ++ src/box/memtx_space.c | 3 +- src/box/tuple_compare.cc | 30 ++++++++++++++ src/box/vinyl.c | 3 +- test/engine/datetime.result | 77 +++++++++++++++++++++++++++++++++++ test/engine/datetime.test.lua | 35 ++++++++++++++++ 7 files changed, 165 insertions(+), 4 deletions(-) create mode 100644 test/engine/datetime.result create mode 100644 test/engine/datetime.test.lua diff --git a/src/box/field_def.c b/src/box/field_def.c index 6964e3e9f..aaf5f9cff 100644 --- a/src/box/field_def.c +++ b/src/box/field_def.c @@ -193,3 +193,21 @@ field_type_by_name(const char *name, size_t len) return FIELD_TYPE_ANY; return field_type_MAX; } + +const bool field_type_index_allowed[] = + { + /* [FIELD_TYPE_ANY] = */ false, + /* [FIELD_TYPE_UNSIGNED] = */ true, + /* [FIELD_TYPE_STRING] = */ true, + /* [FIELD_TYPE_NUMBER] = */ true, + /* [FIELD_TYPE_DOUBLE] = */ true, + /* [FIELD_TYPE_INTEGER] = */ true, + /* [FIELD_TYPE_BOOLEAN] = */ true, + /* [FIELD_TYPE_VARBINARY]= */ true, + /* [FIELD_TYPE_SCALAR] = */ true, + /* [FIELD_TYPE_DECIMAL] = */ true, + /* [FIELD_TYPE_UUID] = */ true, + /* [FIELD_TYPE_ARRAY] = */ false, + /* [FIELD_TYPE_MAP] = */ false, + /* [FIELD_TYPE_DATETIME] = */ true, +}; diff --git a/src/box/field_def.h b/src/box/field_def.h index 120b2a93d..bd02418df 100644 --- a/src/box/field_def.h +++ b/src/box/field_def.h @@ -120,6 +120,9 @@ extern const uint32_t field_ext_type[]; extern const struct opt_def field_def_reg[]; extern const struct field_def field_def_default; +/** helper table for checking allowed indices for types */ +extern const bool field_type_index_allowed[]; + /** * @brief Field definition * Contains information about of one tuple field. diff --git a/src/box/memtx_space.c b/src/box/memtx_space.c index b71318d24..1ab16122e 100644 --- a/src/box/memtx_space.c +++ b/src/box/memtx_space.c @@ -748,8 +748,7 @@ memtx_space_check_index_def(struct space *space, struct index_def *index_def) /* Check that there are no ANY, ARRAY, MAP parts */ for (uint32_t i = 0; i < key_def->part_count; i++) { struct key_part *part = &key_def->parts[i]; - if (part->type <= FIELD_TYPE_ANY || - part->type >= FIELD_TYPE_ARRAY) { + if (!field_type_index_allowed[part->type]) { diag_set(ClientError, ER_MODIFY_INDEX, index_def->name, space_name(space), tt_sprintf("field type '%s' is not supported", diff --git a/src/box/tuple_compare.cc b/src/box/tuple_compare.cc index 48c833643..4adceebd3 100644 --- a/src/box/tuple_compare.cc +++ b/src/box/tuple_compare.cc @@ -538,6 +538,8 @@ tuple_compare_field_with_type(const char *field_a, enum mp_type a_type, field_b, b_type); case FIELD_TYPE_UUID: return mp_compare_uuid(field_a, field_b); + case FIELD_TYPE_DATETIME: + return mp_compare_datetime(field_a, field_b); default: unreachable(); return 0; @@ -1630,6 +1632,18 @@ hint_uuid_raw(const char *data) return hint_create(MP_CLASS_UUID, val); } +static inline hint_t +hint_datetime(struct datetime_t *date) +{ + /* + * Use at most HINT_VALUE_BITS from datetime + * seconds field as a hint value + */ + uint64_t val = (uint64_t)date->secs & HINT_VALUE_MAX; + + return hint_create(MP_CLASS_DATETIME, val); +} + static inline uint64_t hint_str_raw(const char *s, uint32_t len) { @@ -1761,6 +1775,17 @@ field_hint_uuid(const char *field) return hint_uuid_raw(data); } +static inline hint_t +field_hint_datetime(const char *field) +{ + assert(mp_typeof(*field) == MP_EXT); + int8_t ext_type; + uint32_t len = mp_decode_extl(&field, &ext_type); + assert(ext_type == MP_DATETIME); + struct datetime_t date; + return hint_datetime(datetime_unpack(&field, len, &date)); +} + static inline hint_t field_hint_string(const char *field, struct coll *coll) { @@ -1849,6 +1874,8 @@ field_hint(const char *field, struct coll *coll) return field_hint_decimal(field); case FIELD_TYPE_UUID: return field_hint_uuid(field); + case FIELD_TYPE_DATETIME: + return field_hint_datetime(field); default: unreachable(); } @@ -1963,6 +1990,9 @@ key_def_set_hint_func(struct key_def *def) case FIELD_TYPE_UUID: key_def_set_hint_func(def); break; + case FIELD_TYPE_DATETIME: + key_def_set_hint_func(def); + break; default: /* Invalid key definition. */ def->key_hint = NULL; diff --git a/src/box/vinyl.c b/src/box/vinyl.c index c80b2d99b..360d1fa70 100644 --- a/src/box/vinyl.c +++ b/src/box/vinyl.c @@ -662,8 +662,7 @@ vinyl_space_check_index_def(struct space *space, struct index_def *index_def) /* Check that there are no ANY, ARRAY, MAP parts */ for (uint32_t i = 0; i < key_def->part_count; i++) { struct key_part *part = &key_def->parts[i]; - if (part->type <= FIELD_TYPE_ANY || - part->type >= FIELD_TYPE_ARRAY) { + if (!field_type_index_allowed[part->type]) { diag_set(ClientError, ER_MODIFY_INDEX, index_def->name, space_name(space), tt_sprintf("field type '%s' is not supported", diff --git a/test/engine/datetime.result b/test/engine/datetime.result new file mode 100644 index 000000000..3ff474dee --- /dev/null +++ b/test/engine/datetime.result @@ -0,0 +1,77 @@ +-- test-run result file version 2 +env = require('test_run') + | --- + | ... +test_run = env.new() + | --- + | ... +engine = test_run:get_cfg('engine') + | --- + | ... + +date = require('datetime') + | --- + | ... + +_ = box.schema.space.create('T', {engine = engine}) + | --- + | ... +_ = box.space.T:create_index('pk', {parts={1,'datetime'}}) + | --- + | ... + +box.space.T:insert{date('1970-01-01')}\ +box.space.T:insert{date('1970-01-02')}\ +box.space.T:insert{date('1970-01-03')}\ +box.space.T:insert{date('2000-01-01')} + | --- + | ... + +o = box.space.T:select{} + | --- + | ... +assert(tostring(o[1][1]) == '1970-01-01T00:00Z') + | --- + | - true + | ... +assert(tostring(o[2][1]) == '1970-01-02T00:00Z') + | --- + | - true + | ... +assert(tostring(o[3][1]) == '1970-01-03T00:00Z') + | --- + | - true + | ... +assert(tostring(o[4][1]) == '2000-01-01T00:00Z') + | --- + | - true + | ... + +for i = 1,16 do\ + box.space.T:insert{date.now()}\ +end + | --- + | ... + +a = box.space.T:select{} + | --- + | ... +err = nil + | --- + | ... +for i = 1, #a - 1 do\ + if tostring(a[i][1]) >= tostring(a[i+1][1]) then\ + err = {a[i][1], a[i+1][1]}\ + break\ + end\ +end + | --- + | ... + +err + | --- + | - null + | ... +box.space.T:drop() + | --- + | ... diff --git a/test/engine/datetime.test.lua b/test/engine/datetime.test.lua new file mode 100644 index 000000000..180d9bb72 --- /dev/null +++ b/test/engine/datetime.test.lua @@ -0,0 +1,35 @@ +env = require('test_run') +test_run = env.new() +engine = test_run:get_cfg('engine') + +date = require('datetime') + +_ = box.schema.space.create('T', {engine = engine}) +_ = box.space.T:create_index('pk', {parts={1,'datetime'}}) + +box.space.T:insert{date('1970-01-01')}\ +box.space.T:insert{date('1970-01-02')}\ +box.space.T:insert{date('1970-01-03')}\ +box.space.T:insert{date('2000-01-01')} + +o = box.space.T:select{} +assert(tostring(o[1][1]) == '1970-01-01T00:00Z') +assert(tostring(o[2][1]) == '1970-01-02T00:00Z') +assert(tostring(o[3][1]) == '1970-01-03T00:00Z') +assert(tostring(o[4][1]) == '2000-01-01T00:00Z') + +for i = 1,16 do\ + box.space.T:insert{date.now()}\ +end + +a = box.space.T:select{} +err = nil +for i = 1, #a - 1 do\ + if tostring(a[i][1]) >= tostring(a[i+1][1]) then\ + err = {a[i][1], a[i+1][1]}\ + break\ + end\ +end + +err +box.space.T:drop() -- 2.29.2