Re: SQL/JSON: functions

Nikita Glukhov <n.gluhov@postgrespro.ru>

From: Nikita Glukhov <n.gluhov@postgrespro.ru>
To: Andres Freund <andres@anarazel.de>
Cc: Dmitry Dolgov <9erthalion6@gmail.com>, Pavel Stehule <pavel.stehule@gmail.com>, Oleg Bartunov <obartunov@postgrespro.ru>, PostgreSQL-development <pgsql-hackers@postgresql.org>, Alexander Korotkov <a.korotkov@postgrespro.ru>, Michael Paquier <michael@paquier.xyz>, Simon Riggs <simon@2ndquadrant.com>, Andrew Dunstan <andrew.dunstan@2ndquadrant.com>
Date: 2019-03-01T01:14:09Z
Lists: pgsql-hackers

Attachments

Attached 34th version of the patches.

On 16.02.2019 8:12, Andres Freund wrote:

> On 2018-12-05 02:01:19 +0300, Nikita Glukhov wrote:
>> +		JsonLexContext *lex;
>> +		JsonTokenType tok;
>> +
>> +		lex = makeJsonLexContext(json, false);
>> +
>> +		/* Lex exactly one token from the input and check its type. */
>> +		PG_TRY();
>> +		{
>> +			json_lex(lex);
>> +		}
>> +		PG_CATCH();
>> +		{
>> +			if (ERRCODE_TO_CATEGORY(geterrcode()) == ERRCODE_DATA_EXCEPTION)
>> +			{
>> +				FlushErrorState();
>> +				MemoryContextSwitchTo(mcxt);
>> +				PG_RETURN_BOOL(false);	/* invalid json */
>> +			}
>> +			PG_RE_THROW();
>> +		}
>> +		PG_END_TRY();
>
> It baffles me that a year after I raised this as a serious issue, in
> this thread, this patch still contains code like this.

PG_TRY/PG_CATCH was removed here: 'throwErrors' flag was added to JsonLexContext
instead.


Also usage of subtransactions is SQL/JSON functions (JsonExpr node) was
optimized: they can be not only omitted in ERROR ON ERROR case but also when
the resulting conversion from the SQL/JSON item type to the target SQL type is
no-op.


Below are the results of simple performance test
(operator #>> uses optimization which I recently posted in the separate patch):

                         query                           | time, ms
-------------------------------------------------------------------
  JSON_VALUE(js, '$.x.y.z' RETURNING text) = '123'       | 1923,360 (subtrans!)
  JSON_VALUE(js, '$.x.y.z' RETURNING text
                           ERROR ON ERROR) = '123'       |  970,604
  JSON_VALUE(js, '$.x.y.z' RETURNING numeric) = '123'    |  792,412
  JSON_VALUE(js, '$.x.y.z' RETURNING numeric
                           ERROR ON ERROR) = '123'       |  786,647

  (js->'x'->'y'->'z') = '123'                            | 1104,470
  (js->'x'->'y'->'z')::numeric = '123'                   |  940,037
  (js->'x'->'y'->>'z') = '123'                           |  688,484

  (js #>  '{x,y,z}') = '123'                             | 1127,661
  (js #>  '{x,y,z}')::numeric = '123'                    |  971,931
  (js #>> '{x,y,z}') = '123'                             |  718,173


Table with jsonb rows like  '{"x": {"y": {"z": 123}}}':
CREATE TABLE t AS
SELECT JSON_OBJECT('x' : JSON_OBJECT('y' : JSON_OBJECT('z' : i))) js
FROM generate_series(1, 3000000) i;

Example query:
SELECT * FROM t WHERE JSON_VALUE(js, '$.x.y.z' RETURNING numeric) = '123';

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

Commits

Same data as JSON: GET /api/v1/messages/:b64id/commits the thread's linked commits as JSON, with link sources. API reference →
  1. JSON_TABLE: Add support for NESTED paths and columns

  2. Add basic JSON_TABLE() functionality

  3. Add SQL/JSON query functions

  4. Add soft error handling to some expression nodes

  5. Adjust populate_record_field() to handle errors softly

  6. Refactor code used by jsonpath executor to fetch variables

  7. Add more SQL/JSON constructor functions

  8. SQL/JSON: support the IS JSON predicate

  9. SQL/JSON: add standard JSON constructor functions

  10. Improve readability of SQL/JSON documentation.

  11. Documentation for SQL/JSON features

  12. RETURNING clause for JSON() and JSON_SCALAR()

  13. SQL JSON functions

  14. SQL/JSON query functions

  15. IS JSON predicate

  16. SQL/JSON constructors

  17. Common SQL/JSON clauses

  18. Doc: remove obsolete entries in table of BRIN strategy numbers.

  19. Doc: standardize markup a bit more.

  20. Make pg_regress.c unset PGDATABASE during make installcheck.

  21. Fix handling of GENERATED columns in CREATE TABLE LIKE INCLUDING DEFAULTS.