Movatterモバイル変換


[0]ホーム

URL:


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

Sign up
Appearance settings

Commitabb014a

Browse files
committed
Refactor code into new JsonbValueAsText, and use it more
jsonb_object_field_text and jsonb_array_element_text both containedidentical copies of this code, so extract that into new routineJsonbValueAsText. This can also be used in other places, to measurableperformance benefit: the jsonb_each() and jsonb_array_elements()functions can use it for outputting text forms instead of their lessefficient current implementation (because we no longer need to buildintermediate a jsonb representation of each value).Author: Nikita GlukhovDiscussion:https://postgr.es/m/7c417f90-f95f-247e-ba63-d95e39c0ad14@postgrespro.ru
1 parente56cad8 commitabb014a

File tree

1 file changed

+61
-112
lines changed

1 file changed

+61
-112
lines changed

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

Lines 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
statictext*get_worker(text*json,char**tpath,int*ipath,intnpath,
350350
boolnormalize_results);
351351
staticDatumget_jsonb_path_all(FunctionCallInfofcinfo,boolas_text);
352+
statictext*JsonbValueAsText(JsonbValue*v);
352353

353354
/* semantic action functions for json_array_length */
354355
staticvoidalen_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-
casejbvNull:
771-
break;
772-
casejbvBool:
773-
result=cstring_to_text(v->val.boolean ?"true" :"false");
774-
break;
775-
casejbvString:
776-
result=cstring_to_text_with_len(v->val.string.val,v->val.string.len);
777-
break;
778-
casejbvNumeric:
779-
result=cstring_to_text(DatumGetCString(DirectFunctionCall1(numeric_out,
780-
PointerGetDatum(v->val.numeric))));
781-
break;
782-
casejbvBinary:
783-
{
784-
StringInfojtext=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-
casejbvNull:
888-
break;
889-
casejbvBool:
890-
result=cstring_to_text(v->val.boolean ?"true" :"false");
891-
break;
892-
casejbvString:
893-
result=cstring_to_text_with_len(v->val.string.val,v->val.string.len);
894-
break;
895-
casejbvNumeric:
896-
result=cstring_to_text(DatumGetCString(DirectFunctionCall1(numeric_out,
897-
PointerGetDatum(v->val.numeric))));
898-
break;
899-
casejbvBinary:
900-
{
901-
StringInfojtext=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+
statictext*
1496+
JsonbValueAsText(JsonbValue*v)
1497+
{
1498+
switch (v->type)
1499+
{
1500+
casejbvNull:
1501+
returnNULL;
1502+
1503+
casejbvBool:
1504+
returnv->val.boolean ?
1505+
cstring_to_text_with_len("true",4) :
1506+
cstring_to_text_with_len("false",5);
1507+
1508+
casejbvString:
1509+
returncstring_to_text_with_len(v->val.string.val,
1510+
v->val.string.len);
1511+
1512+
casejbvNumeric:
1513+
{
1514+
Datumcstr;
1515+
1516+
cstr=DirectFunctionCall1(numeric_out,
1517+
PointerGetDatum(v->val.numeric));
1518+
1519+
returncstring_to_text(DatumGetCString(cstr));
1520+
}
1521+
1522+
casejbvBinary:
1523+
{
1524+
StringInfoDatajtext;
1525+
1526+
initStringInfo(&jtext);
1527+
(void)JsonbToCString(&jtext,v->val.binary.data,
1528+
v->val.binary.len);
1529+
1530+
returncstring_to_text_with_len(jtext.data,jtext.len);
1531+
}
1532+
1533+
default:
1534+
elog(ERROR,"unrecognized jsonb type: %d", (int)v->type);
1535+
returnNULL;
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-
StringInfojtext=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-
StringInfojtext=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)

[8]ページ先頭

©2009-2025 Movatter.jp