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

Commit313de22

Browse files
committed
SQL functions returning pass-by-reference types were copying the results
into the wrong memory context, resulting in a query-lifespan memory leak.Bug is new in 8.0, I believe. Per report from Rae Stiening.
1 parent9427cce commit313de22

File tree

1 file changed

+22
-13
lines changed

1 file changed

+22
-13
lines changed

‎src/backend/executor/functions.c

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.96 2005/04/06 16:34:04 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.97 2005/04/10 18:04:20 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -86,12 +86,13 @@ static execution_state *init_execution_state(List *queryTree_list,
8686
staticvoidinit_sql_fcache(FmgrInfo*finfo);
8787
staticvoidpostquel_start(execution_state*es,SQLFunctionCachePtrfcache);
8888
staticTupleTableSlot*postquel_getnext(execution_state*es);
89-
staticvoidpostquel_end(execution_state*es,SQLFunctionCachePtrfcache);
89+
staticvoidpostquel_end(execution_state*es);
9090
staticvoidpostquel_sub_params(SQLFunctionCachePtrfcache,
9191
FunctionCallInfofcinfo);
9292
staticDatumpostquel_execute(execution_state*es,
9393
FunctionCallInfofcinfo,
94-
SQLFunctionCachePtrfcache);
94+
SQLFunctionCachePtrfcache,
95+
MemoryContextresultcontext);
9596
staticvoidsql_exec_error_callback(void*arg);
9697
staticvoidShutdownSQLFunction(Datumarg);
9798

@@ -384,7 +385,7 @@ postquel_getnext(execution_state *es)
384385
}
385386

386387
staticvoid
387-
postquel_end(execution_state*es,SQLFunctionCachePtrfcache)
388+
postquel_end(execution_state*es)
388389
{
389390
SnapshotsaveActiveSnapshot;
390391

@@ -454,10 +455,12 @@ postquel_sub_params(SQLFunctionCachePtr fcache,
454455
staticDatum
455456
postquel_execute(execution_state*es,
456457
FunctionCallInfofcinfo,
457-
SQLFunctionCachePtrfcache)
458+
SQLFunctionCachePtrfcache,
459+
MemoryContextresultcontext)
458460
{
459461
TupleTableSlot*slot;
460462
Datumvalue;
463+
MemoryContextoldcontext;
461464

462465
if (es->status==F_EXEC_START)
463466
postquel_start(es,fcache);
@@ -470,7 +473,7 @@ postquel_execute(execution_state *es,
470473
* We fall out here for all cases except where we have obtained
471474
* a row from a function's final SELECT.
472475
*/
473-
postquel_end(es,fcache);
476+
postquel_end(es);
474477
fcinfo->isnull= true;
475478
return (Datum)NULL;
476479
}
@@ -482,8 +485,12 @@ postquel_execute(execution_state *es,
482485
Assert(LAST_POSTQUEL_COMMAND(es));
483486

484487
/*
485-
* Set up to return the function value.
488+
* Set up to return the function value. For pass-by-reference
489+
* datatypes, be sure to allocate the result in resultcontext,
490+
* not the current memory context (which has query lifespan).
486491
*/
492+
oldcontext=MemoryContextSwitchTo(resultcontext);
493+
487494
if (fcache->returnsTuple)
488495
{
489496
/*
@@ -492,7 +499,7 @@ postquel_execute(execution_state *es,
492499
* reasons why we do this:
493500
*
494501
* 1. To copy the tuple out of the child execution context and
495-
* intoour own context.
502+
* intothe desired result context.
496503
*
497504
* 2. To remove any junk attributes present in the raw subselect
498505
* result. (This is probably not absolutely necessary, but it
@@ -553,21 +560,23 @@ postquel_execute(execution_state *es,
553560
{
554561
/*
555562
* Returning a scalar, which we have to extract from the first
556-
* column of the SELECT result, and then copy intocurrent
557-
*executioncontext if needed.
563+
* column of the SELECT result, and then copy intoresult
564+
* context if needed.
558565
*/
559566
value=slot_getattr(slot,1,&(fcinfo->isnull));
560567

561568
if (!fcinfo->isnull)
562569
value=datumCopy(value,fcache->typbyval,fcache->typlen);
563570
}
564571

572+
MemoryContextSwitchTo(oldcontext);
573+
565574
/*
566575
* If this is a single valued function we have to end the function
567576
* execution now.
568577
*/
569578
if (!fcinfo->flinfo->fn_retset)
570-
postquel_end(es,fcache);
579+
postquel_end(es);
571580

572581
returnvalue;
573582
}
@@ -627,7 +636,7 @@ fmgr_sql(PG_FUNCTION_ARGS)
627636
*/
628637
while (es)
629638
{
630-
result=postquel_execute(es,fcinfo,fcache);
639+
result=postquel_execute(es,fcinfo,fcache,oldcontext);
631640
if (es->status!=F_EXEC_DONE)
632641
break;
633642
es=es->next;
@@ -824,7 +833,7 @@ ShutdownSQLFunction(Datum arg)
824833
{
825834
/* Shut down anything still running */
826835
if (es->status==F_EXEC_RUN)
827-
postquel_end(es,fcache);
836+
postquel_end(es);
828837
/* Reset states to START in case we're called again */
829838
es->status=F_EXEC_START;
830839
es=es->next;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp