Thread: Three questions regarding PL/PGSQL

Three questions regarding PL/PGSQL

From
"Josh Berkus"
Date:
Folks,

1. While I am able to use the %TYPE declaration within
PL/PGSQL functions, I am unable to use this declaration in
the parameters for the function -- I get 'Parse Error at or
near "."'

2. When I have a PL/PGSQL function return a custom message
using a VARCHAR return value, I get backslashes in front of
all of the spaces in the message.

3. Given the odd/weak exception handling within the current
Postgres database engine, has anyone developed strategies to
make certain that their PL/PGSQL functions do not perform
inconsistent updates?  If so, can you give some examples?

Anybody (Jan?) who can shed some light on the above will
receive my enthusiastic gratitude in ASCII text.

-Josh Berkus

P.S. I'm using Postgres 7.0.2 on SuSE 7.0 and use pgaccess
extensively for function editing.

P.P.S. My most heartfelt gratitude to Jan Wieck for writing
some decent compile error text into the PL/PGSQL compiler,
and to Constantin Teodorescu for putting a terrific function
editor into pgaccess!


Re: Three questions regarding PL/PGSQL

From
Jan Wieck
Date:
Josh Berkus wrote:
> Folks,
>
> 1. While I am able to use the %TYPE declaration within
> PL/PGSQL functions, I am unable to use this declaration in
> the parameters for the function -- I get 'Parse Error at or
> near "."'
   I assume you're trying to do something like
       CREATE FUNCTION myfunc(mytab.x%TYPE, mytab.y%TYPE) ...
   because  that's  the  only  way  I've found to get this error   message.  Not PL/pgSQL's error here.  It's  the
main parser   interpreting  the  CREATE  FUNCTION  utility  statement  that   doesn't know how to get it.
 
   Indeed, a good idea  (for  7.2).  Bruce,  put  it  onto  TODO   please.

> 2. When I have a PL/PGSQL function return a custom message
> using a VARCHAR return value, I get backslashes in front of
> all of the spaces in the message.
   Can't  reproduce  that  in 7.1(BETA). Could you send a little   sql snippet reproducing the behaviour?

> 3. Given the odd/weak exception handling within the current
> Postgres database engine, has anyone developed strategies to
> make certain that their PL/PGSQL functions do not perform
> inconsistent updates?  If so, can you give some examples?
   Dunno what's exactly meant by that. Up to now we  don't  have   savepoints  and  thus, anything done eventually in a
PL/pgSQL  trigger or function will allways roll back if  a  transaction   get's  aborted. Single statements (outside
transactionblock)   have their own transaction, so nothing to worry about.
 
   Second you could mean what's been  discussed  over  and  over   again  under  subjects like "LOCK arbitrary string"
andsuch,   to prevent functions to try things that could produce  errors   in the first place.  Lookup those threads in
thearchives.
 
   Or  you could mean to prevent that a trigger, that you expect   to UPDATE/DELETE an exact number  of  rows.  Here
you could   check  after  the  statement in question with GET DIAGNOSTICS   (new feature in 7.1) if the correct number
ofrows  has  been   hit.
 

> Anybody (Jan?) who can shed some light on the above will
> receive my enthusiastic gratitude in ASCII text.
   Some sql examples would allways help.

> P.P.S. My most heartfelt gratitude to Jan Wieck for writing
> some decent compile error text into the PL/PGSQL compiler,
> and to Constantin Teodorescu for putting a terrific function
> editor into pgaccess!
   Getting  better  compile  error  messages (anything else than   "parse error at or near ...") isn't easy in
yacc/bison.  Of   course, the PL/pgSQL function handler does write some more as   DEBUG messages to the Postmaster
log. Unfortunately,  these   don't  show  up  at  the  frontend side and cannot easily get   turned into NOTICE ones
becauseat  that  time  the  original   ERROR  has  already  been  sent  to  the  client and emitting   NOTICE's then
couldconfuse the fe/be protocol.
 


Jan

--

#======================================================================#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me.                                  #
#================================================== JanWieck@Yahoo.com #


_________________________________________________________
Do You Yahoo!?
Get your free @yahoo.com address at http://mail.yahoo.com



Re: Three questions regarding PL/PGSQL

From
Josh Berkus
Date:
Jan,
>     I assume you're trying to do something like
> 
>         CREATE FUNCTION myfunc(mytab.x%TYPE, mytab.y%TYPE) ...
> 
>     because  that's  the  only  way  I've found to get this error

That's correct.

>     Indeed, a good idea  (for  7.2).  Bruce,  put  it  onto  TODO
>     please.

Thanks!  I'm a little surprised that this hasn't come up before -- after
all, why did you include PLSQL-style %TYPE and %ROWTYPE declarations if
not for parameters?

>     Can't  reproduce  that  in 7.1(BETA). Could you send a little
>     sql snippet reproducing the behaviour?

Sure, when I get home.  I've a feeling that it's related to the Function
handler in 7.0.x storing functions as TEXT.  What I'm trying to make
sure of is that it's not related to using PGAccess.

>     Dunno what's exactly meant by that. Up to now we  don't  have
>     savepoints  and  thus, anything done eventually in a PL/pgSQL
>     trigger or function will allways roll back if  a  transaction
>     get's  aborted. Single statements (outside transaction block)
>     have their own transaction, so nothing to worry about.

What I'm talking about is how, if an error occurs, the entire function
rolls back, not just a selected portion.  I can't even include a BEGIN
TRANSACTION statment in a function; it errors out on compile.  Nor can I
return a custom error message in place of a database error.

ALso, in other database engines, I've been able to use transactions to
prevent the interleaving of conflicting updates on the database server. 
For example, I have some functions that insert a row into a table and
then report back the ID of the new row:

INSERT INTO clients ( ... ) VALUES ( ... );
SELECT CURRVAL(client_id) INTO new_client;

It's vitally important that another operation on the clients table does
not execute between the INSERT and the SELECT CURRVAL.  It may be that
by creating transactions by default PGSQL functions are alredy doing
this; some reassurance on that count would be nice.

>     Some sql examples would allways help.

More later when I get back to my PGSQL server.

>     Getting  better  compile  error  messages (anything else than
>     "parse error at or near ...") isn't easy in  yacc/bison.   Of
>     course, the PL/pgSQL function handler does write some more as
>     DEBUG messages to the Postmaster  log.  Unfortunately,  these
>     don't  show  up  at  the  frontend side and cannot easily get
>     turned into NOTICE ones because at  that  time  the  original
>     ERROR  has  already  been  sent  to  the  client and emitting
>     NOTICE's then could confuse the fe/be protocol.

Hey, just the fact that you spit back "Error on Line 38" cuts my
debugging time in half over the SQL handler's "Error at or near ';'"

Of course, running a tail on the postmaster log helps, too ...

-Josh Berkus

-- 
______AGLIO DATABASE SOLUTIONS___________________________                                       Josh Berkus  Complete
informationtechnology      josh@agliodbs.com   and data management solutions       (415) 436-9166  for law firms, small
businesses      fax  436-0137   and non-profit organizations.       pager 338-4078                               San
Francisco