Обсуждение: PL/pgSQL: possible parsing or documentation bug?

Поиск
Список
Период
Сортировка

PL/pgSQL: possible parsing or documentation bug?

От
"Albert REINER"
Дата:
Saluton,

plpgsql seems to get confused when using variable names that coincide
with, e.g., column names:

create Function IdOfPossiblyNewAuthor(text) returns int4 as ' declare   id int4; begin   select id into id from author
wherename = $1;   raise notice ''ID found: %'', id;   if id is null then     insert into author (name) values ($1);
selectcurrval(''author_id_seq'') into id;     raise debug ''Author inserted. ID: %'', id;   end if;   return id; end;
 
' language 'plpgsql' with (IsCachable);

Logically it is clear which "id" should be parsed as the variable,
which as author.id, but I have to use a different name to make this
work. I do not see any mention on this restriction of variable names
(the full extent of which I do not know) in the documentation (7.0.2).

Albert.


-- 

--------------------------------------------------------------------------
Albert Reiner                                   <areiner@tph.tuwien.ac.at>
Deutsch       *       English       *       Esperanto       *       Latine
--------------------------------------------------------------------------


const cast ?

От
Дата:
Hello Postgres Users and Developers,

I have the following scenario:
create table t (i int);
create index ti on t(i);

Now this table is filled with some values and the table is vacuum analyzed.

Now I would like to run queries on this table which should use the index 
whenever possible, so they execute fast.

If I try a simple query like: "select * from t where i=4" the index is used.
A query like: "select * from t where i=abs(4)" is using the index too.
But if I use more complex functions like the following:
"select * from t where i=date_part('year', '2001-01-01'::date)"
a sequential scan on the table is performed.

Now I conclude that the planner/optimizer does not recognize that the
date_part() function returns the same value upon each execution.

What I would like to know: Could we use some const-cast, so the optimzer gets
a hint in optimizing the query ?
I think of something like:
"select * from t where i=date_part('year', '2001-01-01'::date)::const"

Would this be hard to implement, or are there any theoretical issues which
permit this. My thoughts are, that if the user declares something as const,
although it might not always be const, the database should not worry about
the complete truth and just assume the statement as const.

Or Is this feature available already, and I have just missed the correct 
keyword?

-- 
--
---> doj@redaex.de


Re: const cast ?

От
Michael Fork
Дата:
You can create a function with the IsCacheable attribute...

CREATE FUNCTION my_date_part(date) RETURNS int4 AS 'SELECT date_part('year', $1);
' LANGUAGE 'sql' WITH iscachable();

(This can be found in the create function docs, or in Bruce's book -- both
available on the website)

Michael Fork - CCNA - MCP - A+
Network Support - Toledo Internet Access - Toledo Ohio

On Fri, 2 Feb 2001 doj@wwws2.redaex.de wrote:

> Hello Postgres Users and Developers,
> 
> I have the following scenario:
> create table t (i int);
> create index ti on t(i);
> 
> Now this table is filled with some values and the table is vacuum analyzed.
> 
> Now I would like to run queries on this table which should use the index 
> whenever possible, so they execute fast.
> 
> If I try a simple query like: "select * from t where i=4" the index is used.
> A query like: "select * from t where i=abs(4)" is using the index too.
> But if I use more complex functions like the following:
> "select * from t where i=date_part('year', '2001-01-01'::date)"
> a sequential scan on the table is performed.
> 
> Now I conclude that the planner/optimizer does not recognize that the
> date_part() function returns the same value upon each execution.
> 
> What I would like to know: Could we use some const-cast, so the optimzer gets
> a hint in optimizing the query ?
> I think of something like:
> "select * from t where i=date_part('year', '2001-01-01'::date)::const"
> 
> Would this be hard to implement, or are there any theoretical issues which
> permit this. My thoughts are, that if the user declares something as const,
> although it might not always be const, the database should not worry about
> the complete truth and just assume the statement as const.
> 
> Or Is this feature available already, and I have just missed the correct 
> keyword?
> 
> -- 
> --
> ---> doj@redaex.de
> 



Re: const cast ?

От
Tom Lane
Дата:
Michael Fork <mfork@toledolink.com> writes:
> You can create a function with the IsCacheable attribute...
> CREATE FUNCTION my_date_part(date) RETURNS int4 AS '
>     SELECT date_part('year', $1);
> ' LANGUAGE 'sql' WITH iscachable();

The reason date_part --- and most other datetime-related functions ---
is not marked iscachable already is the existence of the special value
CURRENT in some of the datetime datatypes, which makes the result of
any datetime function potentially dependent on when you execute it.
I believe we have agreed that CURRENT is evil and should be eliminated,
but it hasn't gotten done yet.  See past discussions in the pghackers
archives.
        regards, tom lane


Re: PL/pgSQL: possible parsing or documentation bug?

От
Tom Lane
Дата:
"Albert REINER" <areiner@tph.tuwien.ac.at> writes:
> create Function IdOfPossiblyNewAuthor(text) returns int4 as '
>   declare
>     id int4;
>   begin
>     select id into id from author where name = $1;
>     raise notice ''ID found: %'', id;
>     if id is null then
>       insert into author (name) values ($1);
>       select currval(''author_id_seq'') into id;
>       raise debug ''Author inserted. ID: %'', id;
>     end if;
>     return id;
>   end;
> ' language 'plpgsql' with (IsCachable);

> Logically it is clear which "id" should be parsed as the variable,
> which as author.id,

No, it is not so clear.  Consider the following:
declare  x int4;  y int4;begin  x := ...;  select x + f1 into y from tab1 where ...;

The intent here is clearly to find a value tab1.f1 in tab1 and then
add the local variable x to form a value for the local variable y.

In general plpgsql will try to match an unqualified name to a variable
before it will consider whether it might be a field name.  If you don't
want that, qualify the field name:
    select author.id into id from author where name = $1;

Feel free to submit documentation updates to make this clearer...
        regards, tom lane