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

Commitbaecbb9

Browse files
committed
Fix plpython's overoptimistic caching of information about the rowtype of
a trigger's target table. The rowtype could change from one call to thenext, so cope in such cases, while avoiding doing repetitive catalog lookups.Per bug #3847 from Mark Reid.Backpatch to 8.2.x. Likely this fix should go further back, but I can't testit because I no longer have a machine with a pre-2.5 Python installation.(Maybe we should rethink that idea about not supporting Python 2.5 in theolder branches.)
1 parent14b5eaa commitbaecbb9

File tree

1 file changed

+63
-30
lines changed

1 file changed

+63
-30
lines changed

‎src/pl/plpython/plpython.c

Lines changed: 63 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**********************************************************************
22
* plpython.c - python as a procedural language for PostgreSQL
33
*
4-
*$PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.105 2007/11/23 01:46:34 alvherre Exp $
4+
*$PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.106 2008/01/02 03:10:27 tgl Exp $
55
*
66
*********************************************************************
77
*/
@@ -79,7 +79,8 @@ typedef PyObject *(*PLyDatumToObFunc) (const char *);
7979
typedefstructPLyDatumToOb
8080
{
8181
PLyDatumToObFuncfunc;
82-
FmgrInfotypfunc;
82+
FmgrInfotypfunc;/* The type's output function */
83+
Oidtypoid;/* The OID of the type */
8384
Oidtypioparam;
8485
booltypbyval;
8586
}PLyDatumToOb;
@@ -212,6 +213,7 @@ static void PLy_elog(int, const char *,...);
212213
staticchar*PLy_traceback(int*);
213214

214215
staticvoid*PLy_malloc(size_t);
216+
staticvoid*PLy_malloc0(size_t);
215217
staticchar*PLy_strdup(constchar*);
216218
staticvoidPLy_free(void*);
217219

@@ -231,9 +233,8 @@ static PyObject *PLy_procedure_call(PLyProcedure *, char *, PyObject *);
231233
staticPLyProcedure*PLy_procedure_get(FunctionCallInfofcinfo,
232234
Oidtgreloid);
233235

234-
staticPLyProcedure*PLy_procedure_create(FunctionCallInfofcinfo,
235-
Oidtgreloid,
236-
HeapTupleprocTup,char*key);
236+
staticPLyProcedure*PLy_procedure_create(HeapTupleprocTup,Oidtgreloid,
237+
char*key);
237238

238239
staticvoidPLy_procedure_compile(PLyProcedure*,constchar*);
239240
staticchar*PLy_procedure_munge_source(constchar*,constchar*);
@@ -1123,16 +1124,32 @@ PLy_procedure_get(FunctionCallInfo fcinfo, Oid tgreloid)
11231124
}
11241125

11251126
if (proc==NULL)
1126-
proc=PLy_procedure_create(fcinfo,tgreloid,procTup,key);
1127+
proc=PLy_procedure_create(procTup,tgreloid,key);
1128+
1129+
if (OidIsValid(tgreloid))
1130+
{
1131+
/*
1132+
* Input/output conversion for trigger tuples.Use the result
1133+
* TypeInfo variable to store the tuple conversion info. We
1134+
* do this over again on each call to cover the possibility that
1135+
* the relation's tupdesc changed since the trigger was last called.
1136+
* PLy_input_tuple_funcs and PLy_output_tuple_funcs are responsible
1137+
* for not doing repetitive work.
1138+
*/
1139+
TriggerData*tdata= (TriggerData*)fcinfo->context;
1140+
1141+
Assert(CALLED_AS_TRIGGER(fcinfo));
1142+
PLy_input_tuple_funcs(&(proc->result),tdata->tg_relation->rd_att);
1143+
PLy_output_tuple_funcs(&(proc->result),tdata->tg_relation->rd_att);
1144+
}
11271145

11281146
ReleaseSysCache(procTup);
11291147

11301148
returnproc;
11311149
}
11321150

11331151
staticPLyProcedure*
1134-
PLy_procedure_create(FunctionCallInfofcinfo,Oidtgreloid,
1135-
HeapTupleprocTup,char*key)
1152+
PLy_procedure_create(HeapTupleprocTup,Oidtgreloid,char*key)
11361153
{
11371154
charprocName[NAMEDATALEN+256];
11381155
Form_pg_procprocStruct;
@@ -1152,13 +1169,13 @@ PLy_procedure_create(FunctionCallInfo fcinfo, Oid tgreloid,
11521169
rv=snprintf(procName,sizeof(procName),
11531170
"__plpython_procedure_%s_%u_trigger_%u",
11541171
NameStr(procStruct->proname),
1155-
fcinfo->flinfo->fn_oid,
1172+
HeapTupleGetOid(procTup),
11561173
tgreloid);
11571174
else
11581175
rv=snprintf(procName,sizeof(procName),
11591176
"__plpython_procedure_%s_%u",
11601177
NameStr(procStruct->proname),
1161-
fcinfo->flinfo->fn_oid);
1178+
HeapTupleGetOid(procTup));
11621179
if (rv >=sizeof(procName)||rv<0)
11631180
elog(ERROR,"procedure name would overrun buffer");
11641181

@@ -1186,7 +1203,7 @@ PLy_procedure_create(FunctionCallInfo fcinfo, Oid tgreloid,
11861203
* get information required for output conversion of the return value,
11871204
* but only if this isn't a trigger.
11881205
*/
1189-
if (!CALLED_AS_TRIGGER(fcinfo))
1206+
if (!OidIsValid(tgreloid))
11901207
{
11911208
HeapTuplervTypeTup;
11921209
Form_pg_typervTypeStruct;
@@ -1228,28 +1245,18 @@ PLy_procedure_create(FunctionCallInfo fcinfo, Oid tgreloid,
12281245

12291246
ReleaseSysCache(rvTypeTup);
12301247
}
1231-
else
1232-
{
1233-
/*
1234-
* input/output conversion for trigger tuples.use the result
1235-
* TypeInfo variable to store the tuple conversion info.
1236-
*/
1237-
TriggerData*tdata= (TriggerData*)fcinfo->context;
1238-
1239-
PLy_input_tuple_funcs(&(proc->result),tdata->tg_relation->rd_att);
1240-
PLy_output_tuple_funcs(&(proc->result),tdata->tg_relation->rd_att);
1241-
}
12421248

12431249
/*
12441250
* now get information required for input conversion of the
12451251
* procedure's arguments.
12461252
*/
1247-
proc->nargs=fcinfo->nargs;
1253+
proc->nargs=procStruct->pronargs;
12481254
if (proc->nargs)
12491255
{
12501256
argnames=SysCacheGetAttr(PROCOID,procTup,Anum_pg_proc_proargnames,&isnull);
12511257
if (!isnull)
12521258
{
1259+
/* XXX this code is WRONG if there are any output arguments */
12531260
deconstruct_array(DatumGetArrayTypeP(argnames),TEXTOID,-1, false,'i',
12541261
&elems,NULL,&nelems);
12551262
if (nelems!=proc->nargs)
@@ -1260,7 +1267,7 @@ PLy_procedure_create(FunctionCallInfo fcinfo, Oid tgreloid,
12601267
memset(proc->argnames,0,sizeof(char*)*proc->nargs);
12611268
}
12621269
}
1263-
for (i=0;i<fcinfo->nargs;i++)
1270+
for (i=0;i<proc->nargs;i++)
12641271
{
12651272
HeapTupleargTypeTup;
12661273
Form_pg_typeargTypeStruct;
@@ -1453,10 +1460,15 @@ PLy_input_tuple_funcs(PLyTypeInfo * arg, TupleDesc desc)
14531460

14541461
if (arg->is_rowtype==0)
14551462
elog(ERROR,"PLyTypeInfo struct is initialized for a Datum");
1456-
14571463
arg->is_rowtype=1;
1458-
arg->in.r.natts=desc->natts;
1459-
arg->in.r.atts=PLy_malloc(desc->natts*sizeof(PLyDatumToOb));
1464+
1465+
if (arg->in.r.natts!=desc->natts)
1466+
{
1467+
if (arg->in.r.atts)
1468+
PLy_free(arg->in.r.atts);
1469+
arg->in.r.natts=desc->natts;
1470+
arg->in.r.atts=PLy_malloc0(desc->natts*sizeof(PLyDatumToOb));
1471+
}
14601472

14611473
for (i=0;i<desc->natts;i++)
14621474
{
@@ -1465,6 +1477,9 @@ PLy_input_tuple_funcs(PLyTypeInfo * arg, TupleDesc desc)
14651477
if (desc->attrs[i]->attisdropped)
14661478
continue;
14671479

1480+
if (arg->in.r.atts[i].typoid==desc->attrs[i]->atttypid)
1481+
continue;/* already set up this entry */
1482+
14681483
typeTup=SearchSysCache(TYPEOID,
14691484
ObjectIdGetDatum(desc->attrs[i]->atttypid),
14701485
0,0,0);
@@ -1487,10 +1502,15 @@ PLy_output_tuple_funcs(PLyTypeInfo * arg, TupleDesc desc)
14871502

14881503
if (arg->is_rowtype==0)
14891504
elog(ERROR,"PLyTypeInfo struct is initialized for a Datum");
1490-
14911505
arg->is_rowtype=1;
1492-
arg->out.r.natts=desc->natts;
1493-
arg->out.r.atts=PLy_malloc(desc->natts*sizeof(PLyDatumToOb));
1506+
1507+
if (arg->out.r.natts!=desc->natts)
1508+
{
1509+
if (arg->out.r.atts)
1510+
PLy_free(arg->out.r.atts);
1511+
arg->out.r.natts=desc->natts;
1512+
arg->out.r.atts=PLy_malloc0(desc->natts*sizeof(PLyDatumToOb));
1513+
}
14941514

14951515
for (i=0;i<desc->natts;i++)
14961516
{
@@ -1499,6 +1519,9 @@ PLy_output_tuple_funcs(PLyTypeInfo * arg, TupleDesc desc)
14991519
if (desc->attrs[i]->attisdropped)
15001520
continue;
15011521

1522+
if (arg->out.r.atts[i].typoid==desc->attrs[i]->atttypid)
1523+
continue;/* already set up this entry */
1524+
15021525
typeTup=SearchSysCache(TYPEOID,
15031526
ObjectIdGetDatum(desc->attrs[i]->atttypid),
15041527
0,0,0);
@@ -1548,6 +1571,7 @@ PLy_input_datum_func2(PLyDatumToOb * arg, Oid typeOid, HeapTuple typeTup)
15481571

15491572
/* Get the type's conversion information */
15501573
perm_fmgr_info(typeStruct->typoutput,&arg->typfunc);
1574+
arg->typoid=HeapTupleGetOid(typeTup);
15511575
arg->typioparam=getTypeIOParam(typeTup);
15521576
arg->typbyval=typeStruct->typbyval;
15531577

@@ -3015,6 +3039,15 @@ PLy_malloc(size_t bytes)
30153039
returnptr;
30163040
}
30173041

3042+
staticvoid*
3043+
PLy_malloc0(size_tbytes)
3044+
{
3045+
void*ptr=PLy_malloc(bytes);
3046+
3047+
MemSet(ptr,0,bytes);
3048+
returnptr;
3049+
}
3050+
30183051
staticchar*
30193052
PLy_strdup(constchar*str)
30203053
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp