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 747B42508F for ; Fri, 19 Jul 2019 08:17:01 -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 K3bus7kcDoTF for ; Fri, 19 Jul 2019 08:17:01 -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 0C8B52500F for ; Fri, 19 Jul 2019 08:17:01 -0400 (EDT) Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 (Mac OS X Mail 12.2 \(3445.102.3\)) Subject: [tarantool-patches] Re: [PATCH] net.box: ignore absence of _vcollation From: Roman Khabibov In-Reply-To: <20190712095549.ac4hhaxhxzgaik5i@tarantool.org> Date: Fri, 19 Jul 2019 15:16:58 +0300 Content-Transfer-Encoding: quoted-printable Message-Id: <6D947FF2-9C44-40A9-9707-AA94512B27D6@tarantool.org> References: <20190708121338.76309-1-roman.habibov@tarantool.org> <20190712095549.ac4hhaxhxzgaik5i@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: tarantool-patches@freelists.org Cc: Kirill Yukhin , Alexander Turenko > On Jul 12, 2019, at 12:55, Kirill Yukhin = wrote: >=20 > Hello, >=20 > On 08 Jul 15:13, Roman Khabibov wrote: >> Ignore error about absence of _vcollation, when a client connects >> to a server of old Tarantool versions, where this space does not >> exist. >>=20 >> Closes #4307 >> --- >> Branch: = https://github.com/tarantool/tarantool/tree/romanhabibov/gh-4307-vcoll >> Issue: https://github.com/tarantool/tarantool/issues/4307 >>=20 >> src/box/lua/net_box.lua | 33 +++++++++++++++++++++++++-------- >> 1 file changed, 25 insertions(+), 8 deletions(-) >>=20 >> diff --git a/src/box/lua/net_box.lua b/src/box/lua/net_box.lua >> index 2892bb3d3..723e63045 100644 >> --- a/src/box/lua/net_box.lua >> +++ b/src/box/lua/net_box.lua >> @@ -761,6 +761,11 @@ local function create_transport(host, port, = user, password, callback, >> if status ~=3D 0 then >> local body >> body, body_end =3D decode(body_rpos) >> + local err_msg =3D 'Space \'277\' does not exist' >=20 > Space 277? Seriously? This code handles not only collations request. > Should be more generic, IMHO. @@ -685,7 +685,7 @@ local function create_transport(host, port, user, = password, callback, set_state('active') return console_sm(rid) elseif greeting.protocol =3D=3D 'Binary' then - return iproto_auth_sm(greeting.salt) + return iproto_auth_sm(greeting.salt, greeting.version_id) else return error_sm(E_NO_CONNECTION, 'Unknown protocol: '..greeting.protocol) @@ -710,11 +710,11 @@ local function create_transport(host, port, user, = password, callback, end end =20 - iproto_auth_sm =3D function(salt) + iproto_auth_sm =3D function(salt, version_id) set_state('auth') if not user or not password then set_state('fetch_schema') - return iproto_schema_sm() + return iproto_schema_sm(nil, version_id) end encode_auth(send_buf, new_request_id(), user, password, salt) local err, hdr, body_rpos, body_end =3D send_and_recv_iproto() @@ -727,34 +727,52 @@ local function create_transport(host, port, user, = password, callback, return error_sm(E_NO_CONNECTION, body[IPROTO_ERROR_KEY]) end set_state('fetch_schema') - return iproto_schema_sm(hdr[IPROTO_SCHEMA_VERSION_KEY]) + return iproto_schema_sm(hdr[IPROTO_SCHEMA_VERSION_KEY], = version_id) end =20 - iproto_schema_sm =3D function(schema_version) + iproto_schema_sm =3D function(schema_version, version_id) if not callback('will_fetch_schema') then set_state('active') - return iproto_sm(schema_version) + return iproto_sm(schema_version, version_id) end + local need_vcoll + -- 131584 is tarantool_version_id() for 2.2.0. + if version_id ~=3D nil and version_id >=3D 131584 then + need_vcoll =3D true + else + need_vcoll =3D false + end + local select1_id =3D new_request_id() local select2_id =3D new_request_id() - local select3_id =3D new_request_id() + local select3_id =3D nil local response =3D {} -- fetch everything from space _vspace, 2 =3D ITER_ALL encode_select(send_buf, select1_id, VSPACE_ID, 0, 2, 0, = 0xFFFFFFFF, nil) -- fetch everything from space _vindex, 2 =3D ITER_ALL encode_select(send_buf, select2_id, VINDEX_ID, 0, 2, 0, = 0xFFFFFFFF, nil) - -- fetch everything from space _vcollation, 2 =3D ITER_ALL - encode_select(send_buf, select3_id, VCOLLATION_ID, 0, 2, 0, = 0xFFFFFFFF, - nil) + if need_vcoll =3D=3D true then + select3_id =3D new_request_id() + -- fetch everything from space _vcollation, 2 =3D ITER_ALL + encode_select(send_buf, select3_id, VCOLLATION_ID, 0, 2, 0, = 0xFFFFFFFF, + nil) + end =20 schema_version =3D nil -- any schema_version will do provided = that -- it is consistent across responses + + local function vcoll_response(need_vcoll) + if need_vcoll =3D=3D true then + return response[select3_id] + end + return true + end repeat local err, hdr, body_rpos, body_end =3D = send_and_recv_iproto() if err then return error_sm(err, hdr) end dispatch_response_iproto(hdr, body_rpos, body_end) local id =3D hdr[IPROTO_SYNC_KEY] - if id =3D=3D select1_id or id =3D=3D select2_id or id =3D=3D = select3_id then + if id =3D=3D select1_id or id =3D=3D select2_id or id =3D=3D = select3_id and need_vcoll then -- response to a schema query we've submitted local status =3D hdr[IPROTO_STATUS_KEY] local response_schema_version =3D = hdr[IPROTO_SCHEMA_VERSION_KEY] @@ -767,21 +785,21 @@ local function create_transport(host, port, user, = password, callback, schema_version =3D response_schema_version elseif schema_version ~=3D response_schema_version then -- schema changed while fetching schema; restart = loader - return iproto_schema_sm() + return iproto_schema_sm(nil, version_id) end local body body, body_end =3D decode(body_rpos) response[id] =3D body[IPROTO_DATA_KEY] end until response[select1_id] and response[select2_id] and - response[select3_id] + vcoll_response(need_vcoll) callback('did_fetch_schema', schema_version, = response[select1_id], - response[select2_id],response[select3_id]) + response[select2_id], need_vcoll and = response[select3_id] or nil) set_state('active') - return iproto_sm(schema_version) + return iproto_sm(schema_version, version_id) end =20 - iproto_sm =3D function(schema_version) + iproto_sm =3D function(schema_version, version_id) local err, hdr, body_rpos, body_end =3D send_and_recv_iproto() if err then return error_sm(err, hdr) end dispatch_response_iproto(hdr, body_rpos, body_end) @@ -794,9 +812,9 @@ local function create_transport(host, port, user, = password, callback, local body body, body_end =3D decode(body_rpos) set_state('fetch_schema') - return iproto_schema_sm(schema_version) + return iproto_schema_sm(schema_version, version_id) end - return iproto_sm(schema_version) + return iproto_sm(schema_version, version_id) end =20 error_sm =3D function(err, msg) >> @@ -1270,16 +1275,28 @@ function = remote_methods:_install_schema(schema_version, spaces, indices, >> local pktype =3D index[PARTS][k][2] or = index[PARTS][k].type >> local pkfield =3D index[PARTS][k][1] or = index[PARTS][k].field >> local pkcollation =3D nil >> - if pkcollationid ~=3D nil then >> + if pkcollationid ~=3D nil and collations ~=3D nil = then >> pkcollation =3D collations[pkcollationid + 1][2] >> end >>=20 >> - local pk =3D { >> - type =3D pktype, >> - fieldno =3D pkfield + 1, >> - collation =3D pkcollation, >> - is_nullable =3D pknullable >> - } >> + local pk >> + if collations ~=3D nil then >> + pk =3D { >> + type =3D pktype, >> + fieldno =3D pkfield + 1, >> + collation =3D pkcollation, >> + is_nullable =3D pknullable >> + } >> + else >> + pk =3D { >> + type =3D pktype, >> + fieldno =3D pkfield + 1, >> + collation_id =3D pkcollationid, >> + is_nullable =3D pknullable >> + } >> + end >=20 > IMHO, it'd be better to not duplicate code and put actual difference > under if-then-else hammock. @@ -1270,16 +1288,21 @@ function = remote_methods:_install_schema(schema_version, spaces, indices, local pktype =3D index[PARTS][k][2] or = index[PARTS][k].type local pkfield =3D index[PARTS][k][1] or = index[PARTS][k].field local pkcollation =3D nil - if pkcollationid ~=3D nil then + if pkcollationid ~=3D nil and collations ~=3D nil then pkcollation =3D collations[pkcollationid + 1][2] end =20 local pk =3D { type =3D pktype, fieldno =3D pkfield + 1, - collation =3D pkcollation, is_nullable =3D pknullable } + if collations ~=3D nil then + pk.collation =3D pkcollation + else + pk.collation_id =3D pkcollationid + end + commit abc88ef8d38e21a6c7faf925a19105ce65d45467 Author: Roman Khabibov Date: Mon Jul 8 14:52:48 2019 +0300 net.box: take into account _vcollation presence =20 The error occured, when a client connects to a server of old Tarantool versions, where _vcollation space does not exist. After this patch, _vcollation is fetched depending on a server version. =20 Closes #4307 diff --git a/src/box/lua/net_box.lua b/src/box/lua/net_box.lua index 2892bb3d3..9fe792195 100644 --- a/src/box/lua/net_box.lua +++ b/src/box/lua/net_box.lua @@ -685,7 +685,7 @@ local function create_transport(host, port, user, = password, callback, set_state('active') return console_sm(rid) elseif greeting.protocol =3D=3D 'Binary' then - return iproto_auth_sm(greeting.salt) + return iproto_auth_sm(greeting.salt, greeting.version_id) else return error_sm(E_NO_CONNECTION, 'Unknown protocol: '..greeting.protocol) @@ -710,11 +710,11 @@ local function create_transport(host, port, user, = password, callback, end end =20 - iproto_auth_sm =3D function(salt) + iproto_auth_sm =3D function(salt, version_id) set_state('auth') if not user or not password then set_state('fetch_schema') - return iproto_schema_sm() + return iproto_schema_sm(nil, version_id) end encode_auth(send_buf, new_request_id(), user, password, salt) local err, hdr, body_rpos, body_end =3D send_and_recv_iproto() @@ -727,34 +727,52 @@ local function create_transport(host, port, user, = password, callback, return error_sm(E_NO_CONNECTION, body[IPROTO_ERROR_KEY]) end set_state('fetch_schema') - return iproto_schema_sm(hdr[IPROTO_SCHEMA_VERSION_KEY]) + return iproto_schema_sm(hdr[IPROTO_SCHEMA_VERSION_KEY], = version_id) end =20 - iproto_schema_sm =3D function(schema_version) + iproto_schema_sm =3D function(schema_version, version_id) if not callback('will_fetch_schema') then set_state('active') - return iproto_sm(schema_version) + return iproto_sm(schema_version, version_id) end + local need_vcoll + -- 131584 is tarantool_version_id() for 2.2.0. + if version_id ~=3D nil and version_id >=3D 131584 then + need_vcoll =3D true + else + need_vcoll =3D false + end + local select1_id =3D new_request_id() local select2_id =3D new_request_id() - local select3_id =3D new_request_id() + local select3_id =3D nil local response =3D {} -- fetch everything from space _vspace, 2 =3D ITER_ALL encode_select(send_buf, select1_id, VSPACE_ID, 0, 2, 0, = 0xFFFFFFFF, nil) -- fetch everything from space _vindex, 2 =3D ITER_ALL encode_select(send_buf, select2_id, VINDEX_ID, 0, 2, 0, = 0xFFFFFFFF, nil) - -- fetch everything from space _vcollation, 2 =3D ITER_ALL - encode_select(send_buf, select3_id, VCOLLATION_ID, 0, 2, 0, = 0xFFFFFFFF, - nil) + if need_vcoll =3D=3D true then + select3_id =3D new_request_id() + -- fetch everything from space _vcollation, 2 =3D ITER_ALL + encode_select(send_buf, select3_id, VCOLLATION_ID, 0, 2, 0, = 0xFFFFFFFF, + nil) + end =20 schema_version =3D nil -- any schema_version will do provided = that -- it is consistent across responses + + local function vcoll_response(need_vcoll) + if need_vcoll =3D=3D true then + return response[select3_id] + end + return true + end repeat local err, hdr, body_rpos, body_end =3D = send_and_recv_iproto() if err then return error_sm(err, hdr) end dispatch_response_iproto(hdr, body_rpos, body_end) local id =3D hdr[IPROTO_SYNC_KEY] - if id =3D=3D select1_id or id =3D=3D select2_id or id =3D=3D = select3_id then + if id =3D=3D select1_id or id =3D=3D select2_id or id =3D=3D = select3_id and need_vcoll then -- response to a schema query we've submitted local status =3D hdr[IPROTO_STATUS_KEY] local response_schema_version =3D = hdr[IPROTO_SCHEMA_VERSION_KEY] @@ -767,21 +785,21 @@ local function create_transport(host, port, user, = password, callback, schema_version =3D response_schema_version elseif schema_version ~=3D response_schema_version then -- schema changed while fetching schema; restart = loader - return iproto_schema_sm() + return iproto_schema_sm(nil, version_id) end local body body, body_end =3D decode(body_rpos) response[id] =3D body[IPROTO_DATA_KEY] end until response[select1_id] and response[select2_id] and - response[select3_id] + vcoll_response(need_vcoll) callback('did_fetch_schema', schema_version, = response[select1_id], - response[select2_id],response[select3_id]) + response[select2_id], need_vcoll and = response[select3_id] or nil) set_state('active') - return iproto_sm(schema_version) + return iproto_sm(schema_version, version_id) end =20 - iproto_sm =3D function(schema_version) + iproto_sm =3D function(schema_version, version_id) local err, hdr, body_rpos, body_end =3D send_and_recv_iproto() if err then return error_sm(err, hdr) end dispatch_response_iproto(hdr, body_rpos, body_end) @@ -794,9 +812,9 @@ local function create_transport(host, port, user, = password, callback, local body body, body_end =3D decode(body_rpos) set_state('fetch_schema') - return iproto_schema_sm(schema_version) + return iproto_schema_sm(schema_version, version_id) end - return iproto_sm(schema_version) + return iproto_sm(schema_version, version_id) end =20 error_sm =3D function(err, msg) @@ -1270,16 +1288,21 @@ function = remote_methods:_install_schema(schema_version, spaces, indices, local pktype =3D index[PARTS][k][2] or = index[PARTS][k].type local pkfield =3D index[PARTS][k][1] or = index[PARTS][k].field local pkcollation =3D nil - if pkcollationid ~=3D nil then + if pkcollationid ~=3D nil and collations ~=3D nil then pkcollation =3D collations[pkcollationid + 1][2] end =20 local pk =3D { type =3D pktype, fieldno =3D pkfield + 1, - collation =3D pkcollation, is_nullable =3D pknullable } + if collations ~=3D nil then + pk.collation =3D pkcollation + else + pk.collation_id =3D pkcollationid + end + idx.parts[k] =3D pk end idx.unique =3D not not index[OPTS].unique