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

Commit8571ecb

Browse files
committed
Fix JSON aggregates to work properly when final function is re-executed.
Davide S. reported that json_agg() sometimes produced multiple trailingright brackets. This turns out to be because json_agg_finalfn() attachesthe final right bracket, and was doing so by modifying the aggregate statein-place. That's verboten, though unfortunately it seems there's no wayfor nodeAgg.c to check for such mistakes.Fix that back to 9.3 where the broken code was introduced. In 9.4 andHEAD, likewise fix json_object_agg(), which had copied the erroneous logic.Make some cosmetic cleanups as well.
1 parent10b81fb commit8571ecb

File tree

1 file changed

+28
-4
lines changed

1 file changed

+28
-4
lines changed

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

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ static void json_categorize_type(Oid typoid,
8585
Oid*outfuncoid);
8686
staticvoiddatum_to_json(Datumval,boolis_null,StringInforesult,
8787
JsonTypeCategorytcategory,Oidoutfuncoid);
88+
statictext*catenate_stringinfo_string(StringInfobuffer,constchar*addon);
8889

8990
/* the null action object used for pure validation */
9091
staticJsonSemActionnullSemAction=
@@ -166,7 +167,7 @@ lex_expect(JsonParseContext ctx, JsonLexContext *lex, JsonTokenType token)
166167

167168
/* utility function to check if a string is a valid JSON number */
168169
externbool
169-
IsValidJsonNumber(constchar*str,intlen)
170+
IsValidJsonNumber(constchar*str,intlen)
170171
{
171172
boolnumeric_error;
172173
JsonLexContextdummy_lex;
@@ -191,7 +192,7 @@ IsValidJsonNumber(const char * str, int len)
191192

192193
json_lex_number(&dummy_lex,dummy_lex.input,&numeric_error);
193194

194-
return !numeric_error;
195+
return !numeric_error;
195196
}
196197

197198
/*
@@ -1359,6 +1360,7 @@ datum_to_json(Datum val, bool is_null, StringInfo result,
13591360
break;
13601361
caseJSONTYPE_NUMERIC:
13611362
outputstr=OidOutputFunctionCall(outfuncoid,val);
1363+
13621364
/*
13631365
* Don't call escape_json for a non-key if it's a valid JSON
13641366
* number.
@@ -1646,6 +1648,8 @@ to_json(PG_FUNCTION_ARGS)
16461648

16471649
/*
16481650
* json_agg transition function
1651+
*
1652+
* aggregate input column as a json array value.
16491653
*/
16501654
Datum
16511655
json_agg_transfn(PG_FUNCTION_ARGS)
@@ -1732,12 +1736,32 @@ json_agg_finalfn(PG_FUNCTION_ARGS)
17321736

17331737
state=PG_ARGISNULL(0) ?NULL : (StringInfo)PG_GETARG_POINTER(0);
17341738

1739+
/* NULL result for no rows in, as is standard with aggregates */
17351740
if (state==NULL)
17361741
PG_RETURN_NULL();
17371742

1738-
appendStringInfoChar(state,']');
1743+
/* Else return state with appropriate array terminator added */
1744+
PG_RETURN_TEXT_P(catenate_stringinfo_string(state,"]"));
1745+
}
1746+
1747+
/*
1748+
* Helper function for aggregates: return given StringInfo's contents plus
1749+
* specified trailing string, as a text datum. We need this because aggregate
1750+
* final functions are not allowed to modify the aggregate state.
1751+
*/
1752+
statictext*
1753+
catenate_stringinfo_string(StringInfobuffer,constchar*addon)
1754+
{
1755+
/* custom version of cstring_to_text_with_len */
1756+
intbuflen=buffer->len;
1757+
intaddlen=strlen(addon);
1758+
text*result= (text*)palloc(buflen+addlen+VARHDRSZ);
1759+
1760+
SET_VARSIZE(result,buflen+addlen+VARHDRSZ);
1761+
memcpy(VARDATA(result),buffer->data,buflen);
1762+
memcpy(VARDATA(result)+buflen,addon,addlen);
17391763

1740-
PG_RETURN_TEXT_P(cstring_to_text(state->data));
1764+
returnresult;
17411765
}
17421766

17431767
/*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp