Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit abb014a

Browse filesBrowse files
committed
Refactor code into new JsonbValueAsText, and use it more
jsonb_object_field_text and jsonb_array_element_text both contained identical copies of this code, so extract that into new routine JsonbValueAsText. This can also be used in other places, to measurable performance benefit: the jsonb_each() and jsonb_array_elements() functions can use it for outputting text forms instead of their less efficient current implementation (because we no longer need to build intermediate a jsonb representation of each value). Author: Nikita Glukhov Discussion: https://postgr.es/m/7c417f90-f95f-247e-ba63-d95e39c0ad14@postgrespro.ru
1 parent e56cad8 commit abb014a
Copy full SHA for abb014a

File tree

Expand file treeCollapse file tree

1 file changed

+61
-112
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+61
-112
lines changed

‎src/backend/utils/adt/jsonfuncs.c

Copy file name to clipboardExpand all lines: src/backend/utils/adt/jsonfuncs.c
+61-112Lines changed: 61 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,7 @@ static Datum get_path_all(FunctionCallInfo fcinfo, bool as_text);
349349
static text *get_worker(text *json, char **tpath, int *ipath, int npath,
350350
bool normalize_results);
351351
static Datum get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text);
352+
static text *JsonbValueAsText(JsonbValue *v);
352353

353354
/* semantic action functions for json_array_length */
354355
static void alen_object_start(void *state);
@@ -761,39 +762,9 @@ jsonb_object_field_text(PG_FUNCTION_ARGS)
761762
VARDATA_ANY(key),
762763
VARSIZE_ANY_EXHDR(key));
763764

764-
if (v != NULL)
765-
{
766-
text *result = NULL;
767765

768-
switch (v->type)
769-
{
770-
case jbvNull:
771-
break;
772-
case jbvBool:
773-
result = cstring_to_text(v->val.boolean ? "true" : "false");
774-
break;
775-
case jbvString:
776-
result = cstring_to_text_with_len(v->val.string.val, v->val.string.len);
777-
break;
778-
case jbvNumeric:
779-
result = cstring_to_text(DatumGetCString(DirectFunctionCall1(numeric_out,
780-
PointerGetDatum(v->val.numeric))));
781-
break;
782-
case jbvBinary:
783-
{
784-
StringInfo jtext = makeStringInfo();
785-
786-
(void) JsonbToCString(jtext, v->val.binary.data, -1);
787-
result = cstring_to_text_with_len(jtext->data, jtext->len);
788-
}
789-
break;
790-
default:
791-
elog(ERROR, "unrecognized jsonb type: %d", (int) v->type);
792-
}
793-
794-
if (result)
795-
PG_RETURN_TEXT_P(result);
796-
}
766+
if (v != NULL && v->type != jbvNull)
767+
PG_RETURN_TEXT_P(JsonbValueAsText(v));
797768

798769
PG_RETURN_NULL();
799770
}
@@ -878,39 +849,9 @@ jsonb_array_element_text(PG_FUNCTION_ARGS)
878849
}
879850

880851
v = getIthJsonbValueFromContainer(&jb->root, element);
881-
if (v != NULL)
882-
{
883-
text *result = NULL;
884-
885-
switch (v->type)
886-
{
887-
case jbvNull:
888-
break;
889-
case jbvBool:
890-
result = cstring_to_text(v->val.boolean ? "true" : "false");
891-
break;
892-
case jbvString:
893-
result = cstring_to_text_with_len(v->val.string.val, v->val.string.len);
894-
break;
895-
case jbvNumeric:
896-
result = cstring_to_text(DatumGetCString(DirectFunctionCall1(numeric_out,
897-
PointerGetDatum(v->val.numeric))));
898-
break;
899-
case jbvBinary:
900-
{
901-
StringInfo jtext = makeStringInfo();
902852

903-
(void) JsonbToCString(jtext, v->val.binary.data, -1);
904-
result = cstring_to_text_with_len(jtext->data, jtext->len);
905-
}
906-
break;
907-
default:
908-
elog(ERROR, "unrecognized jsonb type: %d", (int) v->type);
909-
}
910-
911-
if (result)
912-
PG_RETURN_TEXT_P(result);
913-
}
853+
if (v != NULL && v->type != jbvNull)
854+
PG_RETURN_TEXT_P(JsonbValueAsText(v));
914855

915856
PG_RETURN_NULL();
916857
}
@@ -1548,6 +1489,53 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text)
15481489
}
15491490
}
15501491

1492+
/*
1493+
* Return the text representation of the given JsonbValue.
1494+
*/
1495+
static text *
1496+
JsonbValueAsText(JsonbValue *v)
1497+
{
1498+
switch (v->type)
1499+
{
1500+
case jbvNull:
1501+
return NULL;
1502+
1503+
case jbvBool:
1504+
return v->val.boolean ?
1505+
cstring_to_text_with_len("true", 4) :
1506+
cstring_to_text_with_len("false", 5);
1507+
1508+
case jbvString:
1509+
return cstring_to_text_with_len(v->val.string.val,
1510+
v->val.string.len);
1511+
1512+
case jbvNumeric:
1513+
{
1514+
Datum cstr;
1515+
1516+
cstr = DirectFunctionCall1(numeric_out,
1517+
PointerGetDatum(v->val.numeric));
1518+
1519+
return cstring_to_text(DatumGetCString(cstr));
1520+
}
1521+
1522+
case jbvBinary:
1523+
{
1524+
StringInfoData jtext;
1525+
1526+
initStringInfo(&jtext);
1527+
(void) JsonbToCString(&jtext, v->val.binary.data,
1528+
v->val.binary.len);
1529+
1530+
return cstring_to_text_with_len(jtext.data, jtext.len);
1531+
}
1532+
1533+
default:
1534+
elog(ERROR, "unrecognized jsonb type: %d", (int) v->type);
1535+
return NULL;
1536+
}
1537+
}
1538+
15511539
/*
15521540
* SQL function json_array_length(json) -> int
15531541
*/
@@ -1758,26 +1746,7 @@ each_worker_jsonb(FunctionCallInfo fcinfo, const char *funcname, bool as_text)
17581746
values[1] = (Datum) NULL;
17591747
}
17601748
else
1761-
{
1762-
text *sv;
1763-
1764-
if (v.type == jbvString)
1765-
{
1766-
/* In text mode, scalar strings should be dequoted */
1767-
sv = cstring_to_text_with_len(v.val.string.val, v.val.string.len);
1768-
}
1769-
else
1770-
{
1771-
/* Turn anything else into a json string */
1772-
StringInfo jtext = makeStringInfo();
1773-
Jsonb *jb = JsonbValueToJsonb(&v);
1774-
1775-
(void) JsonbToCString(jtext, &jb->root, 0);
1776-
sv = cstring_to_text_with_len(jtext->data, jtext->len);
1777-
}
1778-
1779-
values[1] = PointerGetDatum(sv);
1780-
}
1749+
values[1] = PointerGetDatum(JsonbValueAsText(&v));
17811750
}
17821751
else
17831752
{
@@ -2053,13 +2022,7 @@ elements_worker_jsonb(FunctionCallInfo fcinfo, const char *funcname,
20532022
/* use the tmp context so we can clean up after each tuple is done */
20542023
old_cxt = MemoryContextSwitchTo(tmp_cxt);
20552024

2056-
if (!as_text)
2057-
{
2058-
Jsonb *val = JsonbValueToJsonb(&v);
2059-
2060-
values[0] = PointerGetDatum(val);
2061-
}
2062-
else
2025+
if (as_text)
20632026
{
20642027
if (v.type == jbvNull)
20652028
{
@@ -2068,26 +2031,14 @@ elements_worker_jsonb(FunctionCallInfo fcinfo, const char *funcname,
20682031
values[0] = (Datum) NULL;
20692032
}
20702033
else
2071-
{
2072-
text *sv;
2073-
2074-
if (v.type == jbvString)
2075-
{
2076-
/* in text mode scalar strings should be dequoted */
2077-
sv = cstring_to_text_with_len(v.val.string.val, v.val.string.len);
2078-
}
2079-
else
2080-
{
2081-
/* turn anything else into a json string */
2082-
StringInfo jtext = makeStringInfo();
2083-
Jsonb *jb = JsonbValueToJsonb(&v);
2084-
2085-
(void) JsonbToCString(jtext, &jb->root, 0);
2086-
sv = cstring_to_text_with_len(jtext->data, jtext->len);
2087-
}
2034+
values[0] = PointerGetDatum(JsonbValueAsText(&v));
2035+
}
2036+
else
2037+
{
2038+
/* Not in text mode, just return the Jsonb */
2039+
Jsonb *val = JsonbValueToJsonb(&v);
20882040

2089-
values[0] = PointerGetDatum(sv);
2090-
}
2041+
values[0] = PointerGetDatum(val);
20912042
}
20922043

20932044
tuple = heap_form_tuple(ret_tdesc, values, nulls);
@@ -4430,7 +4381,6 @@ jsonb_delete_idx(PG_FUNCTION_ARGS)
44304381

44314382
/*
44324383
* SQL function jsonb_set(jsonb, text[], jsonb, boolean)
4433-
*
44344384
*/
44354385
Datum
44364386
jsonb_set(PG_FUNCTION_ARGS)
@@ -4522,7 +4472,6 @@ jsonb_delete_path(PG_FUNCTION_ARGS)
45224472

45234473
/*
45244474
* SQL function jsonb_insert(jsonb, text[], jsonb, boolean)
4525-
*
45264475
*/
45274476
Datum
45284477
jsonb_insert(PG_FUNCTION_ARGS)

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.