Thread: parse error for function def

parse error for function def

From
Terence Kearns
Date:
CREATE FUNCTION base.fn_fkey_check(text, text, int4) RETURNS bool AS
'DECLARE
BEGIN  RETURN (SELECT count($1) FROM $2 where $1 = $3)::bool;
END;'
LANGUAGE 'sql';

produces this error
ERROR:  parser: parse error at or near "RETURN" at character 20

I'm trying to create a function to use on a trigger to check reference 
to views since pg does not support foreign keys referencing views.



-- 
Terence Kearns ~ ph: +61 2 6201 5516
IT Database/Applications Developer
Enterprise Information Systems
Client Services Division
University of Canberra
www.canberra.edu.au



Re: parse error for function def

From
greg@turnstep.com
Date:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1


> I'm trying to create a function to use on a trigger to check reference 
> to views since pg does not support foreign keys referencing views.

Can you explain exactly what you are trying to do and why? You are getting 
the error because a SQL function does not RETURN, it must end with a 
SELECT statement. It also has no DECLARE, BEGIN, or END. You can either 
remove all of those or change the language to plpgsql. See:

http://www.postgresql.org/docs/7.3/static/xfunc-sql.html

In addition, you cannot (with SQL) use an argument as the tablename. You 
also probably want to use EXISTS, not "count..::bool".

- --
Greg Sabino Mullane greg@turnstep.com
PGP Key: 0x14964AC8 200307171005

-----BEGIN PGP SIGNATURE-----
Comment: http://www.turnstep.com/pgp.html

iD8DBQE/Fq/7vJuQZxSWSsgRAj01AKCz9BA4aYrp8pnqWy8VHA4i3WGjtgCgjndA
yzNOE52VAvJBOEvilACSGvA=
=EcwZ
-----END PGP SIGNATURE-----




Re: parse error for function def

From
Dmitry Tkach
Date:
Terence Kearns wrote:

> CREATE FUNCTION base.fn_fkey_check(text, text, int4) RETURNS bool AS
> 'DECLARE
> BEGIN
>   RETURN (SELECT count($1) FROM $2 where $1 = $3)::bool;
> END;'
> LANGUAGE 'sql';
>
> produces this error
> ERROR:  parser: parse error at or near "RETURN" at character 20
>
> I'm trying to create a function to use on a trigger to check reference 
> to views since pg does not support foreign keys referencing views.


First, you are using wrong language.
In 'sql' you do not need begin, end or return.

Second, you cannot have trigger functions in sql anyway, so you'd need 
to change your language to 'plpgsql' - it may than even compile, but I 
am not sure, because I never used that language.

Third, trigger functions are special in that they can only take constant 
strings as arguments, so your $1 = $3 is, most probably not going to 
work. They also must return 'opaque' (in 7.2) or 'triggers' (in 7.3) - 
you can't return bool, because there is nobody who'd be able to look at 
the result after the function is called. Instead, you should check your 
condition, and if it is not satisfied, raise an error to abort the 
transaction.

Fourth, select count ... may not be very efficient if you just need to 
check if the key exists - you may be better off with select true ... 
limit 1;

And finally, you can (relatively easily) write a function that will 
check if the key exists in the view whenever you insert/update the 
table... But what about the other way around - what if somebody deletes 
a key from the underlying table in the view while there is still 
referencing entries on the other table? You can't have a trigger on a 
view, so there would be no way to check that...

Why not avoid all that by just creating an FK between the actual 
table(s), used by the view and the 'child' table you care about?

Dima





Re: parse error for function def

From
Stephan Szabo
Date:
On Thu, 17 Jul 2003, Terence Kearns wrote:

> CREATE FUNCTION base.fn_fkey_check(text, text, int4) RETURNS bool AS
> 'DECLARE
> BEGIN
>    RETURN (SELECT count($1) FROM $2 where $1 = $3)::bool;
> END;'
> LANGUAGE 'sql';
>
> produces this error
> ERROR:  parser: parse error at or near "RETURN" at character 20
>
> I'm trying to create a function to use on a trigger to check reference
> to views since pg does not support foreign keys referencing views.

As others have said, the function above is much closer to a plpgsql
function, excepting that you still couldn't use $2 in the from clause
without execute I believe.  In addition, the above isn't going to simulate
a foreign key unless the view is entirely static (if it were that simple,
we'd have implemented it) since changes to the view's base table(s) could
make the constraint be invalid as well.



Re: parse error for function def

From
Jonathan Gardner
Date:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Thursday 17 July 2003 03:46, Terence Kearns wrote:
> CREATE FUNCTION base.fn_fkey_check(text, text, int4) RETURNS bool AS
> 'DECLARE
> BEGIN
>    RETURN (SELECT count($1) FROM $2 where $1 = $3)::bool;
> END;'
> LANGUAGE 'sql';
>
> produces this error
> ERROR:  parser: parse error at or near "RETURN" at character 20
>
> I'm trying to create a function to use on a trigger to check reference
> to views since pg does not support foreign keys referencing views.

If you want to write triggers, there is great documentation on that in the
PL/pgSQL documentation.

I'll give this a shot:

CREATE FUNCTION base.fn_fkey_check(name, name, name, name) RETURNS TRIGGER AS
'
BEGIN   " $1 column1 (the table that has the foreign key column)   " $2 - table2 $3 - column2 (the table/column that is
theprimary key being  
reference)   EXECUTE ''SELECT $3 FROM $2 WHERE $3=NEW.$1'';   IF FOUND   THEN RETURN NEW      RAISE ERROR ''Foreign key
violation.'';  RETURN; 
END'
LANGUAGE 'plpgsql';

- --
Jonathan Gardner <jgardner@jonathangardner.net>
(was jgardn@alumni.washington.edu)
Live Free, Use Linux!
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (GNU/Linux)

iD8DBQE/Fxb9WgwF3QvpWNwRAh6tAJ9TxkqmKd8NrsQSwadV9FQ8PuSFIACg2sg9
6KPuw+msH/faa8F0xR+FSTI=
=Yo2a
-----END PGP SIGNATURE-----