Обсуждение: Cannot assign ROWTYPE, RECORD variables in PL/pgSQL

Поиск
Список
Период
Сортировка

Cannot assign ROWTYPE, RECORD variables in PL/pgSQL

От
Josh Berkus
Дата:
Bug: Cannot assign ROWTYPE, RECORD variables in PL/pgSQL
Affects: PL/pgSQL
Severity:  Annoyance
Priority:  Minor Enhancement
Confirmed On: 7.3beta2, Linux

Given the following function:
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
create or replace function rowtype_test ()
returns text as '
declare this_row candidates%rowtype;
    that_row candidates%rowtype;
begin
select * into this_row
from candidates;

that_row :=3D this_row;

return that_row.first_name;

end;'
language 'plpgsql';
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D

... it will error out at the assignment "that_row :=3D this_row".

For that matter, any attempt to assign the contents of two ROWTYPE or RECOR=
D=20
variables directly to each other will error out:

that_record :=3D this_record;

SELECT this_row INTO that_row;

SELECT * INTO that_row
FROM this_row;

The only way to populate that_row with a copy of this_row is by re-querying=
=20
the source table.   While a relatively easy workaround, this behaviour is=
=20
annoying and inconsistent.  It would be nice to fix in 7.3.1 or 7.4.

Thanks for your attention.

--=20
-Josh Berkus
 Aglio Database Solutions
 San Francisco

Re: Cannot assign ROWTYPE, RECORD variables in PL/pgSQL

От
Neil Conway
Дата:
Josh Berkus <josh@agliodbs.com> writes:
> create or replace function rowtype_test ()
> returns text as '
> declare this_row candidates%rowtype;
>     that_row candidates%rowtype;
> begin
> select * into this_row
> from candidates;
>
> that_row := this_row;
>
> return that_row.first_name;
>
> end;'
> language 'plpgsql';
> =======================================
>
> ... it will error out at the assignment "that_row := this_row".

So we'd want a deep copy, right?

> The only way to populate that_row with a copy of this_row is by re-querying
> the source table.

Well, you can also iterate through the fields of this_row and assign
them to that_row manually -- of course, that's not much better.

> While a relatively easy workaround, this behaviour is annoying and
> inconsistent.  It would be nice to fix in 7.3.1 or 7.4.

Unless anyone sees a problem with this, I'll work on this. I
definately think it's inappropriate for 7.3.1 though.

Cheers,

Neil

--
Neil Conway <neilc@samurai.com> || PGP Key ID: DB3C29FC

Re: Cannot assign ROWTYPE, RECORD variables in PL/pgSQL

От
"Josh Berkus"
Дата:
Neil,

> Unless anyone sees a problem with this, I'll work on this. I
> definately think it's inappropriate for 7.3.1 though.

Thank you!

-Josh Berkus

Re: Cannot assign ROWTYPE, RECORD variables in PL/pgSQL

От
elein
Дата:
Deep copy with User defined data types sometimes get a little=20
wild, possibly with alignment and memory context.  For example=20
a UDT which is a char followed by an int might be tricky to recognize
that alignment might be needed.  It might even be better to  have=20
the UDT writer write their own deep copy function if their type=20
is not compatible with a straight memcpy.

One of the other reasons this was a real PITB at informix was that=20
columns could also contain row (composite) types.  We do not=20
have that feature (yet?), but if deep copy is done in a type=20
blind way which is open to adding recursion we would not shut=20
the door on the possibility.  Tables have rows which have columns
containing rows which have columns containing udts and rows....

However, I suspect that postgresql row handling is a lot cleaner than
the informix row handling (with or without rows as columns) and it=20
has been a while since I looked at the problem so maybe it is a=20
non-issue.  But I'm raising it just in case...

elein


On Thursday 07 November 2002 13:56, Neil Conway wrote:
> Josh Berkus <josh@agliodbs.com> writes:
> > create or replace function rowtype_test ()
> > returns text as '
> > declare this_row candidates%rowtype;
> >     that_row candidates%rowtype;
> > begin
> > select * into this_row
> > from candidates;
> >
> > that_row :=3D this_row;
> >
> > return that_row.first_name;
> >
> > end;'
> > language 'plpgsql';
> > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> >
> > ... it will error out at the assignment "that_row :=3D this_row".
>
> So we'd want a deep copy, right?
>
> > The only way to populate that_row with a copy of this_row is by
> > re-querying the source table.
>
> Well, you can also iterate through the fields of this_row and assign
> them to that_row manually -- of course, that's not much better.
>
> > While a relatively easy workaround, this behaviour is annoying and
> > inconsistent.  It would be nice to fix in 7.3.1 or 7.4.
>
> Unless anyone sees a problem with this, I'll work on this. I
> definately think it's inappropriate for 7.3.1 though.
>
> Cheers,
>
> Neil