В Postgres более эффективный способ получения настроек уровня сеанса

#postgresql

#postgresql

Вопрос:

В Postgres следующая команда вернет значение настройки:

 SELECT current_setting('foo');
  

Если параметр не существует, он выдаст исключение.

У нас есть случай, когда параметр может существовать, а может и не существовать, поэтому нам пришлось создать функцию, которая улавливает исключение и возвращает null:

 CREATE OR REPLACE FUNCTION public.get_foo() 
RETURNS varchar 
LANGUAGE plpgsql AS $$
BEGIN

RETURN (SELECT current_setting('foo'));

EXCEPTION 
WHEN others THEN
    RETURN NULL;
END;
$$;
  

Однако это ужасно работает, когда параметр не существует, предположительно потому, что выдача и перехват исключения обходятся дорого.

Есть ли способ проверить, существует ли параметр?

Ответ №1:

На самом деле есть две названные функции current_setting . Первый, который вы использовали, принимает одно string значение, представляющее имя переменной. Другой принимает два аргумента: a string для имени переменной и a boolean , указывающий, подходит ли отсутствующее имя переменной.

Просто используйте SELECT coalesce(current_setting('my.foo', true), 'mydefault');

пример:

 postgres=> set session my.foo to 'baz';
SET
postgres=> select current_setting('public.foo', true);
 current_setting 
-----------------
 baz
(1 row)
postgres=> select current_setting('public.bar', true);
 current_setting 
-----------------
 
(1 row)
postgres=> select coalesce(current_setting('public.bar', true), 'mydefault');
 coalesce  
-----------
 mydefault
(1 row)
  

Ответ №2:

Попробуйте это системное представление вместо current_setting функции.

 SELECT setting FROM pg_catalog.pg_settings WHERE name = 'foo';
  

Еще одним «бонусом» является то, что вы можете использовать его как обычную таблицу:

 (filip@[local]:5432) filip=# SELECT name, setting, unit, source, boot_val FROM pg_settings WHERE name ~ 'mem';
            name            | setting | unit |       source       | boot_val 
---------------------------- --------- ------ -------------------- ----------
 autovacuum_work_mem        | -1      | kB   | default            | -1
 dynamic_shared_memory_type | posix   | NULL | configuration file | posix
 hash_mem_multiplier        | 1       | NULL | default            | 1
 logical_decoding_work_mem  | 65536   | kB   | default            | 65536
 maintenance_work_mem       | 512000  | kB   | session            | 65536
 shared_memory_type         | mmap    | NULL | default            | mmap
 work_mem                   | 20480   | kB   | session            | 4096
(7 rows)


(filip@[local]:5432) filip=# SELECT source, count(*) FROM pg_settings GROUP BY 1;
        source        | count 
---------------------- -------
 client               |     2
 environment variable |     1
 configuration file   |    26
 default              |   291
 session              |     2
 override             |    13
(6 rows)