Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit e36ce0c

Browse files
committed
Get rid of more cases of the "must detoast before output function" meme.
I missed that json.c was doing this too, because for some bizarre reason it wasn't doing it adjacent to the output function call.
1 parent b006f4d commit e36ce0c

File tree

1 file changed

+7
-53
lines changed

1 file changed

+7
-53
lines changed

src/backend/utils/adt/json.c

+7-53
Original file line numberDiff line numberDiff line change
@@ -1425,8 +1425,7 @@ composite_to_json(Datum composite, StringInfo result, bool use_line_feeds)
14251425

14261426
for (i = 0; i < tupdesc->natts; i++)
14271427
{
1428-
Datum val,
1429-
origval;
1428+
Datum val;
14301429
bool isnull;
14311430
char *attname;
14321431
TYPCATEGORY tcategory;
@@ -1445,7 +1444,7 @@ composite_to_json(Datum composite, StringInfo result, bool use_line_feeds)
14451444
escape_json(result, attname);
14461445
appendStringInfoChar(result, ':');
14471446

1448-
origval = heap_getattr(tuple, i + 1, tupdesc, &isnull);
1447+
val = heap_getattr(tuple, i + 1, tupdesc, &isnull);
14491448

14501449
getTypeOutputInfo(tupdesc->attrs[i]->atttypid,
14511450
&typoutput, &typisvarlena);
@@ -1480,20 +1479,7 @@ composite_to_json(Datum composite, StringInfo result, bool use_line_feeds)
14801479
else
14811480
tcategory = TypeCategory(tupdesc->attrs[i]->atttypid);
14821481

1483-
/*
1484-
* If we have a toasted datum, forcibly detoast it here to avoid
1485-
* memory leakage inside the type's output routine.
1486-
*/
1487-
if (typisvarlena && !isnull)
1488-
val = PointerGetDatum(PG_DETOAST_DATUM(origval));
1489-
else
1490-
val = origval;
1491-
14921482
datum_to_json(val, isnull, result, tcategory, typoutput);
1493-
1494-
/* Clean up detoasted copy, if any */
1495-
if (val != origval)
1496-
pfree(DatumGetPointer(val));
14971483
}
14981484

14991485
appendStringInfoChar(result, '}');
@@ -1572,10 +1558,9 @@ row_to_json_pretty(PG_FUNCTION_ARGS)
15721558
Datum
15731559
to_json(PG_FUNCTION_ARGS)
15741560
{
1561+
Datum val = PG_GETARG_DATUM(0);
15751562
Oid val_type = get_fn_expr_argtype(fcinfo->flinfo, 0);
15761563
StringInfo result;
1577-
Datum orig_val,
1578-
val;
15791564
TYPCATEGORY tcategory;
15801565
Oid typoutput;
15811566
bool typisvarlena;
@@ -1586,11 +1571,8 @@ to_json(PG_FUNCTION_ARGS)
15861571
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
15871572
errmsg("could not determine input data type")));
15881573

1589-
15901574
result = makeStringInfo();
15911575

1592-
orig_val = PG_ARGISNULL(0) ? (Datum) 0 : PG_GETARG_DATUM(0);
1593-
15941576
getTypeOutputInfo(val_type, &typoutput, &typisvarlena);
15951577

15961578
if (val_type > FirstNormalObjectId)
@@ -1623,21 +1605,8 @@ to_json(PG_FUNCTION_ARGS)
16231605
else
16241606
tcategory = TypeCategory(val_type);
16251607

1626-
/*
1627-
* If we have a toasted datum, forcibly detoast it here to avoid memory
1628-
* leakage inside the type's output routine.
1629-
*/
1630-
if (typisvarlena && orig_val != (Datum) 0)
1631-
val = PointerGetDatum(PG_DETOAST_DATUM(orig_val));
1632-
else
1633-
val = orig_val;
1634-
16351608
datum_to_json(val, false, result, tcategory, typoutput);
16361609

1637-
/* Clean up detoasted copy, if any */
1638-
if (val != orig_val)
1639-
pfree(DatumGetPointer(val));
1640-
16411610
PG_RETURN_TEXT_P(cstring_to_text(result->data));
16421611
}
16431612

@@ -1651,8 +1620,7 @@ json_agg_transfn(PG_FUNCTION_ARGS)
16511620
MemoryContext aggcontext,
16521621
oldcontext;
16531622
StringInfo state;
1654-
Datum orig_val,
1655-
val;
1623+
Datum val;
16561624
TYPCATEGORY tcategory;
16571625
Oid typoutput;
16581626
bool typisvarlena;
@@ -1692,13 +1660,12 @@ json_agg_transfn(PG_FUNCTION_ARGS)
16921660
/* fast path for NULLs */
16931661
if (PG_ARGISNULL(1))
16941662
{
1695-
orig_val = (Datum) 0;
1696-
datum_to_json(orig_val, true, state, 0, InvalidOid);
1663+
val = (Datum) 0;
1664+
datum_to_json(val, true, state, 0, InvalidOid);
16971665
PG_RETURN_POINTER(state);
16981666
}
16991667

1700-
1701-
orig_val = PG_GETARG_DATUM(1);
1668+
val = PG_GETARG_DATUM(1);
17021669

17031670
getTypeOutputInfo(val_type, &typoutput, &typisvarlena);
17041671

@@ -1732,15 +1699,6 @@ json_agg_transfn(PG_FUNCTION_ARGS)
17321699
else
17331700
tcategory = TypeCategory(val_type);
17341701

1735-
/*
1736-
* If we have a toasted datum, forcibly detoast it here to avoid memory
1737-
* leakage inside the type's output routine.
1738-
*/
1739-
if (typisvarlena)
1740-
val = PointerGetDatum(PG_DETOAST_DATUM(orig_val));
1741-
else
1742-
val = orig_val;
1743-
17441702
if (!PG_ARGISNULL(0) &&
17451703
(tcategory == TYPCATEGORY_ARRAY || tcategory == TYPCATEGORY_COMPOSITE))
17461704
{
@@ -1749,10 +1707,6 @@ json_agg_transfn(PG_FUNCTION_ARGS)
17491707

17501708
datum_to_json(val, false, state, tcategory, typoutput);
17511709

1752-
/* Clean up detoasted copy, if any */
1753-
if (val != orig_val)
1754-
pfree(DatumGetPointer(val));
1755-
17561710
/*
17571711
* The transition type for array_agg() is declared to be "internal", which
17581712
* is a pass-by-value type the same size as a pointer. So we can safely

0 commit comments

Comments
 (0)