Comprender la función de retorno de conjuntos (SRF) en la lista SELECT


8

¿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:

  1. 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?

  2. ¿Cuál es la diferencia entre los dos casos que conduce a un comportamiento diferente?

  3. 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álida
Mladen Uzelac

Respuestas:


3

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. Entonces SELECT my_SRF()produce lo mismo que SELECT * FROM my_SRF()para el caso simple. El manual sobre funciones de tabla :

Las funciones de tabla son funciones que producen un conjunto de filas, formadas por tipos de datos base (tipos escalares) o tipos de datos compuestos (filas de tablas).

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 SELECTlista. 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 FROMcláusula. Use una LATERALcombinación si necesita referirse a columnas de otra tabla. El manual sugiere:

La LATERALsintaxis produce resultados menos sorprendentes cuando se llaman múltiples funciones de retorno de conjuntos, y generalmente debería usarse en su lugar.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.