Dyamic updates of NEW with pl/pgsql

Started by strkabout 16 years ago41 messageshackers
Jump to latest
#1strk
strk@keybit.net

How can a pl/pgsql trigger change the
values of dynamic fields in NEW record ?

By "dynamic" I mean that the field name
is a variable in the trigger context.

I've been told it's easy to do with pl/perl but
I'd like to delive a pl/pgsql solution to have
less dependencies.

Thanks in advance.

--strk;

() Free GIS & Flash consultant/developer
/\ http://strk.keybit.net/services.html

#2Pavel Stehule
pavel.stehule@gmail.com
In reply to: strk (#1)
Re: Dyamic updates of NEW with pl/pgsql

2010/3/9 strk <strk@keybit.net>:

How can a pl/pgsql trigger change the
values of dynamic fields in NEW record ?

By "dynamic" I mean that the field name
is a variable in the trigger context.

I've been told it's easy to do with pl/perl but
I'd like to delive a pl/pgsql solution to have
less dependencies.

It isn't possible yet

regards
Pavel Stehule

Show quoted text

Thanks in advance.

--strk;

 ()   Free GIS & Flash consultant/developer
 /\   http://strk.keybit.net/services.html

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#3strk
strk@keybit.net
In reply to: Pavel Stehule (#2)
Re: Dyamic updates of NEW with pl/pgsql

On Tue, Mar 09, 2010 at 06:59:31PM +0100, Pavel Stehule wrote:

2010/3/9 strk <strk@keybit.net>:

How can a pl/pgsql trigger change the
values of dynamic fields in NEW record ?

By "dynamic" I mean that the field name
is a variable in the trigger context.

I've been told it's easy to do with pl/perl but
I'd like to delive a pl/pgsql solution to have
less dependencies.

It isn't possible yet

Any workaround you may suggest ?

--strk;

() Free GIS & Flash consultant/developer
/\ http://strk.keybit.net/services.html

#4Pavel Stehule
pavel.stehule@gmail.com
In reply to: strk (#3)
Re: Dyamic updates of NEW with pl/pgsql

2010/3/9 strk <strk@keybit.net>:

On Tue, Mar 09, 2010 at 06:59:31PM +0100, Pavel Stehule wrote:

2010/3/9 strk <strk@keybit.net>:

How can a pl/pgsql trigger change the
values of dynamic fields in NEW record ?

By "dynamic" I mean that the field name
is a variable in the trigger context.

I've been told it's easy to do with pl/perl but
I'd like to delive a pl/pgsql solution to have
less dependencies.

It isn't possible yet

Any workaround you may suggest ?

I don't know it - use C language maybe.

Pavel

Show quoted text

--strk;

 ()   Free GIS & Flash consultant/developer
 /\   http://strk.keybit.net/services.html

In reply to: Pavel Stehule (#2)
Re: Dyamic updates of NEW with pl/pgsql

On Tue, Mar 09, 2010 at 06:59:31PM +0100, Pavel Stehule wrote:

2010/3/9 strk <strk@keybit.net>:

How can a pl/pgsql trigger change the
values of dynamic fields in NEW record ?

By "dynamic" I mean that the field name
is a variable in the trigger context.

I've been told it's easy to do with pl/perl but
I'd like to delive a pl/pgsql solution to have
less dependencies.

It isn't possible yet

well, it's possible. it's just not nice.

http://www.depesz.com/index.php/2010/03/10/dynamic-updates-of-fields-in-new-in-plpgsql/

depesz

--
Linkedin: http://www.linkedin.com/in/depesz / blog: http://www.depesz.com/
jid/gtalk: depesz@depesz.com / aim:depeszhdl / skype:depesz_hdl / gg:6749007

#6Andrew Dunstan
andrew@dunslane.net
In reply to: hubert depesz lubaczewski (#5)
Re: Dyamic updates of NEW with pl/pgsql

hubert depesz lubaczewski wrote:

On Tue, Mar 09, 2010 at 06:59:31PM +0100, Pavel Stehule wrote:

2010/3/9 strk <strk@keybit.net>:

How can a pl/pgsql trigger change the
values of dynamic fields in NEW record ?

By "dynamic" I mean that the field name
is a variable in the trigger context.

I've been told it's easy to do with pl/perl but
I'd like to delive a pl/pgsql solution to have
less dependencies.

It isn't possible yet

well, it's possible. it's just not nice.

http://www.depesz.com/index.php/2010/03/10/dynamic-updates-of-fields-in-new-in-plpgsql/

Using an hstore in 9.0 it's not too bad, Try something like:

CREATE OR REPLACE FUNCTION dyntrig()
RETURNS trigger
LANGUAGE plpgsql
AS $function$

declare
hst hstore;
begin
hst := hstore(NEW);
hst := hst || ('foo' => 'bar');
NEW := populate_record(NEW,hst);
return NEW;
end;

$function$;

But this question probably belongs on -general rather than -hackers.

cheers

andrew

#7Dmitry Fefelov
fozzy@ac-sw.com
In reply to: strk (#1)
Re: Dyamic updates of NEW with pl/pgsql

How can a pl/pgsql trigger change the
values of dynamic fields in NEW record ?

By "dynamic" I mean that the field name
is a variable in the trigger context.

It's not possible in plpgsql, but you can write plperl function, and later use
it in plpgsql triggers.

Regards,
Dmitry

#8strk
strk@keybit.net
In reply to: Andrew Dunstan (#6)
Re: Dyamic updates of NEW with pl/pgsql

On Wed, Mar 10, 2010 at 07:50:16AM -0500, Andrew Dunstan wrote:

Using an hstore in 9.0 it's not too bad,

Does it still have a limit of 65535 bytes per field ?

--strk;

() Free GIS & Flash consultant/developer
/\ http://strk.keybit.net/services.html

#9David Fetter
david@fetter.org
In reply to: strk (#8)
Re: Dyamic updates of NEW with pl/pgsql

On Thu, Mar 11, 2010 at 03:27:23PM +0100, strk wrote:

On Wed, Mar 10, 2010 at 07:50:16AM -0500, Andrew Dunstan wrote:

Using an hstore in 9.0 it's not too bad,

Does it still have a limit of 65535 bytes per field ?

No. :)

Cheers,
David.
--
David Fetter <david@fetter.org> http://fetter.org/
Phone: +1 415 235 3778 AIM: dfetter666 Yahoo!: dfetter
Skype: davidfetter XMPP: david.fetter@gmail.com
iCal: webcal://www.tripit.com/feed/ical/people/david74/tripit.ics

Remember to vote!
Consider donating to Postgres: http://www.postgresql.org/about/donate

#10Merlin Moncure
mmoncure@gmail.com
In reply to: Andrew Dunstan (#6)
Re: Dyamic updates of NEW with pl/pgsql

On Wed, Mar 10, 2010 at 7:50 AM, Andrew Dunstan <andrew@dunslane.net> wrote:

2010/3/9 strk <strk@keybit.net>:

How can a pl/pgsql trigger change the
values of dynamic fields in NEW record ?

By "dynamic" I mean that the field name
is a variable in the trigger context.

I've been told it's easy to do with pl/perl but
I'd like to delive a pl/pgsql solution to have
less dependencies.

Using an hstore in 9.0 it's not too bad, Try something like:

Agree 100%. The new hstore going to completely nail a broad class of
issues that have historically been awkward in plpgsql functions.
(small aside: the other biggie would be able to push a composite type
in to an update statement...something like 'update foo set foo =
new'). This is really great...some variant of this question is
continually asked it seems.

merlin

#11Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Merlin Moncure (#10)
Re: Dyamic updates of NEW with pl/pgsql

Merlin Moncure escribi�:

(small aside: the other biggie would be able to push a composite type
in to an update statement...something like 'update foo set foo =
new'). This is really great...some variant of this question is
continually asked it seems.

Can't you already do that with EXECUTE ... USING NEW? hmm, ah, but you
have to specify the columns in NEW, so it doesn't really work for you,
does it?

--
Alvaro Herrera http://www.CommandPrompt.com/
The PostgreSQL Company - Command Prompt, Inc.

#12Merlin Moncure
mmoncure@gmail.com
In reply to: Alvaro Herrera (#11)
Re: Dyamic updates of NEW with pl/pgsql

On Thu, Mar 11, 2010 at 11:24 PM, Alvaro Herrera
<alvherre@commandprompt.com> wrote:

Merlin Moncure escribió:

(small aside: the other biggie would be able to push a composite type
in to an update statement...something like 'update foo set foo =
new').  This is really great...some variant of this question is
continually asked it seems.

Can't you already do that with EXECUTE ... USING NEW?  hmm, ah, but you
have to specify the columns in NEW, so it doesn't really work for you,
does it?

right...with inserts you can expand the composite type without listing
the columns. updates can't do it because of syntax issues, even if
you go dynamic.

merlin

#13David Fetter
david@fetter.org
In reply to: Andrew Dunstan (#6)
Re: Dyamic updates of NEW with pl/pgsql

On Wed, Mar 10, 2010 at 07:50:16AM -0500, Andrew Dunstan wrote:

hubert depesz lubaczewski wrote:

On Tue, Mar 09, 2010 at 06:59:31PM +0100, Pavel Stehule wrote:

2010/3/9 strk <strk@keybit.net>:

How can a pl/pgsql trigger change the
values of dynamic fields in NEW record ?

By "dynamic" I mean that the field name
is a variable in the trigger context.

I've been told it's easy to do with pl/perl but
I'd like to delive a pl/pgsql solution to have
less dependencies.

It isn't possible yet

well, it's possible. it's just not nice.

http://www.depesz.com/index.php/2010/03/10/dynamic-updates-of-fields-in-new-in-plpgsql/

Using an hstore in 9.0 it's not too bad, Try something like:

CREATE OR REPLACE FUNCTION dyntrig()
RETURNS trigger
LANGUAGE plpgsql
AS $function$

declare
hst hstore;
begin
hst := hstore(NEW);
hst := hst || ('foo' => 'bar');
NEW := populate_record(NEW,hst);
return NEW;
end;

$function$;

But this question probably belongs on -general rather than -hackers.

This is, by the way, an excellent argument for including hstore in
core in 9.1. :)

Cheers,
David.
--
David Fetter <david@fetter.org> http://fetter.org/
Phone: +1 415 235 3778 AIM: dfetter666 Yahoo!: dfetter
Skype: davidfetter XMPP: david.fetter@gmail.com
iCal: webcal://www.tripit.com/feed/ical/people/david74/tripit.ics

Remember to vote!
Consider donating to Postgres: http://www.postgresql.org/about/donate

#14Pavel Stehule
pavel.stehule@gmail.com
In reply to: David Fetter (#13)
Re: Dyamic updates of NEW with pl/pgsql

2010/3/12 David Fetter <david@fetter.org>:

On Wed, Mar 10, 2010 at 07:50:16AM -0500, Andrew Dunstan wrote:

hubert depesz lubaczewski wrote:

On Tue, Mar 09, 2010 at 06:59:31PM +0100, Pavel Stehule wrote:

2010/3/9 strk <strk@keybit.net>:

How can a pl/pgsql trigger change the
values of dynamic fields in NEW record ?

By "dynamic" I mean that the field name
is a variable in the trigger context.

I've been told it's easy to do with pl/perl but
I'd like to delive a pl/pgsql solution to have
less dependencies.

It isn't possible yet

well, it's possible. it's just not nice.

http://www.depesz.com/index.php/2010/03/10/dynamic-updates-of-fields-in-new-in-plpgsql/

Using an hstore in 9.0 it's not too bad, Try something like:

   CREATE OR REPLACE FUNCTION dyntrig()
    RETURNS trigger
    LANGUAGE plpgsql
   AS $function$

   declare
           hst hstore;
   begin
           hst := hstore(NEW);
           hst := hst || ('foo' => 'bar');
           NEW := populate_record(NEW,hst);
           return NEW;
   end;

   $function$;

But this question probably belongs on -general rather than -hackers.

This is, by the way, an excellent argument for including hstore in
core in 9.1. :)

I like it - but it looking little bit strange - I thinking we need
only one function (maybe with some special support from pl executor)

begin
update_field(NEW, 'field', value);
....

Pavel

Show quoted text

Cheers,
David.
--
David Fetter <david@fetter.org> http://fetter.org/
Phone: +1 415 235 3778  AIM: dfetter666  Yahoo!: dfetter
Skype: davidfetter      XMPP: david.fetter@gmail.com
iCal: webcal://www.tripit.com/feed/ical/people/david74/tripit.ics

Remember to vote!
Consider donating to Postgres: http://www.postgresql.org/about/donate

#15David Fetter
david@fetter.org
In reply to: Pavel Stehule (#14)
Re: Dyamic updates of NEW with pl/pgsql

On Fri, Mar 12, 2010 at 07:35:41PM +0100, Pavel Stehule wrote:

2010/3/12 David Fetter <david@fetter.org>:

This is, by the way, an excellent argument for including hstore in
core in 9.1. :)

I like it - but it looking little bit strange - I thinking we need
only one function (maybe with some special support from pl executor)

begin
update_field(NEW, 'field', value);
....

This doesn't seem like a terribly useful addition, it being specific
to PL/pgsql. Then there's the quoting issue, which the above doesn't
quite address. Putting hstore in would let all the other PLs use it,
to the extent that they need such a thing. :)

Cheers,
David.
--
David Fetter <david@fetter.org> http://fetter.org/
Phone: +1 415 235 3778 AIM: dfetter666 Yahoo!: dfetter
Skype: davidfetter XMPP: david.fetter@gmail.com
iCal: webcal://www.tripit.com/feed/ical/people/david74/tripit.ics

Remember to vote!
Consider donating to Postgres: http://www.postgresql.org/about/donate

#16strk
strk@keybit.net
In reply to: David Fetter (#15)
Re: Dyamic updates of NEW with pl/pgsql

On Fri, Mar 12, 2010 at 10:47:45AM -0800, David Fetter wrote:

On Fri, Mar 12, 2010 at 07:35:41PM +0100, Pavel Stehule wrote:

2010/3/12 David Fetter <david@fetter.org>:

This is, by the way, an excellent argument for including hstore in
core in 9.1. :)

I like it - but it looking little bit strange - I thinking we need
only one function (maybe with some special support from pl executor)

begin
update_field(NEW, 'field', value);
....

This doesn't seem like a terribly useful addition, it being specific
to PL/pgsql. Then there's the quoting issue, which the above doesn't
quite address. Putting hstore in would let all the other PLs use it,
to the extent that they need such a thing. :)

Plus pure SQL use !
I was considering using hstore for a table value too for
a form of "historic table". Just to say I'd also be happy with
it being core in pgsql :)

--strk;

() Free GIS & Flash consultant/developer
/\ http://strk.keybit.net/services.html

#17Pavel Stehule
pavel.stehule@gmail.com
In reply to: strk (#16)
Re: Dyamic updates of NEW with pl/pgsql

2010/3/12 strk <strk@keybit.net>:

On Fri, Mar 12, 2010 at 10:47:45AM -0800, David Fetter wrote:

On Fri, Mar 12, 2010 at 07:35:41PM +0100, Pavel Stehule wrote:

2010/3/12 David Fetter <david@fetter.org>:

This is, by the way, an excellent argument for including hstore in
core in 9.1. :)

I like it - but it looking little bit strange - I thinking we need
only one function (maybe with some special support from pl executor)

begin
  update_field(NEW, 'field', value);
  ....

This doesn't seem like a terribly useful addition, it being specific
to PL/pgsql.  Then there's the quoting issue, which the above doesn't
quite address.  Putting hstore in would let all the other PLs use it,
to the extent that they need such a thing. :)

Plus pure SQL use !
I was considering using hstore for a table value too for
a form of "historic table". Just to say I'd also be happy with
it being core in pgsql :)

I see some disadvantages

a) non intuitive name - hstore is very specific name
b) effectivity (mainly inside trigger body) - plpgsql specific
construct can be 10x faster.

I would to see hash tables in core too, but I don't think so it is
good solution for record updating.

Regards
Pavel

Show quoted text

--strk;

 ()   Free GIS & Flash consultant/developer
 /\   http://strk.keybit.net/services.html

#18Boszormenyi Zoltan
zb@cybertec.at
In reply to: strk (#16)
Re: Dyamic updates of NEW with pl/pgsql

strk �rta:

On Fri, Mar 12, 2010 at 10:47:45AM -0800, David Fetter wrote:

On Fri, Mar 12, 2010 at 07:35:41PM +0100, Pavel Stehule wrote:

2010/3/12 David Fetter <david@fetter.org>:

This is, by the way, an excellent argument for including hstore in
core in 9.1. :)

I like it - but it looking little bit strange - I thinking we need
only one function (maybe with some special support from pl executor)

begin
update_field(NEW, 'field', value);
....

This doesn't seem like a terribly useful addition, it being specific
to PL/pgsql. Then there's the quoting issue, which the above doesn't
quite address. Putting hstore in would let all the other PLs use it,
to the extent that they need such a thing. :)

Plus pure SQL use !

What's wrong with "UPDATE foo SET (foo) = (NEW);" ?

I know it's a little ambiguous, as table "foo" can have fields
named "foo" and "new", but the
UPDATE foo SET (field, ...) = (value, ...);
works in plain SQL and the (...) usually denotes a list with
more than one field/value. pl/pgSQL could treat the
"list with single name" as a special case (maybe checking
whether the table has fields "foo", "new" and/or "old" and
issue a warning when relevant) and treat the above as a
whole-row update.

Best regards,
Zolt�n B�sz�rm�nyi

--
Bible has answers for everything. Proof:
"But let your communication be, Yea, yea; Nay, nay: for whatsoever is more
than these cometh of evil." (Matthew 5:37) - basics of digital technology.
"May your kingdom come" - superficial description of plate tectonics

----------------------------------
Zolt�n B�sz�rm�nyi
Cybertec Sch�nig & Sch�nig GmbH
http://www.postgresql.at/

#19Merlin Moncure
mmoncure@gmail.com
In reply to: Boszormenyi Zoltan (#18)
Re: Dyamic updates of NEW with pl/pgsql

On Fri, Mar 12, 2010 at 3:01 PM, Boszormenyi Zoltan <zb@cybertec.at> wrote:

What's wrong with "UPDATE foo SET (foo) = (NEW);" ?

amen brother! :-)

I say though, since you can do:
SELECT foo FROM foo;
why not
UPDATE foo SET foo = new;?

merlin

#20Boszormenyi Zoltan
zb@cybertec.at
In reply to: Merlin Moncure (#19)
Re: Dyamic updates of NEW with pl/pgsql

Merlin Moncure �rta:

On Fri, Mar 12, 2010 at 3:01 PM, Boszormenyi Zoltan <zb@cybertec.at> wrote:

What's wrong with "UPDATE foo SET (foo) = (NEW);" ?

amen brother! :-)

I say though, since you can do:
SELECT foo FROM foo;
why not
UPDATE foo SET foo = new;?

I just tried this:

zozo=# create table foo (foo integer, bar integer);
CREATE TABLE
zozo=# insert into foo values (1, 2), (2, 4);
INSERT 0 2
zozo=# select foo from foo;
foo
-----
1
2
(2 rows)

zozo=# create table foo1 (foo integer, bar integer);
CREATE TABLE
zozo=# insert into foo1 values (1, 2), (2, 4);
INSERT 0 2
zozo=# select foo1 from foo1;
foo1
-------
(1,2)
(2,4)
(2 rows)

So, if the table has field that's name is the same as the table name
then SELECT foo FROM foo; returns the field, not the whole row,
it's some kind of a precedence handling. What we could do is the
reverse precedence with
UPDATE foo SET foo = 3 WHERE foo = 1;
vs
UPDATE foo SET (foo) = (1,3) WHERE (foo) = (1,2);

Note the WHERE condition, I would expect it to work there, too.
If it works in plain SQL then no special casing would be needed
in PLs.

Best regards,
Zolt�n B�sz�rm�nyi

--
Bible has answers for everything. Proof:
"But let your communication be, Yea, yea; Nay, nay: for whatsoever is more
than these cometh of evil." (Matthew 5:37) - basics of digital technology.
"May your kingdom come" - superficial description of plate tectonics

----------------------------------
Zolt�n B�sz�rm�nyi
Cybertec Sch�nig & Sch�nig GmbH
http://www.postgresql.at/

#21Robert Haas
robertmhaas@gmail.com
In reply to: Boszormenyi Zoltan (#20)
#22Andrew Dunstan
andrew@dunslane.net
In reply to: Pavel Stehule (#17)
#23Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andrew Dunstan (#22)
#24Merlin Moncure
mmoncure@gmail.com
In reply to: Tom Lane (#23)
#25Pavel Stehule
pavel.stehule@gmail.com
In reply to: Tom Lane (#23)
#26Tom Lane
tgl@sss.pgh.pa.us
In reply to: Merlin Moncure (#24)
#27Pavel Stehule
pavel.stehule@gmail.com
In reply to: Tom Lane (#26)
#28Tom Lane
tgl@sss.pgh.pa.us
In reply to: Merlin Moncure (#24)
#29David Fetter
david@fetter.org
In reply to: Tom Lane (#28)
#30Andrew Dunstan
andrew@dunslane.net
In reply to: Tom Lane (#28)
#31Tom Lane
tgl@sss.pgh.pa.us
In reply to: Tom Lane (#28)
#32Merlin Moncure
mmoncure@gmail.com
In reply to: Tom Lane (#31)
#33Andrew Dunstan
andrew@dunslane.net
In reply to: Merlin Moncure (#32)
#34Merlin Moncure
mmoncure@gmail.com
In reply to: Andrew Dunstan (#33)
#35Tom Lane
tgl@sss.pgh.pa.us
In reply to: Merlin Moncure (#34)
#36Merlin Moncure
mmoncure@gmail.com
In reply to: Tom Lane (#35)
#37Tom Lane
tgl@sss.pgh.pa.us
In reply to: Merlin Moncure (#36)
#38Merlin Moncure
mmoncure@gmail.com
In reply to: Tom Lane (#37)
#39Florian Pflug
fgp.phlo.org@gmail.com
In reply to: Tom Lane (#31)
#40Merlin Moncure
mmoncure@gmail.com
In reply to: Florian Pflug (#39)
#41Florian Pflug
fgp.phlo.org@gmail.com
In reply to: Merlin Moncure (#40)