Skip to content

Commit 75f4598

Browse files
author
Nikita Glukhov
committed
Add json[b]_extract_keys()
1 parent dc06809 commit 75f4598

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
@@ -8511,6 +8511,9 @@
85118511
{ oid => '3957', descr => 'get json object keys',
85128512
proname => 'json_object_keys', prorows => '100', proretset => 't',
85138513
prorettype => 'text', proargtypes => 'json', prosrc => 'json_object_keys' },
8514+
{ oid => '8162', descr => 'extract all json object keys',
8515+
proname => 'json_extract_keys', prorows => '100', proretset => 't',
8516+
prorettype => 'text', proargtypes => 'json', prosrc => 'json_extract_keys' },
85148517
{ oid => '3958', descr => 'key value pairs of a json object',
85158518
proname => 'json_each', prorows => '100', proretset => 't',
85168519
prorettype => 'record', proargtypes => 'json',
@@ -9378,6 +9381,9 @@
93789381
{ oid => '3931', descr => 'get jsonb object keys',
93799382
proname => 'jsonb_object_keys', prorows => '100', proretset => 't',
93809383
prorettype => 'text', proargtypes => 'jsonb', prosrc => 'jsonb_object_keys' },
9384+
{ oid => '8161', descr => 'extract all jsonb object keys',
9385+
proname => 'jsonb_extract_keys', prorows => '100', proretset => 't',
9386+
prorettype => 'text', proargtypes => 'jsonb', prosrc => 'jsonb_extract_keys' },
93819387
{ oid => '3208', descr => 'key value pairs of a jsonb object',
93829388
proname => 'jsonb_each', prorows => '100', proretset => 't',
93839389
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