Re: How to implement oracle like rownum(function or seudocolumn) - Mailing list pgsql-hackers

From Jan Wieck
Subject Re: How to implement oracle like rownum(function or seudocolumn)
Date
Msg-id 4437FACD.2060800@Yahoo.com
Whole thread Raw
In response to Re: How to implement oracle like rownum(function or seudocolumn) ?  (Michael Fuhr <mike@fuhr.org>)
Responses Re: How to implement oracle like rownum(function or seudocolumn)  ("Jonah H. Harris" <jonah.harris@gmail.com>)
Re: How to implement oracle like rownum(function or seudocolumn)  (Tom Lane <tgl@sss.pgh.pa.us>)
Re: How to implement oracle like rownum(function or seudocolumn)  (David Fetter <david@fetter.org>)
List pgsql-hackers
Someone correct me if I'm wrong, but I was allways under the impression 
that Oracle's ROWNUM is a thing attached to a row in the final result 
set, whatever (possibly random) order that happens to have. Now a) this 
is something that IMHO belongs into the client or stored procedure code, 
b) if I am right, the code below will break as soon as an ORDER BY is 
added to the query and most importantly c) if a) cannot do the job, it 
indicates that the database schema or business process definition lacks 
some key/referential definition and is in need of a fix.

My humble guess is that c) is also the reason why the ANSI didn't find a 
ROWNUM desirable.


Jan


On 4/8/2006 1:26 PM, Michael Fuhr wrote:
> On Sat, Apr 08, 2006 at 12:46:06PM -0400, Tom Lane wrote:
>> Juan Manuel Diaz Lara <jmdiazlr@yahoo.com> writes:
>> > I need a rownum column, like Oracle. I have searched the mailing lists
>> > and I don't see a satisfactory solution, so I was wondering write a
>> > UDF to implement it, the requirements are:
>> 
>> Try keeping a counter in fcinfo->flinfo->fn_extra.
> 
> Is this close to being correct?
> 
> Datum
> rownum(PG_FUNCTION_ARGS)
> {
>     int64  *row_counter;
> 
>     if (fcinfo->flinfo->fn_extra == NULL) {
>         row_counter = (int64 *)MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
>                                                   sizeof(int64));
>         *row_counter = 0;
>         fcinfo->flinfo->fn_extra = row_counter;
>     }
> 
>     row_counter = fcinfo->flinfo->fn_extra;
> 
>     PG_RETURN_INT64(++(*row_counter));
> }
> 
>> >   3. And more important, need to be called in the right place when
>>  called from subquerys:
>> 
>> Don't expect miracles in this department.  The planner will evaluate the
>> function where it sees fit...
> 
> Would OFFSET 0 be the workaround in this case?
> 
> SELECT rownum(), *
> FROM (SELECT rownum() AS f_rownum, id AS f_id FROM foo) AS f,
>      (SELECT rownum() AS b_rownum, id AS b_id FROM bar) AS b;
>  rownum | f_rownum | f_id  | b_rownum | b_id  
> --------+----------+-------+----------+-------
>       1 |        1 | foo-1 |        1 | bar-1
>       2 |        2 | foo-1 |        2 | bar-2
>       3 |        3 | foo-2 |        3 | bar-1
>       4 |        4 | foo-2 |        4 | bar-2
>       5 |        5 | foo-3 |        5 | bar-1
>       6 |        6 | foo-3 |        6 | bar-2
> (6 rows)
> 
> SELECT rownum(), *
> FROM (SELECT rownum() AS f_rownum, id AS f_id FROM foo OFFSET 0) AS f,
>      (SELECT rownum() AS b_rownum, id AS b_id FROM bar OFFSET 0) AS b;
>  rownum | f_rownum | f_id  | b_rownum | b_id  
> --------+----------+-------+----------+-------
>       1 |        1 | foo-1 |        1 | bar-1
>       2 |        1 | foo-1 |        2 | bar-2
>       3 |        2 | foo-2 |        1 | bar-1
>       4 |        2 | foo-2 |        2 | bar-2
>       5 |        3 | foo-3 |        1 | bar-1
>       6 |        3 | foo-3 |        2 | bar-2
> (6 rows)
> 


-- 
#======================================================================#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me.                                  #
#================================================== JanWieck@Yahoo.com #


pgsql-hackers by date:

Previous
From: "Jonah H. Harris"
Date:
Subject: Re: Support Parallel Query Execution in Executor
Next
From: "Jonah H. Harris"
Date:
Subject: Re: How to implement oracle like rownum(function or seudocolumn)