As development of PostgreSQL 15 is on its way, more and more features get committed. Today we’ll look at a new feature which is not a hammer feature, but a nice thing to have and to know about.

If you take a look at how many settings PostgreSQL comes with as of today, there are 353 (This is PostgreSQL 15dev):

postgres=# select count(*) from pg_settings ;
 count 
-------
   353
(1 row)

Some of those settings are available in the default postgresql.conf, which is created by initdb, others not. Some settings can be re-setted, while you can’t do that for others.

The new function pg_settings_get_flags gives you some more insights into this. To start, lets see how many distinct flags are available right now:

postgres=# select distinct flags from (select pg_settings_get_flags(name) as flags from pg_settings) as x;
              flags               
----------------------------------
 {EXPLAIN}
 {}
 {EXPLAIN,NOT_IN_SAMPLE}
 {NOT_IN_SAMPLE,RUNTIME_COMPUTED}
 {NOT_IN_SAMPLE}
 {NO_RESET_ALL,NOT_IN_SAMPLE}
(6 rows)

The return type of the function is a text array and this is what I can see on my instance. The meaning of the flags is (stolen from here):

  • EXPLAIN: parameters included in EXPLAIN command
  • NO_SHOW_ALL: parameters excluded from SHOW ALL commands
  • NO_RESET_ALL: parameters excluded from RESET ALL commands
  • NOT_IN_SAMPLE: parameters not included in postgresql.conf by default
  • RUNTIME_COMPUTED: runtime-computed parameters

If you, for example, want to know which settings are not included in the default postgresql.conf, you can use the new function for that:

postgres=# with flags_all as (select name,pg_settings_get_flags(name) as flags from pg_settings)
           select * 
             from flags_all 
            where flags_all.flags @> ARRAY['NOT_IN_SAMPLE'];
               name               |              flags               
----------------------------------+----------------------------------
 allow_in_place_tablespaces       | {NOT_IN_SAMPLE}
 allow_system_table_mods          | {NOT_IN_SAMPLE}
 application_name                 | {NOT_IN_SAMPLE}
 backtrace_functions              | {NOT_IN_SAMPLE}
 block_size                       | {NOT_IN_SAMPLE}
 data_checksums                   | {NOT_IN_SAMPLE,RUNTIME_COMPUTED}
 data_directory_mode              | {NOT_IN_SAMPLE,RUNTIME_COMPUTED}
 debug_assertions                 | {NOT_IN_SAMPLE}
 debug_discard_caches             | {NOT_IN_SAMPLE}
 force_parallel_mode              | {EXPLAIN,NOT_IN_SAMPLE}
 ignore_checksum_failure          | {NOT_IN_SAMPLE}
 ignore_invalid_pages             | {NOT_IN_SAMPLE}
 ignore_system_indexes            | {NOT_IN_SAMPLE}
 in_hot_standby                   | {NOT_IN_SAMPLE}
 integer_datetimes                | {NOT_IN_SAMPLE}
 jit_debugging_support            | {NOT_IN_SAMPLE}
 jit_dump_bitcode                 | {NOT_IN_SAMPLE}
 jit_expressions                  | {NOT_IN_SAMPLE}
 jit_profiling_support            | {NOT_IN_SAMPLE}
 jit_tuple_deforming              | {NOT_IN_SAMPLE}
 lc_collate                       | {NOT_IN_SAMPLE}
 lc_ctype                         | {NOT_IN_SAMPLE}
 max_function_args                | {NOT_IN_SAMPLE}
 max_identifier_length            | {NOT_IN_SAMPLE}
 max_index_keys                   | {NOT_IN_SAMPLE}
 post_auth_delay                  | {NOT_IN_SAMPLE}
 pre_auth_delay                   | {NOT_IN_SAMPLE}
 remove_temp_files_after_crash    | {NOT_IN_SAMPLE}
 segment_size                     | {NOT_IN_SAMPLE}
 server_encoding                  | {NOT_IN_SAMPLE}
 server_version                   | {NOT_IN_SAMPLE}
 server_version_num               | {NOT_IN_SAMPLE}
 shared_memory_size               | {NOT_IN_SAMPLE,RUNTIME_COMPUTED}
 shared_memory_size_in_huge_pages | {NOT_IN_SAMPLE,RUNTIME_COMPUTED}
 ssl_library                      | {NOT_IN_SAMPLE}
 trace_notify                     | {NOT_IN_SAMPLE}
 trace_recovery_messages          | {NOT_IN_SAMPLE}
 trace_sort                       | {NOT_IN_SAMPLE}
 transaction_deferrable           | {NO_RESET_ALL,NOT_IN_SAMPLE}
 transaction_isolation            | {NO_RESET_ALL,NOT_IN_SAMPLE}
 transaction_read_only            | {NO_RESET_ALL,NOT_IN_SAMPLE}
 wal_block_size                   | {NOT_IN_SAMPLE}
 wal_consistency_checking         | {NOT_IN_SAMPLE}
 wal_segment_size                 | {NOT_IN_SAMPLE,RUNTIME_COMPUTED}
 zero_damaged_pages               | {NOT_IN_SAMPLE}
(45 rows)

All these are mostly developer or tracing settings, and are therefore not included in the default postgresql.conf. You could ask: Which parameters are not reset if you execute a reset all:

postgres=# with flags_all as (select name,pg_settings_get_flags(name) as flags from pg_settings)
           select * 
             from flags_all 
            where flags_all.flags @> ARRAY['NO_RESET_ALL'];
          name          |            flags             
------------------------+------------------------------
 transaction_deferrable | {NO_RESET_ALL,NOT_IN_SAMPLE}
 transaction_isolation  | {NO_RESET_ALL,NOT_IN_SAMPLE}
 transaction_read_only  | {NO_RESET_ALL,NOT_IN_SAMPLE}
(3 rows)

… or combine two or more flags in your query:

postgres=# with flags_all as (select name,pg_settings_get_flags(name) as flags from pg_settings)
           select * 
             from flags_all 
            where flags_all.flags @> ARRAY['EXPLAIN','NOT_IN_SAMPLE'];
        name         |          flags          
---------------------+-------------------------
 force_parallel_mode | {EXPLAIN,NOT_IN_SAMPLE}
(1 row)

Nice little feature.