Thread: Does Postgresql have a similar pseudo-column "ROWNUM" as Oracle?

Hi:

Oracle has a pseudo-column "ROWNUM" to return the sequence number in which a row was returned when selected from a
table.The first row ROWNUM is 1, the second is 2, and so on. 

Does Postgresql have a similar pseudo-column "ROWNUM" as Oracle? If so, we can write the following query:

select *
from (select RowNum, pg_catalog.pg_proc.*        from pg_catalog.pg_proc) inline_view
where RowNum between 100 and 200;


Thanks,
Dennis



Re: Does Postgresql have a similar pseudo-column "ROWNUM" as

From
Scott Marlowe
Date:
On Thu, 2005-05-12 at 14:07, Dennis.Jiang@thomson.com wrote:
> Hi:
> 
> Oracle has a pseudo-column "ROWNUM" to return the sequence number in which a row was returned when selected from a
table.The first row ROWNUM is 1, the second is 2, and so on.
 
> 
> Does Postgresql have a similar pseudo-column "ROWNUM" as Oracle? If so, we can write the following query:
> 
> select * 
> from (select RowNum, pg_catalog.pg_proc.* 
>         from pg_catalog.pg_proc) inline_view
> where RowNum between 100 and 200;

You can get a functional equivalent with a temporary sequence:

create temp sequence rownum;
select *, nextval('rownum') as rownum from sometable;



Re: Does Postgresql have a similar pseudo-column "ROWNUM" as Oracle?

From
Andrew Sullivan
Date:
On Thu, May 12, 2005 at 01:07:00PM -0600, Dennis.Jiang@thomson.com wrote:
> 
> Does Postgresql have a similar pseudo-column "ROWNUM" as Oracle? If
> so, we can write the following query:

No.  What is the purpose of your query?  You could use ORDER BY and
LIMIT..OFFSET to do what you want. I think.

A

-- 
Andrew Sullivan  | ajs@crankycanuck.ca
The whole tendency of modern prose is away from concreteness.    --George Orwell


Re: Does Postgresql have a similar pseudo-column "ROWNUM" as Oracle?

From
Bruno Wolff III
Date:
On Thu, May 12, 2005 at 13:07:00 -0600, Dennis.Jiang@thomson.com wrote:
> Hi:
> 
> Oracle has a pseudo-column "ROWNUM" to return the sequence number in which a row was returned when selected from a
table.The first row ROWNUM is 1, the second is 2, and so on.
 
> 
> Does Postgresql have a similar pseudo-column "ROWNUM" as Oracle? If so, we can write the following query:

No.

> 
> select * 
> from (select RowNum, pg_catalog.pg_proc.* 
>         from pg_catalog.pg_proc) inline_view
> where RowNum between 100 and 200;

You could use LIMIT and OFFSET to get the values from the table for the
100th through 200th rows (though typically you want to add an ORDER BY
clause). You could have you application supply the rownum column values.


Re: Does Postgresql have a similar pseudo-column "ROWNUM" as

From
Alain
Date:

Andrew Sullivan escreveu:
> On Thu, May 12, 2005 at 01:07:00PM -0600, Dennis.Jiang@thomson.com wrote:
> 
>>Does Postgresql have a similar pseudo-column "ROWNUM" as Oracle? If
>>so, we can write the following query:
> 
> 
> No.  What is the purpose of your query?  You could use ORDER BY and
> LIMIT..OFFSET to do what you want. I think.

The problem is probably speed. I have done a lot of tests, and when 
OFFSET gets to a few thousands on a multimega-recs database, it gets 
very very slow... Is there any other to work around that?

Alain


Re: Does Postgresql have a similar pseudo-column "ROWNUM" as

From
Ragnar Hafstað
Date:
On Tue, 2005-05-17 at 14:48 -0300, Alain wrote:
> 
> Andrew Sullivan escreveu:
> > On Thu, May 12, 2005 at 01:07:00PM -0600, Dennis.Jiang@thomson.com wrote:
> > 
> >>Does Postgresql have a similar pseudo-column "ROWNUM" as Oracle? If
> >>so, we can write the following query:
> > 
> > 
> > No.  What is the purpose of your query?  You could use ORDER BY and
> > LIMIT..OFFSET to do what you want. I think.
> 
> The problem is probably speed. I have done a lot of tests, and when 
> OFFSET gets to a few thousands on a multimega-recs database, it gets 
> very very slow... 

is there not a similar loss of speed using ROWNUM on oracle?

> ... Is there any other to work around that?

if you are ordering by a unique key, you can use the key value
in a WHERE clause.

select ... where ukey>? order by ukey limit 100 offset 100;

(the ? is placeholder for the last value of ukey returned
from previous select)

gnari



ERROR: unterminated quoted string... help

From
Postgres Admin
Date:
Hi

I'm trying to insert encrypted data into the database and I'm noticing
error dealing with quotes. Below is the error print out...

suggestions and/or at least point me in the direction to find a solution,

Thanks,
J



INSERT INTO sample.users (user_name, first_name) VALUES
('jokers', '=ïµiF!¶6(ÖŸã�¾óˆÌ‘'-Iw‰iDÖiJÐÿ† %')

Warning: pg_query() [function.pg-query]: Query failed: ERROR:
unterminated quoted string at or near "'=ïµi" at character 68 in
/usr/local/apache2/htdocs/php/5/Theirry_DB.php on line 162

Re: ERROR: unterminated quoted string... help

From
Scott Marlowe
Date:
On Tue, 2005-05-17 at 13:15, Postgres Admin wrote:
> Hi
>
> I'm trying to insert encrypted data into the database and I'm noticing
> error dealing with quotes. Below is the error print out...
>
> suggestions and/or at least point me in the direction to find a solution,
>
> Thanks,
> J
>
>
>
> INSERT INTO sample.users (user_name, first_name) VALUES
> ('jokers', '=ïµiF!¶6(ÖŸã¾óˆÌ‘'-Iw‰iDÖiJÐÿ† %')
>
> Warning: pg_query() [function.pg-query]: Query failed: ERROR:
> unterminated quoted string at or near "'=ïµi" at character 68 in
> /usr/local/apache2/htdocs/php/5/Theirry_DB.php on line 162

Use a bytea field and use pg_escape_bytea() to prepare the data for
insertion.


Re: ERROR: unterminated quoted string... help

From
Postgres Admin
Date:
Scott Marlowe wrote:

>
>Use a bytea field and use pg_escape_bytea() to prepare the data for
>insertion.
>
>
>
Thanks Scott, I will try it now.

J

Re: Does Postgresql have a similar pseudo-column "ROWNUM" as

From
Alain
Date:
>>>
>>>No.  What is the purpose of your query?  You could use ORDER BY and
>>>LIMIT..OFFSET to do what you want. I think.
>>
>>The problem is probably speed. I have done a lot of tests, and when 
>>OFFSET gets to a few thousands on a multimega-recs database, it gets 
>>very very slow... 
> 
> 
> is there not a similar loss of speed using ROWNUM on oracle?
> 
> 
>>... Is there any other to work around that?
> 
> 
> if you are ordering by a unique key, you can use the key value
> in a WHERE clause.
> 
> select ... where ukey>? order by ukey limit 100 offset 100;
> 
> (the ? is placeholder for the last value of ukey returned
> from previous select)

I tried that. It does not work in the generic case: 6 MegaRec, telephone 
listing, alphabetical order. The problem is that somewhere there is a 
single user with too many entries (over 1000). I even tried to filter 
the repetitions, but somewhere I get stuck if one guy has too mny 
entries (one for each phone number).

I tried using both the name and the primary key (with a combined index), 
to get faster to the record I want, but I was not sucessfull in building 
a where clause.

I would appreciate any help, in fact this is my primary reason for 
joining this list ;-)

Alain


Re: Does Postgresql have a similar pseudo-column "ROWNUM" as

From
Andrew Sullivan
Date:
On Tue, May 17, 2005 at 03:43:32PM -0300, Alain wrote:
> 
> I tried using both the name and the primary key (with a combined index), 
> to get faster to the record I want, but I was not sucessfull in building 
> a where clause.
> 
> I would appreciate any help, in fact this is my primary reason for 
> joining this list ;-)

Well, then, table schemas, data distribution, EXPLAIN and EXPLAIN
ANALYSE output, and some statement of what you're trying to get out
is likely what we need to see.

A

-- 
Andrew Sullivan  | ajs@crankycanuck.ca
This work was visionary and imaginative, and goes to show that visionary
and imaginative work need not end up well.     --Dennis Ritchie


Re: Does Postgresql have a similar pseudo-column "ROWNUM" as

From
Ragnar Hafstað
Date:
On Tue, 2005-05-17 at 15:43 -0300, Alain wrote:
> [how to solve the get next 100 records problem]

I am assuming this is for a web like interface, in other words that
cursors are not applicable
> > [me] 
> > if you are ordering by a unique key, you can use the key value
> > in a WHERE clause.
> > 
> > select ... where ukey>? order by ukey limit 100 offset 100;
> > 
> > (the ? is placeholder for the last value of ukey returned
> > from previous select)
> 
> I tried that. It does not work in the generic case: 6 MegaRec, telephone 
> listing, alphabetical order. The problem is that somewhere there is a 
> single user with too many entries (over 1000). I even tried to filter 
> the repetitions, but somewhere I get stuck if one guy has too mny 
> entries (one for each phone number).
> 
> I tried using both the name and the primary key (with a combined index), 
> to get faster to the record I want, but I was not sucessfull in building 
> a where clause.

lets say pkey is your primary key and skey is your sort key, and 
there exists an index on (skey,pkey)

your first select is
select ... from tab ORDER by skey,pkey LIMIT 100;

your subsequent selects are
select ... from tab WHERE skey>skey_last                       OR (skey=skey_last AND pkey>pkey_last)
ORDER BY skey,pkey                   LIMIT 100 OFFSET 100;
 


> I would appreciate any help, in fact this is my primary reason for 
> joining this list ;-)

gnari




Re: Does Postgresql have a similar pseudo-column "ROWNUM" as

From
PFC
Date:
> your subsequent selects are
> select ... from tab WHERE skey>skey_last
>                        OR (skey=skey_last AND pkey>pkey_last)
>                     ORDER BY skey,pkey
>                     LIMIT 100 OFFSET 100;
why offset ?you should be able to use the skey, pkey values of the last row on the  
page to show the next page, no need for offset then.


Re: Does Postgresql have a similar pseudo-column "ROWNUM" as

From
Ragnar Hafstað
Date:
On Wed, 2005-05-18 at 00:13 +0200, PFC wrote:
> > your subsequent selects are
> > select ... from tab WHERE skey>skey_last
> >                        OR (skey=skey_last AND pkey>pkey_last)
> >                     ORDER BY skey,pkey
> >                     LIMIT 100 OFFSET 100;
> 
>     why offset ?
>     you should be able to use the skey, pkey values of the last row on the  
> page to show the next page, no need for offset then.

of course you are right. the WHERE clause is supposed to replace
the OFFSET. too much cut and pasting without thinking and testing.

gnari




Re: Does Postgresql have a similar pseudo-column "ROWNUM" as

From
Alain
Date:

Ragnar Hafstað escreveu:
>>[how to solve the get next 100 records problem]
> 
>>I tried that. It does not work in the generic case: 6 MegaRec, telephone 
>>listing, alphabetical order.
> 
> lets say pkey is your primary key and skey is your sort key, and 
> there exists an index on (skey,pkey)
> 
> your first select is
> select ... from tab ORDER by skey,pkey LIMIT 100;
> 
> your subsequent selects are
> select ... from tab WHERE skey>skey_last 
>                        OR (skey=skey_last AND pkey>pkey_last) 
>                     ORDER BY skey,pkey
>                     LIMIT 100 OFFSET 100;

I tied that, it is veeery slow, probably due to the OR operand :(

BUT, I think that this is close to a final solution, I made some 
preliminary test ok. Please tell me what you think about this.

Fisrt let's state that I am reading records to put on a screen (in a 
Table/Grid). I separated the problem is *3* parts

-first select is as above:
select ... from tab ORDER by skey,pkey LIMIT 100;

-second method for next 100:
select ... from tab WHERE skey>=skey_last                    ORDER BY skey,pkey                    LIMIT 100;
but here I test for repetitions using pkey and discard them

-now if I get all repetitions or the last 100 have the same skey with 
the second method, I use
select ... from tab WHERE skey=skey_last AND pkey>pkey_last                    ORDER BY skey,pkey
LIMIT100;
 
until I get an empty response, then I go back to the second method.

All queries are extremely fast with 6000000 records and it looks like 
the few redundant or empty queries (but very fast) will not be a problem.

What is your opinion about this (apart that it is a bit complex :) ??

Alain



Re: Does Postgresql have a similar pseudo-column "ROWNUM" as

From
Ragnar Hafstað
Date:
On Tue, 2005-05-17 at 23:16 -0300, Alain wrote:
> 
> Ragnar Hafstað escreveu:
> >>[how to solve the get next 100 records problem]

> BUT, I think that this is close to a final solution, I made some 
> preliminary test ok. Please tell me what you think about this.
> 
> Fisrt let's state that I am reading records to put on a screen (in a 
> Table/Grid). I separated the problem is *3* parts
> 
> -first select is as above:
> select ... from tab ORDER by skey,pkey LIMIT 100;
> 
> -second method for next 100:
> select ... from tab WHERE skey>=skey_last
>                      ORDER BY skey,pkey
>                      LIMIT 100;
> but here I test for repetitions using pkey and discard them
> 
> -now if I get all repetitions or the last 100 have the same skey with 
> the second method, I use
> select ... from tab WHERE skey=skey_last AND pkey>pkey_last
>                      ORDER BY skey,pkey
>                      LIMIT 100;
> until I get an empty response, then I go back to the second method.

if your distribution is such that those skeys that have > 100 records
tend to have a lot more, you might have a higher limit for this case.


> All queries are extremely fast with 6000000 records and it looks like 
> the few redundant or empty queries (but very fast) will not be a problem.
> 
> What is your opinion about this (apart that it is a bit complex :) ??


looks fine

gnari




Changed to: how to solve the get next 100 records problem

From
Alain
Date:
Hi Ragnar (and others),

I found something that is both fast and simple (program side):

Allways assuming that: pkey is a primary key and skey is a sort key, and
there exists an index on (skey,pkey)

first select is
select ... from tab ORDER by skey,pkey LIMIT 100;

subsequent selects are
(select ... from tab WHERE skey=skey_last AND pkey>pkey_last                     ORDER BY skey,pkey LIMIT 100)
UNION
(select ... from tab WHERE skey>skey_last                     ORDER BY skey,pkey LIMIT 100)
ORDER BY skey,pkey LIMIT 100;

The catch is that if the first select would have more than 100 records 
and was limited to 100, the second select's data is completeply 
discarted by the 3rd limit!

The only strange thing is that without the 3rd order by, the order is 
wrong. I didn't expect it because each select is created ordered. Is it 
expected that UNION mixes it all up? (using postgre 7.4.1)

The 3rd order by is not indexed, but it operates in a memory table of no 
more than 200 so it is fast too.

Please comment on this. I tested  and it worked but I really new to sql 
and I feel insecure...

Thanks,
Alain




>>
>>>>[how to solve the get next 100 records problem]
> 
>>BUT, I think that this is close to a final solution, I made some 
>>preliminary test ok. Please tell me what you think about this.
>>
>>Fisrt let's state that I am reading records to put on a screen (in a 
>>Table/Grid). I separated the problem is *3* parts
>>
>>-first select is as above:
>>select ... from tab ORDER by skey,pkey LIMIT 100;
>>
>>-second method for next 100:
>>select ... from tab WHERE skey>=skey_last
>>                     ORDER BY skey,pkey
>>                     LIMIT 100;
>>but here I test for repetitions using pkey and discard them
>>
>>-now if I get all repetitions or the last 100 have the same skey with 
>>the second method, I use
>>select ... from tab WHERE skey=skey_last AND pkey>pkey_last
>>                     ORDER BY skey,pkey
>>                     LIMIT 100;
>>until I get an empty response, then I go back to the second method.
> 
> 
> if your distribution is such that those skeys that have > 100 records
> tend to have a lot more, you might have a higher limit for this case.
> 
> 
> 
>>All queries are extremely fast with 6000000 records and it looks like 
>>the few redundant or empty queries (but very fast) will not be a problem.
>>
>>What is your opinion about this (apart that it is a bit complex :) ??
> 
> 
> 
> looks fine
> 
> gnari
> 
> 
> 
> 



> The only strange thing is that without the 3rd order by, the order is  
> wrong. I didn't expect it because each select is created ordered. Is it  
> expected that UNION mixes it all up? (using postgre 7.4.1)
That's because UNION removes duplicates, which it will probably doing  
using a hash (EXPLAIN ANALYZE is your friend).Use UNION ALL because your WHERE condition allows no duplicates anyway.

UNION ALL preserves the order.So you can get the LIMIT out of the subqueries and put it around the  
UNION ALL.


Re: Changed to: how to solve the get next 100 records problem

From
Ragnar Hafstað
Date:
On Wed, 2005-05-18 at 12:42 -0300, Alain wrote:
> I found something that is both fast and simple (program side):
> ...
> subsequent selects are
> (select ... from tab WHERE skey=skey_last AND pkey>pkey_last
>                       ORDER BY skey,pkey LIMIT 100)
> UNION
> (select ... from tab WHERE skey>skey_last
>                       ORDER BY skey,pkey LIMIT 100)
> ORDER BY skey,pkey LIMIT 100;
> ...
> The only strange thing is that without the 3rd order by, the order is 
> wrong. I didn't expect it because each select is created ordered. Is it 
> expected that UNION mixes it all up? (using postgre 7.4.1)

ORDER BY on subselects are not garanteed by SQL to have any effect,
but Postgres tends to do what you want when possible and not 
detrimental to performance.
In this case, Postgres would probably have kept the order had
you used UNION ALL

a plain UNION implies DISTINCT, which Postgres is free to
implement any way it wants, possibly destroying the order

in this case a UNION ALL is appropriate, as you know that
the 2 selects do not overlap. possibly, a future version
of the planner will be able to detect this.

in any case, the last ORDER BY LIMIT does not cost much, and it
protects you against implementation changes, and limits
the result to 100 records, which might be what you want.

> Please comment on this. I tested  and it worked but I really new to sql 
> and I feel insecure...

it's good.

gnari




Re: Does Postgresql have a similar pseudo-column "ROWNUM" as

From
Chris Browne
Date:
alainm@pobox.com (Alain) writes:
> Andrew Sullivan escreveu:
>> On Thu, May 12, 2005 at 01:07:00PM -0600, Dennis.Jiang@thomson.com wrote:
>>
>>>Does Postgresql have a similar pseudo-column "ROWNUM" as Oracle? If
>>>so, we can write the following query:
>> No.  What is the purpose of your query?  You could use ORDER BY and
>> LIMIT..OFFSET to do what you want. I think.
>
> The problem is probably speed. I have done a lot of tests, and when
> OFFSET gets to a few thousands on a multimega-recs database, it gets
> very very slow... Is there any other to work around that?

The other way to do this would involve creating a cursor against the
table, and using suitable FETCHes to grab the portions that you
needed.

In practice, this has seemed to be the relevant answer to what the
application developer actually wanted.

The common "use case" where I see it is in a web application where
they discover that there are 800K records, and the user only wants a
screenful at a time.  

Establishing a cursor, and having the web app jump around on it, seems
to be the right answer.  (Whether it's reasonably implementable by the
developers may be another question, but that's allowed to be a
separate question ;-).)
-- 
(format nil "~S@~S" "cbbrowne" "acm.org")
http://www.ntlug.org/~cbbrowne/sap.html
Rules of the Evil Overlord #78.  "I will not tell my Legions of Terror
"And he must  be taken alive!" The command will be:  ``And try to take
him alive if it is reasonably practical.''"
<http://www.eviloverlord.com/>


Re: Does Postgresql have a similar pseudo-column "ROWNUM" as

From
Sean Davis
Date:
On May 18, 2005, at 3:52 PM, Chris Browne wrote:

> alainm@pobox.com (Alain) writes:
>> Andrew Sullivan escreveu:
>>> On Thu, May 12, 2005 at 01:07:00PM -0600, Dennis.Jiang@thomson.com 
>>> wrote:
>>>
>>>> Does Postgresql have a similar pseudo-column "ROWNUM" as Oracle? If
>>>> so, we can write the following query:
>>> No.  What is the purpose of your query?  You could use ORDER BY and
>>> LIMIT..OFFSET to do what you want. I think.
>>
>> The problem is probably speed. I have done a lot of tests, and when
>> OFFSET gets to a few thousands on a multimega-recs database, it gets
>> very very slow... Is there any other to work around that?
>
> The other way to do this would involve creating a cursor against the
> table, and using suitable FETCHes to grab the portions that you
> needed.
>
> In practice, this has seemed to be the relevant answer to what the
> application developer actually wanted.
>
> The common "use case" where I see it is in a web application where
> they discover that there are 800K records, and the user only wants a
> screenful at a time.
>
> Establishing a cursor, and having the web app jump around on it, seems
> to be the right answer.  (Whether it's reasonably implementable by the
> developers may be another question, but that's allowed to be a
> separate question ;-).)

In a web app, I doubt that cursors can be useful because of the 
stateless nature of web interaction.  I'd love to hear otherwise, 
but....

Sean



Re: Does Postgresql have a similar pseudo-column "ROWNUM" as

From
"Keith Worthington"
Date:
On Tue, 17 May 2005 12:01:03 -0500, Scott Marlowe wrote
> On Thu, 2005-05-12 at 14:07, Dennis.Jiang@thomson.com wrote:
> > Hi:
> > 
> > Oracle has a pseudo-column "ROWNUM" to return the sequence
> > number in which a row was returned when selected from a table.
> > The first row ROWNUM is 1, the second is 2, and so on.
> > 
> > Does Postgresql have a similar pseudo-column "ROWNUM" as
> > Oracle? If so, we can write the following query:
> > 
> > select * 
> > from (select RowNum, pg_catalog.pg_proc.* 
> >         from pg_catalog.pg_proc) inline_view
> > where RowNum between 100 and 200;
> 
> You can get a functional equivalent with a temporary sequence:
> 
> create temp sequence rownum;
> select *, nextval('rownum') as rownum from sometable;
> 
> ---------------------------(end of broadcast)---------------------------
> TIP 8: explain analyze is your friend

Scott,

I realize that this thread went off in another direction however your
suggestion proved very helpful for a problem that I was trying to solve.  I
wanted the row number of a set returned by a function.  Here is a chopped
version of the function that I wrote.

CREATE OR REPLACE FUNCTION func_bom(integer, integer) RETURNS SETOF func_bom AS
$BODY$  DECLARE     v_number ALIAS FOR $1;     v_line   ALIAS FOR $2;     v_type varchar(8);     r_row
interface.func_so_line_bom%rowtype; BEGIN     SELECT tbl_item.item_type INTO v_type       FROM tbl_line_item       JOIN
tbl_item        ON tbl_line_item.item_id = tbl_item.id      WHERE tbl_line_item.number = v_number        AND
tbl_line_item.line= v_line;     IF v_type = 'ASY' THEN        CREATE TEMP SEQUENCE row_number           INCREMENT BY 1
        START WITH 1;        FOR r_row IN SELECT tbl_line_item.number,                            tbl_line_item.line,
                        nextval('row_number') AS subline,                            tbl_assembly.quantity AS
bom_quantity,                           tbl_assembly.component_id AS bom_item_id,
tbl_item.item_typeAS bom_item_type,                            tbl_item.description AS bom_item_description
         FROM tbl_line_item                       LEFT JOIN tbl_assembly                         ON (
tbl_line_item.item_id::text=                              tbl_assembly.id::text                            )
          JOIN tbl_item                         ON ( tbl_assembly.component_id::text =
tbl_item.id::text                           )                      WHERE tbl_line_item.number = v_number
       AND tbl_line_item.line = v_line                      ORDER BY tbl_line_item.number,
tbl_line_item.line,                               tbl_assembly.component_id        LOOP           RETURN NEXT r_row;
   END LOOP;        DROP SEQUENCE row_number;     ELSIF    v_item_type = 'THIS'           OR v_item_type = 'THAT'
   OR v_item_type = 'OTHER' THEN        FOR r_row IN SELECT           [snip]        LOOP           RETURN NEXT r_row;
    END LOOP;     END IF;     RETURN;  END;
 
$BODY$ LANGUAGE 'plpgsql' VOLATILE STRICT;

Although I have no need to limit the output I tried it just for giggles and it
worked fine.

SELECT * FROM func_bom(12345, 1) WHERE subline between 4 AND 6;

Thanks!

Kind Regards,
Keith


Re: Does Postgresql have a similar pseudo-column "ROWNUM" as

From
Scott Marlowe
Date:
On Fri, 2005-05-20 at 13:27, Keith Worthington wrote:

> Scott,
> 
> I realize that this thread went off in another direction however your
> suggestion proved very helpful for a problem that I was trying to solve.  I
> wanted the row number of a set returned by a function.  Here is a chopped
> version of the function that I wrote.
> 
> CREATE OR REPLACE FUNCTION func_bom(integer, integer)
>   RETURNS SETOF func_bom AS

SNIP

> Although I have no need to limit the output I tried it just for giggles and it
> worked fine.
> 
> SELECT * FROM func_bom(12345, 1) WHERE subline between 4 AND 6;

You're welcome.  I've saved that off to my ~/pgsql directory for future
use.  So, the thanks are back to you. :)