ECHO_HIDDEN

PostgreSQLПару-тройку раз у меня уже встречалась потребность посмотреть код, который выполняет PostgreSQL чтобы выполнить метакоманды psql. Это можно сделать очень просто, но времени много проходит между использованиями этого метода, и я некоторые детали забываю.

Так что решил опубликовать ответ, чтобы можно было его очень быстро найти. Ниже как раз он и приведен.

Итак, метакоманды psql — очень удобная штука. Например, чтобы вывести список доступных баз данных можно выполнить вот такую команду:

\l;

В ответ можно получить примерно такое:

postgres=# \l
                                                 List of databases
   Name    |  Owner   | Encoding |   Collate   |    Ctype    | ICU Locale | Locale Provider |   Access privileges   
-----------+----------+----------+-------------+-------------+------------+-----------------+-----------------------
 postgres  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |            | libc            | 
 template0 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |            | libc            | =c/postgres          +
           |          |          |             |             |            |                 | postgres=CTc/postgres
 template1 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |            | libc            | =c/postgres          +
           |          |          |             |             |            |                 | postgres=CTc/postgres
(3 rows)

Но мы выполнили только крошечную команду, ясное дело что PostgreSQL «разворачивает» её в запрос. Но какой?

Узнать это можно «включив» переменную ECHO_HIDDEN, то есть присвоить ей значение on. Давайте попробуем:

\set ECHO_HIDDEN on

И снова выполним команду \l:

postgres=# \l
********* QUERY **********
SELECT d.datname as "Name",
pg_catalog.pg_get_userbyid(d.datdba) as "Owner",
pg_catalog.pg_encoding_to_char(d.encoding) as "Encoding",
d.datcollate as "Collate",
d.datctype as "Ctype",
d.daticulocale as "ICU Locale",
CASE d.datlocprovider WHEN 'c' THEN 'libc' WHEN 'i' THEN 'icu' END AS "Locale Provider",
pg_catalog.array_to_string(d.datacl, E'\n') AS "Access privileges"
FROM pg_catalog.pg_database d
ORDER BY 1;
**************************
List of databases
Name | Owner | Encoding | Collate | Ctype | ICU Locale | Locale Provider | Access privileges 
-----------+----------+----------+-------------+-------------+------------+-----------------+-----------------------
postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | 
template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | =c/postgres +
| | | | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | =c/postgres +
| | | | | | | postgres=CTc/postgres
(3 rows)

Теперь можно увидеть запрос (в частности, здесь идет обращение к таблице системного каталога pg_database).

Точно так же можно смотреть запросы для других метакоманд.

Узнать текущее значение переменной ECHO_HIDDEN (и других) можно с помощью команды:

\echo :ECHO_HIDDEN 
off

Но мы видим не только запрос, но и результат его работы. А что делать если нам нужно только текст запроса посмотреть? То есть, нам не нужно его выполнять? Для этого можно переменной ECHO_HIDDEN присвоить значение noexec — тогда мы увидим только текст без его выполнения:

postgres=# \set ECHO_HIDDEN noexec 
postgres=# \l
********* QUERY **********
SELECT d.datname as "Name",
pg_catalog.pg_get_userbyid(d.datdba) as "Owner",
pg_catalog.pg_encoding_to_char(d.encoding) as "Encoding",
d.datcollate as "Collate",
d.datctype as "Ctype",
d.daticulocale as "ICU Locale",
CASE d.datlocprovider WHEN 'c' THEN 'libc' WHEN 'i' THEN 'icu' END AS "Locale Provider",
pg_catalog.array_to_string(d.datacl, E'\n') AS "Access privileges"
FROM pg_catalog.pg_database d
ORDER BY 1;
**************************

А если уже не хотите смотреть тексты запросов метакоманд — установите значение этой переменной в off.


Be the first to comment

Leave a Reply

Ваш Mail не будет опубликован.


*