Skip to content

Commit 20d2b76

Browse files
author
Nikita Glukhov
committed
Add json[b]_extract_keys()
1 parent 7fe7b77 commit 20d2b76

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
@@ -572,8 +572,8 @@ makeJsonLexContext(text *json, bool need_escapes)
572572
* limited in size to NAMEDATALEN and the number of keys is unlikely to
573573
* be so huge that it has major memory implications.
574574
*/
575-
Datum
576-
jsonb_object_keys(PG_FUNCTION_ARGS)
575+
static Datum
576+
jsonb_extract_keys_internal(FunctionCallInfo fcinfo, bool outermost)
577577
{
578578
FuncCallContext *funcctx;
579579
OkeysState *state;
@@ -587,18 +587,25 @@ jsonb_object_keys(PG_FUNCTION_ARGS)
587587
JsonbValue v;
588588
JsonbIteratorToken r;
589589

590-
if (JB_ROOT_IS_SCALAR(jb))
591-
ereport(ERROR,
592-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
593-
errmsg("cannot call %s on a scalar",
594-
JSONB"_object_keys")));
595-
else if (JB_ROOT_IS_ARRAY(jb))
596-
ereport(ERROR,
597-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
598-
errmsg("cannot call %s on an array",
599-
JSONB"_object_keys")));
590+
if (outermost)
591+
{
592+
if (JB_ROOT_IS_SCALAR(jb))
593+
ereport(ERROR,
594+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
595+
errmsg("cannot call %s on a scalar",
596+
JSONB"_object_keys")));
597+
else if (JB_ROOT_IS_ARRAY(jb))
598+
ereport(ERROR,
599+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
600+
errmsg("cannot call %s on an array",
601+
JSONB"_object_keys")));
602+
}
600603

601604
funcctx = SRF_FIRSTCALL_INIT();
605+
606+
if (!outermost && JB_ROOT_IS_SCALAR(jb))
607+
SRF_RETURN_DONE(funcctx);
608+
602609
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
603610

604611
state = palloc(sizeof(OkeysState));
@@ -614,7 +621,7 @@ jsonb_object_keys(PG_FUNCTION_ARGS)
614621

615622
while ((r = JsonbIteratorNext(&it, &v, skipNested)) != WJB_DONE)
616623
{
617-
skipNested = true;
624+
skipNested = outermost;
618625

619626
if (r == WJB_KEY)
620627
{
@@ -650,6 +657,18 @@ jsonb_object_keys(PG_FUNCTION_ARGS)
650657
SRF_RETURN_DONE(funcctx);
651658
}
652659

660+
Datum
661+
jsonb_object_keys(PG_FUNCTION_ARGS)
662+
{
663+
return jsonb_extract_keys_internal(fcinfo, true);
664+
}
665+
666+
Datum
667+
jsonb_extract_keys(PG_FUNCTION_ARGS)
668+
{
669+
return jsonb_extract_keys_internal(fcinfo, false);
670+
}
671+
653672
#ifndef JSON_C
654673
/*
655674
* Report a JSON error.

src/include/catalog/pg_proc.dat

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8513,6 +8513,9 @@
85138513
{ oid => '3957', descr => 'get json object keys',
85148514
proname => 'json_object_keys', prorows => '100', proretset => 't',
85158515
prorettype => 'text', proargtypes => 'json', prosrc => 'json_object_keys' },
8516+
{ oid => '8162', descr => 'extract all json object keys',
8517+
proname => 'json_extract_keys', prorows => '100', proretset => 't',
8518+
prorettype => 'text', proargtypes => 'json', prosrc => 'json_extract_keys' },
85168519
{ oid => '3958', descr => 'key value pairs of a json object',
85178520
proname => 'json_each', prorows => '100', proretset => 't',
85188521
prorettype => 'record', proargtypes => 'json',
@@ -9380,6 +9383,9 @@
93809383
{ oid => '3931', descr => 'get jsonb object keys',
93819384
proname => 'jsonb_object_keys', prorows => '100', proretset => 't',
93829385
prorettype => 'text', proargtypes => 'jsonb', prosrc => 'jsonb_object_keys' },
9386+
{ oid => '8161', descr => 'extract all jsonb object keys',
9387+
proname => 'jsonb_extract_keys', prorows => '100', proretset => 't',
9388+
prorettype => 'text', proargtypes => 'jsonb', prosrc => 'jsonb_extract_keys' },
93839389
{ oid => '3208', descr => 'key value pairs of a jsonb object',
93849390
proname => 'jsonb_each', prorows => '100', proretset => 't',
93859391
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