Thread: Round Numeric Type

Round Numeric Type

From
"Ezequias Rodrigues da Rocha"
Date:
Hi list,<br /><br />I did a trigger to update a points on a table but in some cases the PostgreSQL does a round of my
Numericlike.<br /><br />If >= 0.5 so postgresql puts 1<br />If < 0.5 so postgresql puts 0<br /><br />Did anybody
knowsif it is possible to control this matter ? <br /><br /><br />Regards<br />Ezequias  

record datatype comparisons

From
"George Pavlov"
Date:
I am trying to do some record comparisons using IS DISTINCT FROM and I
feel like I am missing something. Basically comparisons between manually
constructed records work as expected, but if I have a record returned by
a select on one (or both sides) of the comparison I get errors "ERROR:
operator does not exist: record = record". I suspect some simple missing
parentheses/syntax issue but I feel like I have tried everything...

The simplest way to reproduce:

select ((1::int,'a'::varchar) is distinct from (2::int,'a'::varchar));

--> true, as expected

select ((1::int,'a'::varchar) is distinct from (select
(2::int,'a'::varchar)));

--> throws the error

Both (1::int,'a'::varchar) and (select (2::int,'a'::varchar)) are of
type record, aren't they?

In real life I want the right side of the IS DISTINCT FROM to be the
result of a query to a table.

Please help. Thanks!

George


Re: Round Numeric Type

From
Andrew Sullivan
Date:
On Tue, Oct 31, 2006 at 05:35:17PM -0200, Ezequias Rodrigues da Rocha wrote:
> Hi list,
> 
> I did a trigger to update a points on a table but in some cases the
> PostgreSQL does a round of my Numeric like.
> 
> If >= 0.5 so postgresql puts 1
> If < 0.5 so postgresql puts 0
> 
> Did anybody knows if it is possible to control this matter ?

Sounds like your datatype doesn't match your input, and that you've
got a type that rounds.  What's the datatype you're putting into?

A

-- 
Andrew Sullivan  | ajs@crankycanuck.ca
Users never remark, "Wow, this software may be buggy and hard 
to use, but at least there is a lot of code underneath."    --Damien Katz


Re: record datatype comparisons

From
Andrew Sullivan
Date:
On Tue, Oct 31, 2006 at 12:38:36PM -0800, George Pavlov wrote:
> Both (1::int,'a'::varchar) and (select (2::int,'a'::varchar)) are of
> type record, aren't they?

I don't think so.  Psql gives you a hint that not:

testing=# SELECT (1::int, 'a'::varchar); row  
-------(1,a)
(1 row)

testing=# SELECT (SELECT(1::int, 'a'::varchar));?column? 
----------(1,a)
(1 row)

Note the column headers.  They're differently shaped.  Because
pseudotype record doesn't have a shape, equality doesn't make sense,
so you need two shapes that are already identical, so they can use
the matching rules for that.

A

-- 
Andrew Sullivan  | ajs@crankycanuck.ca
Everything that happens in the world happens at some place.    --Jane Jacobs 


Re: record datatype comparisons

From
"George Pavlov"
Date:
thanks fo the reply. i was misled by pgAdmin (1.6) giving both as
"record" in the datatype (i thought "row" and "?column?" were just "best
guess" column headers).

so, if they are indeed differently shaped is there any way to make them
be the same shape?

note that this one also fails with the same error (one would think these
are the "same shape"):

select  (select (1,2))
is distinct from  (select (1,2))
;

ERROR: operator does not exist: record = record
SQL state: 42883
Hint: No operator matches the given name and argument type(s). You may
need to add explicit type casts.



> -----Original Message-----
> From: pgsql-sql-owner@postgresql.org
> [mailto:pgsql-sql-owner@postgresql.org] On Behalf Of Andrew Sullivan
> Sent: Tuesday, October 31, 2006 1:23 PM
> To: pgsql-sql@postgresql.org
> Subject: Re: [SQL] record datatype comparisons
>
> On Tue, Oct 31, 2006 at 12:38:36PM -0800, George Pavlov wrote:
> > Both (1::int,'a'::varchar) and (select (2::int,'a'::varchar)) are of
> > type record, aren't they?
>
> I don't think so.  Psql gives you a hint that not:
>
> testing=# SELECT (1::int, 'a'::varchar);
>   row
> -------
>  (1,a)
> (1 row)
>
> testing=# SELECT (SELECT(1::int, 'a'::varchar));
>  ?column?
> ----------
>  (1,a)
> (1 row)
>
> Note the column headers.  They're differently shaped.  Because
> pseudotype record doesn't have a shape, equality doesn't make sense,
> so you need two shapes that are already identical, so they can use
> the matching rules for that.
>
> A
>
> --
> Andrew Sullivan  | ajs@crankycanuck.ca
> Everything that happens in the world happens at some place.
>         --Jane Jacobs


Re: record datatype comparisons

From
Volkan YAZICI
Date:
On Oct 31 04:22, Andrew Sullivan wrote:
> On Tue, Oct 31, 2006 at 12:38:36PM -0800, George Pavlov wrote:
> > Both (1::int,'a'::varchar) and (select (2::int,'a'::varchar)) are of
> > type record, aren't they?
> 
> I don't think so.  Psql gives you a hint that not:
> 
> testing=# SELECT (1::int, 'a'::varchar);
>   row  
> -------
>  (1,a)
> (1 row)
> 
> testing=# SELECT (SELECT(1::int, 'a'::varchar));
>  ?column? 
> ----------
>  (1,a)
> (1 row)
> 
> Note the column headers.  They're differently shaped.  Because
> pseudotype record doesn't have a shape, equality doesn't make sense,
> so you need two shapes that are already identical, so they can use
> the matching rules for that.

Can you be more verbose please? I couldn't understand what you mean with
"shape". AFAIK, both above queries should return same TupleDesc, which I
think means they should share same "shape". I don't have an idea about
the row comparison internals, but I still cannot see a reason for the
difference of returned types. I'd be appreciated if you can clarify the
explanation a little bit.


Regards.


Re: record datatype comparisons

From
Alvaro Herrera
Date:
George Pavlov wrote:
> thanks fo the reply. i was misled by pgAdmin (1.6) giving both as
> "record" in the datatype (i thought "row" and "?column?" were just "best
> guess" column headers). 
> 
> so, if they are indeed differently shaped is there any way to make them
> be the same shape?
> 
> note that this one also fails with the same error (one would think these
> are the "same shape"):
> 
> select 
>   (select (1,2)) 
> is distinct from 
>   (select (1,2)) 
> ;

This one works:

alvherre=# select row(1,2)
is distinct from row(1,2)
;?column? 
----------f
(1 fila)

Is that what you're after?

-- 
Alvaro Herrera                                http://www.CommandPrompt.com/
The PostgreSQL Company - Command Prompt, Inc.


Re: record datatype comparisons

From
Volkan YAZICI
Date:
On Oct 31 06:49, Alvaro Herrera wrote:
> George Pavlov wrote:
> > thanks fo the reply. i was misled by pgAdmin (1.6) giving both as
> > "record" in the datatype (i thought "row" and "?column?" were just "best
> > guess" column headers). 
> > 
> > so, if they are indeed differently shaped is there any way to make them
> > be the same shape?
> > 
> > note that this one also fails with the same error (one would think these
> > are the "same shape"):
> > 
> > select 
> >   (select (1,2)) 
> > is distinct from 
> >   (select (1,2)) 
> > ;
> 
> This one works:
> 
> alvherre=# select
>   row(1,2)
> is distinct from
>   row(1,2)
> ;
>  ?column? 
> ----------
>  f
> (1 fila)

What's the difference between "SELECT (1, 2);" and "SELECT ROW(1, 2);"?


Regards.


Re: Round Numeric Type

From
"Ezequias Rodrigues da Rocha"
Date:
Numeric(9,2)

2006/10/31, Andrew Sullivan <ajs@crankycanuck.ca>:
On Tue, Oct 31, 2006 at 05:35:17PM -0200, Ezequias Rodrigues da Rocha wrote:
> Hi list,
>
> I did a trigger to update a points on a table but in some cases the
> PostgreSQL does a round of my Numeric like.
>
> If >= 0.5 so postgresql puts 1
> If < 0.5 so postgresql puts 0
>
> Did anybody knows if it is possible to control this matter ?

Sounds like your datatype doesn't match your input, and that you've
got a type that rounds.  What's the datatype you're putting into?

A

--
Andrew Sullivan  | ajs@crankycanuck.ca
Users never remark, "Wow, this software may be buggy and hard
to use, but at least there is a lot of code underneath."
                --Damien Katz

---------------------------(end of broadcast)---------------------------
TIP 2: Don't 'kill -9' the postmaster



--
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
                                  Atenciosamente (Sincerely)
                        Ezequias Rodrigues da Rocha
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
A pior das democracias ainda é melhor do que a melhor das ditaduras
The worst of democracies is still better than the better of dictatorships
http://ezequiasrocha.blogspot.com/

Re: record datatype comparisons

From
Andrew Sullivan
Date:
On Tue, Oct 31, 2006 at 11:45:00PM +0200, Volkan YAZICI wrote:
> > 
> > Note the column headers.  They're differently shaped.  Because
> > pseudotype record doesn't have a shape, equality doesn't make sense,
> > so you need two shapes that are already identical, so they can use
> > the matching rules for that.
> 
> Can you be more verbose please? I couldn't understand what you mean with
> "shape". 

It's an analogy, really.  The datatype numeric() for instance, is
determined.  Because it's determined, you can have determinate rules
for comparing one to another.

But the pseudotype record doesn't work that way.  It can accept
whatever you put in there, which is why you can define a variable as
type record, and then select from different tables (or even different
datatypes!) to it in plpgsql: it accommodates these different things. 
The trade-off is that comparing a record to another record won't
always work: because what a record is is not pre-determined, you
can't have determinate rules for comparing one record to another. 
And without determinate rules, you can't have an equality operator.

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: record datatype comparisons

From
Andrew Sullivan
Date:
On Tue, Oct 31, 2006 at 11:58:08PM +0200, Volkan YAZICI wrote:
> On Oct 31 06:49, Alvaro Herrera wrote:
> > > select 
> > >   (select (1,2)) 
> > > is distinct from 
> > >   (select (1,2)) 
> > > ;

> > alvherre=# select
> >   row(1,2)
> > is distinct from
> >   row(1,2)
> 
> What's the difference between "SELECT (1, 2);" and "SELECT ROW(1, 2);"?

It's not the difference between SELECT (1,2) and SELECT ROW(1,2)
that's relevant, but the difference between SELECT (SELECT (1,2)) and
SELECT ROW(1,2).  

The row's datatype(s) is(are) defined.  The record's datatype isn't. 
So you can have an equality operator for the row.  You can see this
from the error message when you do this:

testing=# SELECT ROW(1,2) is distinct from ROW ('a','b');
ERROR:  invalid input syntax for integer: "a"

This is part of the subtle difference between the record and row
datatypes.

A

-- 
Andrew Sullivan  | ajs@crankycanuck.ca
The plural of anecdote is not data.    --Roger Brinner


Re: record datatype comparisons

From
Andrew Sullivan
Date:
On Wed, Nov 01, 2006 at 11:00:04PM +0200, Volkan YAZICI wrote:
> But there should be a way to reach the types of the attributes of the
> record data type. Otherwise, how would it be possible to place it into
> another tuple as an attribute. 

Well, surely there is, but that has to happen at assignment time,
AFAICT.  So you can decide what the record is on the basis of the
datatype, but you can't write an equality operator, because you don't
know what the general rule is going to be in advance.  At least,
that's as far as I'm able to understand how to do this.  But I'm
really past my Latin at this point, because even if I looked at the
code that supports the record type, I wouldn't understand it.

A

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


Re: record datatype comparisons

From
Volkan YAZICI
Date:
On Nov 01 09:28, Andrew Sullivan wrote:
> On Tue, Oct 31, 2006 at 11:45:00PM +0200, Volkan YAZICI wrote:
> > > Note the column headers.  They're differently shaped.  Because
> > > pseudotype record doesn't have a shape, equality doesn't make sense,
> > > so you need two shapes that are already identical, so they can use
> > > the matching rules for that.
> > 
> > Can you be more verbose please? I couldn't understand what you mean with
> > "shape". 

First, thanks for your answer.

> It's an analogy, really.  The datatype numeric() for instance, is
> determined.  Because it's determined, you can have determinate rules
> for comparing one to another.
> 
> But the pseudotype record doesn't work that way.  It can accept
> whatever you put in there

But there should be a way to reach the types of the attributes of the
record data type. Otherwise, how would it be possible to place it into
another tuple as an attribute. And AFAIK, there're some (hardcoded) ways
to get TupleDesc of a record data type. From this point of view, as long
as you're able to get the TupleDesc of a record data type, you should
have been able to compare it with any other row/record data type.

OTOH, let's assume that we have no idea about attributes of a record
data type. So how does PostgreSQL manage to output it without knowing
attributes' typoutput functions due to their data type OIDs? That sounds
like a contradiction to me.

> which is why you can define a variable as type record, and then select
> from different tables (or even different datatypes!) to it in plpgsql:
> it accommodates these different things. 

IMHO, plpgsql's record data type is a totally different thing.

> The trade-off is that comparing a record to another record won't
> always work: because what a record is is not pre-determined, you
> can't have determinate rules for comparing one record to another. 
> And without determinate rules, you can't have an equality operator.

IIRC, there's some kind of type registration mechanism in the PostgreSQL
internals while forming a record data type. (I'm not sure but, IIRC,
BlessTupleDesc() registers the TupleDesc into somewhere, so it'll be
able to reach its attributes through its registered TupleDesc in the
future.)

Can you point me to related source/README files in the PostgreSQL
source? I read a little bit about it in the backend/parser/*.c and
couldn't see the distinction you explained. Maybe I was looking at wrong
lines.


Regards.