From: Tambet Matiisen <t.matiisen@aprote.ee>
To: KÖPFERL Robert <robert.koepferl@sonorys.at>
To: pgsql-sql@postgresql.org
Subject: Re: Function to either return one or all records
Date: Wed, 20 Apr 2005 23:02:53 +0300
Message-ID: <A66A11DBF5525341AEF6B8DE39CDE770088073@black.aprote.com> (raw)
>
> CREATE OR REPLACE FUNCTION getval(integer)
> RETURNS SETOF id_val_tbl AS
> $BODY$
> select * from id_bal_tbl where ( $1 is null )or (id=$1 ); $BODY$
> LANGUAGE 'sql' VOLATILE SECURITY DEFINER;
>
>
> It works fine, however an index is never used (if just one
> record is requested). The column id has a btree-Index but
> what aobut it. I'm wondering how this comes and how one can
> overcome this limit.
The reason why the query worked as plain query may come from the fact that NULL IS NULL was evaluated to constant FALSE and optimized out from OR. In case of function the query was planned before substituting parameters, so the OR was still there and prevented index scan.
Standard technique is to rewrite OR queries to UNION queries. I believe PostgreSQL optimizer does not do that automatically. So you could try instead:
select * from id_bal_tbl where $1 is null
union all
select * from id_bal_tbl where id = $1;
(Note: in general you would need UNION without ALL, to keep the semantics of OR.)
Tambet
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-sql@postgresql.org
Cc: t.matiisen@aprote.ee, robert.koepferl@sonorys.at
Subject: Re: Function to either return one or all records
In-Reply-To: <A66A11DBF5525341AEF6B8DE39CDE770088073@black.aprote.com>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox