29
29
* MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
30
30
*
31
31
* 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 $
33
33
*
34
34
*********************************************************************
35
35
*/
@@ -486,7 +486,6 @@ PLy_modify_tuple(PLyProcedure * proc, PyObject * pltd, TriggerData *tdata,
486
486
HeapTuple rtup ;
487
487
int natts ,
488
488
i ,
489
- j ,
490
489
attn ,
491
490
atti ;
492
491
int * volatile modattrs ;
@@ -531,31 +530,21 @@ PLy_modify_tuple(PLyProcedure * proc, PyObject * pltd, TriggerData *tdata,
531
530
plkeys = PyDict_Keys (plntup );
532
531
natts = PyList_Size (plkeys );
533
532
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 );
544
536
modnulls = palloc (natts + 1 );
545
- memset (modnulls , 'n' , natts );
546
- modnulls [natts ] = '\0' ;
547
537
548
538
tupdesc = tdata -> tg_relation -> rd_att ;
549
539
550
- for (j = 0 ; j < natts ; j ++ )
540
+ for (i = 0 ; i < natts ; i ++ )
551
541
{
552
542
char * src ;
553
543
554
- platt = PyList_GetItem (plkeys , j );
544
+ platt = PyList_GetItem (plkeys , i );
555
545
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 ));
559
548
if (attn == SPI_ERROR_NOATTRIBUTE )
560
549
elog (ERROR , "invalid attribute \"%s\" in tuple" ,
561
550
PyString_AsString (platt ));
@@ -567,30 +556,38 @@ PLy_modify_tuple(PLyProcedure * proc, PyObject * pltd, TriggerData *tdata,
567
556
568
557
Py_INCREF (plval );
569
558
570
- if (plval != Py_None )
559
+ modattrs [i ] = attn ;
560
+
561
+ if (plval != Py_None && !tupdesc -> attrs [atti ]-> attisdropped )
571
562
{
572
563
plstr = PyObject_Str (plval );
573
564
src = PyString_AsString (plstr );
574
565
575
- modvalues [j ] = FunctionCall3 (& proc -> result .out .r .atts [atti ].typfunc ,
566
+ modvalues [i ] = FunctionCall3 (& proc -> result .out .r .atts [atti ].typfunc ,
576
567
CStringGetDatum (src ),
577
568
ObjectIdGetDatum (proc -> result .out .r .atts [atti ].typelem ),
578
569
Int32GetDatum (tupdesc -> attrs [atti ]-> atttypmod ));
579
- modnulls [j ] = ' ' ;
570
+ modnulls [i ] = ' ' ;
580
571
581
572
Py_DECREF (plstr );
582
573
plstr = NULL ;
583
574
}
575
+ else
576
+ {
577
+ modvalues [i ] = (Datum ) 0 ;
578
+ modnulls [i ] = 'n' ;
579
+ }
580
+
584
581
Py_DECREF (plval );
585
582
plval = NULL ;
586
-
587
583
}
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 );
590
587
591
588
/*
592
589
* 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...)
594
591
*/
595
592
pfree (modattrs );
596
593
pfree (modvalues );
@@ -1311,6 +1308,9 @@ PLy_input_tuple_funcs(PLyTypeInfo * arg, TupleDesc desc)
1311
1308
HeapTuple typeTup ;
1312
1309
Form_pg_type typeStruct ;
1313
1310
1311
+ if (desc -> attrs [i ]-> attisdropped )
1312
+ continue ;
1313
+
1314
1314
typeTup = SearchSysCache (TYPEOID ,
1315
1315
ObjectIdGetDatum (desc -> attrs [i ]-> atttypid ),
1316
1316
0 , 0 , 0 );
@@ -1346,6 +1346,9 @@ PLy_output_tuple_funcs(PLyTypeInfo * arg, TupleDesc desc)
1346
1346
HeapTuple typeTup ;
1347
1347
Form_pg_type typeStruct ;
1348
1348
1349
+ if (desc -> attrs [i ]-> attisdropped )
1350
+ continue ;
1351
+
1349
1352
typeTup = SearchSysCache (TYPEOID ,
1350
1353
ObjectIdGetDatum (desc -> attrs [i ]-> atttypid ),
1351
1354
0 , 0 , 0 );
@@ -1533,6 +1536,9 @@ PLyDict_FromTuple(PLyTypeInfo * info, HeapTuple tuple, TupleDesc desc)
1533
1536
bool is_null ;
1534
1537
PyObject * value ;
1535
1538
1539
+ if (desc -> attrs [i ]-> attisdropped )
1540
+ continue ;
1541
+
1536
1542
key = NameStr (desc -> attrs [i ]-> attname );
1537
1543
vattr = heap_getattr (tuple , (i + 1 ), desc , & is_null );
1538
1544
0 commit comments