diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml new file mode 100644 index d607eca..dfc482f *** a/doc/src/sgml/config.sgml --- b/doc/src/sgml/config.sgml *************** *** 24,30 **** All parameter names are case-insensitive. Every parameter takes a value of one of five types: boolean, integer, floating point, ! string, or enum. --- 24,30 ---- All parameter names are case-insensitive. Every parameter takes a value of one of five types: boolean, integer, floating point, ! string, or enum. Floating point values may be expressed as a percentage. *************** include_dir 'conf.d' *** 2411,2418 **** ! Specifies the target of checkpoint completion, as a fraction of ! total time between checkpoints. The default is 0.5. This parameter can only be set in the postgresql.conf file or on the server command line. --- 2411,2418 ---- ! Specifies the target of checkpoint completion, as a percentage of ! total time between checkpoints. The default is 50%. This parameter can only be set in the postgresql.conf file or on the server command line. *************** SELECT * FROM parent WHERE key = 2400; *** 3589,3601 **** ! Sets the planner's estimate of the fraction of a cursor's rows that ! will be retrieved. The default is 0.1. Smaller values of this setting bias the planner towards using fast start plans for cursors, which will retrieve the first few rows quickly while perhaps taking a long time to fetch all rows. Larger values put more emphasis on the total estimated time. At the maximum ! setting of 1.0, cursors are planned exactly like regular queries, considering only the total estimated time and not how soon the first rows might be delivered. --- 3589,3601 ---- ! Sets the planner's estimate of the percentage of a cursor's rows that ! will be retrieved. The default is 10%. Smaller values of this setting bias the planner towards using fast start plans for cursors, which will retrieve the first few rows quickly while perhaps taking a long time to fetch all rows. Larger values put more emphasis on the total estimated time. At the maximum ! setting of 100%, cursors are planned exactly like regular queries, considering only the total estimated time and not how soon the first rows might be delivered. *************** COPY postgres_log FROM '/full/path/to/lo *** 5221,5230 **** ! Specifies a fraction of the table size to add to autovacuum_vacuum_threshold when deciding whether to trigger a VACUUM. ! The default is 0.2 (20% of table size). This parameter can only be set in the postgresql.conf file or on the server command line. This setting can be overridden for individual tables by --- 5221,5230 ---- ! Specifies a percentage of the table size to add to autovacuum_vacuum_threshold when deciding whether to trigger a VACUUM. ! The default is 20% of table size. This parameter can only be set in the postgresql.conf file or on the server command line. This setting can be overridden for individual tables by *************** COPY postgres_log FROM '/full/path/to/lo *** 5241,5250 **** ! Specifies a fraction of the table size to add to autovacuum_analyze_threshold when deciding whether to trigger an ANALYZE. ! The default is 0.1 (10% of table size). This parameter can only be set in the postgresql.conf file or on the server command line. This setting can be overridden for individual tables by --- 5241,5250 ---- ! Specifies a percentage of the table size to add to autovacuum_analyze_threshold when deciding whether to trigger an ANALYZE. ! The default is 10% of table size. This parameter can only be set in the postgresql.conf file or on the server command line. This setting can be overridden for individual tables by diff --git a/src/backend/utils/misc/guc-file.l b/src/backend/utils/misc/guc-file.l new file mode 100644 index 6dca5df..dc2171b *** a/src/backend/utils/misc/guc-file.l --- b/src/backend/utils/misc/guc-file.l *************** UNIT_LETTER [a-zA-Z] *** 74,80 **** INTEGER {SIGN}?({DIGIT}+|0x{HEXDIGIT}+){UNIT_LETTER}* EXPONENT [Ee]{SIGN}?{DIGIT}+ ! REAL {SIGN}?{DIGIT}*"."{DIGIT}*{EXPONENT}? LETTER [A-Za-z_\200-\377] LETTER_OR_DIGIT [A-Za-z_0-9\200-\377] --- 74,83 ---- INTEGER {SIGN}?({DIGIT}+|0x{HEXDIGIT}+){UNIT_LETTER}* EXPONENT [Ee]{SIGN}?{DIGIT}+ ! ! FLOAT {SIGN}?{DIGIT}*"."{DIGIT}*{EXPONENT}? ! PERCENT {SIGN}?{DIGIT}*"."?{DIGIT}*"%" ! REAL {FLOAT}|{PERCENT} LETTER [A-Za-z_\200-\377] LETTER_OR_DIGIT [A-Za-z_0-9\200-\377] diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c new file mode 100644 index b1bff7f..fb67a90 *** a/src/backend/utils/misc/guc.c --- b/src/backend/utils/misc/guc.c *************** static struct config_real ConfigureNames *** 2635,2643 **** { {"cursor_tuple_fraction", PGC_USERSET, QUERY_TUNING_OTHER, ! gettext_noop("Sets the planner's estimate of the fraction of " "a cursor's rows that will be retrieved."), ! NULL }, &cursor_tuple_fraction, DEFAULT_CURSOR_TUPLE_FRACTION, 0.0, 1.0, --- 2635,2644 ---- { {"cursor_tuple_fraction", PGC_USERSET, QUERY_TUNING_OTHER, ! gettext_noop("Sets the planner's estimate of the percentage of " "a cursor's rows that will be retrieved."), ! NULL, ! GUC_SHOW_PERCENT }, &cursor_tuple_fraction, DEFAULT_CURSOR_TUPLE_FRACTION, 0.0, 1.0, *************** static struct config_real ConfigureNames *** 2687,2694 **** { {"autovacuum_vacuum_scale_factor", PGC_SIGHUP, AUTOVACUUM, ! gettext_noop("Number of tuple updates or deletes prior to vacuum as a fraction of reltuples."), ! NULL }, &autovacuum_vac_scale, 0.2, 0.0, 100.0, --- 2688,2696 ---- { {"autovacuum_vacuum_scale_factor", PGC_SIGHUP, AUTOVACUUM, ! gettext_noop("Number of tuple updates or deletes prior to vacuum as a percentage of reltuples."), ! NULL, ! GUC_SHOW_PERCENT }, &autovacuum_vac_scale, 0.2, 0.0, 100.0, *************** static struct config_real ConfigureNames *** 2696,2703 **** }, { {"autovacuum_analyze_scale_factor", PGC_SIGHUP, AUTOVACUUM, ! gettext_noop("Number of tuple inserts, updates, or deletes prior to analyze as a fraction of reltuples."), ! NULL }, &autovacuum_anl_scale, 0.1, 0.0, 100.0, --- 2698,2706 ---- }, { {"autovacuum_analyze_scale_factor", PGC_SIGHUP, AUTOVACUUM, ! gettext_noop("Number of tuple inserts, updates, or deletes prior to analyze as a percentage of reltuples."), ! NULL, ! GUC_SHOW_PERCENT }, &autovacuum_anl_scale, 0.1, 0.0, 100.0, *************** static struct config_real ConfigureNames *** 2706,2713 **** { {"checkpoint_completion_target", PGC_SIGHUP, WAL_CHECKPOINTS, ! gettext_noop("Time spent flushing dirty buffers during checkpoint, as fraction of checkpoint interval."), ! NULL }, &CheckPointCompletionTarget, 0.5, 0.0, 1.0, --- 2709,2717 ---- { {"checkpoint_completion_target", PGC_SIGHUP, WAL_CHECKPOINTS, ! gettext_noop("Time spent flushing dirty buffers during checkpoint, as a percentage of checkpoint interval."), ! NULL, ! GUC_SHOW_PERCENT }, &CheckPointCompletionTarget, 0.5, 0.0, 1.0, *************** parse_int(const char *value, int *result *** 5253,5258 **** --- 5257,5263 ---- /* * Try to parse value as a floating point number in the usual format. + * If the string ends in '%' divide by 100. * If the string parses okay, return true, else false. * If okay and result is not NULL, return the value in *result. */ *************** parse_real(const char *value, double *re *** 5270,5275 **** --- 5275,5287 ---- if (endptr == value || errno == ERANGE) return false; + /* Check for percentage. */ + if (*endptr == '%') + { + val /= 100.0; + endptr++; + } + /* allow whitespace after number */ while (isspace((unsigned char) *endptr)) endptr++; *************** _ShowOption(struct config_generic * reco *** 8208,8215 **** val = (*conf->show_hook) (); else { ! snprintf(buffer, sizeof(buffer), "%g", ! *conf->variable); val = buffer; } } --- 8220,8235 ---- val = (*conf->show_hook) (); else { ! if (record->flags & GUC_SHOW_PERCENT) ! { ! snprintf(buffer, sizeof(buffer), "%g%%", ! *conf->variable * 100.0); ! } ! else ! { ! snprintf(buffer, sizeof(buffer), "%g", ! *conf->variable); ! } val = buffer; } } diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample new file mode 100644 index b053659..0352c2d *** a/src/backend/utils/misc/postgresql.conf.sample --- b/src/backend/utils/misc/postgresql.conf.sample *************** *** 199,205 **** #checkpoint_segments = 3 # in logfile segments, min 1, 16MB each #checkpoint_timeout = 5min # range 30s-1h ! #checkpoint_completion_target = 0.5 # checkpoint target duration, 0.0 - 1.0 #checkpoint_warning = 30s # 0 disables # - Archiving - --- 199,205 ---- #checkpoint_segments = 3 # in logfile segments, min 1, 16MB each #checkpoint_timeout = 5min # range 30s-1h ! #checkpoint_completion_target = 50% # checkpoint target duration, 0-100% #checkpoint_warning = 30s # 0 disables # - Archiving - *************** *** 303,309 **** #default_statistics_target = 100 # range 1-10000 #constraint_exclusion = partition # on, off, or partition ! #cursor_tuple_fraction = 0.1 # range 0.0-1.0 #from_collapse_limit = 8 #join_collapse_limit = 8 # 1 disables collapsing of explicit # JOIN clauses --- 303,309 ---- #default_statistics_target = 100 # range 1-10000 #constraint_exclusion = partition # on, off, or partition ! #cursor_tuple_fraction = 10% # range 0-100% #from_collapse_limit = 8 #join_collapse_limit = 8 # 1 disables collapsing of explicit # JOIN clauses *************** *** 483,490 **** # vacuum #autovacuum_analyze_threshold = 50 # min number of row updates before # analyze ! #autovacuum_vacuum_scale_factor = 0.2 # fraction of table size before vacuum ! #autovacuum_analyze_scale_factor = 0.1 # fraction of table size before analyze #autovacuum_freeze_max_age = 200000000 # maximum XID age before forced vacuum # (change requires restart) #autovacuum_multixact_freeze_max_age = 400000000 # maximum multixact age --- 483,490 ---- # vacuum #autovacuum_analyze_threshold = 50 # min number of row updates before # analyze ! #autovacuum_vacuum_scale_factor = 20% # percent of table size before vacuum ! #autovacuum_analyze_scale_factor = 10% # percent of table size before analyze #autovacuum_freeze_max_age = 200000000 # maximum XID age before forced vacuum # (change requires restart) #autovacuum_multixact_freeze_max_age = 400000000 # maximum multixact age diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h new file mode 100644 index 80813d2..fd7bde5 *** a/src/include/utils/guc.h --- b/src/include/utils/guc.h *************** typedef enum *** 215,220 **** --- 215,221 ---- #define GUC_NOT_WHILE_SEC_REST 0x8000 /* can't set if security restricted */ #define GUC_DISALLOW_IN_AUTO_FILE 0x00010000 /* can't set in * PG_AUTOCONF_FILENAME */ + #define GUC_SHOW_PERCENT 0x00020000 /* Display as percent. */ /* GUC vars that are actually declared in guc.c, rather than elsewhere */ extern bool log_duration; diff --git a/src/test/regress/expected/guc.out b/src/test/regress/expected/guc.out new file mode 100644 index 4f0065c..95feb8c *** a/src/test/regress/expected/guc.out --- b/src/test/regress/expected/guc.out *************** SHOW datestyle; *** 9,14 **** --- 9,15 ---- -- SET to some nondefault value SET vacuum_cost_delay TO 40; SET datestyle = 'ISO, YMD'; + SET cursor_tuple_fraction = '15%'; SHOW vacuum_cost_delay; vacuum_cost_delay ------------------- *************** SHOW datestyle; *** 21,26 **** --- 22,33 ---- ISO, YMD (1 row) + SHOW cursor_tuple_fraction; + cursor_tuple_fraction + ----------------------- + 15% + (1 row) + SELECT '2006-08-13 12:34:56'::timestamptz; timestamptz ------------------------ diff --git a/src/test/regress/sql/guc.sql b/src/test/regress/sql/guc.sql new file mode 100644 index 3de8a6b..4fef222 *** a/src/test/regress/sql/guc.sql --- b/src/test/regress/sql/guc.sql *************** SHOW datestyle; *** 5,12 **** --- 5,14 ---- -- SET to some nondefault value SET vacuum_cost_delay TO 40; SET datestyle = 'ISO, YMD'; + SET cursor_tuple_fraction = '15%'; SHOW vacuum_cost_delay; SHOW datestyle; + SHOW cursor_tuple_fraction; SELECT '2006-08-13 12:34:56'::timestamptz; -- SET LOCAL has no effect outside of a transaction