Re: Error en funcion SOLUCIONADO

From: Alvaro Herrera <alvherre(at)commandprompt(dot)com>
To: "masc68(at)gmail(dot)com" <masc68(at)gmail(dot)com>
Cc: Jaime Casanova <jaime(at)2ndquadrant(dot)com>, pgsql-es-ayuda <pgsql-es-ayuda(at)postgresql(dot)org>
Subject: Re: Error en funcion SOLUCIONADO
Date: 2010-11-15 19:50:04
Message-ID: 1289849798-sup-5874@alvh.no-ip.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-es-ayuda

Excerpts from Alvaro Herrera's message of mié oct 27 11:19:08 -0300 2010:
> Excerpts from masc68(at)gmail(dot)com's message of mié oct 27 11:07:04 -0300 2010:
> > Alvaro, muy buena explicación acerca de los tipos, pero disculpen mi
> > insistencia el porque en un insert normal esta situación no se
> > produce, pero en una función si se dá éste problema
>
> Lo voy a investigar y te cuento.

La explicación era bien sencilla: el cast desde int4 a int2 es "en
asignación". Esto quiere decir que se aplica cuando se asigna el valor
a una columna de una tabla. Es decir, si tienes

CREATE TABLE masc (a int2)
INSERT INTO masc VALUES (42);

el valor 42 recibe inicialmente tipo int4, pero como se está asignando a
una columna de tipo int2, se aplica cualquier cast de asignación que
exista. Por lo tanto eso funciona.

En cambio, cuando llamas a una función,

CREATE FUNCTION masc (a int2) RETURNS int4 LANGUAGE sql AS $$
SELECT $1 + 1 $$;

sólo se permiten casts de tipo implícito. Ese no es implícito así que
no funciona:

alvherre=# select masc(42);
ERROR: no existe la función masc(integer)
LÍNEA 1: select masc(42);
^
SUGERENCIA: Ninguna función coincide en el nombre y tipos de argumentos. Puede desear agregar conversión explícita de tipos.

Pero por ej. el cast int4 a float8 sí es implícito, así que esto sí funciona:

alvherre=# CREATE or replace FUNCTION masc2 (a float8) RETURNS int4 LANGUAGE sql AS $$
select cast($1 + 1 as integer); $$;
CREATE FUNCTION
alvherre=# select masc2(42);
masc2
───────
43
(1 fila)

El motivo por el cual la conversión de int4 a int2 es explícito pero el
de int4 a float8 es en asignación tiene que ver con el hecho de que int2
no necesariamente puede representar todo el dominio de int4.

Para más detalles sobre las conversiones de tipo (“casts”), mira la
referencia de CREATE CAST:
http://www.postgresql.org/docs/9.0/static/sql-createcast.html

--
Álvaro Herrera <alvherre(at)commandprompt(dot)com>
The PostgreSQL Company - Command Prompt, Inc.
PostgreSQL Replication, Consulting, Custom Development, 24x7 support

In response to

Responses

Browse pgsql-es-ayuda by date

  From Date Subject
Next Message Miguel Angel Hernandez Moreno 2010-11-15 19:50:13 Re: Depurar funciones
Previous Message Miguel Angel Hernandez Moreno 2010-11-15 19:44:11 Re: warning en bd