Skip site navigation (1) Skip section navigation (2)

Re: BUG #1329: Bug in IF-ELSEIF-ELSE construct

From: Neil Conway <neilc(at)samurai(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: Rico Wind <rw(at)rico-wind(dot)dk>, pgsql-bugs(at)postgresql(dot)org
Subject: Re: BUG #1329: Bug in IF-ELSEIF-ELSE construct
Date: 2004-11-27 06:17:40
Message-ID: 41A81C04.7050206@samurai.com (view raw or flat)
Thread:
Lists: pgsql-bugspgsql-patches
Tom Lane wrote:
> There is no ELSEIF construct.

Sure, but it would be nice to throw a syntax error rather than silently 
accepting the function. Unfortunately the way PL/PgSQL's parser works 
doesn't make this very easy. (BTW, I think that fixing how we do parsing 
would be one of the prime motivations for rewriting PL/PgSQL. One 
possibility would be to integrate the PL/PgSQL parser into the main SQL 
parser, although there may be a cleaner way to improve PL/PgSQL parsing.)

In any case, given this function:

create or replace function foo() returns int as
'
#option dump
begin
     if 5 > 5 then
         return 10;
     elseif 5 > 6 then
         return 15;
     else
         return 20;
     end if;
end;' language 'plpgsql';

We produce this parsetree: (helpfully dumped via the undocumented 
"#option dump" feature)

Functions statements:
   2:BLOCK <<*unnamed*>>
   3:  IF 'SELECT  5 > 5' THEN
   4:    RETURN 'SELECT  10'
   5:    EXECSQL 'elseif 5 > 6 then 15 15'
       ELSE
   8:    RETURN 'SELECT  20'
       ENDIF
     END -- *unnamed*

One way to fix the specific bug reported here would be to add K_ELSEIF 
to the PL/PgSQL lexer, and then throw a syntax error in the stmt_else 
production. But that is a very limited fix: if the user specifies any 
other word in the place of 'elseif', we will not throw a syntax error.

Another solution would be to teach the PL/PgSQL lexer to recognize the 
initial tokens of every SQL statement (SELECT, UPDATE, and so forth). 
Right now we just assume an unrecognized word must be the beginning of a 
SQL statement; if we taught the lexer about the initial tokens of all 
legal SQL statements, we could reject unrecognized words. But this is 
kind of ugly as well, as it means duplicating the knowledge about what 
constitutes a legal SQL statement in multiple places.

Alternatively, we could arrange to have the PL/PgSQL parser pass a block 
of text it has identified as a possible SQL statement to the main SQL 
parser; if it produces a syntax error, we can pass that syntax error 
back to the user. I'm not sure if this would have any negative 
ramifications, though.

Comments?

(BTW, another thing this example exposes is that we don't issue warnings 
about trivially-dead-code, such as statements in a basic block that 
follow a RETURN. This would probably be also worth doing.)

-Neil

In response to

Responses

pgsql-bugs by date

Next:From: Ing. Aleš PROCHÁZKADate: 2004-11-27 10:41:05
Subject: Troubles with windows instaler of PostgreSql 8 beta 5
Previous:From: Bruce MomjianDate: 2004-11-27 05:03:01
Subject: Re: [BUGS] solaris non gcc compiler debug options

pgsql-patches by date

Next:From: Neil ConwayDate: 2004-11-27 13:56:31
Subject: plpgsql unreachable code (was BUG #1329: Bug in IF-ELSEIF-ELSE construct)
Previous:From: Bruce MomjianDate: 2004-11-27 06:02:44
Subject: Re: FAQ update

Privacy Policy | About PostgreSQL
Copyright © 1996-2014 The PostgreSQL Global Development Group