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

Commit96e6319

Browse files
committed
Fix plpython to generate separate cached procedure data for each
relation, when the same function is used as a trigger on more thanone relation. This avoids crashes due to differing rowtypes fordifferent relations. Per bug report from Lance Thomas, 7-Feb-03.
1 parentefebe26 commit96e6319

File tree

1 file changed

+37
-25
lines changed

1 file changed

+37
-25
lines changed

‎src/pl/plpython/plpython.c

Lines changed: 37 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
* MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
3030
*
3131
* IDENTIFICATION
32-
*$Header: /cvsroot/pgsql/src/pl/plpython/plpython.c,v 1.39 2003/08/04 18:40:50 tgl Exp $
32+
*$Header: /cvsroot/pgsql/src/pl/plpython/plpython.c,v 1.40 2003/09/14 17:13:06 tgl Exp $
3333
*
3434
*********************************************************************
3535
*/
@@ -224,13 +224,11 @@ static HeapTuple PLy_modify_tuple(PLyProcedure *, PyObject *,
224224

225225
staticPyObject*PLy_procedure_call(PLyProcedure*,char*,PyObject*);
226226

227-
/* returns a cached PLyProcedure, or creates, stores and returns
228-
* a new PLyProcedure.
229-
*/
230-
staticPLyProcedure*PLy_procedure_get(FunctionCallInfofcinfo,bool);
227+
staticPLyProcedure*PLy_procedure_get(FunctionCallInfofcinfo,
228+
Oidtgreloid);
231229

232230
staticPLyProcedure*PLy_procedure_create(FunctionCallInfofcinfo,
233-
boolis_trigger,
231+
Oidtgreloid,
234232
HeapTupleprocTup,char*key);
235233

236234
staticvoidPLy_procedure_compile(PLyProcedure*,constchar*);
@@ -326,7 +324,6 @@ plpython_call_handler(PG_FUNCTION_ARGS)
326324
{
327325
DECLARE_EXC();
328326
Datumretval;
329-
volatileboolis_trigger;
330327
PLyProcedure*volatileproc=NULL;
331328

332329
enter();
@@ -337,7 +334,6 @@ plpython_call_handler(PG_FUNCTION_ARGS)
337334
elog(ERROR,"could not connect to SPI manager");
338335

339336
CALL_LEVEL_INC();
340-
is_trigger=CALLED_AS_TRIGGER(fcinfo);
341337

342338
SAVE_EXC();
343339
if (TRAP_EXC())
@@ -364,16 +360,21 @@ plpython_call_handler(PG_FUNCTION_ARGS)
364360
* PLy_restart_in_progress);
365361
*/
366362

367-
proc=PLy_procedure_get(fcinfo,is_trigger);
368-
369-
if (is_trigger)
363+
if (CALLED_AS_TRIGGER(fcinfo))
370364
{
371-
HeapTupletrv=PLy_trigger_handler(fcinfo,proc);
365+
TriggerData*tdata= (TriggerData*)fcinfo->context;
366+
HeapTupletrv;
372367

368+
proc=PLy_procedure_get(fcinfo,
369+
RelationGetRelid(tdata->tg_relation));
370+
trv=PLy_trigger_handler(fcinfo,proc);
373371
retval=PointerGetDatum(trv);
374372
}
375373
else
374+
{
375+
proc=PLy_procedure_get(fcinfo,InvalidOid);
376376
retval=PLy_function_handler(fcinfo,proc);
377+
}
377378

378379
CALL_LEVEL_DEC();
379380
RESTORE_EXC();
@@ -962,10 +963,17 @@ PLy_function_build_args(FunctionCallInfo fcinfo, PLyProcedure * proc)
962963
}
963964

964965

965-
/* PLyProcedure functions
966+
/*
967+
* PLyProcedure functions
968+
*/
969+
970+
/* PLy_procedure_get: returns a cached PLyProcedure, or creates, stores and
971+
* returns a new PLyProcedure. fcinfo is the call info, tgreloid is the
972+
* relation OID when calling a trigger, or InvalidOid (zero) for ordinary
973+
* function calls.
966974
*/
967975
staticPLyProcedure*
968-
PLy_procedure_get(FunctionCallInfofcinfo,boolis_trigger)
976+
PLy_procedure_get(FunctionCallInfofcinfo,Oidtgreloid)
969977
{
970978
Oidfn_oid;
971979
HeapTupleprocTup;
@@ -983,9 +991,7 @@ PLy_procedure_get(FunctionCallInfo fcinfo, bool is_trigger)
983991
if (!HeapTupleIsValid(procTup))
984992
elog(ERROR,"cache lookup failed for function %u",fn_oid);
985993

986-
rv=snprintf(key,sizeof(key),"%u%s",
987-
fn_oid,
988-
is_trigger ?"_trigger" :"");
994+
rv=snprintf(key,sizeof(key),"%u_%u",fn_oid,tgreloid);
989995
if ((rv >=sizeof(key))|| (rv<0))
990996
elog(ERROR,"key too long");
991997

@@ -1012,15 +1018,15 @@ PLy_procedure_get(FunctionCallInfo fcinfo, bool is_trigger)
10121018
}
10131019

10141020
if (proc==NULL)
1015-
proc=PLy_procedure_create(fcinfo,is_trigger,procTup,key);
1021+
proc=PLy_procedure_create(fcinfo,tgreloid,procTup,key);
10161022

10171023
ReleaseSysCache(procTup);
10181024

10191025
returnproc;
10201026
}
10211027

10221028
staticPLyProcedure*
1023-
PLy_procedure_create(FunctionCallInfofcinfo,boolis_trigger,
1029+
PLy_procedure_create(FunctionCallInfofcinfo,Oidtgreloid,
10241030
HeapTupleprocTup,char*key)
10251031
{
10261032
charprocName[NAMEDATALEN+256];
@@ -1037,11 +1043,17 @@ PLy_procedure_create(FunctionCallInfo fcinfo, bool is_trigger,
10371043

10381044
procStruct= (Form_pg_proc)GETSTRUCT(procTup);
10391045

1040-
rv=snprintf(procName,sizeof(procName),
1041-
"__plpython_procedure_%s_%u%s",
1042-
NameStr(procStruct->proname),
1043-
fcinfo->flinfo->fn_oid,
1044-
is_trigger ?"_trigger" :"");
1046+
if (OidIsValid(tgreloid))
1047+
rv=snprintf(procName,sizeof(procName),
1048+
"__plpython_procedure_%s_%u_trigger_%u",
1049+
NameStr(procStruct->proname),
1050+
fcinfo->flinfo->fn_oid,
1051+
tgreloid);
1052+
else
1053+
rv=snprintf(procName,sizeof(procName),
1054+
"__plpython_procedure_%s_%u",
1055+
NameStr(procStruct->proname),
1056+
fcinfo->flinfo->fn_oid);
10451057
if ((rv >=sizeof(procName))|| (rv<0))
10461058
elog(ERROR,"procedure name would overrun buffer");
10471059

@@ -1073,7 +1085,7 @@ PLy_procedure_create(FunctionCallInfo fcinfo, bool is_trigger,
10731085
* get information required for output conversion of the return value,
10741086
* but only if this isn't a trigger.
10751087
*/
1076-
if (!is_trigger)
1088+
if (!CALLED_AS_TRIGGER(fcinfo))
10771089
{
10781090
HeapTuplervTypeTup;
10791091
Form_pg_typervTypeStruct;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp