Skip to content

Commit b8f8896

Browse files
committed
Fix some problems with dropped columns in plpython trigger functions.
1 parent 8723e37 commit b8f8896

File tree

1 file changed

+32
-26
lines changed

1 file changed

+32
-26
lines changed

src/pl/plpython/plpython.c

Lines changed: 32 additions & 26 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.40 2003/09/14 17:13:06 tgl Exp $
32+
* $Header: /cvsroot/pgsql/src/pl/plpython/plpython.c,v 1.41 2003/09/16 01:07:51 tgl Exp $
3333
*
3434
*********************************************************************
3535
*/
@@ -486,7 +486,6 @@ PLy_modify_tuple(PLyProcedure * proc, PyObject * pltd, TriggerData *tdata,
486486
HeapTuple rtup;
487487
int natts,
488488
i,
489-
j,
490489
attn,
491490
atti;
492491
int *volatile modattrs;
@@ -531,31 +530,21 @@ PLy_modify_tuple(PLyProcedure * proc, PyObject * pltd, TriggerData *tdata,
531530
plkeys = PyDict_Keys(plntup);
532531
natts = PyList_Size(plkeys);
533532

534-
if (natts != proc->result.out.r.natts)
535-
elog(ERROR, "TD[\"new\"] has an incorrect number of keys");
536-
537-
modattrs = palloc(natts * sizeof(int));
538-
modvalues = palloc(natts * sizeof(Datum));
539-
for (i = 0; i < natts; i++)
540-
{
541-
modattrs[i] = i + 1;
542-
modvalues[i] = (Datum) NULL;
543-
}
533+
/* +1 to avoid palloc(0) on empty tuple */
534+
modattrs = palloc(natts * sizeof(int) + 1);
535+
modvalues = palloc(natts * sizeof(Datum) + 1);
544536
modnulls = palloc(natts + 1);
545-
memset(modnulls, 'n', natts);
546-
modnulls[natts] = '\0';
547537

548538
tupdesc = tdata->tg_relation->rd_att;
549539

550-
for (j = 0; j < natts; j++)
540+
for (i = 0; i < natts; i++)
551541
{
552542
char *src;
553543

554-
platt = PyList_GetItem(plkeys, j);
544+
platt = PyList_GetItem(plkeys, i);
555545
if (!PyString_Check(platt))
556-
elog(ERROR, "attribute is not a string");
557-
attn = modattrs[j] = SPI_fnumber(tupdesc, PyString_AsString(platt));
558-
546+
elog(ERROR, "attribute name is not a string");
547+
attn = SPI_fnumber(tupdesc, PyString_AsString(platt));
559548
if (attn == SPI_ERROR_NOATTRIBUTE)
560549
elog(ERROR, "invalid attribute \"%s\" in tuple",
561550
PyString_AsString(platt));
@@ -567,30 +556,38 @@ PLy_modify_tuple(PLyProcedure * proc, PyObject * pltd, TriggerData *tdata,
567556

568557
Py_INCREF(plval);
569558

570-
if (plval != Py_None)
559+
modattrs[i] = attn;
560+
561+
if (plval != Py_None && !tupdesc->attrs[atti]->attisdropped)
571562
{
572563
plstr = PyObject_Str(plval);
573564
src = PyString_AsString(plstr);
574565

575-
modvalues[j] = FunctionCall3(&proc->result.out.r.atts[atti].typfunc,
566+
modvalues[i] = FunctionCall3(&proc->result.out.r.atts[atti].typfunc,
576567
CStringGetDatum(src),
577568
ObjectIdGetDatum(proc->result.out.r.atts[atti].typelem),
578569
Int32GetDatum(tupdesc->attrs[atti]->atttypmod));
579-
modnulls[j] = ' ';
570+
modnulls[i] = ' ';
580571

581572
Py_DECREF(plstr);
582573
plstr = NULL;
583574
}
575+
else
576+
{
577+
modvalues[i] = (Datum) 0;
578+
modnulls[i] = 'n';
579+
}
580+
584581
Py_DECREF(plval);
585582
plval = NULL;
586-
587583
}
588-
rtup = SPI_modifytuple(tdata->tg_relation, otup, natts, modattrs,
589-
modvalues, modnulls);
584+
585+
rtup = SPI_modifytuple(tdata->tg_relation, otup, natts,
586+
modattrs, modvalues, modnulls);
590587

591588
/*
592589
* FIXME -- these leak if not explicitly pfree'd by other elog calls,
593-
* no?
590+
* no? (No, I think, but might as well leave the pfrees here...)
594591
*/
595592
pfree(modattrs);
596593
pfree(modvalues);
@@ -1311,6 +1308,9 @@ PLy_input_tuple_funcs(PLyTypeInfo * arg, TupleDesc desc)
13111308
HeapTuple typeTup;
13121309
Form_pg_type typeStruct;
13131310

1311+
if (desc->attrs[i]->attisdropped)
1312+
continue;
1313+
13141314
typeTup = SearchSysCache(TYPEOID,
13151315
ObjectIdGetDatum(desc->attrs[i]->atttypid),
13161316
0, 0, 0);
@@ -1346,6 +1346,9 @@ PLy_output_tuple_funcs(PLyTypeInfo * arg, TupleDesc desc)
13461346
HeapTuple typeTup;
13471347
Form_pg_type typeStruct;
13481348

1349+
if (desc->attrs[i]->attisdropped)
1350+
continue;
1351+
13491352
typeTup = SearchSysCache(TYPEOID,
13501353
ObjectIdGetDatum(desc->attrs[i]->atttypid),
13511354
0, 0, 0);
@@ -1533,6 +1536,9 @@ PLyDict_FromTuple(PLyTypeInfo * info, HeapTuple tuple, TupleDesc desc)
15331536
bool is_null;
15341537
PyObject *value;
15351538

1539+
if (desc->attrs[i]->attisdropped)
1540+
continue;
1541+
15361542
key = NameStr(desc->attrs[i]->attname);
15371543
vattr = heap_getattr(tuple, (i + 1), desc, &is_null);
15381544

0 commit comments

Comments
 (0)