Общо решение
Създадох чиста sql функция с помощта на set_config().
Това решение поддържа задаване на множество схеми в низ, разделен със запетая. По подразбиране промяната се прилага за текущата сесия. Задаването на параметъра "is_local" на true прави промяната приложима само към текущата транзакция, вижте http://www.postgresql.org/docs/9.4/static/functions-admin.html за повече подробности.
CREATE OR REPLACE FUNCTION public.set_search_path(path TEXT, is_local BOOLEAN DEFAULT false) RETURNS TEXT AS $$
SELECT set_config('search_path', regexp_replace(path, '[^\w ,]', '', 'g'), is_local);
$$ LANGUAGE sql;
Тъй като не изпълняваме динамичен sql, трябва да има по-малък шанс за инжектиране на sql. Само за да съм сигурен, добавих малко наивно дезинфекция на текста, като премахнах всички знаци с изключение на букви, цифри, интервал и запетая. Избягването/цитирането на низа не беше тривиално, но аз не съм експерт, така че.. =)
Не забравяйте, че няма обратна връзка, ако зададете неправилно образуван път.
Ето примерен код за тестване:
DROP SCHEMA IF EXISTS testschema CASCADE;
CREATE SCHEMA testschema;
CREATE TABLE testschema.mytable ( id INTEGER );
SELECT set_search_path('testschema, public');
SHOW search_path;
INSERT INTO mytable VALUES(123);
SELECT * FROM mytable;
Тест, базиран на оригиналния код на OP
Тъй като не знаем схемата за mytable предварително, трябва да използваме динамичен sql. Вградих set_config-oneliner във функцията get_sections() вместо да използвам общата функция.
Забележка: Трябваше да задам is_local=false в set_config(), за да работи това. Това означава, че модифицираният път остава след изпълнението на функцията. Не съм сигурен защо.
DROP SCHEMA IF EXISTS testschema CASCADE;
CREATE SCHEMA testschema;
SET search_path TO public;
CREATE TABLE testschema.mytable ( id INTEGER, name varchar, type varchar );
INSERT INTO testschema.mytable VALUES (123,'name', 'some-type');
INSERT INTO testschema.mytable VALUES (567,'name2', 'beer');
CREATE OR REPLACE FUNCTION get_sections(schema_name TEXT) RETURNS
TABLE(id integer, name varchar, type varchar) AS $$
BEGIN
PERFORM set_config('search_path', regexp_replace(schema_name||', public', '[^\w ,]', '', 'g'), true);
EXECUTE 'SELECT id, name, type FROM mytable';
END;
$$ LANGUAGE plpgsql;
SET search_path TO public;
SELECT * FROM get_sections('testschema');
SHOW search_path; -- Unfortunately this has modified the search_path for the whole session.