Skip to content

Commit 5085a24

Browse files
author
Nikita Glukhov
committed
Add json[b]_extract_keys()
1 parent 10fc88c commit 5085a24

File tree

3 files changed

+39
-13
lines changed

3 files changed

+39
-13
lines changed

src/backend/utils/adt/json.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
#define jsonb_object_field json_object_field
5858
#define jsonb_object_field_text json_object_field_text
5959
#define jsonb_object_keys json_object_keys
60+
#define jsonb_extract_keys json_extract_keys
6061
#define jsonb_populate_record json_populate_record
6162
#define jsonb_populate_recordset json_populate_recordset
6263
#define jsonb_pretty json_pretty

src/backend/utils/adt/jsonfuncs.c

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -577,8 +577,8 @@ makeJsonLexContext(text *json, bool need_escapes)
577577
* limited in size to NAMEDATALEN and the number of keys is unlikely to
578578
* be so huge that it has major memory implications.
579579
*/
580-
Datum
581-
jsonb_object_keys(PG_FUNCTION_ARGS)
580+
static Datum
581+
jsonb_extract_keys_internal(FunctionCallInfo fcinfo, bool outermost)
582582
{
583583
FuncCallContext *funcctx;
584584
OkeysState *state;
@@ -592,18 +592,25 @@ jsonb_object_keys(PG_FUNCTION_ARGS)
592592
JsonbValue v;
593593
JsonbIteratorToken r;
594594

595-
if (JB_ROOT_IS_SCALAR(jb))
596-
ereport(ERROR,
597-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
598-
errmsg("cannot call %s on a scalar",
599-
JSONB"_object_keys")));
600-
else if (JB_ROOT_IS_ARRAY(jb))
601-
ereport(ERROR,
602-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
603-
errmsg("cannot call %s on an array",
604-
JSONB"_object_keys")));
595+
if (outermost)
596+
{
597+
if (JB_ROOT_IS_SCALAR(jb))
598+
ereport(ERROR,
599+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
600+
errmsg("cannot call %s on a scalar",
601+
JSONB"_object_keys")));
602+
else if (JB_ROOT_IS_ARRAY(jb))
603+
ereport(ERROR,
604+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
605+
errmsg("cannot call %s on an array",
606+
JSONB"_object_keys")));
607+
}
605608

606609
funcctx = SRF_FIRSTCALL_INIT();
610+
611+
if (!outermost && JB_ROOT_IS_SCALAR(jb))
612+
SRF_RETURN_DONE(funcctx);
613+
607614
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
608615

609616
state = palloc(sizeof(OkeysState));
@@ -619,7 +626,7 @@ jsonb_object_keys(PG_FUNCTION_ARGS)
619626

620627
while ((r = JsonbIteratorNext(&it, &v, skipNested)) != WJB_DONE)
621628
{
622-
skipNested = true;
629+
skipNested = outermost;
623630

624631
if (r == WJB_KEY)
625632
{
@@ -655,6 +662,18 @@ jsonb_object_keys(PG_FUNCTION_ARGS)
655662
SRF_RETURN_DONE(funcctx);
656663
}
657664

665+
Datum
666+
jsonb_object_keys(PG_FUNCTION_ARGS)
667+
{
668+
return jsonb_extract_keys_internal(fcinfo, true);
669+
}
670+
671+
Datum
672+
jsonb_extract_keys(PG_FUNCTION_ARGS)
673+
{
674+
return jsonb_extract_keys_internal(fcinfo, false);
675+
}
676+
658677
#ifndef JSON_C
659678
/*
660679
* Report a JSON error.

src/include/catalog/pg_proc.dat

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8707,6 +8707,9 @@
87078707
{ oid => '3957', descr => 'get json object keys',
87088708
proname => 'json_object_keys', prorows => '100', proretset => 't',
87098709
prorettype => 'text', proargtypes => 'json', prosrc => 'json_object_keys' },
8710+
{ oid => '8162', descr => 'extract all json object keys',
8711+
proname => 'json_extract_keys', prorows => '100', proretset => 't',
8712+
prorettype => 'text', proargtypes => 'json', prosrc => 'json_extract_keys' },
87108713
{ oid => '3958', descr => 'key value pairs of a json object',
87118714
proname => 'json_each', prorows => '100', proretset => 't',
87128715
prorettype => 'record', proargtypes => 'json',
@@ -9574,6 +9577,9 @@
95749577
{ oid => '3931', descr => 'get jsonb object keys',
95759578
proname => 'jsonb_object_keys', prorows => '100', proretset => 't',
95769579
prorettype => 'text', proargtypes => 'jsonb', prosrc => 'jsonb_object_keys' },
9580+
{ oid => '8161', descr => 'extract all jsonb object keys',
9581+
proname => 'jsonb_extract_keys', prorows => '100', proretset => 't',
9582+
prorettype => 'text', proargtypes => 'jsonb', prosrc => 'jsonb_extract_keys' },
95779583
{ oid => '3208', descr => 'key value pairs of a jsonb object',
95789584
proname => 'jsonb_each', prorows => '100', proretset => 't',
95799585
prorettype => 'record', proargtypes => 'jsonb',

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy