Talk About Network

Google


Register and Login
Nick
Password
Register create new account Sign up is FREE and you can post replies, new topics, bookmark posts and more!
Recover lost password


Data Bases > Pgsql General > Re: choiche of ...
Latest [ Topics | Posts ] Archive Post A New Topic Post a Reply
<< Topic < Post Post 6 of 8 Topic 15498 of 17437
Post > Topic >>

Re: choiche of function language was: Re: dynamic procedure call

by tgl@[EMAIL PROTECTED] (Tom Lane) May 10, 2008 at 11:50 AM

I wrote:
> We've poked a few loopholes in the strong typing over the years
> --- the whole business of EXECUTE versus direct evaluation of a
> query can be seen as allowing weak typing for EXECUTE'd queries.
> But it's still the language's design center.

Rereading that, it suddenly struck me that Pavel's recent addition of
USING to EXECUTE provides a klugy way to get at a run-time-determined
member of a row variable, which seems to be the single most-requested
facility in this area.  I put together the following test case, which
tries to print out the values of fields selected by trigger arguments:

create or replace function foo() returns trigger as $$
declare
  r record;
begin
  for i in 1 .. tg_argv[0] loop
    execute 'select $1 . ' || tg_argv[i] || ' as x'
      into r using NEW;
    raise notice '% = %', tg_argv[i], r.x;
  end loop;
  return new;
end $$ language plpgsql;

create table tab(f1 int, f2 text, f3 timestamptz);

create trigger footrig before insert on tab for each row
  execute procedure foo (3,f1,f2,f3);

insert into tab values(42, 'foo', now());

(BTW, in this example it's truly annoying that TG_ARGV[] isn't a
"real" array that you can use array_lower/array_upper on.  Maybe
that is worth fixing sometime.)

Unfortunately this doesn't quite work, because plpgsql is resolutely
strongly typed:

NOTICE:  f1 = 42
ERROR:  type of "r.x" does not match that when preparing the plan
CONTEXT:  PL/pgSQL function "foo" line 6 at RAISE

IOW, it gets through the first cycle of the loop okay, but in the
second one the "r.x" subexpression has already been planned on the
expectation that r.x is of type int.

You can get around this if you are willing to coerce all possible
results to the same type, eg text:

create or replace function foo() returns trigger as $$
declare
  t text;
begin
  for i in 1 .. tg_argv[0] loop
    execute 'select cast ( $1 . ' || tg_argv[i] || ' as text)'
      into t using new;
    raise notice '% = %', tg_argv[i], t;
  end loop;
  return new;
end $$ language plpgsql;

et voila:

NOTICE:  f1 = 42
NOTICE:  f2 = foo
NOTICE:  f3 = 2008-05-10 11:38:33.677035-04

So, it's a hack, and it relies on a feature that won't be out till 8.4,
but it *is* possible ...

			regards, tom lane

-- 
Sent via pgsql-general mailing list (pgsql-general@[EMAIL PROTECTED]
)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general
 




 8 Posts in Topic:
dynamic procedure call
tekwiz <ryoung@[EMAIL   2008-05-09 12:05:26 
Re: dynamic procedure call
pavel.stehule@[EMAIL PROT  2008-05-10 07:35:36 
choiche of function language was: Re: dynamic procedure
mail@[EMAIL PROTECTED] (  2008-05-10 09:14:14 
Re: choiche of function language was: Re: dynamic procedure call
steve@[EMAIL PROTECTED]   2008-05-10 07:27:01 
Re: choiche of function language was: Re: dynamic procedure call
tgl@[EMAIL PROTECTED] (T  2008-05-10 11:19:27 
Re: choiche of function language was: Re: dynamic procedure call
tgl@[EMAIL PROTECTED] (T  2008-05-10 11:50:06 
Re: choiche of function language was: Re: dynamic procedure call
Chris Browne <cbbrowne  2008-05-12 11:27:26 
Re: choiche of function language was: Re: dynamic procedure call
pavel.stehule@[EMAIL PROT  2008-05-10 12:08:42 

Post A Reply:
  Go here to Signup

AddThis Feed Button


About - Advertising - Contact - Frequently Asked Questions - Privacy Policy - Terms of Use - Signup

Contact
tan12V112 Sat Nov 22 12:16:34 CST 2008.