Skip to content

Commit a0af4ad

Browse files
author
Nikita Glukhov
committed
Add json[b]_extract_keys()
1 parent ed7a6ac commit a0af4ad

File tree

3 files changed

+36
-13
lines changed

3 files changed

+36
-13
lines changed

src/backend/utils/adt/json.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
#define jsonb_object_field json_object_field
5656
#define jsonb_object_field_text json_object_field_text
5757
#define jsonb_object_keys json_object_keys
58+
#define jsonb_extract_keys json_extract_keys
5859
#define jsonb_populate_record json_populate_record
5960
#define jsonb_populate_recordset json_populate_recordset
6061
#define jsonb_pretty json_pretty

src/backend/utils/adt/jsonfuncs.c

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -519,8 +519,8 @@ static Datum jsonb_strip_nulls_internal(Jsonb *jb);
519519
* limited in size to NAMEDATALEN and the number of keys is unlikely to
520520
* be so huge that it has major memory implications.
521521
*/
522-
Datum
523-
jsonb_object_keys(PG_FUNCTION_ARGS)
522+
static Datum
523+
jsonb_extract_keys_internal(FunctionCallInfo fcinfo, bool outermost)
524524
{
525525
FuncCallContext *funcctx;
526526
OkeysState *state;
@@ -535,18 +535,25 @@ jsonb_object_keys(PG_FUNCTION_ARGS)
535535
JsonbValue v;
536536
JsonbIteratorToken r;
537537

538-
if (JB_ROOT_IS_SCALAR(jb))
539-
ereport(ERROR,
540-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
541-
errmsg("cannot call %s on a scalar",
542-
JSONB"_object_keys")));
543-
else if (JB_ROOT_IS_ARRAY(jb))
544-
ereport(ERROR,
545-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
546-
errmsg("cannot call %s on an array",
547-
JSONB"_object_keys")));
538+
if (outermost)
539+
{
540+
if (JB_ROOT_IS_SCALAR(jb))
541+
ereport(ERROR,
542+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
543+
errmsg("cannot call %s on a scalar",
544+
JSONB"_object_keys")));
545+
else if (JB_ROOT_IS_ARRAY(jb))
546+
ereport(ERROR,
547+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
548+
errmsg("cannot call %s on an array",
549+
JSONB"_object_keys")));
550+
}
548551

549552
funcctx = SRF_FIRSTCALL_INIT();
553+
554+
if (!outermost && JB_ROOT_IS_SCALAR(jb))
555+
SRF_RETURN_DONE(funcctx);
556+
550557
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
551558

552559
state = palloc(sizeof(OkeysState));
@@ -562,7 +569,7 @@ jsonb_object_keys(PG_FUNCTION_ARGS)
562569

563570
while ((r = JsonbIteratorNext(&it, &v, skipNested)) != WJB_DONE)
564571
{
565-
skipNested = true;
572+
skipNested = outermost;
566573

567574
if (r == WJB_KEY)
568575
{
@@ -604,6 +611,17 @@ jsonb_object_keys(PG_FUNCTION_ARGS)
604611
SRF_RETURN_DONE(funcctx);
605612
}
606613

614+
Datum
615+
jsonb_object_keys(PG_FUNCTION_ARGS)
616+
{
617+
return jsonb_extract_keys_internal(fcinfo, true);
618+
}
619+
620+
Datum
621+
jsonb_extract_keys(PG_FUNCTION_ARGS)
622+
{
623+
return jsonb_extract_keys_internal(fcinfo, false);
624+
}
607625

608626
#ifndef JSON_GENERIC
609627
Datum

src/include/catalog/pg_proc.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4507,6 +4507,8 @@ DATA(insert OID = 3956 ( json_array_length PGNSP PGUID 12 1 0 0 0 f f f f t f
45074507
DESCR("length of json array");
45084508
DATA(insert OID = 3957 ( json_object_keys PGNSP PGUID 12 1 100 0 0 f f f f t t i s 1 0 25 "114" _null_ _null_ _null_ _null_ _null_ json_object_keys _null_ _null_ _null_ ));
45094509
DESCR("get json object keys");
4510+
DATA(insert OID = 4159 ( json_extract_keys PGNSP PGUID 12 1 100 0 0 f f f f t t i s 1 0 25 "114" _null_ _null_ _null_ _null_ _null_ json_extract_keys _null_ _null_ _null_ ));
4511+
DESCR("extract all keys from a json");
45104512
DATA(insert OID = 3958 ( json_each PGNSP PGUID 12 1 100 0 0 f f f f t t i s 1 0 2249 "114" "{114,25,114}" "{i,o,o}" "{from_json,key,value}" _null_ _null_ json_each _null_ _null_ _null_ ));
45114513
DESCR("key value pairs of a json object");
45124514
DATA(insert OID = 3959 ( json_each_text PGNSP PGUID 12 1 100 0 0 f f f f t t i s 1 0 2249 "114" "{114,25,25}" "{i,o,o}" "{from_json,key,value}" _null_ _null_ json_each_text _null_ _null_ _null_ ));
@@ -4957,6 +4959,8 @@ DATA(insert OID = 3207 ( jsonb_array_length PGNSP PGUID 12 1 0 0 0 f f f f t
49574959
DESCR("length of jsonb array");
49584960
DATA(insert OID = 3931 ( jsonb_object_keys PGNSP PGUID 12 1 100 0 0 f f f f t t i s 1 0 25 "3802" _null_ _null_ _null_ _null_ _null_ jsonb_object_keys _null_ _null_ _null_ ));
49594961
DESCR("get jsonb object keys");
4962+
DATA(insert OID = 4158 ( jsonb_extract_keys PGNSP PGUID 12 1 100 0 0 f f f f t t i s 1 0 25 "3802" _null_ _null_ _null_ _null_ _null_ jsonb_extract_keys _null_ _null_ _null_ ));
4963+
DESCR("extract all keys from a jsonb");
49604964
DATA(insert OID = 3208 ( jsonb_each PGNSP PGUID 12 1 100 0 0 f f f f t t i s 1 0 2249 "3802" "{3802,25,3802}" "{i,o,o}" "{from_json,key,value}" _null_ _null_ jsonb_each _null_ _null_ _null_ ));
49614965
DESCR("key value pairs of a jsonb object");
49624966
DATA(insert OID = 3932 ( jsonb_each_text PGNSP PGUID 12 1 100 0 0 f f f f t t i s 1 0 2249 "3802" "{3802,25,25}" "{i,o,o}" "{from_json,key,value}" _null_ _null_ jsonb_each_text _null_ _null_ _null_ ));

0 commit comments

Comments
 (0)