PG::UndefinedFunction:错误:函数 array_append(anyarray,anyelement) 不存在

May*_*hah 6 ruby postgresql rspec ruby-on-rails github

在我的应用程序中,我们有几个使用 GitHub 工作流程配置的测试用例,即使我的文件上只有与空间相关的更改,但仍然出现以下错误。不知道为什么我的规格仍然失败,它之前工作正常。

An error occurred in a `before(:suite)` hook.
Failure/Error: ActiveMedian.create_function

ActiveRecord::StatementInvalid:
  PG::UndefinedFunction: ERROR:  function array_append(anyarray, anyelement) does not exist
  :       CREATE OR REPLACE FUNCTION median(anyarray)
           RETURNS float8 AS
        $$
          WITH q AS
          (
             SELECT val
             FROM unnest($***) val
             WHERE VAL IS NOT NULL
             ORDER BY ***
          ),
          cnt AS
          (
            SELECT COUNT(*) AS c FROM q
          )
          SELECT AVG(val)::float8
          FROM
          (
            SELECT val FROM q
            LIMIT  2 - MOD((SELECT c FROM cnt), 2)
            OFFSET GREATEST(CEIL((SELECT c FROM cnt) / 2.0) - ***,0)
          ) q2;
        $$
        LANGUAGE sql IMMUTABLE;

        DROP AGGREGATE IF EXISTS median(numeric);
        DROP AGGREGATE IF EXISTS median(double precision);
        DROP AGGREGATE IF EXISTS median(anyelement);
        CREATE AGGREGATE median(anyelement) (
          SFUNC=array_append,
          STYPE=anyarray,
          FINALFUNC=median,
          INITCOND='{}'
        );
# ./spec/rails_helper.rb:***54:in `seed'
# ./spec/rails_helper.rb:***:in `block (2 levels) in <top (required)>'
# ------------------
# --- Caused by: ---

# PG::UndefinedFunction:
#   ERROR:  function array_append(anyarray, anyelement) does not exist
#   ./spec/rails_helper.rb:***54:in `seed'
Run Code Online (Sandbox Code Playgroud)

有可能导致该问题的ActiveMedian.create_function原因。spec/rails_helper.rb

任何线索或建议将不胜感激

Edo*_*ard 12

您正在使用 PostGreSQL 14,不是吗?

因为对于 postgres 13 及之前的版本,这应该可以工作,请参阅dbfiddle中的测试结果 。

我确认这不适用于 postgres 14,请参阅dbfiddle中的测试结果。

PostGres 14 手册中解释了原因:

必须重新创建引用某些内置数组函数及其参数类型的用户定义对象 (Tom Lane)

具体来说,array_append()、 array_prepend() 、 array_cat() 、 array_position() 、 array_positions() 、 array_remove() 、 array_replace() 和 width_bucket()曾经接受 anyarray 参数,但现在接受 anyknownarray。因此,用户定义的对象(例如引用这些数组函数签名的聚合和运算符)必须在升级之前删除,并在升级完成后重新创建。

为了使其正常工作,您可以这样做:

CREATE OR REPLACE FUNCTION median(anycompatiblearray)
RETURNS float8 AS
$$
...
$$ LANGUAGE sql IMMUTABLE ;

...

CREATE AGGREGATE median(anycompatible) (
  SFUNC=array_append,
  STYPE=anycompatiblearray,
  FINALFUNC=median,
  INITCOND='{}'
);
Run Code Online (Sandbox Code Playgroud)


May*_*hah 0

经过一番研究,我通过更改 GitHub 上的 Postgres 镜像版本解决了这个问题,如下所示。

文件.github/workflows/build.yml

services:
      postgres:
        image: postgres:13
        ports:
          - 5432:5432
Run Code Online (Sandbox Code Playgroud)

解决方案:这是 Postgres 14 版本的问题,为了快速解决,请将其降级到 Postgres 13。