]> granicus.if.org Git - postgresql/commitdiff
Get rid of more cases of the "must detoast before output function" meme.
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 3 Nov 2013 16:55:37 +0000 (11:55 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 3 Nov 2013 16:55:37 +0000 (11:55 -0500)
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.

src/backend/utils/adt/json.c

index b6199fbf68da699303e9cd5c8b5ff14c8310f0c9..7685410f185e2dc121725fa78d4254815c480d7e 100644 (file)
@@ -1425,8 +1425,7 @@ composite_to_json(Datum composite, StringInfo result, bool use_line_feeds)
 
        for (i = 0; i < tupdesc->natts; i++)
        {
-               Datum           val,
-                                       origval;
+               Datum           val;
                bool            isnull;
                char       *attname;
                TYPCATEGORY tcategory;
@@ -1445,7 +1444,7 @@ composite_to_json(Datum composite, StringInfo result, bool use_line_feeds)
                escape_json(result, attname);
                appendStringInfoChar(result, ':');
 
-               origval = heap_getattr(tuple, i + 1, tupdesc, &isnull);
+               val = heap_getattr(tuple, i + 1, tupdesc, &isnull);
 
                getTypeOutputInfo(tupdesc->attrs[i]->atttypid,
                                                  &typoutput, &typisvarlena);
@@ -1480,20 +1479,7 @@ composite_to_json(Datum composite, StringInfo result, bool use_line_feeds)
                else
                        tcategory = TypeCategory(tupdesc->attrs[i]->atttypid);
 
-               /*
-                * If we have a toasted datum, forcibly detoast it here to avoid
-                * memory leakage inside the type's output routine.
-                */
-               if (typisvarlena && !isnull)
-                       val = PointerGetDatum(PG_DETOAST_DATUM(origval));
-               else
-                       val = origval;
-
                datum_to_json(val, isnull, result, tcategory, typoutput);
-
-               /* Clean up detoasted copy, if any */
-               if (val != origval)
-                       pfree(DatumGetPointer(val));
        }
 
        appendStringInfoChar(result, '}');
@@ -1572,10 +1558,9 @@ row_to_json_pretty(PG_FUNCTION_ARGS)
 Datum
 to_json(PG_FUNCTION_ARGS)
 {
+       Datum           val = PG_GETARG_DATUM(0);
        Oid                     val_type = get_fn_expr_argtype(fcinfo->flinfo, 0);
        StringInfo      result;
-       Datum           orig_val,
-                               val;
        TYPCATEGORY tcategory;
        Oid                     typoutput;
        bool            typisvarlena;
@@ -1586,11 +1571,8 @@ to_json(PG_FUNCTION_ARGS)
                                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                 errmsg("could not determine input data type")));
 
-
        result = makeStringInfo();
 
-       orig_val = PG_ARGISNULL(0) ? (Datum) 0 : PG_GETARG_DATUM(0);
-
        getTypeOutputInfo(val_type, &typoutput, &typisvarlena);
 
        if (val_type > FirstNormalObjectId)
@@ -1623,21 +1605,8 @@ to_json(PG_FUNCTION_ARGS)
        else
                tcategory = TypeCategory(val_type);
 
-       /*
-        * If we have a toasted datum, forcibly detoast it here to avoid memory
-        * leakage inside the type's output routine.
-        */
-       if (typisvarlena && orig_val != (Datum) 0)
-               val = PointerGetDatum(PG_DETOAST_DATUM(orig_val));
-       else
-               val = orig_val;
-
        datum_to_json(val, false, result, tcategory, typoutput);
 
-       /* Clean up detoasted copy, if any */
-       if (val != orig_val)
-               pfree(DatumGetPointer(val));
-
        PG_RETURN_TEXT_P(cstring_to_text(result->data));
 }
 
@@ -1651,8 +1620,7 @@ json_agg_transfn(PG_FUNCTION_ARGS)
        MemoryContext aggcontext,
                                oldcontext;
        StringInfo      state;
-       Datum           orig_val,
-                               val;
+       Datum           val;
        TYPCATEGORY tcategory;
        Oid                     typoutput;
        bool            typisvarlena;
@@ -1692,13 +1660,12 @@ json_agg_transfn(PG_FUNCTION_ARGS)
        /* fast path for NULLs */
        if (PG_ARGISNULL(1))
        {
-               orig_val = (Datum) 0;
-               datum_to_json(orig_val, true, state, 0, InvalidOid);
+               val = (Datum) 0;
+               datum_to_json(val, true, state, 0, InvalidOid);
                PG_RETURN_POINTER(state);
        }
 
-
-       orig_val = PG_GETARG_DATUM(1);
+       val = PG_GETARG_DATUM(1);
 
        getTypeOutputInfo(val_type, &typoutput, &typisvarlena);
 
@@ -1732,15 +1699,6 @@ json_agg_transfn(PG_FUNCTION_ARGS)
        else
                tcategory = TypeCategory(val_type);
 
-       /*
-        * If we have a toasted datum, forcibly detoast it here to avoid memory
-        * leakage inside the type's output routine.
-        */
-       if (typisvarlena)
-               val = PointerGetDatum(PG_DETOAST_DATUM(orig_val));
-       else
-               val = orig_val;
-
        if (!PG_ARGISNULL(0) &&
          (tcategory == TYPCATEGORY_ARRAY || tcategory == TYPCATEGORY_COMPOSITE))
        {
@@ -1749,10 +1707,6 @@ json_agg_transfn(PG_FUNCTION_ARGS)
 
        datum_to_json(val, false, state, tcategory, typoutput);
 
-       /* Clean up detoasted copy, if any */
-       if (val != orig_val)
-               pfree(DatumGetPointer(val));
-
        /*
         * The transition type for array_agg() is declared to be "internal", which
         * is a pass-by-value type the same size as a pointer.  So we can safely