Skip to content

Commit 84d723b

Browse files
committed
Previous fix for temporary file management broke returning a set from
PL/pgSQL function within an exception handler. Make sure we use the right resource owner when we create the tuplestore to hold returned tuples. Simplify tuplestore API so that the caller doesn't need to be in the right memory context when calling tuplestore_put* functions. tuplestore.c automatically switches to the memory context used when the tuplestore was created. Tuplesort was already modified like this earlier. This patch also removes the now useless MemoryContextSwitch calls from callers. Report by Aleksei on pgsql-bugs on Dec 22 2009. Backpatch to 8.1, like the previous patch that broke this.
1 parent 50ef9f7 commit 84d723b

File tree

14 files changed

+75
-103
lines changed

14 files changed

+75
-103
lines changed

contrib/dblink/dblink.c

+1-4
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Darko Prenosil <[email protected]>
99
* Shridhar Daithankar <[email protected]>
1010
*
11-
* $PostgreSQL: pgsql/contrib/dblink/dblink.c,v 1.84 2009/09/12 23:20:52 joe Exp $
11+
* $PostgreSQL: pgsql/contrib/dblink/dblink.c,v 1.85 2009/12/29 17:40:59 heikki Exp $
1212
* Copyright (c) 2001-2009, PostgreSQL Global Development Group
1313
* ALL RIGHTS RESERVED;
1414
*
@@ -1703,10 +1703,7 @@ dblink_get_notify(PG_FUNCTION_ARGS)
17031703
else
17041704
nulls[2] = true;
17051705

1706-
/* switch to appropriate context while storing the tuple */
1707-
MemoryContextSwitchTo(per_query_ctx);
17081706
tuplestore_putvalues(tupstore, tupdesc, values, nulls);
1709-
MemoryContextSwitchTo(oldcontext);
17101707

17111708
PQfreemem(notify);
17121709
PQconsumeInput(conn);

contrib/pg_stat_statements/pg_stat_statements.c

+3-8
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* Copyright (c) 2008-2009, PostgreSQL Global Development Group
1515
*
1616
* IDENTIFICATION
17-
* $PostgreSQL: pgsql/contrib/pg_stat_statements/pg_stat_statements.c,v 1.9 2009/12/15 20:04:49 tgl Exp $
17+
* $PostgreSQL: pgsql/contrib/pg_stat_statements/pg_stat_statements.c,v 1.10 2009/12/29 17:40:59 heikki Exp $
1818
*
1919
*-------------------------------------------------------------------------
2020
*/
@@ -783,6 +783,8 @@ pg_stat_statements(PG_FUNCTION_ARGS)
783783
rsinfo->setResult = tupstore;
784784
rsinfo->setDesc = tupdesc;
785785

786+
MemoryContextSwitchTo(oldcontext);
787+
786788
LWLockAcquire(pgss->lock, LW_SHARED);
787789

788790
hash_seq_init(&hash_seq, pgss_hash);
@@ -793,9 +795,6 @@ pg_stat_statements(PG_FUNCTION_ARGS)
793795
int i = 0;
794796
Counters tmp;
795797

796-
/* generate junk in short-term context */
797-
MemoryContextSwitchTo(oldcontext);
798-
799798
memset(values, 0, sizeof(values));
800799
memset(nulls, 0, sizeof(nulls));
801800

@@ -833,8 +832,6 @@ pg_stat_statements(PG_FUNCTION_ARGS)
833832

834833
Assert(i == PG_STAT_STATEMENTS_COLS);
835834

836-
/* switch to appropriate context while storing the tuple */
837-
MemoryContextSwitchTo(per_query_ctx);
838835
tuplestore_putvalues(tupstore, tupdesc, values, nulls);
839836
}
840837

@@ -843,8 +840,6 @@ pg_stat_statements(PG_FUNCTION_ARGS)
843840
/* clean up and return the tuplestore */
844841
tuplestore_donestoring(tupstore);
845842

846-
MemoryContextSwitchTo(oldcontext);
847-
848843
return (Datum) 0;
849844
}
850845

contrib/tablefunc/tablefunc.c

+2-27
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* $PostgreSQL: pgsql/contrib/tablefunc/tablefunc.c,v 1.60 2009/06/11 14:48:52 momjian Exp $
2+
* $PostgreSQL: pgsql/contrib/tablefunc/tablefunc.c,v 1.61 2009/12/29 17:40:59 heikki Exp $
33
*
44
*
55
* tablefunc
@@ -567,14 +567,9 @@ crosstab(PG_FUNCTION_ARGS)
567567
{
568568
HeapTuple tuple;
569569

570-
/* build the tuple */
570+
/* build the tuple and store it */
571571
tuple = BuildTupleFromCStrings(attinmeta, values);
572-
573-
/* switch to appropriate context while storing the tuple */
574-
oldcontext = MemoryContextSwitchTo(per_query_ctx);
575572
tuplestore_puttuple(tupstore, tuple);
576-
MemoryContextSwitchTo(oldcontext);
577-
578573
heap_freetuple(tuple);
579574
}
580575

@@ -807,7 +802,6 @@ get_crosstab_tuplestore(char *sql,
807802
HeapTuple tuple;
808803
int ret;
809804
int proc;
810-
MemoryContext SPIcontext;
811805

812806
/* initialize our tuplestore (while still in query context!) */
813807
tupstore = tuplestore_begin_heap(randomAccess, false, work_mem);
@@ -907,10 +901,7 @@ get_crosstab_tuplestore(char *sql,
907901
/* rowid changed, flush the previous output row */
908902
tuple = BuildTupleFromCStrings(attinmeta, values);
909903

910-
/* switch to appropriate context while storing the tuple */
911-
SPIcontext = MemoryContextSwitchTo(per_query_ctx);
912904
tuplestore_puttuple(tupstore, tuple);
913-
MemoryContextSwitchTo(SPIcontext);
914905

915906
for (j = 0; j < result_ncols; j++)
916907
xpfree(values[j]);
@@ -943,10 +934,7 @@ get_crosstab_tuplestore(char *sql,
943934
/* flush the last output row */
944935
tuple = BuildTupleFromCStrings(attinmeta, values);
945936

946-
/* switch to appropriate context while storing the tuple */
947-
SPIcontext = MemoryContextSwitchTo(per_query_ctx);
948937
tuplestore_puttuple(tupstore, tuple);
949-
MemoryContextSwitchTo(SPIcontext);
950938
}
951939

952940
if (SPI_finish() != SPI_OK_FINISH)
@@ -1232,7 +1220,6 @@ build_tuplestore_recursively(char *key_fld,
12321220
Tuplestorestate *tupstore)
12331221
{
12341222
TupleDesc tupdesc = attinmeta->tupdesc;
1235-
MemoryContext oldcontext;
12361223
int ret;
12371224
int proc;
12381225
int serial_column;
@@ -1310,15 +1297,9 @@ build_tuplestore_recursively(char *key_fld,
13101297
/* construct the tuple */
13111298
tuple = BuildTupleFromCStrings(attinmeta, values);
13121299

1313-
/* switch to long lived context while storing the tuple */
1314-
oldcontext = MemoryContextSwitchTo(per_query_ctx);
1315-
13161300
/* now store it */
13171301
tuplestore_puttuple(tupstore, tuple);
13181302

1319-
/* now reset the context */
1320-
MemoryContextSwitchTo(oldcontext);
1321-
13221303
/* increment level */
13231304
level++;
13241305
}
@@ -1404,15 +1385,9 @@ build_tuplestore_recursively(char *key_fld,
14041385
xpfree(current_key);
14051386
xpfree(current_key_parent);
14061387

1407-
/* switch to long lived context while storing the tuple */
1408-
oldcontext = MemoryContextSwitchTo(per_query_ctx);
1409-
14101388
/* store the tuple for later use */
14111389
tuplestore_puttuple(tupstore, tuple);
14121390

1413-
/* now reset the context */
1414-
MemoryContextSwitchTo(oldcontext);
1415-
14161391
heap_freetuple(tuple);
14171392

14181393
/* recurse using current_key_parent as the new start_with */

contrib/xml2/xpath.c

+1-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* $PostgreSQL: pgsql/contrib/xml2/xpath.c,v 1.23 2009/06/11 14:48:53 momjian Exp $
2+
* $PostgreSQL: pgsql/contrib/xml2/xpath.c,v 1.24 2009/12/29 17:40:59 heikki Exp $
33
*
44
* Parser interface for DOM-based parser (libxml) rather than
55
* stream-based SAX-type parser
@@ -821,9 +821,7 @@ xpath_table(PG_FUNCTION_ARGS)
821821
{
822822
/* not well-formed, so output all-NULL tuple */
823823
ret_tuple = BuildTupleFromCStrings(attinmeta, values);
824-
oldcontext = MemoryContextSwitchTo(per_query_ctx);
825824
tuplestore_puttuple(tupstore, ret_tuple);
826-
MemoryContextSwitchTo(oldcontext);
827825
heap_freetuple(ret_tuple);
828826
}
829827
else
@@ -897,9 +895,7 @@ xpath_table(PG_FUNCTION_ARGS)
897895
if (had_values)
898896
{
899897
ret_tuple = BuildTupleFromCStrings(attinmeta, values);
900-
oldcontext = MemoryContextSwitchTo(per_query_ctx);
901898
tuplestore_puttuple(tupstore, ret_tuple);
902-
MemoryContextSwitchTo(oldcontext);
903899
heap_freetuple(ret_tuple);
904900
}
905901

src/backend/commands/prepare.c

+4-8
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* Copyright (c) 2002-2009, PostgreSQL Global Development Group
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/commands/prepare.c,v 1.100 2009/11/04 22:26:05 tgl Exp $
13+
* $PostgreSQL: pgsql/src/backend/commands/prepare.c,v 1.101 2009/12/29 17:40:59 heikki Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -779,6 +779,9 @@ pg_prepared_statement(PG_FUNCTION_ARGS)
779779
tuplestore_begin_heap(rsinfo->allowedModes & SFRM_Materialize_Random,
780780
false, work_mem);
781781

782+
/* generate junk in short-term context */
783+
MemoryContextSwitchTo(oldcontext);
784+
782785
/* hash table might be uninitialized */
783786
if (prepared_queries)
784787
{
@@ -791,9 +794,6 @@ pg_prepared_statement(PG_FUNCTION_ARGS)
791794
Datum values[5];
792795
bool nulls[5];
793796

794-
/* generate junk in short-term context */
795-
MemoryContextSwitchTo(oldcontext);
796-
797797
MemSet(nulls, 0, sizeof(nulls));
798798

799799
values[0] = CStringGetTextDatum(prep_stmt->stmt_name);
@@ -803,17 +803,13 @@ pg_prepared_statement(PG_FUNCTION_ARGS)
803803
prep_stmt->plansource->num_params);
804804
values[4] = BoolGetDatum(prep_stmt->from_sql);
805805

806-
/* switch to appropriate context while storing the tuple */
807-
MemoryContextSwitchTo(per_query_ctx);
808806
tuplestore_putvalues(tupstore, tupdesc, values, nulls);
809807
}
810808
}
811809

812810
/* clean up and return the tuplestore */
813811
tuplestore_donestoring(tupstore);
814812

815-
MemoryContextSwitchTo(oldcontext);
816-
817813
rsinfo->returnMode = SFRM_Materialize;
818814
rsinfo->setResult = tupstore;
819815
rsinfo->setDesc = tupdesc;

src/backend/executor/execQual.c

+1-6
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.256 2009/12/14 02:15:49 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.257 2009/12/29 17:40:59 heikki Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -2038,15 +2038,10 @@ ExecMakeTableFunctionResult(ExprState *funcexpr,
20382038
tmptup.t_len = HeapTupleHeaderGetDatumLength(td);
20392039
tmptup.t_data = td;
20402040

2041-
oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
20422041
tuplestore_puttuple(tupstore, &tmptup);
20432042
}
20442043
else
2045-
{
2046-
oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
20472044
tuplestore_putvalues(tupstore, tupdesc, &result, &fcinfo.isnull);
2048-
}
2049-
MemoryContextSwitchTo(oldcontext);
20502045

20512046
/*
20522047
* Are we done?

src/backend/executor/functions.c

+1-4
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.138 2009/12/15 04:57:47 rhaas Exp $
11+
* $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.139 2009/12/29 17:40:59 heikki Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -1405,15 +1405,12 @@ static void
14051405
sqlfunction_receive(TupleTableSlot *slot, DestReceiver *self)
14061406
{
14071407
DR_sqlfunction *myState = (DR_sqlfunction *) self;
1408-
MemoryContext oldcxt;
14091408

14101409
/* Filter tuple as needed */
14111410
slot = ExecFilterJunk(myState->filter, slot);
14121411

14131412
/* Store the filtered tuple into the tuplestore */
1414-
oldcxt = MemoryContextSwitchTo(myState->cxt);
14151413
tuplestore_puttupleslot(myState->tstore, slot);
1416-
MemoryContextSwitchTo(oldcxt);
14171414
}
14181415

14191416
/*

src/backend/executor/nodeWindowAgg.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
* Portions Copyright (c) 1994, Regents of the University of California
2828
*
2929
* IDENTIFICATION
30-
* $PostgreSQL: pgsql/src/backend/executor/nodeWindowAgg.c,v 1.7 2009/09/27 21:10:53 tgl Exp $
30+
* $PostgreSQL: pgsql/src/backend/executor/nodeWindowAgg.c,v 1.8 2009/12/29 17:40:59 heikki Exp $
3131
*
3232
*-------------------------------------------------------------------------
3333
*/
@@ -723,7 +723,7 @@ spool_tuples(WindowAggState *winstate, int64 pos)
723723

724724
outerPlan = outerPlanState(winstate);
725725

726-
/* Must be in query context to call outerplan or touch tuplestore */
726+
/* Must be in query context to call outerplan */
727727
oldcontext = MemoryContextSwitchTo(winstate->ss.ps.ps_ExprContext->ecxt_per_query_memory);
728728

729729
while (winstate->spooled_rows <= pos || pos == -1)

src/backend/executor/tstoreReceiver.c

+1-4
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* Portions Copyright (c) 1994, Regents of the University of California
1414
*
1515
* IDENTIFICATION
16-
* $PostgreSQL: pgsql/src/backend/executor/tstoreReceiver.c,v 1.23 2009/06/11 14:48:57 momjian Exp $
16+
* $PostgreSQL: pgsql/src/backend/executor/tstoreReceiver.c,v 1.24 2009/12/29 17:40:59 heikki Exp $
1717
*
1818
*-------------------------------------------------------------------------
1919
*/
@@ -94,11 +94,8 @@ static void
9494
tstoreReceiveSlot_notoast(TupleTableSlot *slot, DestReceiver *self)
9595
{
9696
TStoreState *myState = (TStoreState *) self;
97-
MemoryContext oldcxt = MemoryContextSwitchTo(myState->cxt);
9897

9998
tuplestore_puttupleslot(myState->tstore, slot);
100-
101-
MemoryContextSwitchTo(oldcxt);
10299
}
103100

104101
/*

src/backend/utils/mmgr/portalmem.c

+4-8
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* Portions Copyright (c) 1994, Regents of the University of California
1313
*
1414
* IDENTIFICATION
15-
* $PostgreSQL: pgsql/src/backend/utils/mmgr/portalmem.c,v 1.113 2009/01/01 17:23:53 momjian Exp $
15+
* $PostgreSQL: pgsql/src/backend/utils/mmgr/portalmem.c,v 1.114 2009/12/29 17:40:59 heikki Exp $
1616
*
1717
*-------------------------------------------------------------------------
1818
*/
@@ -923,6 +923,9 @@ pg_cursor(PG_FUNCTION_ARGS)
923923
tuplestore_begin_heap(rsinfo->allowedModes & SFRM_Materialize_Random,
924924
false, work_mem);
925925

926+
/* generate junk in short-term context */
927+
MemoryContextSwitchTo(oldcontext);
928+
926929
hash_seq_init(&hash_seq, PortalHashTable);
927930
while ((hentry = hash_seq_search(&hash_seq)) != NULL)
928931
{
@@ -934,9 +937,6 @@ pg_cursor(PG_FUNCTION_ARGS)
934937
if (!portal->visible)
935938
continue;
936939

937-
/* generate junk in short-term context */
938-
MemoryContextSwitchTo(oldcontext);
939-
940940
MemSet(nulls, 0, sizeof(nulls));
941941

942942
values[0] = CStringGetTextDatum(portal->name);
@@ -946,16 +946,12 @@ pg_cursor(PG_FUNCTION_ARGS)
946946
values[4] = BoolGetDatum(portal->cursorOptions & CURSOR_OPT_SCROLL);
947947
values[5] = TimestampTzGetDatum(portal->creation_time);
948948

949-
/* switch to appropriate context while storing the tuple */
950-
MemoryContextSwitchTo(per_query_ctx);
951949
tuplestore_putvalues(tupstore, tupdesc, values, nulls);
952950
}
953951

954952
/* clean up and return the tuplestore */
955953
tuplestore_donestoring(tupstore);
956954

957-
MemoryContextSwitchTo(oldcontext);
958-
959955
rsinfo->returnMode = SFRM_Materialize;
960956
rsinfo->setResult = tupstore;
961957
rsinfo->setDesc = tupdesc;

0 commit comments

Comments
 (0)