Обсуждение: 5 is not a smallint but '5' is

Поиск
Список
Период
Сортировка

5 is not a smallint but '5' is

От
John DeSoi
Дата:
I was surprised to discover this today. I can work around it, but it seems counterintuitive. If 5 can't be parsed as a
smallint,I would feel better if '5' was not one either. 

John DeSoi, Ph.D.



psql (9.2.4)
Type "help" for help.

temp=# create or replace function itest (param smallint) returns integer as $$ select $1 + 5; $$ language sql;
CREATE FUNCTION
temp=# select itest(5);
ERROR:  function itest(integer) does not exist
LINE 1: select itest(5);
               ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
temp=# select itest('5');
 itest
-------
    10
(1 row)

Re: 5 is not a smallint but '5' is

От
bricklen
Дата:
On Mon, Jul 29, 2013 at 8:11 AM, John DeSoi <desoi@pgedit.com> wrote:
I was surprised to discover this today. I can work around it, but it seems counterintuitive. If 5 can't be parsed as a smallint, I would feel better if '5' was not one either.


temp=# create or replace function itest (param smallint) returns integer as $$ select $1 + 5; $$ language sql;
CREATE FUNCTION
temp=# select itest(5);
ERROR:  function itest(integer) does not exist
LINE 1: select itest(5);
               ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
temp=# select itest('5');
 itest
-------
    10
(1 row)



FWIW, It works if you don't rely on the implicit cast, and explicitly cast it to smallint:

select itest(5::smallint);
 itest
-------
    10

Re: 5 is not a smallint but '5' is

От
Tom Lane
Дата:
John DeSoi <desoi@pgedit.com> writes:
> I was surprised to discover this today. I can work around it, but it seems counterintuitive. If 5 can't be parsed as
asmallint, I would feel better if '5' was not one either. 

Yeah, 5 is an int not a smallint, but '5' is not a smallint: it's a
literal of unknown type, for which we try to deduce a type from context.

> temp=# select itest(5);
> ERROR:  function itest(integer) does not exist
> temp=# select itest('5');
>  itest
> -------
>     10
> (1 row)

In this example, since you only have one function named itest(),
the parser is able to deduce that the literal must be intended
to be of type smallint.

By and large, since there's an implicit cast from smallint to int and
not vice versa, it's usually best to declare functions as taking int
even if you expect they'll mainly be called with smallint parameters.

            regards, tom lane