简体   繁体   English

postgres函数/扩展名未正确转储或还原?

[英]postgres functions / extensions not dumped or restored correctly?

Update 更新

Self-answered, see first comment here and my own answer. 自我解答,请参阅此处的第一条评论和我自己的答案。

Original question 原始问题

I'm setting up a local development postgres db with some sql files, one of them creates a custom function for distance calculations. 我正在使用一些sql文件设置本地开发postgres db,其中一个创建用于距离计算的自定义函数。 Extensions "cube" and "earthdistance" are created, the function works as expected. 创建了扩展名“ cube”和“ earthdistance”,该功能按预期工作。

I'm dumping the local development postgres db, the sql dumps contains the extension creation and the custom function - looks ok. 我正在转储本地开发postgres db,sql转储包含扩展创建和自定义函数-看起来还可以。

I'm importing the dump on another test machine without error messages. 我正在将转储导入另一台测试计算机,而没有任何错误消息。

But here I'm getting an exception when using the function: 但是在使用函数时,这里出现异常:

Caused by: org.postgresql.util.PSQLException: ERROR: function ll_to_earth(numeric, numeric) does not exist
  Hint: No function matches the given name and argument types. You might need to add explicit type casts.
  Where: PL/pgSQL function opengeodb_radius_selection(numeric,numeric,integer,integer) line 3 at RETURN QUERY

The complete SQL code used when setting up the local db: 设置本地数据库时使用的完整SQL代码:

CREATE EXTENSION cube;
CREATE EXTENSION earthdistance;

CREATE FUNCTION
    opengeodb_radius_selection(
        baseLatitude numeric(9,6),
        baseLongitude numeric(9,6),
        radius_in_metres integer,
        opengeodb_level integer)
    RETURNS TABLE(
        locid integer,
        name character varying(255),
        distance float8)
AS
$func$
BEGIN
    RETURN QUERY
    SELECT subQueryAlias.locid, subQueryAlias.name, subQueryAlias.distance
FROM
(
    SELECT *, earth_distance(ll_to_earth(baseLatitude,baseLongitude), ll_to_earth(lat,lon)) as distance
    FROM opengeodb
    GROUP BY opengeodb.locid, opengeodb.lat, opengeodb.lon, opengeodb.name, distance
) subQueryAlias
WHERE plz is not null
AND plz <> ''
AND level = opengeodb_level
AND earth_box(ll_to_earth(lat,lon),radius_in_metres) @> ll_to_earth(baseLatitude,baseLongitude)
AND subQueryAlias.distance <= radius_in_metres
ORDER BY subQueryAlias.distance;
END
$func$ LANGUAGE plpgsql;

The complete SQL code in the dump: 转储中的完整SQL代码:

--
-- PostgreSQL database dump
--

SET statement_timeout = 0;
SET lock_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SET check_function_bodies = false;
SET client_min_messages = warning;

--
-- Name: plpgsql; Type: EXTENSION; Schema: -; Owner: 
--

CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;


--
-- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner: 
--

COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language';


--
-- Name: cube; Type: EXTENSION; Schema: -; Owner: 
--

CREATE EXTENSION IF NOT EXISTS cube WITH SCHEMA public;


--
-- Name: EXTENSION cube; Type: COMMENT; Schema: -; Owner: 
--

COMMENT ON EXTENSION cube IS 'data type for multidimensional cubes';


--
-- Name: earthdistance; Type: EXTENSION; Schema: -; Owner: 
--

CREATE EXTENSION IF NOT EXISTS earthdistance WITH SCHEMA public;


--
-- Name: EXTENSION earthdistance; Type: COMMENT; Schema: -; Owner: 
--

COMMENT ON EXTENSION earthdistance IS 'calculate great-circle distances on the surface of the Earth';


SET search_path = public, pg_catalog;

--
-- Name: opengeodb_radius_selection(numeric, numeric, integer, integer); Type: FUNCTION; Schema: public; Owner: postgres
--

CREATE FUNCTION opengeodb_radius_selection(baselatitude numeric, baselongitude numeric, radius_in_metres integer, opengeodb_level integer) RETURNS TABLE(locid integer, name character varying, distance double precision)
    LANGUAGE plpgsql
    AS $$
BEGIN
    RETURN QUERY
    SELECT subQueryAlias.locid, subQueryAlias.name, subQueryAlias.distance
    FROM
    (
        SELECT *, earth_distance(ll_to_earth(baseLatitude,baseLongitude), ll_to_earth(lat,lon)) as distance
        FROM opengeodb
        GROUP BY opengeodb.locid, opengeodb.lat, opengeodb.lon, opengeodb.name, distance
    ) subQueryAlias
    WHERE plz is not null
    AND plz <> ''
    AND level = opengeodb_level
    AND earth_box(ll_to_earth(lat,lon),radius_in_metres) @> ll_to_earth(baseLatitude,baseLongitude)
    AND subQueryAlias.distance <= radius_in_metres
    ORDER BY subQueryAlias.distance;
END
$$;


ALTER FUNCTION public.opengeodb_radius_selection(baselatitude numeric, baselongitude numeric, radius_in_metres integer, opengeodb_level integer) OWNER TO postgres;

SET default_tablespace = '';

SET default_with_oids = false;

...(followed by table creation and so on)

Is this my fault or erroneous behaviour? 这是我的错还是错误的行为?

ll_to_earth is defined as taking arguments (float8, float8) , but you are passing numeric, numeric . ll_to_earth被定义为采用参数(float8, float8) ,但是您要传递numeric, numeric So you will need to add some casts to your function. 因此,您将需要在函数中添加一些强制类型转换。

It's not clear why it worked previously. 目前尚不清楚为什么它以前可以工作。 Perhaps you were upgrading from an older version? 也许您是从旧版本升级的?

Self-Answering (see first question comment) 自我回答(请参阅第一个问题评论)

On the debian system 9.4.10 was installed, and there is no postgresql-contrib for 9.4.10 for debian (but in my development windows postgres package, also 9.4.10) 在debian系统上安装了9.4.10,并且没有为debian安装9.4.10的postgresql-contrib(但在我的开发Windows postgres软件包中,也是9.4.10)

We've updated the debian system to 9.4.12 and now contrib is included, the function works fine as expected. 我们已经将debian系统更新为9.4.12,现在包含了contrib,该功能可以正常运行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM