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

Commit76cc2fe

Browse files
committed
Fix dblink and tablefunc to not return with the wrong CurrentMemoryContext.
Per buildfarm results.
1 parentc1f3073 commit76cc2fe

File tree

2 files changed

+37
-28
lines changed

2 files changed

+37
-28
lines changed

‎contrib/dblink/dblink.c

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Darko Prenosil <Darko.Prenosil@finteh.hr>
99
* Shridhar Daithankar <shridhar_daithankar@persistent.co.in>
1010
*
11-
* $PostgreSQL: pgsql/contrib/dblink/dblink.c,v 1.75 2008/09/22 13:55:13 tgl Exp $
11+
* $PostgreSQL: pgsql/contrib/dblink/dblink.c,v 1.76 2008/11/30 23:23:52 tgl Exp $
1212
* Copyright (c) 2001-2008, PostgreSQL Global Development Group
1313
* ALL RIGHTS RESERVED;
1414
*
@@ -213,7 +213,6 @@ dblink_connect(PG_FUNCTION_ARGS)
213213
char*connstr=NULL;
214214
char*connname=NULL;
215215
char*msg;
216-
MemoryContextoldcontext;
217216
PGconn*conn=NULL;
218217
remoteConn*rconn=NULL;
219218

@@ -227,17 +226,14 @@ dblink_connect(PG_FUNCTION_ARGS)
227226
elseif (PG_NARGS()==1)
228227
connstr=text_to_cstring(PG_GETARG_TEXT_PP(0));
229228

230-
oldcontext=MemoryContextSwitchTo(TopMemoryContext);
231-
232229
if (connname)
233-
rconn= (remoteConn*)palloc(sizeof(remoteConn));
230+
rconn= (remoteConn*)MemoryContextAlloc(TopMemoryContext,
231+
sizeof(remoteConn));
234232

235233
/* check password in connection string if not superuser */
236234
dblink_connstr_check(connstr);
237235
conn=PQconnectdb(connstr);
238236

239-
MemoryContextSwitchTo(oldcontext);
240-
241237
if (PQstatus(conn)==CONNECTION_BAD)
242238
{
243239
msg=pstrdup(PQerrorMessage(conn));
@@ -562,10 +558,10 @@ dblink_fetch(PG_FUNCTION_ARGS)
562558
funcctx=SRF_FIRSTCALL_INIT();
563559

564560
/*
565-
* switch to memory context appropriate for multiple function calls
561+
* Try to execute the query. Note that since libpq uses malloc,
562+
* the PGresult will be long-lived even though we are still in
563+
* a short-lived memory context.
566564
*/
567-
oldcontext=MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
568-
569565
res=PQexec(conn,buf.data);
570566
if (!res||
571567
(PQresultStatus(res)!=PGRES_COMMAND_OK&&
@@ -607,24 +603,32 @@ dblink_fetch(PG_FUNCTION_ARGS)
607603
break;
608604
}
609605

610-
/* make sure we have a persistent copy of the tupdesc */
611-
tupdesc=CreateTupleDescCopy(tupdesc);
612-
613606
/* check result and tuple descriptor have the same number of columns */
614607
if (PQnfields(res)!=tupdesc->natts)
615608
ereport(ERROR,
616609
(errcode(ERRCODE_DATATYPE_MISMATCH),
617610
errmsg("remote query result rowtype does not match "
618611
"the specified FROM clause rowtype")));
619612

620-
/* fast track when no results */
613+
/*
614+
* fast track when no results. We could exit earlier, but then
615+
* we'd not report error if the result tuple type is wrong.
616+
*/
621617
if (funcctx->max_calls<1)
622618
{
623-
if (res)
624-
PQclear(res);
619+
PQclear(res);
625620
SRF_RETURN_DONE(funcctx);
626621
}
627622

623+
/*
624+
* switch to memory context appropriate for multiple function calls,
625+
* so we can make long-lived copy of tupdesc etc
626+
*/
627+
oldcontext=MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
628+
629+
/* make sure we have a persistent copy of the tupdesc */
630+
tupdesc=CreateTupleDescCopy(tupdesc);
631+
628632
/* store needed metadata for subsequent calls */
629633
attinmeta=TupleDescGetAttInMetadata(tupdesc);
630634
funcctx->attinmeta=attinmeta;
@@ -815,7 +819,10 @@ dblink_record_internal(FunctionCallInfo fcinfo, bool is_async, bool do_get)
815819
res=PQgetResult(conn);
816820
/* NULL means we're all done with the async results */
817821
if (!res)
822+
{
823+
MemoryContextSwitchTo(oldcontext);
818824
SRF_RETURN_DONE(funcctx);
825+
}
819826
}
820827

821828
if (!res||
@@ -825,6 +832,7 @@ dblink_record_internal(FunctionCallInfo fcinfo, bool is_async, bool do_get)
825832
dblink_res_error(conname,res,"could not execute query",fail);
826833
if (freeconn)
827834
PQfinish(conn);
835+
MemoryContextSwitchTo(oldcontext);
828836
SRF_RETURN_DONE(funcctx);
829837
}
830838

@@ -894,6 +902,7 @@ dblink_record_internal(FunctionCallInfo fcinfo, bool is_async, bool do_get)
894902
{
895903
if (res)
896904
PQclear(res);
905+
MemoryContextSwitchTo(oldcontext);
897906
SRF_RETURN_DONE(funcctx);
898907
}
899908

@@ -1261,8 +1270,11 @@ dblink_get_pkey(PG_FUNCTION_ARGS)
12611270
funcctx->user_fctx=results;
12621271
}
12631272
else
1273+
{
12641274
/* fast track when no results */
1275+
MemoryContextSwitchTo(oldcontext);
12651276
SRF_RETURN_DONE(funcctx);
1277+
}
12661278

12671279
MemoryContextSwitchTo(oldcontext);
12681280
}

‎contrib/tablefunc/tablefunc.c

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* $PostgreSQL: pgsql/contrib/tablefunc/tablefunc.c,v 1.55 2008/10/29 00:00:38 tgl Exp $
2+
* $PostgreSQL: pgsql/contrib/tablefunc/tablefunc.c,v 1.56 2008/11/30 23:23:52 tgl Exp $
33
*
44
*
55
* tablefunc
@@ -381,11 +381,6 @@ crosstab(PG_FUNCTION_ARGS)
381381
/* create a function context for cross-call persistence */
382382
funcctx=SRF_FIRSTCALL_INIT();
383383

384-
/*
385-
* switch to memory context appropriate for multiple function calls
386-
*/
387-
oldcontext=MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
388-
389384
/* Connect to SPI manager */
390385
if ((ret=SPI_connect())<0)
391386
/* internal error */
@@ -426,9 +421,6 @@ crosstab(PG_FUNCTION_ARGS)
426421
SRF_RETURN_DONE(funcctx);
427422
}
428423

429-
/* SPI switches context on us, so reset it */
430-
MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
431-
432424
/* get a tuple descriptor for our result type */
433425
switch (get_call_result_type(fcinfo,NULL,&tupdesc))
434426
{
@@ -448,9 +440,6 @@ crosstab(PG_FUNCTION_ARGS)
448440
break;
449441
}
450442

451-
/* make sure we have a persistent copy of the tupdesc */
452-
tupdesc=CreateTupleDescCopy(tupdesc);
453-
454443
/*
455444
* Check that return tupdesc is compatible with the data we got from
456445
* SPI, at least based on number and type of attributes
@@ -461,6 +450,14 @@ crosstab(PG_FUNCTION_ARGS)
461450
errmsg("return and sql tuple descriptions are " \
462451
"incompatible")));
463452

453+
/*
454+
* switch to memory context appropriate for multiple function calls
455+
*/
456+
oldcontext=MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
457+
458+
/* make sure we have a persistent copy of the tupdesc */
459+
tupdesc=CreateTupleDescCopy(tupdesc);
460+
464461
/*
465462
* Generate attribute metadata needed later to produce tuples from raw
466463
* C strings

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp