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