¿Por qué hay una diferencia en el comportamiento entre usar una Función de retorno de conjunto (SRF) en la lista SELECCIONAR versus usar SRF en la cláusula FROM?
Por ejemplo, para un SRF simple que devuelve 2 filas:
CREATE OR REPLACE FUNCTION gen_series(out integer, out int)
RETURNS SETOF record AS $$
SELECT 1,1
UNION
SELECT 2,2;
$$ LANGUAGE SQL;
SELECT gen_series();
devuelve dos filas de columnas individuales, cada una con un registro:
=> gen_series
------------
(1,1)
(2,2)
(2 rows)
Mientras que SELECT * FROM gen_series();
devuelve dos filas con el registro expandido:
=> column1 | column2
---------+---------
1 | 1
2 | 2
(2 rows)
En comparación, si el SRF está devolviendo una sola columna, entonces llamar al SRF en la cláusula SELECT o FROM no hace ninguna diferencia. p.ej:
=> SELECT generate_series(1,2);
generate_series
-----------------
1
2
(2 rows)
=> SELECT * FROM generate_series(1,2);
generate_series
-----------------
1
2
(2 rows)
Mis preguntas son:
No entiendo por qué en el segundo caso, el comportamiento de SRF es diferente del primer caso solo porque la tabla devuelta tiene una sola columna. ¿Es este comportamiento realmente consistente en términos de tipos, tuplas y conjuntos?
¿Cuál es la diferencia entre los dos casos que conduce a un comportamiento diferente?
SRF se puede usar como tablas como se muestra arriba, pero ¿se pueden usar tablas para reemplazar los SRF también? p.ej
SELECT my_table;
Aparentemente, esto no se puede hacer, pero ¿por qué es SELECT my_SRF();
posible, mientras
SELECT my_table;
que no está permitido (en términos de relaciones y matemáticas)?
SELECT my_table;
no es una sintaxis válidaRespuestas:
Postgres trata el caso simple de manera diferente. Las columnas múltiples se tratan como tipo compuesto (fila de tabla), que solo se descompone con
SELECT * FROM ...
, mientras que una sola columna de tipo escalar se trata solo como eso, sin envoltorio de tipo compuesto agregado. EntoncesSELECT my_SRF()
produce lo mismo queSELECT * FROM my_SRF()
para el caso simple. El manual sobre funciones de tabla :Estoy de acuerdo en que esto es confuso, y usted no es el primero en confundirse. (Considere la alternativa, sin embargo: agregar un contenedor de tipo compuesto alrededor de una sola columna puede ser aún más confuso).
Pero no es tan confuso como lo que sucede cuando combina múltiples funciones SRF en la
SELECT
lista. Sin embargo, esto va a cambiar con Postgres 10 para siempre:La forma segura y menos confusa para cualquier caso es mover las funciones SRF a la
FROM
cláusula. Use unaLATERAL
combinación si necesita referirse a columnas de otra tabla. El manual sugiere:fuente