我在具有相同函數名稱的單個數據庫中有兩個類似的模式。 每個模式都由與模式名稱相匹配的角色擁有。使用嵌套函數的PL/pgSQL函數名稱解析
我有關於嵌套函數的函數名稱解析的問題。 我在期待外層函數會調用同一模式中的內層函數,但它不會! 這個名字是在運行時基於search_path動態解析的,這使得一些敏感,但不是如我所願。
這是一個測試用例。比方說,例如模式和角色被命名爲test和prod,如下所示。
測試模式:CREATE ROLE test NOLOGIN;
CREATE SCHEMA test AUTHORIZATION test;
CREATE OR REPLACE FUNCTION test.inner_func() RETURNS TEXT
AS $BODY$
BEGIN
RETURN 'test function';
END
$BODY$ LANGUAGE 'plpgsql';
ALTER FUNCTION test.inner_func() OWNER TO test;
CREATE OR REPLACE FUNCTION test.outer_func() RETURNS SETOF TEXT
AS $BODY$
BEGIN
RETURN QUERY SELECT inner_func();
END
$BODY$ LANGUAGE 'plpgsql';
ALTER FUNCTION test.outer_func() OWNER TO test;
PROD模式:
CREATE ROLE prod NOLOGIN;
CREATE SCHEMA prod AUTHORIZATION prod;
CREATE OR REPLACE FUNCTION prod.inner_func() RETURNS TEXT
AS $BODY$
BEGIN
RETURN 'prod function';
END
$BODY$ LANGUAGE 'plpgsql';
ALTER FUNCTION prod.inner_func() OWNER TO prod;
CREATE OR REPLACE FUNCTION prod.outer_func() RETURNS SETOF TEXT
AS $BODY$
BEGIN
RETURN QUERY SELECT inner_func();
END
$BODY$ LANGUAGE 'plpgsql';
ALTER FUNCTION prod.outer_func() OWNER TO prod;
測試用例:
SET search_path=test,public;
SELECT outer_func();
> test function
SELECT prod.outer_func();
> test function <<<---- was expecting prod function
SET search_path=prod,public;
SELECT prod.outer_func();
> prod function
試驗表明,功能名稱解析動態基礎上,search_path
在運行時。有一種方法可以在模式範圍內綁定內部函數嗎?
我可以通過使用SECURITY DEFINER
函數與動態SQL和CURRENT_USER
得到這樣的行爲,但我正在尋找更直接的東西。
您可以設置所需的搜索路徑作爲函數的屬性(在函數定義中使用'SET')。 Btw:語言名稱是一個標識符,不要把它放在單引號中。這是已被棄用的語法,將在未來被刪除 –
@ a_horse_with_no_name好!工作得很好。請使用答案按鈕而不是評論,以便我可以分配點並將問題設置爲已回答。 – lessj
@a_horse_with_no_name是正確的。但是,我不確定爲什麼你在連接後不設置search_path。您在這裏做的事聽起來有點像很常見的多租戶模式,您可以根據客戶名稱創建一系列相同的模式,然後在連接時將搜索路徑設置爲當前客戶。將系統作爲「測試」運行,在連接後設置search_path等。 –