Thread: row-wise comparison question/issue

row-wise comparison question/issue

From
Jeremy Drake
Date:
I noticed something odd when trying to use the row-wise comparison
mentioned in the release notes for 8.2 and in the docs
http://developer.postgresql.org/pgdocs/postgres/functions-comparisons.html#ROW-WISE-COMPARISON

This sets up a suitable test:

create type myrowtype AS (a integer, b integer);
create table myrowtypetable (rowval myrowtype);

insert into myrowtypetable select (a, b)::myrowtype from   generate_series(1,5) a, generate_series(1,5) b;

First I get this error:

select rowval < rowval from myrowtypetable ;
ERROR:  operator does not exist: myrowtype < myrowtype
LINE 1: select rowval < rowval from myrowtypetable ;                     ^
HINT:  No operator matches the given name and argument type(s). You may
need to add explicit type casts.

OK, I guess I can live with that.  I did create a new type, and there are
no operators for it...

Now, I can do the following (pointless) query
select ROW((rowval).*) < ROW((rowval).*) from myrowtypetable ;

and I get 25 rows of 'f'.  So far so good.

But if I try to do
select rowval from myrowtypetable ORDER BY ROW((rowval).*);
ERROR:  could not identify an ordering operator for type record
HINT:  Use an explicit ordering operator or modify the query.

or even
select rowval from myrowtypetable ORDER BY ROW((rowval).*) USING <;
ERROR:  operator does not exist: record < record
HINT:  No operator matches the given name and argument type(s). You may
need to add explicit type casts.

I know that that less-than operator exists, because I just used it in the
query that worked above.  It seems that ORDER BY just can't find it for
some reason.

Is it supposed to not work in order by?  That doesn't really make sense to
me why order by should be special for this.



-- 
All extremists should be taken out and shot.


Re: row-wise comparison question/issue

From
"Merlin Moncure"
Date:
On 10/20/06, Jeremy Drake <pgsql@jdrake.com> wrote:
> I noticed something odd when trying to use the row-wise comparison
> mentioned in the release notes for 8.2 and in the docs
> http://developer.postgresql.org/pgdocs/postgres/functions-comparisons.html#ROW-WISE-COMPARISON
>
> This sets up a suitable test:
>
> create type myrowtype AS (a integer, b integer);
> create table myrowtypetable (rowval myrowtype);
>
> insert into myrowtypetable select (a, b)::myrowtype from
>     generate_series(1,5) a, generate_series(1,5) b;
>
> First I get this error:
>
> select rowval < rowval from myrowtypetable ;
> ERROR:  operator does not exist: myrowtype < myrowtype
> LINE 1: select rowval < rowval from myrowtypetable ;
>                       ^
> HINT:  No operator matches the given name and argument type(s). You may
> need to add explicit type casts.
>
> OK, I guess I can live with that.  I did create a new type, and there are
> no operators for it...
>
> Now, I can do the following (pointless) query
> select ROW((rowval).*) < ROW((rowval).*) from myrowtypetable ;
>
> and I get 25 rows of 'f'.  So far so good.
>
> But if I try to do
> select rowval from myrowtypetable ORDER BY ROW((rowval).*);
> ERROR:  could not identify an ordering operator for type record
> HINT:  Use an explicit ordering operator or modify the query.
>
> or even
> select rowval from myrowtypetable ORDER BY ROW((rowval).*) USING <;
> ERROR:  operator does not exist: record < record
> HINT:  No operator matches the given name and argument type(s). You may
> need to add explicit type casts.
>
> I know that that less-than operator exists, because I just used it in the
> query that worked above.  It seems that ORDER BY just can't find it for
> some reason.
>
> Is it supposed to not work in order by?  That doesn't really make sense to
> me why order by should be special for this.

that would be neat.  i know that row construction and comparison as
currently implemented is sql standard...is the stuff you are
suggesting also standard? (im guessing no).

I'll throw something else on the pile:

esilo=# select (foo).* from foo order by (foo).*;
ERROR:  column foo.* does not exist

esilo=# select (foo).* from foo;a | b | c
---+---+---
(0 rows)

seems a little contradictory...

note jeremy that the more common use of row comparison would be to
construct rows on the fly, usually on fields comprising a key with an
explicit order by:

select a,b,c from foo where (a,b,c) > (1,2,3) order by a,b,c;

works fine

merlin


Re: row-wise comparison question/issue

From
Tom Lane
Date:
Jeremy Drake <pgsql@jdrake.com> writes:
> select rowval from myrowtypetable ORDER BY ROW((rowval).*) USING <;
> ERROR:  operator does not exist: record < record

This isn't required by the spec, and it's not implemented.  I don't
see that it'd give any new functionality anyway, since you can always
do ORDER BY rowval.f1, rowval.f2, ...

The cases that are implemented are comparisons of explicit row
constructors, eg "(a,b,c) < (d,e,f)" --- which I think is all
you'll find support for in the spec.
        regards, tom lane


Re: row-wise comparison question/issue

From
Jeremy Drake
Date:
On Fri, 20 Oct 2006, Tom Lane wrote:

> Jeremy Drake <pgsql@jdrake.com> writes:
> > select rowval from myrowtypetable ORDER BY ROW((rowval).*) USING <;
> > ERROR:  operator does not exist: record < record
>
> This isn't required by the spec, and it's not implemented.  I don't
> see that it'd give any new functionality anyway, since you can always
> do ORDER BY rowval.f1, rowval.f2, ...
>
> The cases that are implemented are comparisons of explicit row
> constructors, eg "(a,b,c) < (d,e,f)" --- which I think is all
> you'll find support for in the spec.

I just think it is quite unexpected that the operator < is defined in some
places and not in others.  And the way I wrote the order by, it should
have been comparing explicit row constructors (compare the explicitly
constructed row for each rowval in order to sort).  I don't understand how
the operator < in a where clause would be different than the operator <
used by the order by.  If I were to make a custom type in C, and write
these same operators for it, they would work in both places, right?  Why
then would this be any different?


-- 
If someone had told me I would be Pope one day, I would have studied
harder.    -- Pope John Paul I


Re: row-wise comparison question/issue

From
Tom Lane
Date:
Jeremy Drake <pgsql@jdrake.com> writes:
> I just think it is quite unexpected that the operator < is defined in some
> places and not in others.

Row-wise comparison isn't an operator, it's a syntactic construct.
Consider

(now(), 'foo', 42) < (SELECT timestampcol, textcol, intcol FROM sometable WHERE ...)

There isn't any single operator in the system that implements that.

(And no, orthogonality is not one of the strong points of SQL...)
        regards, tom lane