Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1gla3I-0001qU-LY for pgsql-hackers@arkaria.postgresql.org; Mon, 21 Jan 2019 13:55:49 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1gla3H-0006DM-DW for pgsql-hackers@arkaria.postgresql.org; Mon, 21 Jan 2019 13:55:47 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1gla3H-0006D9-2Z for pgsql-hackers@lists.postgresql.org; Mon, 21 Jan 2019 13:55:47 +0000 Received: from mail.postgrespro.ru ([93.174.131.138]) by magus.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1gla3E-00088A-A0 for pgsql-hackers@postgresql.org; Mon, 21 Jan 2019 13:55:46 +0000 Received: from localhost (localhost [127.0.0.1]) by mail.postgrespro.ru (Postfix) with ESMTP id 9439121DC68B; Mon, 21 Jan 2019 16:55:42 +0300 (MSK) X-Virus-Scanned: Debian amavisd-new at postgrespro.ru X-Spam-Flag: NO X-Spam-Score: 0 X-Spam-Level: X-Spam-Status: No, score=x tagged_above=-99 required=4 WHITELISTED tests=[] autolearn=unavailable Received: from [10.100.236.31] (unknown [195.82.154.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client did not present a certificate) by mail.postgrespro.ru (Postfix) with ESMTPSA id 058AD21DA8C9; Mon, 21 Jan 2019 16:55:41 +0300 (MSK) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=postgrespro.ru; s=mail; t=1548078942; bh=yDQl0Zkff7Pr499Vb0yoNWvdEHVOtGhld4Zxt8Dopnw=; h=Subject:To:Cc:References:From:Date:In-Reply-To; b=BMvpo24dAzdK0BCwf4NZF89W4gc9J4R8+KFGHAvUTKgKk5UCcIdLxVgauLpYEH056 3FKSmYNoN+JJAE2REOus0Ikg2SlmNLWVtyTfqkQhPf8884N8kq1BA7CwJHngRBtTvY 64FDpqjxzliyTn1h63YN+A8/8hEj25Vs7qOd5S5U= Subject: Re: jsonpath To: Alexander Korotkov Cc: Tomas Vondra , Michael Paquier , Stas Kelvich , PostgreSQL-development , Thomas Munro , David Steele , Tom Lane , Andrew Dunstan , Robert Haas , Oleg Bartunov , Pavel Stehule References: <42272F2B-16D1-43D6-B22F-273AE1DA6D6B@postgrespro.ru> <715c1c44-9bb9-6b9f-7c59-61b66578f107@postgrespro.ru> <20181002023317.GI11712@paquier.xyz> <063560d8-bc0b-945b-8796-5ba998d79dc6@2ndquadrant.com> <9a175c2d-b0a9-475f-078b-febc185282ff@postgrespro.ru> <86a0e7df-443b-3f20-70b0-655a1f5dcbb2@2ndquadrant.com> <2265b7fe-3b0e-c437-fe15-ac1807319b73@2ndquadrant.com> <64e3108c-888f-092e-30a2-58dea157707e@postgrespro.ru> <43e52ed7-9c21-db2c-693a-9245f9e8ce2a@2ndquadrant.com> <38018365-5793-2827-e3c1-5a3b259fb6ae@postgrespro.ru> <885de241-5a51-29c8-a6b3-f1dda22aba13@postgrespro.ru> From: Nikita Glukhov Organization: Postgres Professional Message-ID: Date: Mon, 21 Jan 2019 16:56:46 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.2.1 MIME-Version: 1.0 In-Reply-To: Content-Type: multipart/alternative; boundary="------------4436C931E3408299AA363DF3" Content-Language: en-US List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk This is a multi-part message in MIME format. --------------4436C931E3408299AA363DF3 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit On 20.01.2019 2:45, Alexander Korotkov wrote: > 3) How do we calculate the "id" property returned by keyvalue() > function? It's not documented. Even presence of "id" columns isn't > documented. Standard stands that it's implementation-depended > indetifier of object holding key-value pair. The way of its > calculation is also not clear from the code. Why do we need constant > of 10000000000? > > id = jb->type != jbvBinary ? 0 : > (int64)((char *) jb->val.binary.data - > (char *) cxt->baseObject.jbc); > id += (int64) cxt->baseObject.id * INT64CONST(10000000000); I decided to construct object id from the two parts: base object id and its binary offset in its base object's jsonb: object_id = 10000000000 * base_object_id + object_offset_in_base_object 10000000000 (10^10) -- is a first round decimal number greater than 2^32 (maximal offset in jsonb). Decimal multiplier is used here to improve the readability of identifiers. Base object is usually a root object of the path: context item '$' or path variable '$var', literals can't produce objects for now. But if the path contains generated objects (.keyvalue() itself, for example), then they become base object for the subsequent .keyvalue(). See example: '$.a.b.keyvalue().value.keyvalue()' : - base for the first .keyvalue() is '$' - base for the second .keyvalue() is '$.a.b.keyvalue()' Id of '$' is 0. Id of '$var' is its ordinal (positive) number in the list of variables. Ids for generated objects are assigned using global counter 'JsonPathExecContext.generatedObjectId' starting from 'number_of_vars + 1'. Corresponding comments will be added in the upcoming version of the patches. -- Nikita Glukhov Postgres Professional: http://www.postgrespro.com The Russian Postgres Company --------------4436C931E3408299AA363DF3 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: 7bit

On 20.01.2019 2:45, Alexander Korotkov wrote:

3) How do we calculate the "id" property returned by keyvalue()
function?  It's not documented.  Even presence of "id" columns isn't
documented.  Standard stands that it's implementation-depended
indetifier of object holding key-value pair.  The way of its
calculation is also not clear from the code.  Why do we need constant
of 10000000000?

                id = jb->type != jbvBinary ? 0 :
                    (int64)((char *) jb->val.binary.data -
                            (char *) cxt->baseObject.jbc);
                id += (int64) cxt->baseObject.id * INT64CONST(10000000000);
I decided to construct object id from the two parts: base object id and its
binary offset in its base object's jsonb:

object_id = 10000000000 * base_object_id + object_offset_in_base_object


10000000000 (10^10) -- is a first round decimal number greater than 2^32
(maximal offset in jsonb).  Decimal multiplier is used here to improve the
readability of identifiers.


Base object is usually a root object of the path: context item '$' or path
variable '$var', literals can't produce objects for now.  But if the path
contains generated objects (.keyvalue() itself, for example), then they become
base object for the subsequent .keyvalue().  See example:

'$.a.b.keyvalue().value.keyvalue()' :
 - base for the first .keyvalue() is '$'
 - base for the second .keyvalue() is '$.a.b.keyvalue()'


Id of '$' is 0.
Id of '$var' is its ordinal (positive) number in the list of variables.
Ids for generated objects are assigned using global counter
'JsonPathExecContext.generatedObjectId' starting from 'number_of_vars + 1'.


Corresponding comments will be added in the upcoming version of the patches.

-- 
Nikita Glukhov
Postgres Professional: http://www.postgrespro.com
The Russian Postgres Company

--------------4436C931E3408299AA363DF3--