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

Commitc027d84

Browse files
committed
Fix memory leaks in record_out() and record_send().
record_out() leaks memory: it fails to free the strings returned by theper-column output functions, and also is careless about detoasted values.This results in a query-lifespan memory leakage when returning compositevalues to the client, because printtup() runs the output functions in thequery-lifespan memory context. Fix it to handle these issues the same wayprinttup() does. Also fix a similar leakage in record_send().(At some point we might want to try to run output functions inshorter-lived memory contexts, so that we don't need a zero-leakage policyfor them. But that would be a significantly more invasive patch, whichdoesn't seem like material for back-patching.)In passing, use appendStringInfoCharMacro instead of appendStringInfoCharin the innermost data-copying loop of record_out, to try to shave a fewcycles from this function's runtime.Per trouble report from Carlos Henrique Reimer. Back-patch to allsupported versions.
1 parent2faab1a commitc027d84

File tree

1 file changed

+40
-12
lines changed

1 file changed

+40
-12
lines changed

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

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ typedef struct ColumnIOData
3232
Oidcolumn_type;
3333
Oidtypiofunc;
3434
Oidtypioparam;
35+
booltypisvarlena;
3536
FmgrInfoproc;
3637
}ColumnIOData;
3738

@@ -340,6 +341,7 @@ record_out(PG_FUNCTION_ARGS)
340341
{
341342
ColumnIOData*column_info=&my_extra->columns[i];
342343
Oidcolumn_type=tupdesc->attrs[i]->atttypid;
344+
Datumattr;
343345
char*value;
344346
char*tmp;
345347
boolnq;
@@ -363,17 +365,24 @@ record_out(PG_FUNCTION_ARGS)
363365
*/
364366
if (column_info->column_type!=column_type)
365367
{
366-
booltypIsVarlena;
367-
368368
getTypeOutputInfo(column_type,
369369
&column_info->typiofunc,
370-
&typIsVarlena);
370+
&column_info->typisvarlena);
371371
fmgr_info_cxt(column_info->typiofunc,&column_info->proc,
372372
fcinfo->flinfo->fn_mcxt);
373373
column_info->column_type=column_type;
374374
}
375375

376-
value=OutputFunctionCall(&column_info->proc,values[i]);
376+
/*
377+
* If we have a toasted datum, forcibly detoast it here to avoid
378+
* memory leakage inside the type's output routine.
379+
*/
380+
if (column_info->typisvarlena)
381+
attr=PointerGetDatum(PG_DETOAST_DATUM(values[i]));
382+
else
383+
attr=values[i];
384+
385+
value=OutputFunctionCall(&column_info->proc,attr);
377386

378387
/* Detect whether we need double quotes for this value */
379388
nq= (value[0]=='\0');/* force quotes for empty string */
@@ -392,17 +401,23 @@ record_out(PG_FUNCTION_ARGS)
392401

393402
/* And emit the string */
394403
if (nq)
395-
appendStringInfoChar(&buf,'"');
404+
appendStringInfoCharMacro(&buf,'"');
396405
for (tmp=value;*tmp;tmp++)
397406
{
398407
charch=*tmp;
399408

400409
if (ch=='"'||ch=='\\')
401-
appendStringInfoChar(&buf,ch);
402-
appendStringInfoChar(&buf,ch);
410+
appendStringInfoCharMacro(&buf,ch);
411+
appendStringInfoCharMacro(&buf,ch);
403412
}
404413
if (nq)
405-
appendStringInfoChar(&buf,'"');
414+
appendStringInfoCharMacro(&buf,'"');
415+
416+
pfree(value);
417+
418+
/* Clean up detoasted copy, if any */
419+
if (DatumGetPointer(attr)!=DatumGetPointer(values[i]))
420+
pfree(DatumGetPointer(attr));
406421
}
407422

408423
appendStringInfoChar(&buf,')');
@@ -690,6 +705,7 @@ record_send(PG_FUNCTION_ARGS)
690705
{
691706
ColumnIOData*column_info=&my_extra->columns[i];
692707
Oidcolumn_type=tupdesc->attrs[i]->atttypid;
708+
Datumattr;
693709
bytea*outputbytes;
694710

695711
/* Ignore dropped columns in datatype */
@@ -710,23 +726,35 @@ record_send(PG_FUNCTION_ARGS)
710726
*/
711727
if (column_info->column_type!=column_type)
712728
{
713-
booltypIsVarlena;
714-
715729
getTypeBinaryOutputInfo(column_type,
716730
&column_info->typiofunc,
717-
&typIsVarlena);
731+
&column_info->typisvarlena);
718732
fmgr_info_cxt(column_info->typiofunc,&column_info->proc,
719733
fcinfo->flinfo->fn_mcxt);
720734
column_info->column_type=column_type;
721735
}
722736

723-
outputbytes=SendFunctionCall(&column_info->proc,values[i]);
737+
/*
738+
* If we have a toasted datum, forcibly detoast it here to avoid
739+
* memory leakage inside the type's output routine.
740+
*/
741+
if (column_info->typisvarlena)
742+
attr=PointerGetDatum(PG_DETOAST_DATUM(values[i]));
743+
else
744+
attr=values[i];
745+
746+
outputbytes=SendFunctionCall(&column_info->proc,attr);
724747

725748
/* We assume the result will not have been toasted */
726749
pq_sendint(&buf,VARSIZE(outputbytes)-VARHDRSZ,4);
727750
pq_sendbytes(&buf,VARDATA(outputbytes),
728751
VARSIZE(outputbytes)-VARHDRSZ);
752+
729753
pfree(outputbytes);
754+
755+
/* Clean up detoasted copy, if any */
756+
if (DatumGetPointer(attr)!=DatumGetPointer(values[i]))
757+
pfree(DatumGetPointer(attr));
730758
}
731759

732760
pfree(values);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp