On Sun, Jul 12, 2009 at 10:28 AM, Pavel Stehule<[email protected]> 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 ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs