On Sun, Jul 12, 2009 at 10:28 AM, Pavel Stehule<pavel.steh...@gmail.com> wrote:
> Hello
>
> there is fix for bug Re: [BUGS] BUG #4907: stored procedures and changed 
> tables
>

this one applies, compiles and it actually fixes the bug...
it should be backpatched until 8.3... but applies cleanly only until
8.4 (what a surprise), attached is an adapted version for 8.3

the only thing that is bothered me is that the same solution is used
again and again... seems like we can use a function like
make_tuple_from_row (maybe something like make_tuple_from_datum or
eliminate_dropped_cols_from_tuple or something like that) for avoiding
duplicate code... but that's another patch, is worth the trouble?

-- 
Atentamente,
Jaime Casanova
Soporte y capacitación de PostgreSQL
Asesoría y desarrollo de sistemas
Guayaquil - Ecuador
Cel. +59387171157
Index: src/pl/plpgsql/src/pl_exec.c
===================================================================
RCS file: /home/postgres/pgrepo/pgsql/src/pl/plpgsql/src/pl_exec.c,v
retrieving revision 1.202.2.5
diff -c -r1.202.2.5 pl_exec.c
*** src/pl/plpgsql/src/pl_exec.c	2 Apr 2009 01:16:17 -0000	1.202.2.5
--- src/pl/plpgsql/src/pl_exec.c	20 Jul 2009 06:37:15 -0000
***************
*** 2156,2161 ****
--- 2156,2166 ----
  					   PLpgSQL_stmt_return_query *stmt)
  {
  	Portal		portal;
+  	int			i;
+  	bool		dropped_columns = false;
+  	Datum		*dvalues;
+  	bool		*nulls;
+  	int			natts;
  
  	if (!estate->retisset)
  		ereport(ERROR,
***************
*** 2172,2177 ****
--- 2177,2191 ----
  				(errcode(ERRCODE_DATATYPE_MISMATCH),
  		  errmsg("structure of query does not match function result type")));
  
+  	natts = estate->rettupdesc->natts;
+  	
+  	if (natts > portal->tupDesc->natts)
+  	{
+  		dropped_columns = true;
+  		dvalues = (Datum *) palloc0(natts * sizeof(Datum));
+  		nulls = (bool *) palloc(natts * sizeof(bool));
+ 	}
+ 
  	while (true)
  	{
  		MemoryContext old_cxt;
***************
*** 2186,2197 ****
  		{
  			HeapTuple	tuple = SPI_tuptable->vals[i];
  
! 			tuplestore_puttuple(estate->tuple_store, tuple);
  		}
  		MemoryContextSwitchTo(old_cxt);
  
  		SPI_freetuptable(SPI_tuptable);
  	}
  
  	SPI_freetuptable(SPI_tuptable);
  	SPI_cursor_close(portal);
--- 2200,2238 ----
  		{
  			HeapTuple	tuple = SPI_tuptable->vals[i];
  
!  			if (!dropped_columns)
! 				tuplestore_puttuple(estate->tuple_store, tuple);
! 			else
!  			{
!  				int		anum;
!  				int		j = 0;
!  				bool	isnull;
!  
!  				for (anum = 0; anum < natts; anum++)
!  				{
!  					if (estate->rettupdesc->attrs[anum]->attisdropped)
!  						nulls[anum] = true;
!  					else
!  					{
!  						dvalues[anum] = SPI_getbinval(tuple, portal->tupDesc,
!  										    ++j, &isnull);
!  						nulls[anum] = isnull;
!  					}
!  				}
!  				tuple = heap_form_tuple(estate->rettupdesc, dvalues, nulls);
!  				tuplestore_puttuple(estate->tuple_store, tuple);
!  			}
  		}
  		MemoryContextSwitchTo(old_cxt);
  
  		SPI_freetuptable(SPI_tuptable);
  	}
+  	
+  	if (dropped_columns)
+  	{
+  		pfree(dvalues);
+  		pfree(nulls);
+  	}
  
  	SPI_freetuptable(SPI_tuptable);
  	SPI_cursor_close(portal);
***************
*** 4910,4923 ****
  compatible_tupdesc(TupleDesc td1, TupleDesc td2)
  {
  	int			i;
! 
! 	if (td1->natts != td2->natts)
! 		return false;
  
  	for (i = 0; i < td1->natts; i++)
  	{
! 		if (td1->attrs[i]->atttypid != td2->attrs[i]->atttypid)
! 			return false;
  	}
  
  	return true;
--- 4951,4963 ----
  compatible_tupdesc(TupleDesc td1, TupleDesc td2)
  {
  	int			i;
!  	int			j = 0;
  
  	for (i = 0; i < td1->natts; i++)
  	{
!  		if (!td1->attrs[i]->attisdropped)
! 			if (td1->attrs[i]->atttypid != td2->attrs[j++]->atttypid)
! 				return false;
  	}
  
  	return true;
-- 
Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs

Reply via email to