Thread: data type of string literal

data type of string literal

From
nobs@nobswolf.info (Emil Obermayr)
Date:
Hi List,

I just joined because I found a behaviour of implicit casts I don't
understand. I am quite new to Postgre, trying out things and
tried this sql-code:

select cast('8.000' as text) = 8.00 as test, 1 as case
union
select cast('8.000' as text) = 8.000, 2
union
select '8.00' = 8.000, 3

This gives me the following result:

test => f    case => 1
test => t    case => 2
test => t    case => 3

Why is the string literal in case 3 parsed as float so the
comparision is true. While in the other cases the
float literal is auto-casted to a string, so the
comparision is only true if the number of zeros is equal?

Is there a exact column type that fits a string literal? Explicit
casts to char or varchar instead of text gives the same results.

Yours,

Emil 'nobs' Obermayr

Re: data type of string literal

From
Tom Lane
Date:
nobs@nobswolf.info (Emil Obermayr) writes:
> select cast('8.000' as text) = 8.00 as test, 1 as case
> union
> select cast('8.000' as text) = 8.000, 2
> union
> select '8.00' = 8.000, 3

> Why is the string literal in case 3 parsed as float so the
> comparision is true.

The quoted literal is initially considered to be of "unknown" data type,
whereas the unquoted 8.000 is initially considered to be of type
numeric.  Then the "unknown = numeric" operator is resolved as "numeric
= numeric", so the string literal is converted to numeric, and in the
numeric domain 8.00 and 8.000 compare equal.

I can tell that you are not running the latest PG release, btw, because
your first two examples fail entirely in 8.3:

regression=# select cast('8.000' as text) = 8.00 as test;
ERROR:  operator does not exist: text = numeric
LINE 1: select cast('8.000' as text) = 8.00 as test;
                                     ^
HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.

This is a consequence of having made numeric-to-text conversion not
happen without an explicit cast.  In prior releases what you were
getting there was silent conversion of the numeric constant to text
followed by a textual comparison.  That behavior led to lots of
confusion, and I think it's contributing to yours...

You can find more details in the "Type Conversion" section of the
manual.

            regards, tom lane

Re: data type of string literal

From
Michael Glaesemann
Date:
On Feb 26, 2008, at 3:42 , Emil Obermayr wrote:

> Why is the string literal in case 3 parsed as float so the
> comparision is true.

It's not a string literal: it's just a literal. The right hand side
of the comparison is a valid float representation (and not a valid
string representation), while the left hand side is both a valid
float representation and a valid string representation, so Postgres
is interpreting the left hand side as a float.

> While in the other cases the
> float literal is auto-casted to a string, so the
> comparision is only true if the number of zeros is equal?

In cases 1 and 2, you've explicitly cast the left hand side to text,
so Postgres will attempt to interpret the right hand side as text if
it can. This works in 8.2 (and prior versions), but 8.3 is more
strict and throws errors:


test=# select cast('8.000' as text) = 8.00 as test;
ERROR:  operator does not exist: text = numeric
LINE 1: select cast('8.000' as text) = 8.00 as test;
                                      ^
HINT:  No operator matches the given name and argument type(s). You
might need to add explicit type casts.

test=# select cast('8.000' as text) = 8.000;
ERROR:  operator does not exist: text = numeric
LINE 1: select cast('8.000' as text) = 8.000;
                                      ^
HINT:  No operator matches the given name and argument type(s). You
might need to add explicit type casts.

In 8.3, case 3 still works:

test=# select '8.00' = 8.000;
  ?column?
----------
  t
(1 row)

Michael Glaesemann
grzm seespotcode net