Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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)