@@ -896,31 +896,30 @@ static HeapTuple
896896PLy_modify_tuple (PLyProcedure * proc ,PyObject * pltd ,TriggerData * tdata ,
897897HeapTuple otup )
898898{
899+ HeapTuple rtup ;
899900PyObject * volatile plntup ;
900901PyObject * volatile plkeys ;
901902PyObject * volatile plval ;
902- HeapTuple rtup ;
903- int natts ,
904- i ,
905- attn ,
906- atti ;
907- int * volatile modattrs ;
908903Datum * volatile modvalues ;
909- char * volatile modnulls ;
910- TupleDesc tupdesc ;
904+ bool * volatile modnulls ;
905+ bool * volatile modrepls ;
911906ErrorContextCallback plerrcontext ;
912907
913908plerrcontext .callback = plpython_trigger_error_callback ;
914909plerrcontext .previous = error_context_stack ;
915910error_context_stack = & plerrcontext ;
916911
917912plntup = plkeys = plval = NULL ;
918- modattrs = NULL ;
919913modvalues = NULL ;
920914modnulls = NULL ;
915+ modrepls = NULL ;
921916
922917PG_TRY ();
923918{
919+ TupleDesc tupdesc ;
920+ int nkeys ,
921+ i ;
922+
924923if ((plntup = PyDict_GetItemString (pltd ,"new" ))== NULL )
925924ereport (ERROR ,
926925(errcode (ERRCODE_UNDEFINED_OBJECT ),
@@ -932,18 +931,20 @@ PLy_modify_tuple(PLyProcedure *proc, PyObject *pltd, TriggerData *tdata,
932931errmsg ("TD[\"new\"] is not a dictionary" )));
933932
934933plkeys = PyDict_Keys (plntup );
935- natts = PyList_Size (plkeys );
936-
937- modattrs = (int * )palloc (natts * sizeof (int ));
938- modvalues = (Datum * )palloc (natts * sizeof (Datum ));
939- modnulls = (char * )palloc (natts * sizeof (char ));
934+ nkeys = PyList_Size (plkeys );
940935
941936tupdesc = tdata -> tg_relation -> rd_att ;
942937
943- for (i = 0 ;i < natts ;i ++ )
938+ modvalues = (Datum * )palloc0 (tupdesc -> natts * sizeof (Datum ));
939+ modnulls = (bool * )palloc0 (tupdesc -> natts * sizeof (bool ));
940+ modrepls = (bool * )palloc0 (tupdesc -> natts * sizeof (bool ));
941+
942+ for (i = 0 ;i < nkeys ;i ++ )
944943{
945944PyObject * platt ;
946945char * plattstr ;
946+ int attn ;
947+ PLyObToDatum * att ;
947948
948949platt = PyList_GetItem (plkeys ,i );
949950if (PyString_Check (platt ))
@@ -963,62 +964,57 @@ PLy_modify_tuple(PLyProcedure *proc, PyObject *pltd, TriggerData *tdata,
963964(errcode (ERRCODE_UNDEFINED_COLUMN ),
964965errmsg ("key \"%s\" found in TD[\"new\"] does not exist as a column in the triggering row" ,
965966plattstr )));
966- atti = attn - 1 ;
967+ if (attn <=0 )
968+ ereport (ERROR ,
969+ (errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
970+ errmsg ("cannot set system attribute \"%s\"" ,
971+ plattstr )));
972+ att = & proc -> result .out .r .atts [attn - 1 ];
967973
968974plval = PyDict_GetItem (plntup ,platt );
969975if (plval == NULL )
970976elog (FATAL ,"Python interpreter is probably corrupted" );
971977
972978Py_INCREF (plval );
973979
974- modattrs [i ]= attn ;
975-
976- if (tupdesc -> attrs [atti ]-> attisdropped )
977- {
978- modvalues [i ]= (Datum )0 ;
979- modnulls [i ]= 'n' ;
980- }
981- else if (plval != Py_None )
980+ if (plval != Py_None )
982981{
983- PLyObToDatum * att = & proc -> result .out .r .atts [atti ];
984-
985- modvalues [i ]= (att -> func ) (att ,
986- tupdesc -> attrs [atti ]-> atttypmod ,
987- plval ,
988- false);
989- modnulls [i ]= ' ' ;
982+ modvalues [attn - 1 ]=
983+ (att -> func ) (att ,
984+ tupdesc -> attrs [attn - 1 ]-> atttypmod ,
985+ plval ,
986+ false);
987+ modnulls [attn - 1 ]= false;
990988}
991989else
992990{
993- modvalues [i ]=
994- InputFunctionCall (& proc -> result . out . r . atts [ atti ]. typfunc ,
991+ modvalues [attn - 1 ]=
992+ InputFunctionCall (& att -> typfunc ,
995993NULL ,
996- proc -> result . out . r . atts [ atti ]. typioparam ,
997- tupdesc -> attrs [atti ]-> atttypmod );
998- modnulls [i ]= 'n' ;
994+ att -> typioparam ,
995+ tupdesc -> attrs [attn - 1 ]-> atttypmod );
996+ modnulls [attn - 1 ]= true ;
999997}
998+ modrepls [attn - 1 ]= true;
1000999
10011000Py_DECREF (plval );
10021001plval = NULL ;
10031002}
10041003
1005- rtup = SPI_modifytuple (tdata -> tg_relation ,otup ,natts ,
1006- modattrs ,modvalues ,modnulls );
1007- if (rtup == NULL )
1008- elog (ERROR ,"SPI_modifytuple failed: error %d" ,SPI_result );
1004+ rtup = heap_modify_tuple (otup ,tupdesc ,modvalues ,modnulls ,modrepls );
10091005}
10101006PG_CATCH ();
10111007{
10121008Py_XDECREF (plntup );
10131009Py_XDECREF (plkeys );
10141010Py_XDECREF (plval );
10151011
1016- if (modnulls )
1017- pfree (modnulls );
10181012if (modvalues )
10191013pfree (modvalues );
1020- if (modattrs )
1021- pfree (modattrs );
1014+ if (modnulls )
1015+ pfree (modnulls );
1016+ if (modrepls )
1017+ pfree (modrepls );
10221018
10231019PG_RE_THROW ();
10241020}
@@ -1027,9 +1023,9 @@ PLy_modify_tuple(PLyProcedure *proc, PyObject *pltd, TriggerData *tdata,
10271023Py_DECREF (plntup );
10281024Py_DECREF (plkeys );
10291025
1030- pfree (modattrs );
10311026pfree (modvalues );
10321027pfree (modnulls );
1028+ pfree (modrepls );
10331029
10341030error_context_stack = plerrcontext .previous ;
10351031