获取函数在 vacuumdb 中不存在错误

Getting function does not exist error in vacuumdb

我们有一个函数尝试(递归地)从 FHIR 格式的 JSONB 字段中提取所有资源引用(其中引用如下所示:

{
  "reference": "ResourceType/12345"
}

看起来工作正常,我可以使用普通方法创建索引:

directory-db=# drop index index_resources_on_resource_references;
DROP INDEX
directory-db=# CREATE OR REPLACE FUNCTION get_all_references (KEY varchar, value jsonb)
directory-db-#   RETURNS text[]
directory-db-#   AS $$
directory-db$# DECLARE
directory-db$#   results text[];
directory-db$#   i record;
directory-db$# BEGIN
directory-db$#   IF (KEY = 'reference') THEN
directory-db$#     results = ARRAY[value #>> '{}'];
directory-db$#   ELSE
directory-db$#     CASE WHEN jsonb_typeof(value) = 'object' THEN
directory-db$#       FOR i IN
directory-db$#       SELECT
directory-db$#         *
directory-db$#       FROM
directory-db$#         jsonb_each(value)
directory-db$#         LOOP
directory-db$#           SELECT
directory-db$#             INTO results array_cat(results, get_all_references (i.key, i.value));
directory-db$#           END LOOP;
directory-db$#     WHEN jsonb_typeof(value) = 'array' THEN
directory-db$#       FOR i IN
directory-db$#       SELECT
directory-db$#         *
directory-db$#       FROM
directory-db$#         jsonb_array_elements(value) AS value LOOP
directory-db$#     SELECT
directory-db$#       INTO results array_cat(results, get_all_references (NULL, i.value));
directory-db$#   END LOOP;
directory-db$#   ELSE
directory-db$#     results = ARRAY[]::text[];
directory-db$#   END CASE;
directory-db$#   END IF;
directory-db$#   RETURN results;
directory-db$# END;
directory-db$# $$
directory-db-# LANGUAGE plpgsql
directory-db-# IMMUTABLE;
CREATE FUNCTION
directory-db=# 
directory-db=# CREATE INDEX IF NOT EXISTS index_resources_on_resource_references ON resources USING gin ((get_all_references (NULL, data)));
CREATE INDEX
directory-db=# 

我也可以从 psql 中清除索引,但我收到警告。

directory-db=# vacuum (analyze,verbose) index_resources_on_resource_references;
WARNING:  skipping "index_resources_on_resource_references" --- cannot vacuum non-tables or special system tables
VACUUM

但是,当我从命令行工具中清理时,出现错误:

~/src/directory$ vacuumdb -z
vacuumdb: vacuuming database "directory-db"
vacuumdb: error: vacuuming of table "public.resources" in database "directory-db" failed: ERROR:  function get_all_references(text, jsonb) does not exist
LINE 2:                          array_cat(results, get_all_referenc...
                                                    ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
QUERY:  SELECT
                         array_cat(results, get_all_references (i.key::text, to_jsonb(i.value))::text[])
CONTEXT:  PL/pgSQL function public.get_all_references(text,jsonb) line 16 at SQL statement
~/src/directory$ 

就是说,除了从命令行清理外,一切似乎都运行良好。我关心这个警告吗?命令行工具很方便。无论如何要避免在这种情况下出错?如果这有所作为,我们仍然是 运行 PG @ 9.6。

出于安全原因,VACUUM 将使用空 search_path,因此对 get_all_references 的递归函数调用将找不到该函数。

使用架构名称限定调用:

array_cat(结果,<strong>架构名称</strong>。get_all_references(...))

或者,您可以

改变函数get_all_references(varchar, jsonb) SET search_path = <strong>schemaname</strong>;

这里,<strong>schemaname</strong>是包含函数的schema。

出于安全原因,这也是必要的。让该功能依赖于 search_path.

的当前设置是个坏主意