From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp10.mail.ru (smtp10.mail.ru [94.100.181.92]) (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 3EF3A469719 for ; Thu, 1 Oct 2020 14:38:18 +0300 (MSK) Date: Thu, 1 Oct 2020 14:38:30 +0300 From: Alexander Turenko Message-ID: <20201001113830.p7af3m647h6vwem6@tkn_work_nb> References: <20200921121100.10052-1-i.kosarev@tarantool.org> <20200925183450.atsuxr4ine7c2dv7@tkn_work_nb> <1601157194.729560301@f185.i.mail.ru> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <1601157194.729560301@f185.i.mail.ru> Subject: Re: [Tarantool-patches] [PATCH] key_def: support composite types extraction List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Ilya Kosarev Cc: tarantool-patches@dev.tarantool.org > >How about lbox_key_def_merge() and underlying functions? I'm not sure > >they will work correct. At least I tried this on the branch: > > > > | tarantool> key_def = require('key_def') > > | tarantool> kd1 = key_def.new({{fieldno = 1, type = 'array'}}) > > | tarantool> kd2 = key_def.new({{fieldno = 1, type = 'map'}}) > > | tarantool> kd1:merge(kd2) > > | --- > > | - - type: array > > | is_nullable: false > > | fieldno: 1 > > | ... > > > >It does not look correct. > This turns out to be the correct behavior: >   > tarantool> kd1 = key_def.new({{fieldno = 1, type = 'unsigned'}}) > --- > ... > tarantool> kd2 = key_def.new({{fieldno = 1, type = 'string'}}) > --- > ... > tarantool> kd1:merge(kd2) > --- > - - type: unsigned >     is_nullable: false >     fieldno: 1 > … I'm not sure it is correct. But at least you proved that it is not in the scope of your current task :) An attempt to create conflicting indices gives an error, so I guess this case is not handled, because it was not possible until we exposed key_def directly to Lua. But another case makes me doubt even more: | tarantool> key_def = require('key_def') | tarantool> kd1 = key_def.new({{fieldno = 1, type = 'scalar'}}) | tarantool> kd2 = key_def.new({{fieldno = 1, type = 'integer'}}) | tarantool> kd1:merge(kd2) | --- | - - type: scalar | is_nullable: false | fieldno: 1 | ... | | tarantool> kd1 = key_def.new({{fieldno = 1, type = 'integer'}}) | tarantool> kd2 = key_def.new({{fieldno = 1, type = 'scalar'}}) | tarantool> kd1:merge(kd2) | --- | - - type: integer | is_nullable: false | fieldno: 1 | ... It would be natural to get most restricted type, when one type is subset of another. I assume the following invariant: for any given kd1 and kd2 kd1:merge(kd2) should accept only those tuples that both kd1 and kd2 accept (kd accepts a tuple when it is valid against kd). OTOH, the main use case for :merge() function is to compare tuples in the same way as a non-unique secondary index do (when a key parts of a primary index are implicitly merged into the secondary index ones). In this sense we can choose either subtype or supertype: it will not affect an order of tuples. So choosing of the first (secondary index's) key part looks okay. I don't know whether we should change anything or not, so just shared my findings and thoughts. If I'll somehow end with an idea that we should do something here, I'll file an issue. WBR, Alexander Turenko.