TL; DRあなたは二つのことを "間違ってやっていた":returns integer
はreturns float
でなければならず、最後select ..
はreturn ..
でなければなりません。
詳細:
RETURN
PL/pgSQL関数から値を返します - あなたはそれの代わりに、最後のSELECT
を使用する必要があります。 st_distance(..)
はfloat
の値がhttp://postgis.refractions.net/docs/ST_Distance.htmlになるため、最初の行にreturns float
が必要です。
これを試してみてください:
CREATE OR REPLACE FUNCTION calc_distance_for_cities(fromCityId bigint, toCityId bigint) RETURNS float LANGUAGE plpgsql as $$
DECLARE
fromCityCoords Geometry;
toCityCoords Geometry;
BEGIN
SELECT coords INTO fromCityCoords FROM geo_cities WHERE geo_cities.id = fromCityId;
SELECT coords INTO toCityCoords FROM geo_cities WHERE geo_cities.id = toCityId;
RETURN ST_Distance(fromCityCoords, toCityCoords, true);
END;
$$;
また、この関数は実際にPL/pgSQL言語を必要とせず、簡単にCTE(https://www.postgresql.org/docs/current/static/queries-with.html)で、プレーンなSQLで実装することができます。
create or replace function calc_distance_for_cities(int8, int8) returns float as $$
with _from(city_coords) as (
select coords from geo_cities where geo_cities.id = $1
), _to(city_coords) as (
select coords from geo_cities where geo_cities.id = $2
)
select st_distance(_from.city_coords, _to.city_coords)
from _from, _to;
$$ language sql;
かさらに無制限CTE:
create or replace function calc_distance_for_cities(int8, int8) returns float as $$
select st_distance(
(select coords from geo_cities where geo_cities.id = $1),
(select coords from geo_cities where geo_cities.id = $2)
);
$$ language sql;