Thread: allowed variable names in functions?
Hello. I suspect that in a plpgsql function DECLARE c2 REAL; cadiv REAL; works but c2 REAL; c2div REAL; doesn't. Is this true, and if so, what are the rules for the names in the function? I use 8.1.
Hello it works in my 8.1 postgres=# CREATE LANGUAGE plpgsql; CREATE LANGUAGE postgres=# create or replace function foo(a int) returns void as $$declare c2 real; c2div real; begin c2div := 10.9; end; $$ language plpgsql; CREATE FUNCTION postgres=# select foo(10); foo ----- (1 row) Regards Pavel Stehule 2008/6/30 A B <gentosaker@gmail.com>: > Hello. > I suspect that in a plpgsql function > > DECLARE > c2 REAL; > cadiv REAL; > > works but > > c2 REAL; > c2div REAL; > > doesn't. > > Is this true, and if so, what are the rules for the names in the > function? I use 8.1. > > -- > Sent via pgsql-general mailing list (pgsql-general@postgresql.org) > To make changes to your subscription: > http://www.postgresql.org/mailpref/pgsql-general >
Then my assumption was wrong. Here is the entire function and it fails with the names c2,c2div,c3,c3div, but if names are changed, it works! (by works I mean I get the "hello" lines printed) There is nothing wrong with the select statement either, that works fine if I run it stand-alone, or with the names of c2,c2div,c3,c3div changed. CREATE OR REPLACE FUNCTION foo(pid_ INTEGER) RETURNS void AS $$ DECLARE c2 REAL; c2div REAL; c3 REAL; c3div REAL; weights RECORD; tmp RECORD; retval RECORD; t RECORD; BEGIN RAISE NOTICE 'starting...'; FOR tmp IN SELECT id,c2,c3 FROM Master WHERE pid=pid_ AND c3 !=0 LOOP RAISE NOTICE 'hello %',tmp.id; END LOOP; RETURN; END; $$ LANGUAGE plpgsql; 2008/6/30 Pavel Stehule <pavel.stehule@gmail.com>: > Hello > > it works in my 8.1 > > postgres=# CREATE LANGUAGE plpgsql; > CREATE LANGUAGE > postgres=# create or replace function foo(a int) returns void as > $$declare c2 real; c2div real; begin c2div := 10.9; end; $$ language > plpgsql; > CREATE FUNCTION > postgres=# select foo(10); > foo > ----- > > (1 row) > Regards > Pavel Stehule > > 2008/6/30 A B <gentosaker@gmail.com>: >> Hello. >> I suspect that in a plpgsql function >> >> DECLARE >> c2 REAL; >> cadiv REAL; >> >> works but >> >> c2 REAL; >> c2div REAL; >> >> doesn't. >> >> Is this true, and if so, what are the rules for the names in the >> function? I use 8.1.
By changing c2,c3,etc. to something else xc2,xc3, etc. it worked! So was the problem that I refered to the same names in the SELECT statement? 2008/6/30 A B <gentosaker@gmail.com>: > Then my assumption was wrong. > Here is the entire function and it fails with the names > c2,c2div,c3,c3div, but if names are changed, it works! > (by works I mean I get the "hello" lines printed) There is nothing > wrong with the select statement either, that works fine if I run it > stand-alone, or with the names of c2,c2div,c3,c3div changed. > > CREATE OR REPLACE FUNCTION foo(pid_ INTEGER) RETURNS void AS $$ > DECLARE > c2 REAL; > c2div REAL; > c3 REAL; > c3div REAL; > BEGIN > FOR tmp IN SELECT id,c2,c3 FROM Master WHERE pid=pid_ AND c3 !=0 LOOP
am Mon, dem 30.06.2008, um 12:38:40 +0200 mailte A B folgendes: > Then my assumption was wrong. > Here is the entire function and it fails with the names > c2,c2div,c3,c3div, but if names are changed, it works! > (by works I mean I get the "hello" lines printed) There is nothing > wrong with the select statement either, that works fine if I run it > stand-alone, or with the names of c2,c2div,c3,c3div changed. > > CREATE OR REPLACE FUNCTION foo(pid_ INTEGER) RETURNS void AS $$ > DECLARE > c2 REAL; > c2div REAL; > c3 REAL; > c3div REAL; > weights RECORD; > tmp RECORD; > retval RECORD; > t RECORD; > BEGIN > RAISE NOTICE 'starting...'; > FOR tmp IN SELECT id,c2,c3 FROM Master WHERE pid=pid_ AND c3 !=0 LOOP > RAISE NOTICE 'hello %',tmp.id; > END LOOP; > RETURN; > END; $$ LANGUAGE plpgsql; Don't use the same names for plpgsql-variables and for column names. Andreas -- Andreas Kretschmer Kontakt: Heynitz: 035242/47150, D1: 0160/7141639 (mehr: -> Header) GnuPG-ID: 0x3FFF606C, privat 0x7F4584DA http://wwwkeys.de.pgp.net
I see one big problem. You have colision between column and variable names! When you has SQL inside function use prefix for variables or use qualified names. DECLARE a varchar; BEGIN FOR a IN SELECT a FROM ... -- is bug you have to do DELARE _a varchar; BEGIN FOR _a IN SELECT t.a FROM tab t ... Regards Pavel Stehule 2008/6/30 A B <gentosaker@gmail.com>: > Then my assumption was wrong. > Here is the entire function and it fails with the names > c2,c2div,c3,c3div, but if names are changed, it works! > (by works I mean I get the "hello" lines printed) There is nothing > wrong with the select statement either, that works fine if I run it > stand-alone, or with the names of c2,c2div,c3,c3div changed. > > CREATE OR REPLACE FUNCTION foo(pid_ INTEGER) RETURNS void AS $$ > DECLARE > c2 REAL; > c2div REAL; > c3 REAL; > c3div REAL; > weights RECORD; > tmp RECORD; > retval RECORD; > t RECORD; > BEGIN > RAISE NOTICE 'starting...'; > FOR tmp IN SELECT id,c2,c3 FROM Master WHERE pid=pid_ AND c3 !=0 LOOP > RAISE NOTICE 'hello %',tmp.id; > END LOOP; > RETURN; > END; $$ LANGUAGE plpgsql; > > > 2008/6/30 Pavel Stehule <pavel.stehule@gmail.com>: >> Hello >> >> it works in my 8.1 >> >> postgres=# CREATE LANGUAGE plpgsql; >> CREATE LANGUAGE >> postgres=# create or replace function foo(a int) returns void as >> $$declare c2 real; c2div real; begin c2div := 10.9; end; $$ language >> plpgsql; >> CREATE FUNCTION >> postgres=# select foo(10); >> foo >> ----- >> >> (1 row) >> Regards >> Pavel Stehule >> >> 2008/6/30 A B <gentosaker@gmail.com>: >>> Hello. >>> I suspect that in a plpgsql function >>> >>> DECLARE >>> c2 REAL; >>> cadiv REAL; >>> >>> works but >>> >>> c2 REAL; >>> c2div REAL; >>> >>> doesn't. >>> >>> Is this true, and if so, what are the rules for the names in the >>> function? I use 8.1. > > -- > Sent via pgsql-general mailing list (pgsql-general@postgresql.org) > To make changes to your subscription: > http://www.postgresql.org/mailpref/pgsql-general >
On Mon, Jun 30, 2008 at 12:44:31PM +0200, A B wrote: > By changing c2,c3,etc. to something else xc2,xc3, etc. it worked! > So was the problem that I refered to the same names in the SELECT statement? Yes. Karsten -- GPG key ID E4071346 @ wwwkeys.pgp.net E167 67FD A291 2BEA 73BD 4537 78B9 A9F9 E407 1346
Thank you both! :-)
But there not any problem with returning values with code like this DECLARE retval RECORD; retval.c2 := .... RETRUN NEXT retval; if c2 is a field on some table? 2008/6/30 Karsten Hilbert <Karsten.Hilbert@gmx.net>: > On Mon, Jun 30, 2008 at 12:44:31PM +0200, A B wrote: > >> By changing c2,c3,etc. to something else xc2,xc3, etc. it worked! >> So was the problem that I refered to the same names in the SELECT statement? > Yes. > > Karsten > -- > GPG key ID E4071346 @ wwwkeys.pgp.net > E167 67FD A291 2BEA 73BD 4537 78B9 A9F9 E407 1346 > > -- > Sent via pgsql-general mailing list (pgsql-general@postgresql.org) > To make changes to your subscription: > http://www.postgresql.org/mailpref/pgsql-general >
> But there not any problem with returning values with code like this > > DECLARE > retval RECORD; > > retval.c2 := .... > RETRUN NEXT retval; > > if c2 is a field on some table? Oh, that seems also to be problematic.
A B wrote: > Here is the entire function and it fails with the names > c2,c2div,c3,c3div, but if names are changed, it works! > (by works I mean I get the "hello" lines printed) There is nothing > wrong with the select statement either, that works fine if I run it > stand-alone, or with the names of c2,c2div,c3,c3div changed. > > CREATE OR REPLACE FUNCTION foo(pid_ INTEGER) RETURNS void AS $$ > DECLARE > c2 REAL; > c2div REAL; > c3 REAL; > c3div REAL; > weights RECORD; > tmp RECORD; > retval RECORD; > t RECORD; > BEGIN > RAISE NOTICE 'starting...'; > FOR tmp IN SELECT id,c2,c3 FROM Master WHERE pid=pid_ AND c3 !=0 LOOP > RAISE NOTICE 'hello %',tmp.id; > END LOOP; > RETURN; > END; $$ LANGUAGE plpgsql; That is because c2 and c3 in the SELECT statement are replaced with the variables before the SQL statement is executed. See the documentation: http://www.postgresql.org/docs/current/static/plpgsql-implementation.html#PLPGSQL-VAR-SUBST You should qualify the column names: SELECT master.id, master.c2, master.c3 FROM master WHERE ... AND master.c3 <> 0 Yours, Laurenz Albe