获取函数在 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
.
的当前设置是个坏主意
我们有一个函数尝试(递归地)从 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
.