Обсуждение: can a function return a virtual table?

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

can a function return a virtual table?

От
Kai Hessing
Дата:
This is the question i'm telling myself. It is because we don't really
delete table entries, just setting a status field to '-1'. So a valid
select would look like: SELECT xyz, abc FROM (SELECT * FROM tablex WHERE
status > -1);
It would be much nicer to have to write something like: SELECT xyz, abc
FROM active(tablex); where the function 'active(x)' returns a virtual
table with all entries from table x where status is > -1. But sadly I
have no idea how write such a function. Good old O'reilly can't help (or
i'm to dumb *g*).



-- 
GnuPG-PublicKey -> http://www.hobsons.de/pgp/kai_hessing.asc

Bei seinen Handlungen ist vorzubedenken besser als nachzubedenken.
(Demokrit, um 460 v. Chr.)


Re: can a function return a virtual table?

От
Michael Fuhr
Дата:
On Wed, Apr 13, 2005 at 03:44:25PM +0200, Kai Hessing wrote:
>
> This is the question i'm telling myself. It is because we don't really
> delete table entries, just setting a status field to '-1'. So a valid
> select would look like: SELECT xyz, abc FROM (SELECT * FROM tablex WHERE
> status > -1);

I'll pick a nit and point out that the above isn't a valid query:

test=> SELECT xyz, abc FROM (SELECT * FROM tablex WHERE status > -1);
ERROR:  subquery in FROM must have an alias
HINT:  For example, FROM (SELECT ...) [AS] foo.

In this simple example you could omit the subquery altogether:

SELECT xyz, abc FROM tablex WHERE status > -1;

> It would be much nicer to have to write something like: SELECT xyz, abc
> FROM active(tablex); where the function 'active(x)' returns a virtual
> table with all entries from table x where status is > -1. But sadly I
> have no idea how write such a function. Good old O'reilly can't help (or
> i'm to dumb *g*).

See the documentation for writing set-returning functions (SRFs).
The following links should get you started (if you're using a version
of PostgreSQL older than 8.0, then see the documentation for that
version):

http://www.postgresql.org/docs/8.0/interactive/queries-table-expressions.html#QUERIES-TABLEFUNCTIONS
http://www.postgresql.org/docs/8.0/interactive/xfunc-sql.html#AEN29503
http://www.postgresql.org/docs/8.0/interactive/plpgsql-control-structures.html#AEN32823

Another possibility would be to use views.  You'd need to create a
view on each table.

http://www.postgresql.org/docs/8.0/interactive/tutorial-views.html
http://www.postgresql.org/docs/8.0/interactive/sql-createview.html

Yet another possibility would be to move the inactive rows to a
separate table.  You could reconstruct the original table with a
UNION of the active and inactive tables.

http://www.postgresql.org/docs/8.0/interactive/queries-union.html

-- 
Michael Fuhr
http://www.fuhr.org/~mfuhr/


Re: can a function return a virtual table?

От
KÖPFERL Robert
Дата:
That was a nice answer - rather compleete.

However at least I am questioning myself for a long time about what happens
if one does a select from a SRF. The function may return millions of records
(i.e. select * from x where a>1). Is this data streamed through the query
process or does postgres create a temporary table.

An "explain select * from srf()" just returns a function invocation. :-/
How does this work?


|-----Original Message-----
|From: Michael Fuhr [mailto:mike@fuhr.org]
|Sent: Dienstag, 19. April 2005 04:43
|To: Kai Hessing
|Cc: pgsql-sql@postgresql.org
|Subject: Re: [SQL] can a function return a virtual table?
|
|
|On Wed, Apr 13, 2005 at 03:44:25PM +0200, Kai Hessing wrote:
|>
|> This is the question i'm telling myself. It is because we 
|don't really
|> delete table entries, just setting a status field to '-1'. So a valid
|> select would look like: SELECT xyz, abc FROM (SELECT * FROM 
|tablex WHERE
|> status > -1);
|
|I'll pick a nit and point out that the above isn't a valid query:
|
|test=> SELECT xyz, abc FROM (SELECT * FROM tablex WHERE status > -1);
|ERROR:  subquery in FROM must have an alias
|HINT:  For example, FROM (SELECT ...) [AS] foo.
|
|In this simple example you could omit the subquery altogether:
|
|SELECT xyz, abc FROM tablex WHERE status > -1;
|
|> It would be much nicer to have to write something like: 
|SELECT xyz, abc
|> FROM active(tablex); where the function 'active(x)' returns a virtual
|> table with all entries from table x where status is > -1. But sadly I
|> have no idea how write such a function. Good old O'reilly 
|can't help (or
|> i'm to dumb *g*).
|
|See the documentation for writing set-returning functions (SRFs).
|The following links should get you started (if you're using a version
|of PostgreSQL older than 8.0, then see the documentation for that
|version):
|
|http://www.postgresql.org/docs/8.0/interactive/queries-table-ex
|pressions.html#QUERIES-TABLEFUNCTIONS
|http://www.postgresql.org/docs/8.0/interactive/xfunc-sql.html#AEN29503
|http://www.postgresql.org/docs/8.0/interactive/plpgsql-control-
|structures.html#AEN32823
|
|Another possibility would be to use views.  You'd need to create a
|view on each table.
|
|http://www.postgresql.org/docs/8.0/interactive/tutorial-views.html
|http://www.postgresql.org/docs/8.0/interactive/sql-createview.html
|
|Yet another possibility would be to move the inactive rows to a
|separate table.  You could reconstruct the original table with a
|UNION of the active and inactive tables.
|
|http://www.postgresql.org/docs/8.0/interactive/queries-union.html
|
|-- 
|Michael Fuhr
|http://www.fuhr.org/~mfuhr/
|
|---------------------------(end of 
|broadcast)---------------------------
|TIP 8: explain analyze is your friend
|


Re: can a function return a virtual table?

От
Bruno Wolff III
Дата:
On Tue, Apr 19, 2005 at 09:34:43 +0200, KÖPFERL Robert <robert.koepferl@sonorys.at> wrote:
> That was a nice answer - rather compleete.
> 
> However at least I am questioning myself for a long time about what happens
> if one does a select from a SRF. The function may return millions of records
> (i.e. select * from x where a>1). Is this data streamed through the query
> process or does postgres create a temporary table.
> 
> An "explain select * from srf()" just returns a function invocation. :-/
> How does this work?

If the function isn't written using a language of SQL, it isn't going to
optimize well when you only want to see part of the table.


Re: can a function return a virtual table?

От
Kai Hessing
Дата:
Hi,

and thanks for the answer  ;)  (*upps* just noticed, that I sent the
answer accidently direct to poster^^ *sorry*)

Michael Fuhr schrieb:

>> I'll pick a nit and point out that the above isn't a valid query:
>>
>> test=> SELECT xyz, abc FROM (SELECT * FROM tablex WHERE status > -1);
>> ERROR:  subquery in FROM must have an alias
>> HINT:  For example, FROM (SELECT ...) [AS] foo.

*yeah* sure you're right. I shortened it to much^^


>> In this simple example you could omit the subquery altogether:
>> SELECT xyz, abc FROM tablex WHERE status > -1;

It is not about such a simple example. When joining tables (especially
with outer joins) it isn't trivial  ;)

>> See the documentation for writing set-returning functions (SRFs).
>> The following links should get you started (if you're using a version
>> of PostgreSQL older than 8.0, then see the documentation for that
>> version):

Thanks, I think this is what I've searched for (btw. we use 7.3). But
what I want to do is:

CREATE FUNCTION active(char) RETURNS setof $1 AS '   SELECT * FROM $1 WHERE status>-1;
' LANGUAGE SQL;

But this does not work. So I'll use views instead  ;)  It also should be
more performant. Thanks...


Re: can a function return a virtual table?

От
Josh Berkus
Дата:
Kai,

> It would be much nicer to have to write something like: SELECT xyz, abc
> FROM active(tablex); where the function 'active(x)' returns a virtual
> table with all entries from table x where status is > -1. But sadly I
> have no idea how write such a function. Good old O'reilly can't help (or
> i'm to dumb *g*).

http://techdocs.postgresql.org/guides/SetReturningFunctions

Beware, though, that query plan estimation for SRFs is less accurate than for 
regular subqueries, so you could end up with unnecessarily slow query 
execution.  Test!

-- 
Josh Berkus
Aglio Database Solutions
San Francisco