diff --git a/config.yaml b/config.yaml index e835ce66e3..ba66b91bc6 100644 --- a/config.yaml +++ b/config.yaml @@ -8,6 +8,23 @@ options: either "all", "majority" or a positive integer value. type: string default: "all" + connection_authentication_timeout: + description: | + Sets the maximum allowed time to complete client authentication. + Allowed values are: from 1 to 600. + type: int + default: 60 + connection_statement_timeout: + description: | + Sets the maximum allowed duration of any statement. + Allowed values are: from 0 to 2147483647. + type: int + default: 0 + cpu_parallel_leader_participation: + description: | + Controls whether Gather and Gather Merge also run subplans. + type: boolean + default: true durability_synchronous_commit: description: | Sets the current transactions synchronization level. This charm allows only the @@ -15,6 +32,10 @@ options: crashes and there are replicas. type: string default: "on" + experimental_max_connections: + type: int + description: | + [EXPERIMENTAL] Force set max_connections. instance_default_text_search_config: description: | Selects the text search configuration that is used by those variants of the text @@ -37,6 +58,18 @@ options: Allowed values are: “md5” and “scram-sha-256”. type: string default: "scram-sha-256" + instance_synchronize_seqscans: + description: | + Enable synchronized sequential scans. + type: boolean + default: true + logging_client_min_messages: + description: | + Sets the message levels that are sent to the client. + Allowed values are one of 'debug5', 'debug4', 'debug3', 'debug2', 'debug1', 'log', 'notice', 'warning' or 'error'. + Each level includes all the levels that follow it. The later the level, the fewer messages are sent. + type: string + default: "notice" logging_log_connections: description: | Logs each successful connection. @@ -59,6 +92,13 @@ options: statement durations). type: int default: -1 + logging_track_functions: + description: | + Collects function-level statistics on database activity. + Allowed values are one of 'none', 'pl', 'all'. + Enables tracking of function call counts and time used. Specify pl to track only procedural-language functions + type: string + default: "none" memory_maintenance_work_mem: description: | Sets the maximum memory (KB) to be used for maintenance operations. @@ -96,251 +136,513 @@ options: Allowed values are: “on”, “off” and “partition”. type: string default: "partition" + optimizer_cpu_index_tuple_cost: + description: | + Sets the planner's estimate of the cost of processing each index entry during an index scan. + Allowed values are: from 0 to 1.80E+308. + type: float + default: 0.005 + optimizer_cpu_operator_cost: + description: | + Sets the planner's estimate of the cost of processing each operator or function call. + Allowed values are: from 0 to 1.80E+308. + type: float + default: 0.0025 + optimizer_cpu_tuple_cost: + description: | + Sets the planner's estimate of the cost of processing each tuple (row). + Allowed values are: from 0 to 1.80E+308. + type: float + default: 0.01 + optimizer_cursor_tuple_fraction: + description: | + Sets the planner's estimate of the fraction of a cursor's rows that will be retrieved. + Allowed values are: from 0 to 1. + type: float + default: 0.1 optimizer_default_statistics_target: description: | Sets the default statistics target. Allowed values are: from 1 to 10000. type: int default: 100 + optimizer_enable_async_append: + description: | + Enables the planner's use of async append plans. + type: boolean + default: true + optimizer_enable_bitmapscan: + description: | + Enables the planner's use of bitmap-scan plans. + type: boolean + default: true + optimizer_enable_gathermerge: + description: | + Enables the planner's use of gather merge plans. + type: boolean + default: true + optimizer_enable_hashagg: + description: | + Enables the planner's use of hashed aggregation plans. + type: boolean + default: true + optimizer_enable_hashjoin: + description: | + Enables the planner's use of hash join plans. + type: boolean + default: true + optimizer_enable_incremental_sort: + description: | + Enables the planner's use of incremental sort steps. + type: boolean + default: true + optimizer_enable_indexonlyscan: + description: | + Enables the planner's use of index-only-scan plans. + type: boolean + default: true + optimizer_enable_indexscan: + description: | + Enables the planner's use of index-scan plans. + type: boolean + default: true + optimizer_enable_material: + description: | + Enables the planner's use of materialization. + type: boolean + default: true + optimizer_enable_memoize: + description: | + Enables the planner's use of memoization. + type: boolean + default: true + optimizer_enable_mergejoin: + description: | + Enables the planner's use of merge join plans. + type: boolean + default: true + optimizer_enable_nestloop: + description: | + Enables the planner's use of nested-loop join plans. + type: boolean + default: true + optimizer_enable_parallel_append: + description: | + Enables the planner's use of parallel append plans. + type: boolean + default: true + optimizer_enable_parallel_hash: + description: | + Enables the planner's use of parallel hash plans. + type: boolean + default: true + optimizer_enable_partition_pruning: + description: | + Enables plan-time and execution-time partition pruning. + type: boolean + default: true + optimizer_enable_partitionwise_aggregate: + description: | + Enables partitionwise aggregation and grouping. + type: boolean + default: false + optimizer_enable_partitionwise_join: + description: | + Enables partitionwise join. + type: boolean + default: false + optimizer_enable_seqscan: + description: | + Enables the planner's use of sequential-scan plans. + type: boolean + default: true + optimizer_enable_sort: + description: | + Enables the planner's use of explicit sort steps. + type: boolean + default: true + optimizer_enable_tidscan: + description: | + Enables the planner's use of TID scan plans. + type: boolean + default: true optimizer_from_collapse_limit: description: | Sets the FROM-list size beyond which subqueries are not collapsed. Allowed values are: from 1 to 2147483647. type: int default: 8 + optimizer_geqo: + description: | + Enables genetic query optimization. + type: boolean + default: true + optimizer_geqo_effort: + description: | + GEQO: effort is used to set the default for other GEQO parameters. + Allowed values are: from 1 to 10. + type: int + default: 5 + optimizer_geqo_generations: + description: | + GEQO: number of iterations of the algorithm. + Allowed values are: from 0 to 2147483647. + type: int + default: 0 + optimizer_geqo_pool_size: + description: | + GEQO: number of individuals in the population. + Allowed values are: from 0 to 2147483647. + type: int + default: 0 + optimizer_geqo_seed: + description: | + GEQO: seed for random path selection. + Allowed values are: from 0 to 1. + type: float + default: 0.0 + optimizer_geqo_selection_bias: + description: | + GEQO: selective pressure within the population. + Allowed values are: from 1.5 to 2. + type: float + default: 2.0 + optimizer_geqo_threshold: + description: | + Sets the threshold of FROM items beyond which GEQO is used. + Allowed values are: from 2 to 2147483647. + type: int + default: 12 + optimizer_jit: + description: | + Allow JIT compilation. + type: boolean + default: true + optimizer_jit_above_cost: + description: | + Perform JIT compilation if query is more expensive. + Allowed values are: from -1 to 1.80E+308. + type: float + default: 100000.0 + optimizer_jit_inline_above_cost: + description: | + Perform JIT inlining if query is more expensive. + Allowed values are: from -1 to 1.80E+308. + type: float + default: 500000.0 + optimizer_jit_optimize_above_cost: + description: | + Optimize JIT-compiled functions if query is more expensive. + Allowed values are: from -1 to 1.80E+308. + type: float + default: 500000.0 optimizer_join_collapse_limit: description: | Sets the FROM-list size beyond which JOIN constructs are not flattened. Allowed values are: from 1 to 2147483647. type: int default: 8 - plugin_citext_enable: + optimizer_min_parallel_index_scan_size: + description: | + Sets the minimum amount of index data for a parallel scan. + Allowed values are: from 0 to 715827882. + type: int + default: 64 + optimizer_min_parallel_table_scan_size: + description: | + Sets the minimum amount of table data for a parallel scan. + Allowed values are: from 0 to 715827882. + type: int + default: 1024 + optimizer_parallel_setup_cost: + description: | + Sets the planner's estimate of the cost of starting up worker processes for parallel query. + Allowed values are: from 0 to 1.80E+308. + type: float + default: 1000.0 + optimizer_parallel_tuple_cost: + description: | + Sets the planner's estimate of the cost of passing each tuple (row) from worker to leader backend. + Allowed values are: from 0 to 1.80E+308. + type: float + default: 0.1 + plugin_address_standardizer_data_us_enable: default: false type: boolean - description: Enable citext extension. - plugin_debversion_enable: + description: Enable address_standardizer_data_us extension + plugin_address_standardizer_enable: default: false type: boolean - description: Enable debversion extension. - plugin_hstore_enable: - default: false + description: Enable address_standardizer extension + plugin_audit_enable: + default: true type: boolean - description: Enable hstore extension. - plugin_pg_trgm_enable: + description: Enable pgAudit extension + plugin_bloom_enable: default: false type: boolean - description: Enable pg_trgm extension. - plugin_plpython3u_enable: + description: Enable bloom extension + plugin_bool_plperl_enable: default: false type: boolean - description: Enable PL/Python extension. - plugin_unaccent_enable: + description: Enable bool_plperl extension + plugin_btree_gin_enable: default: false type: boolean - description: Enable unaccent extension. - plugin_bloom_enable: + description: Enable btree_gin extension + plugin_btree_gist_enable: default: false type: boolean - description: Enable bloom extension. - plugin_btree_gin_enable: + description: Enable btree_gist extension + plugin_citext_enable: default: false type: boolean - description: Enable btree_gin extension. - plugin_btree_gist_enable: + description: Enable citext extension + plugin_cube_enable: default: false type: boolean - description: Enable btree_gist extension. - plugin_cube_enable: + description: Enable cube extension + plugin_debversion_enable: default: false type: boolean - description: Enable cube extension. + description: Enable debversion extension plugin_dict_int_enable: default: false type: boolean - description: Enable dict_int extension. + description: Enable dict_int extension plugin_dict_xsyn_enable: default: false type: boolean - description: Enable dict_xsyn extension. + description: Enable dict_xsyn extension plugin_earthdistance_enable: default: false type: boolean - description: Enable earthdistance extension. + description: Enable earthdistance extension plugin_fuzzystrmatch_enable: default: false type: boolean - description: Enable fuzzystrmatch extension. - plugin_intarray_enable: + description: Enable fuzzystrmatch extension + plugin_hll_enable: default: false type: boolean - description: Enable intarray extension. - plugin_isn_enable: + description: Enable hll extension + plugin_hstore_enable: default: false type: boolean - description: Enable isn extension. - plugin_lo_enable: + description: Enable hstore extension + plugin_hypopg_enable: default: false type: boolean - description: Enable lo extension. - plugin_ltree_enable: + description: Enable hypopg extension + plugin_icu_ext_enable: default: false type: boolean - description: Enable ltree extension. - plugin_old_snapshot_enable: + description: Enable icu_ext extension + plugin_intarray_enable: default: false type: boolean - description: Enable old_snapshot extension. - plugin_pg_freespacemap_enable: + description: Enable intarray extension + plugin_ip4r_enable: default: false type: boolean - description: Enable pg_freespacemap extension. - plugin_pgrowlocks_enable: + description: Enable ip4r extension + plugin_isn_enable: default: false type: boolean - description: Enable pgrowlocks extension. - plugin_pgstattuple_enable: + description: Enable isn extension + plugin_jsonb_plperl_enable: default: false type: boolean - description: Enable pgstattuple extension. - plugin_pg_visibility_enable: + description: Enable jsonb_plperl extension + plugin_lo_enable: default: false type: boolean - description: Enable pg_visibility extension. - plugin_seg_enable: + description: Enable lo extension + plugin_ltree_enable: default: false type: boolean - description: Enable seg extension. - plugin_tablefunc_enable: + description: Enable ltree extension + plugin_old_snapshot_enable: default: false type: boolean - description: Enable tablefunc extension. - plugin_tcn_enable: + description: Enable old_snapshot extension + plugin_orafce_enable: default: false type: boolean - description: Enable tcn extension. - plugin_tsm_system_rows_enable: + description: Enable orafce extension + plugin_pg_freespacemap_enable: default: false type: boolean - description: Enable tsm_system_rows extension. - plugin_tsm_system_time_enable: + description: Enable pg_freespacemap extension + plugin_pg_similarity_enable: default: false type: boolean - description: Enable tsm_system_time extension. - plugin_uuid_ossp_enable: + description: Enable pg_similarity extension + plugin_pg_trgm_enable: default: false type: boolean - description: Enable uuid_ossp extension. - plugin_spi_enable: + description: Enable pg_trgm extension + plugin_pg_visibility_enable: default: false type: boolean - description: Enable spi extension. - plugin_bool_plperl_enable: + description: Enable pg_visibility extension + plugin_pgrowlocks_enable: default: false type: boolean - description: Enable bool_plperl extension. - plugin_hll_enable: + description: Enable pgrowlocks extension + plugin_pgstattuple_enable: default: false type: boolean - description: Enable hll extension. - plugin_hypopg_enable: + description: Enable pgstattuple extension + plugin_plperl_enable: default: false type: boolean - description: Enable hypopg extension. - plugin_ip4r_enable: + description: Enable plperl extension + plugin_plpython3u_enable: default: false type: boolean - description: Enable ip4r extension. - plugin_plperl_enable: + description: Enable PL/Python extension + plugin_pltcl_enable: default: false type: boolean - description: Enable plperl extension. - plugin_jsonb_plperl_enable: + description: Enable pltcl extension + plugin_postgis_enable: default: false type: boolean - description: Enable jsonb_plperl extension. - plugin_orafce_enable: + description: Enable postgis extension + plugin_postgis_raster_enable: default: false type: boolean - description: Enable orafce extension. - plugin_pg_similarity_enable: + description: Enable postgis_raster extension + plugin_postgis_tiger_geocoder_enable: + default: false + type: boolean + description: Enable postgis_tiger_geocoder extension + plugin_postgis_topology_enable: default: false type: boolean - description: Enable pg_similarity extension. + description: Enable postgis_topology extension plugin_prefix_enable: default: false type: boolean - description: Enable prefix extension. + description: Enable prefix extension plugin_rdkit_enable: default: false type: boolean - description: Enable rdkit extension. - plugin_tds_fdw_enable: + description: Enable rdkit extension + plugin_seg_enable: default: false type: boolean - description: Enable tds_fdw extension. - plugin_icu_ext_enable: + description: Enable seg extension + plugin_spi_enable: default: false type: boolean - description: Enable icu_ext extension. - plugin_pltcl_enable: + description: Enable spi extension + plugin_tablefunc_enable: default: false type: boolean - description: Enable pltcl extension. - plugin_postgis_enable: + description: Enable tablefunc extension + plugin_tcn_enable: default: false type: boolean - description: Enable postgis extension. - plugin_address_standardizer_enable: + description: Enable tcn extension + plugin_tds_fdw_enable: default: false type: boolean - description: Enable address_standardizer extension. - plugin_postgis_raster_enable: + description: Enable tds_fdw extension + plugin_timescaledb_enable: default: false type: boolean - description: Enable postgis_raster extension. - plugin_address_standardizer_data_us_enable: + description: Enable timescaledb extension + plugin_tsm_system_rows_enable: default: false type: boolean - description: Enable address_standardizer_data_us extension. - plugin_postgis_tiger_geocoder_enable: + description: Enable tsm_system_rows extension + plugin_tsm_system_time_enable: default: false type: boolean - description: Enable postgis_tiger_geocoder extension. - plugin_postgis_topology_enable: + description: Enable tsm_system_time extension + plugin_unaccent_enable: default: false type: boolean - description: Enable postgis_topology extension. - plugin_vector_enable: + description: Enable unaccent extension + plugin_uuid_ossp_enable: default: false type: boolean - description: Enable pgvector extension - plugin_timescaledb_enable: + description: Enable uuid_ossp extension + plugin_vector_enable: default: false type: boolean - description: Enable timescaledb extension - plugin_audit_enable: - default: true - type: boolean - description: Enable pgAudit extension + description: Enable pgvector extension profile: - description: | + description: | Profile representing the scope of deployment, and used to tune resource allocation. Allowed values are: “production” and “testing”. Production will tune postgresql for maximum performance while testing will tune for minimal running performance. - type: string - default: "production" + type: string + default: "production" profile_limit_memory: type: int description: | Amount of memory in Megabytes to limit PostgreSQL and associated process to. If unset, this will be decided according to the default memory limit in the selected profile. Only comes into effect when the `production` profile is selected. + request_array_nulls: + description: | + Enable input of NULL elements in arrays. + type: boolean + default: true + request_backslash_quote: + description: | + Sets whether "\'" is allowed in string literals. + Allowed values are "safe_encoding" and "on" and "off". + Safe_encoding is allow only if client encoding does not allow ASCII \ within a multibyte character. + type: string + default: "safe_encoding" request_date_style: description: | Sets the display format for date and time values. Allowed formats are explained in https://www.postgresql.org/docs/14/runtime-config-client.html#GUC-DATESTYLE. type: string default: "ISO, MDY" + request_deadlock_timeout: + description: | + Sets the time to wait on a lock before checking for deadlock. + Allowed values are: from 1 to 2147483647. + type: int + default: 1000 + request_default_transaction_deferrable: + escription: | + Sets the default deferrable status of new transactions. + type: boolean + default: false + request_default_transaction_isolation: + description: | + Sets the transaction isolation level of each new transaction. + Allowed values are one of 'serializable', 'repeatable read', 'read committed', 'read uncommitted'. + Read commited or read uncommited is a statement can only see rows committed before it began. + Repeatable read is all statements of the current transaction can only see rows committed before + the first query or data-modification statement was executed in this transaction. + Serializable is all statements of the current transaction can only see rows committed before the first + query or data-modification statement was executed in this transaction. + type: string + default: "read committed" + request_default_transaction_read_only: + description: | + Sets the default read-only status of new transactions. + type: boolean + default: false + request_escape_string_warning: + description: | + Warn about backslash escapes in ordinary string literals. + type: boolean + default: true + request_lock_timeout: + description: | + Sets the maximum allowed duration of any wait for a lock. + Allowed values are: from 0 to 2147483647. + type: int + default: 0 request_standard_conforming_strings: description: | Causes ... strings to treat backslashes literally. @@ -353,12 +655,52 @@ options: like PST and POSIX-style time zone specifications. type: string default: "UTC" + request_track_activity_query_size: + description: | + Sets the size reserved for pg_stat_activity.query, in bytes. + Allowed values are: from 100 to 1048576. + type: int + default: 1024 + request_transform_null_equals: + description: | + Treats "expr=NULL" as "expr IS NULL" + type: boolean + default: false + request_xmlbinary: + description: | + Sets how binary values are to be encoded in XML. + Allowed values are one of 'base64', 'hex'. + type: string + default: "base64" + request_xmloption: + description: | + Sets whether XML data in implicit parsing and serialization operations is to be considered as documents or content fragments. + Allowed values are one of 'content', 'document'. + type: string + default: "content" response_bytea_output: description: | Sets the output format for bytes. Allowed values are: “escape” and “hex”. type: string default: "hex" + response_exit_on_error: + description: | + Terminate session on any error. + type: boolean + default: false + response_extra_float_digits: + description: | + Sets the number of digits displayed for floating-point values. + Allowed values are: from -15 to 3. + type: int + default: 1 + response_gin_fuzzy_search_limit: + description: | + Sets the maximum allowed result for exact search by GIN. + Allowed values are: from 0 to 2147483647. + type: int + default: 0 response_lc_monetary: description: | Sets the locale for formatting monetary amounts. @@ -377,6 +719,42 @@ options: Allowed values are the locales available in the unit. type: string default: "C" + session_idle_in_transaction_session_timeout: + description: | + Sets the maximum allowed idle time between queries, when in a transaction. + Allowed values are: from 0 to 2147483647. + type: int + default: 0 + storage_bgwriter_lru_maxpages: + description: | + Background writer maximum number of LRU pages to flush per round. + Allowed values are: from 0 to 1073741823. + type: int + default: 100 + storage_bgwriter_lru_multiplier: + description: | + Multiple of the average buffer usage to free per round. + Allowed values are: from 0 to 10. + type: float + default: 2.0 + storage_default_table_access_method: + description: | + Sets the default table access method for new tables. + These entries can be created using the CREATE ACCESS METHOD SQL command. + type: string + default: "heap" + storage_gin_pending_list_limit: + description: | + Sets the maximum size of the pending list for GIN index. + Allowed values are: from 64 to 2147483647. + type: int + default: 4096 + storage_old_snapshot_threshold: + description: | + Time before a snapshot is too old to read pages changed after the snapshot was taken. + Allowed values are: from -1 to 86400. + type: int + default: -1 vacuum_autovacuum_analyze_scale_factor: description: | Specifies a fraction of the table size to add to autovacuum_vacuum_threshold when @@ -396,6 +774,12 @@ options: transaction ID wraparound. Allowed values are: from 100000 to 2000000000. type: int default: 200000000 + vacuum_autovacuum_naptime: + description: | + Time to sleep between autovacuum runs. + Allowed values are: from 1 to 2147483. + type: int + default: 60 vacuum_autovacuum_vacuum_cost_delay: description: | Sets cost delay value (milliseconds) that will be used in automatic VACUUM operations. @@ -403,6 +787,24 @@ options: vacuum_cost_delay value). type: float default: 2.0 + vacuum_autovacuum_vacuum_cost_limit: + description: | + Vacuum cost amount available before napping, for autovacuum. + Allowed values are: from -1 to 10000. + type: int + default: -1 + vacuum_autovacuum_vacuum_insert_scale_factor: + description: | + Number of tuple inserts prior to vacuum as a fraction of reltuples. + Allowed values are: from 0 to 100. + type: float + default: 0.2 + vacuum_autovacuum_vacuum_insert_threshold: + description: | + Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums. + Allowed values are: from -1 to 2147483647. + type: int + default: 1000 vacuum_autovacuum_vacuum_scale_factor: description: | Specifies a fraction of the table size to add to autovacuum_vacuum_threshold when @@ -410,13 +812,75 @@ options: Allowed values are: from 0 to 100. type: float default: 0.2 + vacuum_autovacuum_vacuum_threshold: + description: | + Minimum number of tuple updates or deletes prior to vacuum. + Allowed values are: from 0 to 2147483647. + type: int + default: 50 + vacuum_vacuum_cost_delay: + description: | + Vacuum cost delay in milliseconds. + Allowed values are: from 0 to 100. + type: float + default: 0.0 + vacuum_vacuum_cost_limit: + description: | + Vacuum cost amount available before napping. + Allowed values are: from 1 to 10000. + type: int + default: 200 + vacuum_vacuum_cost_page_dirty: + description: | + Vacuum cost for a page dirtied by vacuum. + Allowed values are: from 0 to 10000. + type: int + default: 20 + vacuum_vacuum_cost_page_hit: + description: | + Vacuum cost for a page found in the buffer cache. + Allowed values are: from 0 to 10000. + type: int + default: 1 + vacuum_vacuum_cost_page_miss: + description: | + Vacuum cost for a page not found in the buffer cache. + Allowed values are: from 0 to 10000. + type: int + default: 2 + vacuum_vacuum_failsafe_age: + description: | + Age at which VACUUM should trigger failsafe to avoid a wraparound outage. + Allowed values are: from 0 to 2100000000. + type: int + default: 1600000000 + vacuum_vacuum_freeze_min_age: + description: | + Minimum age at which VACUUM should freeze a table row. + Allowed values are: from 0 to 1000000000. + type: int + default: 50000000 vacuum_vacuum_freeze_table_age: description: | Age (in transactions) at which VACUUM should scan whole table to freeze tuples. Allowed values are: from 0 to 2000000000. type: int default: 150000000 - experimental_max_connections: + vacuum_vacuum_multixact_failsafe_age: + description: | + Multixact age at which VACUUM should trigger failsafe to avoid a wraparound outage. + Allowed values are: from 0 to 2100000000. type: int + default: 1600000000 + vacuum_vacuum_multixact_freeze_min_age: description: | - [EXPERIMENTAL] Force set max_connections. + Minimum age at which VACUUM should freeze a MultiXactId in a table row. + Allowed values are: from 0 to 1000000000. + type: int + default: 5000000 + vacuum_vacuum_multixact_freeze_table_age: + description: | + Multixact age at which VACUUM should scan whole table to freeze tuples. + Allowed values are: from 0 to 2000000000. + type: int + default: 150000000 \ No newline at end of file diff --git a/lib/charms/postgresql_k8s/v0/postgresql.py b/lib/charms/postgresql_k8s/v0/postgresql.py index 8e2b7072ad..9fe1957e4f 100644 --- a/lib/charms/postgresql_k8s/v0/postgresql.py +++ b/lib/charms/postgresql_k8s/v0/postgresql.py @@ -35,7 +35,7 @@ # Increment this PATCH version before using `charmcraft publish-lib` or reset # to 0 if you are raising the major API version -LIBPATCH = 45 +LIBPATCH = 46 # Groups to distinguish database permissions PERMISSIONS_GROUP_ADMIN = "admin" @@ -483,6 +483,19 @@ def get_postgresql_timezones(self) -> Set[str]: timezones = cursor.fetchall() return {timezone[0] for timezone in timezones} + def get_postgresql_default_table_access_methods(self) -> Set[str]: + """Returns the PostgreSQL available table access methods. + + Returns: + Set of PostgreSQL table access methods. + """ + with self._connect_to_database( + database_host=self.current_host + ) as connection, connection.cursor() as cursor: + cursor.execute("SELECT amname FROM pg_am WHERE amtype = 't';") + access_methods = cursor.fetchall() + return {access_method[0] for access_method in access_methods} + def get_postgresql_version(self, current_host=True) -> str: """Returns the PostgreSQL version. @@ -653,6 +666,8 @@ def build_postgresql_parameters( for config, value in config_options.items(): # Filter config option not related to PostgreSQL parameters. if not config.startswith(( + "connection", + "cpu", "durability", "instance", "logging", @@ -660,6 +675,8 @@ def build_postgresql_parameters( "optimizer", "request", "response", + "session", + "storage", "vacuum", )): continue diff --git a/src/charm.py b/src/charm.py index 9be1593b5b..cb04d58d57 100755 --- a/src/charm.py +++ b/src/charm.py @@ -2002,6 +2002,14 @@ def _validate_config_options(self) -> None: if self.config.request_time_zone not in self.postgresql.get_postgresql_timezones(): raise ValueError("request_time_zone config option has an invalid value") + if ( + self.config.storage_default_table_access_method + not in self.postgresql.get_postgresql_default_table_access_methods() + ): + raise ValueError( + "storage_default_table_access_method config option has an invalid value" + ) + container = self.unit.get_container("postgresql") output, _ = container.exec(["locale", "-a"]).wait_output() locales = list(output.splitlines()) diff --git a/src/config.py b/src/config.py index 5b8098268d..f3b3bf4fc1 100644 --- a/src/config.py +++ b/src/config.py @@ -17,91 +17,172 @@ class CharmConfig(BaseConfigModel): """Manager for the structured configuration.""" synchronous_node_count: Literal["all", "majority"] | PositiveInt + connection_authentication_timeout: int | None + connection_statement_timeout: int | None + cpu_parallel_leader_participation: bool | None durability_synchronous_commit: str | None + experimental_max_connections: int | None instance_default_text_search_config: str | None instance_max_locks_per_transaction: int | None instance_password_encryption: str | None + instance_synchronize_seqscans: bool | None + logging_client_min_messages: str | None logging_log_connections: bool | None logging_log_disconnections: bool | None logging_log_lock_waits: bool | None logging_log_min_duration_statement: int | None + logging_track_functions: str | None memory_maintenance_work_mem: int | None memory_max_prepared_transactions: int | None memory_shared_buffers: int | None memory_temp_buffers: int | None memory_work_mem: int | None optimizer_constraint_exclusion: str | None + optimizer_cpu_index_tuple_cost: float | None + optimizer_cpu_operator_cost: float | None + optimizer_cpu_tuple_cost: float | None + optimizer_cursor_tuple_fraction: float | None optimizer_default_statistics_target: int | None + optimizer_enable_async_append: bool | None + optimizer_enable_bitmapscan: bool | None + optimizer_enable_gathermerge: bool | None + optimizer_enable_hashagg: bool | None + optimizer_enable_hashjoin: bool | None + optimizer_enable_incremental_sort: bool | None + optimizer_enable_indexonlyscan: bool | None + optimizer_enable_indexscan: bool | None + optimizer_enable_material: bool | None + optimizer_enable_memoize: bool | None + optimizer_enable_mergejoin: bool | None + optimizer_enable_nestloop: bool | None + optimizer_enable_parallel_append: bool | None + optimizer_enable_parallel_hash: bool | None + optimizer_enable_partition_pruning: bool | None + optimizer_enable_partitionwise_aggregate: bool | None + optimizer_enable_partitionwise_join: bool | None + optimizer_enable_seqscan: bool | None + optimizer_enable_sort: bool | None + optimizer_enable_tidscan: bool | None optimizer_from_collapse_limit: int | None + optimizer_geqo: bool | None + optimizer_geqo_effort: int | None + optimizer_geqo_generations: int | None + optimizer_geqo_pool_size: int | None + optimizer_geqo_seed: float | None + optimizer_geqo_selection_bias: float | None + optimizer_geqo_threshold: int | None + optimizer_jit: bool | None + optimizer_jit_above_cost: float | None + optimizer_jit_inline_above_cost: float | None + optimizer_jit_optimize_above_cost: float | None optimizer_join_collapse_limit: int | None - profile: str - profile_limit_memory: int | None + optimizer_min_parallel_index_scan_size: int | None + optimizer_min_parallel_table_scan_size: int | None + optimizer_parallel_setup_cost: float | None + optimizer_parallel_tuple_cost: float | None + plugin_address_standardizer_data_us_enable: bool + plugin_address_standardizer_enable: bool plugin_audit_enable: bool - plugin_citext_enable: bool - plugin_debversion_enable: bool - plugin_hstore_enable: bool - plugin_pg_trgm_enable: bool - plugin_plpython3u_enable: bool - plugin_unaccent_enable: bool plugin_bloom_enable: bool + plugin_bool_plperl_enable: bool plugin_btree_gin_enable: bool plugin_btree_gist_enable: bool + plugin_citext_enable: bool plugin_cube_enable: bool + plugin_debversion_enable: bool plugin_dict_int_enable: bool plugin_dict_xsyn_enable: bool plugin_earthdistance_enable: bool plugin_fuzzystrmatch_enable: bool + plugin_hll_enable: bool + plugin_hstore_enable: bool + plugin_hypopg_enable: bool + plugin_icu_ext_enable: bool plugin_intarray_enable: bool + plugin_ip4r_enable: bool plugin_isn_enable: bool + plugin_jsonb_plperl_enable: bool plugin_lo_enable: bool plugin_ltree_enable: bool plugin_old_snapshot_enable: bool + plugin_orafce_enable: bool plugin_pg_freespacemap_enable: bool + plugin_pg_similarity_enable: bool + plugin_pg_trgm_enable: bool + plugin_pg_visibility_enable: bool plugin_pgrowlocks_enable: bool plugin_pgstattuple_enable: bool - plugin_pg_visibility_enable: bool + plugin_plperl_enable: bool + plugin_plpython3u_enable: bool + plugin_pltcl_enable: bool + plugin_postgis_enable: bool + plugin_postgis_raster_enable: bool + plugin_postgis_tiger_geocoder_enable: bool + plugin_postgis_topology_enable: bool + plugin_prefix_enable: bool + plugin_rdkit_enable: bool plugin_seg_enable: bool + plugin_spi_enable: bool plugin_tablefunc_enable: bool plugin_tcn_enable: bool + plugin_tds_fdw_enable: bool + plugin_timescaledb_enable: bool plugin_tsm_system_rows_enable: bool plugin_tsm_system_time_enable: bool + plugin_unaccent_enable: bool plugin_uuid_ossp_enable: bool - plugin_spi_enable: bool - plugin_bool_plperl_enable: bool - plugin_hll_enable: bool - plugin_hypopg_enable: bool - plugin_ip4r_enable: bool - plugin_plperl_enable: bool - plugin_jsonb_plperl_enable: bool - plugin_orafce_enable: bool - plugin_pg_similarity_enable: bool - plugin_prefix_enable: bool - plugin_rdkit_enable: bool - plugin_tds_fdw_enable: bool - plugin_icu_ext_enable: bool - plugin_pltcl_enable: bool - plugin_postgis_enable: bool - plugin_address_standardizer_enable: bool - plugin_address_standardizer_data_us_enable: bool - plugin_postgis_tiger_geocoder_enable: bool - plugin_postgis_topology_enable: bool - plugin_postgis_raster_enable: bool plugin_vector_enable: bool - plugin_timescaledb_enable: bool + profile: str + profile_limit_memory: int | None + request_array_nulls: bool | None + request_backslash_quote: str | None request_date_style: str | None + request_deadlock_timeout: int | None + request_default_transaction_deferrable: bool | None + request_default_transaction_isolation: str | None + request_default_transaction_read_only: bool | None + request_escape_string_warning: bool | None + request_lock_timeout: int | None request_standard_conforming_strings: bool | None request_time_zone: str | None + request_track_activity_query_size: int | None + request_transform_null_equals: bool | None + request_xmlbinary: str | None + request_xmloption: str | None response_bytea_output: str | None + response_exit_on_error: bool | None + response_extra_float_digits: float | None + response_gin_fuzzy_search_limit: int | None response_lc_monetary: str | None response_lc_numeric: str | None response_lc_time: str | None + session_idle_in_transaction_session_timeout: int | None + storage_bgwriter_lru_maxpages: int | None + storage_bgwriter_lru_multiplier: float | None + storage_default_table_access_method: str | None + storage_gin_pending_list_limit: int | None + storage_old_snapshot_threshold: int | None vacuum_autovacuum_analyze_scale_factor: float | None vacuum_autovacuum_analyze_threshold: int | None vacuum_autovacuum_freeze_max_age: int | None + vacuum_autovacuum_naptime: int | None vacuum_autovacuum_vacuum_cost_delay: float | None + vacuum_autovacuum_vacuum_cost_limit: int | None + vacuum_autovacuum_vacuum_insert_scale_factor: float | None + vacuum_autovacuum_vacuum_insert_threshold: int | None vacuum_autovacuum_vacuum_scale_factor: float | None + vacuum_autovacuum_vacuum_threshold: int | None + vacuum_vacuum_cost_delay: float | None + vacuum_vacuum_cost_limit: int | None + vacuum_vacuum_cost_page_dirty: int | None + vacuum_vacuum_cost_page_hit: int | None + vacuum_vacuum_cost_page_miss: int | None + vacuum_vacuum_failsafe_age: int | None + vacuum_vacuum_freeze_min_age: int | None vacuum_vacuum_freeze_table_age: int | None - experimental_max_connections: int | None + vacuum_vacuum_multixact_failsafe_age: int | None + vacuum_vacuum_multixact_freeze_min_age: int | None + vacuum_vacuum_multixact_freeze_table_age: int | None @classmethod def keys(cls) -> list[str]: @@ -241,15 +322,6 @@ def profile_limit_memory_validator(cls, value: int) -> int | None: return value - @validator("response_bytea_output") - @classmethod - def response_bytea_output_values(cls, value: str) -> str | None: - """Check response_bytea_output config option is one of `escape` or `hex`.""" - if value not in ["escape", "hex"]: - raise ValueError("Value not one of 'escape' or 'hex'") - - return value - @validator("vacuum_autovacuum_analyze_scale_factor", "vacuum_autovacuum_vacuum_scale_factor") @classmethod def vacuum_autovacuum_vacuum_scale_factor_values(cls, value: float) -> float | None: @@ -294,3 +366,476 @@ def vacuum_vacuum_freeze_table_age_values(cls, value: int) -> int | None: raise ValueError("Value is not between 0 and 2000000000") return value + + @validator("connection_authentication_timeout") + @classmethod + def connection_authentication_timeout_values(cls, value: int) -> int | None: + """Check connection_authentication_timeout config option is between 1 and 600.""" + if value < 1 or value > 600: + raise ValueError("Value is not between 1 and 600") + + return value + + @validator("vacuum_autovacuum_naptime") + @classmethod + def vacuum_autovacuum_naptime_values(cls, value: int) -> int | None: + """Check vacuum_autovacuum_naptime config option is between 1 and 2147483.""" + if value < 1 or value > 2147483: + raise ValueError("Value is not between 1 and 2147483") + + return value + + @validator("vacuum_autovacuum_vacuum_cost_limit") + @classmethod + def vacuum_autovacuum_vacuum_cost_limit_values(cls, value: int) -> int | None: + """Check vacuum_autovacuum_vacuum_cost_limit config option is between -1 and 10000.""" + if value < -1 or value > 10000: + raise ValueError("Value is not between -1 and 10000") + + return value + + @validator("vacuum_autovacuum_vacuum_insert_scale_factor") + @classmethod + def vacuum_autovacuum_vacuum_insert_scale_factor_values(cls, value: float) -> float | None: + """Check vacuum_autovacuum_vacuum_insert_scale_factor config option is between 0 and 100.""" + if value < 0 or value > 100: + raise ValueError("Value is not between 0 and 100") + + return value + + @validator("vacuum_autovacuum_vacuum_insert_threshold") + @classmethod + def vacuum_autovacuum_vacuum_insert_threshold_values(cls, value: int) -> int | None: + """Check vacuum_autovacuum_vacuum_insert_threshold config option is between -1 and 2147483647.""" + if value < -1 or value > 2147483647: + raise ValueError("Value is not between -1 and 2147483647") + + return value + + @validator("vacuum_autovacuum_vacuum_threshold") + @classmethod + def vacuum_autovacuum_vacuum_threshold_values(cls, value: int) -> int | None: + """Check vacuum_autovacuum_vacuum_threshold config option is between 0 and 2147483647.""" + if value < 0 or value > 2147483647: + raise ValueError("Value is not between 0 and 2147483647") + + return value + + @validator("request_backslash_quote") + @classmethod + def request_backslash_quote_values(cls, value: str) -> str | None: + """Check request_backslash_quote config option is one of `safe_encoding`, `on` or 'off'.""" + if value not in ["safe_encoding", "on", "off"]: + raise ValueError("Value not one of `safe_encoding` or `on` or 'off'") + + return value + + @validator("storage_bgwriter_lru_maxpages") + @classmethod + def storage_bgwriter_lru_maxpages_values(cls, value: int) -> int | None: + """Check storage_bgwriter_lru_maxpages config option is between 0 and 1073741823.""" + if value < 0 or value > 1073741823: + raise ValueError("Value is not between 0 and 1073741823") + + return value + + @validator("storage_bgwriter_lru_multiplier") + @classmethod + def storage_bgwriter_lru_multiplier_values(cls, value: float) -> float | None: + """Check storage_bgwriter_lru_multiplier config option is between 0 and 10.""" + if value < 0 or value > 10: + raise ValueError("Value is not between 0 and 10") + + return value + + @validator("response_bytea_output") + @classmethod + def response_bytea_output_values(cls, value: str) -> str | None: + """Check response_bytea_output config option is one of `escape` or `hex`.""" + if value not in ["escape", "hex"]: + raise ValueError("Value not one of 'escape' or 'hex'") + + return value + + @validator("logging_client_min_messages") + @classmethod + def logging_client_min_messages_values(cls, value: str) -> str | None: + """Check logging_client_min_messages config option is one of 'debug5', 'debug4', 'debug3', 'debug2', 'debug1', 'log', 'notice', 'warning' or 'error'.""" + if value not in [ + "debug5", + "debug4", + "debug3", + "debug2", + "debug1", + "log", + "notice", + "warning", + "error", + ]: + raise ValueError( + "Value not one of 'debug5', 'debug4', 'debug3', 'debug2', 'debug1', 'log', 'notice', 'warning' or 'error'." + ) + + return value + + @validator("optimizer_cpu_index_tuple_cost") + @classmethod + def optimizer_cpu_index_tuple_cost_values(cls, value: float) -> float | None: + """Check optimizer_cpu_index_tuple_cost config option is between 0 and 1.80E+308.""" + if value < 0 or value > 1.80e308: + raise ValueError("Value is not between 0 and 1.80E+308") + + return value + + @validator("optimizer_cpu_operator_cost") + @classmethod + def optimizer_cpu_operator_cost_values(cls, value: float) -> float | None: + """Check optimizer_cpu_operator_cost config option is between 0 and 1.80E+308.""" + if value < 0 or value > 1.80e308: + raise ValueError("Value is not between 0 and 1.80E+308") + + return value + + @validator("optimizer_cpu_tuple_cost") + @classmethod + def optimizer_cpu_tuple_cost_values(cls, value: float) -> float | None: + """Check optimizer_cpu_tuple_cost config option is between 0 and 1.80E+308.""" + if value < 0 or value > 1.80e308: + raise ValueError("Value is not between 0 and 1.80E+308") + + return value + + @validator("optimizer_cursor_tuple_fraction") + @classmethod + def optimizer_cursor_tuple_fraction_values(cls, value: float) -> float | None: + """Check optimizer_cursor_tuple_fraction config option is between 0 and 1.""" + if value < 0 or value > 1: + raise ValueError("Value is not between 0 and 1") + + return value + + @validator("request_deadlock_timeout") + @classmethod + def request_deadlock_timeout_values(cls, value: int) -> int | None: + """Check request_deadlock_timeout config option is between 1 and 2147483647.""" + if value < 1 or value > 2147483647: + raise ValueError("Value is not between 1 and 2147483647") + + return value + + @validator("request_default_transaction_isolation") + @classmethod + def request_default_transaction_isolation_values(cls, value: str) -> str | None: + """Check request_default_transaction_isolation config option is one of 'serializable', 'repeatable read', 'read committed', 'read uncommitted'.""" + if value not in ["serializable", "repeatable read", "read committed", "read uncommitted"]: + raise ValueError( + "Value not one of 'serializable', 'repeatable read', 'read committed', 'read uncommitted'." + ) + + return value + + @validator("response_extra_float_digits") + @classmethod + def response_extra_float_digits_values(cls, value: int) -> int | None: + """Check response_extra_float_digits config option is between -15 and 3.""" + if value < -15 or value > 3: + raise ValueError("Value is not between -15 and 3") + + return value + + @validator("optimizer_geqo_effort") + @classmethod + def optimizer_geqo_effort_values(cls, value: int) -> int | None: + """Check optimizer_geqo_effort config option is between 1 and 10.""" + if value < 1 or value > 10: + raise ValueError("Value is not between 1 and 10") + + return value + + @validator("optimizer_geqo_generations") + @classmethod + def optimizer_geqo_generations_values(cls, value: int) -> int | None: + """Check optimizer_geqo_generations config option is between 0 and 2147483647.""" + if value < 0 or value > 2147483647: + raise ValueError("Value is not between 0 and 2147483647") + + return value + + @validator("optimizer_geqo_pool_size") + @classmethod + def optimizer_geqo_pool_size_values(cls, value: int) -> int | None: + """Check optimizer_geqo_pool_size config option is between 0 and 2147483647.""" + if value < 0 or value > 2147483647: + raise ValueError("Value is not between 0 and 2147483647") + + return value + + @validator("optimizer_geqo_seed") + @classmethod + def optimizer_geqo_seed_values(cls, value: float) -> float | None: + """Check optimizer_geqo_seed config option is between 0 and 1.""" + if value < 0 or value > 1: + raise ValueError("Value is not between 0 and 1") + + return value + + @validator("optimizer_geqo_selection_bias") + @classmethod + def optimizer_geqo_selection_bias_values(cls, value: float) -> float | None: + """Check optimizer_geqo_selection_bias config option is between 1.5 and 2.""" + if value < 1.5 or value > 2: + raise ValueError("Value is not between 1.5 and 2") + + return value + + @validator("optimizer_geqo_threshold") + @classmethod + def optimizer_geqo_threshold_values(cls, value: int) -> int | None: + """Check optimizer_geqo_threshold config option is between 2 and 2147483647.""" + if value < 2 or value > 2147483647: + raise ValueError("Value is not between 2 and 2147483647") + + return value + + @validator("response_gin_fuzzy_search_limit") + @classmethod + def response_gin_fuzzy_search_limit_values(cls, value: int) -> int | None: + """Check response_gin_fuzzy_search_limit config option is between 0 and 2147483647.""" + if value < 0 or value > 2147483647: + raise ValueError("Value is not between 0 and 2147483647") + + return value + + @validator("storage_gin_pending_list_limit") + @classmethod + def storage_gin_pending_list_limit_values(cls, value: int) -> int | None: + """Check storage_gin_pending_list_limit config option is between 64 and 2147483647.""" + if value < 64 or value > 2147483647: + raise ValueError("Value is not between 64 and 2147483647") + + return value + + @validator("session_idle_in_transaction_session_timeout") + @classmethod + def session_idle_in_transaction_session_timeout_values(cls, value: int) -> int | None: + """Check session_idle_in_transaction_session_timeout config option is between 0 and 2147483647.""" + if value < 0 or value > 2147483647: + raise ValueError("Value is not between 0 and 2147483647") + + return value + + @validator("optimizer_jit_above_cost") + @classmethod + def optimizer_jit_above_cost_values(cls, value: float) -> float | None: + """Check optimizer_jit_above_cost config option is between -1 and 1.80E+308.""" + if value < -1 or value > 1.80e308: + raise ValueError("Value is not between -1 and 1.80E+308") + + return value + + @validator("optimizer_jit_inline_above_cost") + @classmethod + def optimizer_jit_inline_above_cost_values(cls, value: float) -> float | None: + """Check optimizer_jit_inline_above_cost config option is between -1 and 1.80E+308.""" + if value < -1 or value > 1.80e308: + raise ValueError("Value is not between -1 and 1.80E+308") + + return value + + @validator("optimizer_jit_optimize_above_cost") + @classmethod + def optimizer_jit_optimize_above_cost_values(cls, value: float) -> float | None: + """Check optimizer_jit_optimize_above_cost config option is between -1 and 1.80E+308.""" + if value < -1 or value > 1.80e308: + raise ValueError("Value is not between -1 and 1.80E+308") + + return value + + @validator("request_lock_timeout") + @classmethod + def request_lock_timeout_values(cls, value: int) -> int | None: + """Check request_lock_timeout config option is between 0 and 2147483647.""" + if value < 0 or value > 2147483647: + raise ValueError("Value is not between 0 and 2147483647") + + return value + + @validator("optimizer_min_parallel_index_scan_size") + @classmethod + def optimizer_min_parallel_index_scan_size_values(cls, value: int) -> int | None: + """Check optimizer_min_parallel_index_scan_size config option is between 0 and 715827882.""" + if value < 0 or value > 715827882: + raise ValueError("Value is not between 0 and 715827882") + + return value + + @validator("optimizer_min_parallel_table_scan_size") + @classmethod + def optimizer_min_parallel_table_scan_size_values(cls, value: int) -> int | None: + """Check optimizer_min_parallel_table_scan_size config option is between 0 and 715827882.""" + if value < 0 or value > 715827882: + raise ValueError("Value is not between 0 and 715827882") + + return value + + @validator("storage_old_snapshot_threshold") + @classmethod + def storage_old_snapshot_threshold_values(cls, value: int) -> int | None: + """Check storage_old_snapshot_threshold config option is between -1 and 86400.""" + if value < -1 or value > 86400: + raise ValueError("Value is not between -1 and 86400") + + return value + + @validator("optimizer_parallel_setup_cost") + @classmethod + def optimizer_parallel_setup_cost_values(cls, value: float) -> float | None: + """Check optimizer_parallel_setup_cost config option is between 0 and 1.80E+308.""" + if value < 0 or value > 1.80e308: + raise ValueError("Value is not between 0 and 1.80E+308") + + return value + + @validator("optimizer_parallel_tuple_cost") + @classmethod + def optimizer_parallel_tuple_cost_values(cls, value: float) -> float | None: + """Check optimizer_parallel_tuple_cost config option is between 0 and 1.80E+308.""" + if value < 0 or value > 1.80e308: + raise ValueError("Value is not between 0 and 1.80E+308") + + return value + + @validator("connection_statement_timeout") + @classmethod + def connection_statement_timeout_values(cls, value: int) -> int | None: + """Check connection_statement_timeout config option is between 0 and 2147483647.""" + if value < 0 or value > 2147483647: + raise ValueError("Value is not between 0 and 2147483647") + + return value + + @validator("request_track_activity_query_size") + @classmethod + def request_track_activity_query_size_values(cls, value: int) -> int | None: + """Check request_track_activity_query_size config option is between 100 and 1048576.""" + if value < 100 or value > 1048576: + raise ValueError("Value is not between 100 and 1048576") + + return value + + @validator("logging_track_functions") + @classmethod + def logging_track_functions_values(cls, value: str) -> str | None: + """Check logging_track_functions config option is one of 'none', 'pl', 'all'.""" + if value not in ["none", "pl", "all"]: + raise ValueError("Value not one of 'none', 'pl', 'all'.") + + return value + + @validator("vacuum_vacuum_cost_delay") + @classmethod + def vacuum_vacuum_cost_delay_values(cls, value: float) -> float | None: + """Check vacuum_vacuum_cost_delay config option is between 0 and 100.""" + if value < 0 or value > 100: + raise ValueError("Value is not between 0 and 100") + + return value + + @validator("vacuum_vacuum_cost_limit") + @classmethod + def vacuum_vacuum_cost_limit_values(cls, value: int) -> int | None: + """Check vacuum_vacuum_cost_limit config option is between 1 and 10000.""" + if value < 1 or value > 10000: + raise ValueError("Value is not between 1 and 10000") + + return value + + @validator("vacuum_vacuum_cost_page_dirty") + @classmethod + def vacuum_vacuum_cost_page_dirty_values(cls, value: int) -> int | None: + """Check vacuum_vacuum_cost_page_dirty config option is between 0 and 10000.""" + if value < 0 or value > 10000: + raise ValueError("Value is not between 0 and 10000") + + return value + + @validator("vacuum_vacuum_cost_page_hit") + @classmethod + def vacuum_vacuum_cost_page_hit_values(cls, value: int) -> int | None: + """Check vacuum_vacuum_cost_page_hit config option is between 0 and 10000.""" + if value < 0 or value > 10000: + raise ValueError("Value is not between 0 and 10000") + + return value + + @validator("vacuum_vacuum_cost_page_miss") + @classmethod + def vacuum_vacuum_cost_page_miss_values(cls, value: int) -> int | None: + """Check vacuum_vacuum_cost_page_miss config option is between 0 and 10000.""" + if value < 0 or value > 10000: + raise ValueError("Value is not between 0 and 10000") + + return value + + @validator("vacuum_vacuum_failsafe_age") + @classmethod + def vacuum_vacuum_failsafe_age_values(cls, value: int) -> int | None: + """Check vacuum_vacuum_failsafe_age config option is between 0 and 2100000000.""" + if value < 0 or value > 2100000000: + raise ValueError("Value is not between 0 and 2100000000") + + return value + + @validator("vacuum_vacuum_freeze_min_age") + @classmethod + def vacuum_vacuum_freeze_min_age_values(cls, value: int) -> int | None: + """Check vacuum_vacuum_freeze_min_age config option is between 0 and 1000000000.""" + if value < 0 or value > 1000000000: + raise ValueError("Value is not between 0 and 1000000000") + + return value + + @validator("vacuum_vacuum_multixact_failsafe_age") + @classmethod + def vacuum_vacuum_multixact_failsafe_age_values(cls, value: int) -> int | None: + """Check vacuum_vacuum_multixact_failsafe_age config option is between 0 and 2100000000.""" + if value < 0 or value > 2100000000: + raise ValueError("Value is not between 0 and 2100000000") + + return value + + @validator("vacuum_vacuum_multixact_freeze_min_age") + @classmethod + def vacuum_vacuum_multixact_freeze_min_age_values(cls, value: int) -> int | None: + """Check vacuum_vacuum_multixact_freeze_min_age config option is between 0 and 1000000000.""" + if value < 0 or value > 1000000000: + raise ValueError("Value is not between 0 and 1000000000") + + return value + + @validator("vacuum_vacuum_multixact_freeze_table_age") + @classmethod + def vacuum_vacuum_multixact_freeze_table_age_values(cls, value: int) -> int | None: + """Check vacuum_vacuum_multixact_freeze_table_age config option is between 0 and 2000000000.""" + if value < 0 or value > 2000000000: + raise ValueError("Value is not between 0 and 2000000000") + + return value + + @validator("request_xmlbinary") + @classmethod + def request_xmlbinary_values(cls, value: str) -> str | None: + """Check request_xmlbinary config option is 'base64' or 'hex'.""" + if value not in ["base64", "hex"]: + raise ValueError("Value not 'base64' or 'hex'.") + + return value + + @validator("request_xmloption") + @classmethod + def request_xmloption_values(cls, value: str) -> str | None: + """Check request_xmloption config option is 'content' or 'document'.""" + if value not in ["content", "document"]: + raise ValueError("Value not 'content' or 'document'.") + + return value diff --git a/tests/integration/test_config.py b/tests/integration/test_config.py index 70f20f15d9..229450b715 100644 --- a/tests/integration/test_config.py +++ b/tests/integration/test_config.py @@ -33,18 +33,28 @@ async def test_config_parameters(ops_test: OpsTest, charm) -> None: { "synchronous_node_count": [test_string, "all"] }, # config option is one of `all`, `minority` or `majority` + {"connection_authentication_timeout": ["0", "60"]}, # config option is from 1 and 600 + {"connection_statement_timeout": ["-1", "0"]}, # config option is from 0 to 2147483647 { "durability_synchronous_commit": [test_string, "on"] }, # config option is one of `on`, `remote_apply` or `remote_write` + { + "instance_default_text_search_config": [test_string, "pg_catalog.simple"] + }, # config option is validated against the db { "instance_max_locks_per_transaction": ["-1", "64"] }, # config option is between 64 and 2147483647 { "instance_password_encryption": [test_string, "scram-sha-256"] }, # config option is one of `md5` or `scram-sha-256` + {"logging_client_min_messages": [test_string, "notice"]}, + # config option is one of 'debug5', 'debug4', 'debug3', 'debug2', 'debug1', 'log', 'notice', 'warning' or 'error'. { "logging_log_min_duration_statement": ["-2", "-1"] }, # config option is between -1 and 2147483647 + { + "logging_track_functions": [test_string, "none"] + }, # config option is one of 'none', 'pl', 'all'. { "memory_maintenance_work_mem": ["1023", "65536"] }, # config option is between 1024 and 2147483647 @@ -55,21 +65,101 @@ async def test_config_parameters(ops_test: OpsTest, charm) -> None: { "optimizer_constraint_exclusion": [test_string, "partition"] }, # config option is one of `on`, `off` or `partition` + { + "optimizer_cpu_index_tuple_cost": ["-1", "0.005"] + }, # config option is between 0 and 1.80E+308 + { + "optimizer_cpu_operator_cost": ["-1", "0.0025"] + }, # config option is between 0 and 1.80E+308 + {"optimizer_cpu_tuple_cost": ["-1", "0.01"]}, # config option is between 0 and 1.80E+308 + {"optimizer_cursor_tuple_fraction": ["-1", "0.1"]}, # config option is between 0 and 1 { "optimizer_default_statistics_target": ["0", "100"] }, # config option is between 1 and 10000 {"optimizer_from_collapse_limit": ["0", "8"]}, # config option is between 1 and 2147483647 + {"optimizer_geqo_effort": ["-1", "5"]}, # config option is between 1 and 10 + {"optimizer_geqo_generations": ["-1", "0"]}, # config option is between 1 and 2147483647 + {"optimizer_geqo_pool_size": ["-1", "0"]}, # config option is between 1 and 2147483647 + {"optimizer_geqo_seed": ["-1", "0.0"]}, # config option is between 1 and 1 + {"optimizer_geqo_selection_bias": ["-1", "2.0"]}, # config option is between 1 and 2 + {"optimizer_geqo_threshold": ["-1", "12"]}, # config option is between 1 and 2147483647 + { + "optimizer_jit_above_cost": ["-2", "100000.0"] + }, # config option is between -1 and 1.80E+308 + { + "optimizer_jit_inline_above_cost": ["-2", "500000.0"] + }, # config option is between -1 and 1.80E+308 + { + "optimizer_jit_optimize_above_cost": ["-2", "500000.0"] + }, # config option is between -1 and 1.80E+308 {"optimizer_join_collapse_limit": ["0", "8"]}, # config option is between 1 and 2147483647 + { + "optimizer_min_parallel_index_scan_size": ["-1", "64"] + }, # config option is between 0 and 715827882 + { + "optimizer_min_parallel_table_scan_size": ["-1", "1024"] + }, # config option is between 0 and 715827882 + { + "optimizer_parallel_setup_cost": ["-1", "1000.0"] + }, # config option is between 0 and 1.80E+308 + { + "optimizer_parallel_tuple_cost": ["-1", "0.1"] + }, # config option is between 0 and 1.80E+308 {"profile": [test_string, "testing"]}, # config option is one of `testing` or `production` - # {"profile_limit_memory": {"127", "128"}}, # config option is between 128 and 9999999 + # { + # "profile_limit_memory": {"127", "128"} + # }, # config option is between 128 and 9999999 + { + "request_backslash_quote": [test_string, "safe_encoding"] + }, # config option is one of `safe_encoding` and `on` and `off` + { + "request_date_style": [test_string, "ISO, MDY"] + }, # config option is validated against the db + {"request_deadlock_timeout": ["-1", "1000"]}, # config option is between 1 and 2147483647 + { + "request_default_transaction_isolation": [test_string, "read committed"] + }, # config option is one of `serializable`, `repeatable read`, `read committed`, `read uncommitted`. + {"request_lock_timeout": ["-1", "0"]}, # config option is between 0 and 2147483647 + {"request_time_zone": [test_string, "UTC"]}, # config option is validated against the db + { + "request_track_activity_query_size": ["-1", "1024"] + }, # config option is between 100 and 1048576 + {"request_xmlbinary": [test_string, "base64"]}, # config option is one of `base64`, `hex`. + { + "request_xmloption": [test_string, "content"] + }, # config option is one of `content`, `document`. { "response_bytea_output": [test_string, "hex"] }, # config option is one of `escape` or `hex` + {"response_extra_float_digits": ["5", "1"]}, # config option is between -15 and 3 { - "vacuum_autovacuum_analyze_scale_factor": ["-1", "0.1"] - }, # config option is between 0 and 100 + "response_gin_fuzzy_search_limit": ["-1", "0"] + }, # config option is between 0 and 2147483647 { - "vacuum_autovacuum_vacuum_scale_factor": ["-1", "0.2"] + "response_lc_monetary": [test_string, "C"] + }, # allowed values are the locales available in the unit. + { + "response_lc_numeric": [test_string, "C"] + }, # allowed values are the locales available in the unit. + { + "response_lc_time": [test_string, "C"] + }, # allowed values are the locales available in the unit. + { + "session_idle_in_transaction_session_timeout": ["-1", "0"] + }, # config option is between 0 and 2147483647 + { + "storage_bgwriter_lru_maxpages": ["-1", "100"] + }, # config option is between 0 and 1073741823 + {"storage_bgwriter_lru_multiplier": ["-1", "2.0"]}, # config option is between 0 and 10 + { + "storage_default_table_access_method": [test_string, "heap"] + }, # config option entries can be created using the CREATE ACCESS METHOD SQL command. default `heap` + { + "storage_gin_pending_list_limit": ["-1", "4096"] + }, # config option is between 64 and 2147483647 + {"storage_old_snapshot_threshold": ["-2", "-1"]}, # config option is between -1 and 86400 + { + "vacuum_autovacuum_analyze_scale_factor": ["-1", "0.1"] }, # config option is between 0 and 100 { "vacuum_autovacuum_analyze_threshold": ["-1", "50"] @@ -77,19 +167,48 @@ async def test_config_parameters(ops_test: OpsTest, charm) -> None: { "vacuum_autovacuum_freeze_max_age": ["99999", "200000000"] }, # config option is between 100000 and 2000000000 + {"vacuum_autovacuum_naptime": ["-1", "60"]}, # config option is between 1 and 2147483 { "vacuum_autovacuum_vacuum_cost_delay": ["-2", "2.0"] }, # config option is between -1 and 100 + { + "vacuum_autovacuum_vacuum_cost_limit": ["-2", "-1"] + }, # config option is between -1 and 10000 + { + "vacuum_autovacuum_vacuum_insert_scale_factor": ["-1", "0.2"] + }, # config option is between 0 and 100 + { + "vacuum_autovacuum_vacuum_insert_threshold": ["-2", "1000"] + }, # config option is between -1 and 2147483647 + { + "vacuum_autovacuum_vacuum_scale_factor": ["-1", "0.2"] + }, # config option is between 0 and 100 + { + "vacuum_autovacuum_vacuum_threshold": ["-1", "50"] + }, # config option is between 0 and 2147483647 + {"vacuum_vacuum_cost_delay": ["-1", "0.0"]}, # config option is between 0 and 100 + {"vacuum_vacuum_cost_limit": ["-1", "200"]}, # config option is between 1 and 10000 + {"vacuum_vacuum_cost_page_dirty": ["-1", "20"]}, # config option is between 0 and 10000 + {"vacuum_vacuum_cost_page_hit": ["-1", "1"]}, # config option is between 0 and 10000 + {"vacuum_vacuum_cost_page_miss": ["-1", "2"]}, # config option is between 0 and 10000 + { + "vacuum_vacuum_failsafe_age": ["-1", "1600000000"] + }, # config option is between 0 and 2100000000 + { + "vacuum_vacuum_freeze_min_age": ["-1", "50000000"] + }, # config option is between 0 and 1000000000 { "vacuum_vacuum_freeze_table_age": ["-1", "150000000"] }, # config option is between 0 and 2000000000 { - "instance_default_text_search_config": [test_string, "pg_catalog.simple"] - }, # config option is validated against the db + "vacuum_vacuum_multixact_failsafe_age": ["-1", "1600000000"] + }, # config option is between 0 and 2100000000 { - "request_date_style": [test_string, "ISO, MDY"] - }, # config option is validated against the db - {"request_time_zone": [test_string, "UTC"]}, # config option is validated against the db + "vacuum_vacuum_multixact_freeze_min_age": ["-1", "5000000"] + }, # config option is between 0 and 1000000000 + { + "vacuum_vacuum_multixact_freeze_table_age": ["-1", "150000000"] + }, # config option is between 0 and 2000000000 ] charm_config = {}