Es necesario convertir la matriz en una fila. Por ejemplo, el uso de generate_series
:
SELECT ARRAY(SELECT ROUND(ARRAY[1.53224,0.23411234])[i], 2) FROM generate_series(1,2) AS s(i));
Sé que es bastante feo. Debería haber una función de ayuda para facilitar tales asignaciones.
Tal vez algo así como (sí que es horrible, lento y frágil código dinámico):
CREATE OR REPLACE FUNCTION map_with_arg(TEXT, ANYARRAY, TEXT)
RETURNS ANYARRAY
IMMUTABLE STRICT
LANGUAGE 'plpgsql' AS
$$
DECLARE
i INTEGER;
t TEXT;
cmd TEXT;
BEGIN
FOR i IN array_lower($2, 1) .. array_upper($2, 1) LOOP
cmd := 'SELECT ('||quote_ident($1)||'('||quote_nullable($2[i])||', '||quote_nullable($3)||'))::TEXT';
EXECUTE cmd INTO t;
$2[i] := t;
END LOOP;
RETURN $2;
END;
$$;
select map_with_arg('repeat', array['can','to']::TEXT[], '2');
map_with_arg
---------------
{cancan,toto}
actualización Se me ocurre que podríamos utilizar un único estado dinámico para todo el bucle. Esto podría mitigar algunas de las preocupaciones de rendimiento.
CREATE OR REPLACE FUNCTION map_with_arg(TEXT, ANYARRAY, TEXT)
RETURNS ANYARRAY
IMMUTABLE STRICT
LANGUAGE 'plpgsql' AS
$$
DECLARE
cmd TEXT;
rv TEXT;
BEGIN
cmd := 'SELECT ARRAY(SELECT (' || quote_ident($1)||'($1[i], '||quote_nullable($3)||'))::TEXT FROM generate_subscripts($1, 1) AS gs(i))';
EXECUTE cmd USING $2 INTO rv;
RETURN rv;
END;
$$;
sugerencias increíbles de todos. Creo que iré con el proceso almacenado ya que necesito aplicar este tipo de función de 'mapa' todo el tiempo. Sería aún mayor si pudiera pasar una función al proceso almacenado, convirtiéndolo así en un proceso almacenado de fábrica que lo convertiría en una verdadera función de "mapa". Pero, esto funcionará por ahora. Gracias de nuevo, a todos. – punkish
Re: paso en una función: puede estar interesado en http://stackoverflow.com/questions/8346065/function-as-parameter-to-another-function-in-postgres. (Está lejos de ser ideal, pero puede obtener algún uso de él.) – ruakh