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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy