Generate GUC tables from .dat file

Store the information in guc_tables.c in a .dat file similar to the
catalog data in src/include/catalog/, and generate a part of
guc_tables.c from that.  The goal is to make it easier to edit that
information, and to be able to make changes to the downstream data
structures more easily.  (Essentially, those are the same reasons as
for the original adoption of the .dat format.)

Reviewed-by: John Naylor <johncnaylorls@gmail.com>
Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
Reviewed-by: David E. Wheeler <david@justatheory.com>
Discussion: https://www.postgresql.org/message-id/flat/dae6fe89-1e0c-4c3f-8d92-19d23374fb10%40eisentraut.org
master
Peter Eisentraut 1 week ago
parent aba8f61c30
commit 6359989654
  1. 1
      src/backend/utils/.gitignore
  2. 11
      src/backend/utils/Makefile
  3. 131
      src/backend/utils/misc/gen_guc_tables.pl
  4. 3473
      src/backend/utils/misc/guc_parameters.dat
  5. 4736
      src/backend/utils/misc/guc_tables.c
  6. 2
      src/bin/pg_dump/dumputils.c
  7. 18
      src/include/libpq/libpq.h
  8. 1
      src/include/utils/.gitignore
  9. 23
      src/include/utils/guc.h
  10. 18
      src/include/utils/inval.h
  11. 7
      src/include/utils/meson.build
  12. 4
      src/timezone/pgtz.c

@ -2,5 +2,6 @@
/fmgroids.h
/fmgrprotos.h
/fmgr-stamp
/guc_tables.inc.c
/probes.h
/errcodes.h

@ -43,7 +43,7 @@ generated-header-symlinks: $(top_builddir)/src/include/utils/header-stamp submak
submake-adt-headers:
$(MAKE) -C adt jsonpath_gram.h
$(SUBDIRS:%=%-recursive): fmgr-stamp errcodes.h
$(SUBDIRS:%=%-recursive): fmgr-stamp errcodes.h guc_tables.inc.c
# fmgr-stamp records the last time we ran Gen_fmgrtab.pl. We don't rely on
# the timestamps of the individual output files, because the Perl script
@ -55,6 +55,9 @@ fmgr-stamp: Gen_fmgrtab.pl $(catalogdir)/Catalog.pm $(top_srcdir)/src/include/ca
errcodes.h: $(top_srcdir)/src/backend/utils/errcodes.txt generate-errcodes.pl
$(PERL) $(srcdir)/generate-errcodes.pl --outfile $@ $<
guc_tables.inc.c: $(top_srcdir)/src/backend/utils/misc/guc_parameters.dat $(top_srcdir)/src/backend/utils/misc/gen_guc_tables.pl
$(PERL) $(top_srcdir)/src/backend/utils/misc/gen_guc_tables.pl $< $@
ifeq ($(enable_dtrace), yes)
probes.h: postprocess_dtrace.sed probes.h.tmp
sed -f $^ >$@
@ -70,8 +73,8 @@ endif
# These generated headers must be symlinked into src/include/.
# We use header-stamp to record that we've done this because the symlinks
# themselves may appear older than fmgr-stamp.
$(top_builddir)/src/include/utils/header-stamp: fmgr-stamp errcodes.h probes.h
cd '$(dir $@)' && for file in fmgroids.h fmgrprotos.h errcodes.h probes.h; do \
$(top_builddir)/src/include/utils/header-stamp: fmgr-stamp errcodes.h probes.h guc_tables.inc.c
cd '$(dir $@)' && for file in fmgroids.h fmgrprotos.h errcodes.h probes.h guc_tables.inc.c; do \
rm -f $$file && $(LN_S) "../../../$(subdir)/$$file" . ; \
done
touch $@
@ -89,4 +92,4 @@ uninstall-data:
clean:
rm -f probes.h probes.h.tmp
rm -f fmgroids.h fmgrprotos.h fmgrtab.c fmgr-stamp errcodes.h
rm -f fmgroids.h fmgrprotos.h fmgrtab.c fmgr-stamp errcodes.h guc_tables.inc.c

@ -0,0 +1,131 @@
#!/usr/bin/perl
#----------------------------------------------------------------------
#
# Generate guc_tables.c from guc_parameters.dat.
#
# Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
# Portions Copyright (c) 1994, Regents of the University of California
#
# src/backend/utils/misc/gen_guc_tables.pl
#
#----------------------------------------------------------------------
use strict;
use warnings FATAL => 'all';
use FindBin;
use lib "$FindBin::RealBin/../../catalog";
use Catalog;
die "Usage: $0 INPUT_FILE OUTPUT_FILE\n" unless @ARGV == 2;
my ($input_fname, $output_fname) = @ARGV;
my $parse = Catalog::ParseData($input_fname);
open my $ofh, '>', $output_fname or die;
print_boilerplate($ofh, $output_fname, 'GUC tables');
foreach my $type (qw(bool int real string enum))
{
print_one_table($ofh, $type);
}
close $ofh;
# Adds double quotes and escapes as necessary for C strings.
sub dquote
{
my ($s) = @_;
return q{"} . $s =~ s/"/\\"/gr . q{"};
}
# Print GUC table for one type.
sub print_one_table
{
my ($ofh, $type) = @_;
my $Type = ucfirst $type;
print $ofh "\n\n";
print $ofh "struct config_${type} ConfigureNames${Type}[] =\n";
print $ofh "{\n";
foreach my $entry (@{$parse})
{
next if $entry->{type} ne $type;
print $ofh "#ifdef $entry->{ifdef}\n" if $entry->{ifdef};
print $ofh "\t{\n";
printf $ofh "\t\t{%s, %s, %s,\n",
dquote($entry->{name}),
$entry->{context},
$entry->{group};
printf $ofh "\t\t\tgettext_noop(%s),\n", dquote($entry->{short_desc});
if ($entry->{long_desc})
{
printf $ofh "\t\t\tgettext_noop(%s)", dquote($entry->{long_desc});
}
else
{
print $ofh "\t\t\tNULL";
}
if ($entry->{flags})
{
print $ofh ",\n\t\t\t$entry->{flags}\n";
}
else
{
print $ofh "\n";
}
print $ofh "\t\t},\n";
print $ofh "\t\t&$entry->{variable},\n";
print $ofh "\t\t$entry->{boot_val},";
print $ofh " $entry->{min},"
if $entry->{type} eq 'int' || $entry->{type} eq 'real';
print $ofh " $entry->{max},"
if $entry->{type} eq 'int' || $entry->{type} eq 'real';
print $ofh " $entry->{options},"
if $entry->{type} eq 'enum';
print $ofh "\n";
printf $ofh "\t\t%s, %s, %s\n",
($entry->{check_hook} || 'NULL'),
($entry->{assign_hook} || 'NULL'),
($entry->{show_hook} || 'NULL');
print $ofh "\t},\n";
print $ofh "#endif\n" if $entry->{ifdef};
print $ofh "\n";
}
print $ofh "\t/* End-of-list marker */\n";
print $ofh "\t{{0}}\n";
print $ofh "};\n";
return;
}
sub print_boilerplate
{
my ($fh, $fname, $descr) = @_;
printf $fh <<EOM, $fname, $descr;
/*-------------------------------------------------------------------------
*
* %s
* %s
*
* Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* NOTES
* ******************************
* *** DO NOT EDIT THIS FILE! ***
* ******************************
*
* It has been GENERATED by src/backend/utils/misc/gen_guc_tables.pl
*
*-------------------------------------------------------------------------
*/
EOM
return;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -724,7 +724,7 @@ emitShSecLabels(PGconn *conn, PGresult *res, PQExpBuffer buffer,
* currently known to guc.c, so that it'd be unsafe for extensions to declare
* GUC_LIST_QUOTE variables anyway. Lacking a solution for that, it doesn't
* seem worth the work to do more than have this list, which must be kept in
* sync with the variables actually marked GUC_LIST_QUOTE in guc_tables.c.
* sync with the variables actually marked GUC_LIST_QUOTE in guc_parameters.dat.
*/
bool
variable_is_guc_list_quote(const char *name)

@ -118,6 +118,24 @@ extern PGDLLIMPORT bool SSLPreferServerCiphers;
extern PGDLLIMPORT bool ssl_loaded_verify_locations;
#endif
#ifdef USE_SSL
#define SSL_LIBRARY "OpenSSL"
#else
#define SSL_LIBRARY ""
#endif
#ifdef USE_OPENSSL
#define DEFAULT_SSL_CIPHERS "HIGH:MEDIUM:+3DES:!aNULL"
#else
#define DEFAULT_SSL_CIPHERS "none"
#endif
#ifdef USE_SSL
#define DEFAULT_SSL_GROUPS "X25519:prime256v1"
#else
#define DEFAULT_SSL_GROUPS "none"
#endif
/*
* prototypes for functions in be-secure-gssapi.c
*/

@ -1,5 +1,6 @@
/fmgroids.h
/fmgrprotos.h
/guc_tables.inc.c
/probes.h
/errcodes.h
/header-stamp

@ -254,8 +254,31 @@ extern PGDLLIMPORT bool Debug_pretty_print;
extern PGDLLIMPORT bool Debug_copy_parse_plan_trees;
extern PGDLLIMPORT bool Debug_write_read_parse_plan_trees;
extern PGDLLIMPORT bool Debug_raw_expression_coverage_test;
/*
* support for legacy compile-time settings
*/
#ifdef COPY_PARSE_PLAN_TREES
#define DEFAULT_DEBUG_COPY_PARSE_PLAN_TREES true
#else
#define DEFAULT_DEBUG_COPY_PARSE_PLAN_TREES false
#endif
#ifdef READ_WRITE_PARSE_PLAN_TREES
#define DEFAULT_DEBUG_READ_WRITE_PARSE_PLAN_TREES true
#else
#define DEFAULT_DEBUG_READ_WRITE_PARSE_PLAN_TREES false
#endif
#ifdef RAW_EXPRESSION_COVERAGE_TEST
#define DEFAULT_DEBUG_RAW_EXPRESSION_COVERAGE_TEST true
#else
#define DEFAULT_DEBUG_RAW_EXPRESSION_COVERAGE_TEST false
#endif
#endif /* DEBUG_NODE_TESTS_ENABLED */
extern PGDLLIMPORT bool log_parser_stats;
extern PGDLLIMPORT bool log_planner_stats;
extern PGDLLIMPORT bool log_executor_stats;

@ -20,6 +20,24 @@
extern PGDLLIMPORT int debug_discard_caches;
#define MIN_DEBUG_DISCARD_CACHES 0
#ifdef DISCARD_CACHES_ENABLED
/* Set default based on older compile-time-only cache clobber macros */
#if defined(CLOBBER_CACHE_RECURSIVELY)
#define DEFAULT_DEBUG_DISCARD_CACHES 3
#elif defined(CLOBBER_CACHE_ALWAYS)
#define DEFAULT_DEBUG_DISCARD_CACHES 1
#else
#define DEFAULT_DEBUG_DISCARD_CACHES 0
#endif
#define MAX_DEBUG_DISCARD_CACHES 5
#else /* not DISCARD_CACHES_ENABLED */
#define DEFAULT_DEBUG_DISCARD_CACHES 0
#define MAX_DEBUG_DISCARD_CACHES 0
#endif /* not DISCARD_CACHES_ENABLED */
typedef void (*SyscacheCallbackFunction) (Datum arg, int cacheid, uint32 hashvalue);
typedef void (*RelcacheCallbackFunction) (Datum arg, Oid relid);
typedef void (*RelSyncCallbackFunction) (Datum arg, Oid relid);

@ -30,6 +30,13 @@ errcodes = custom_target('errcodes',
)
generated_headers += errcodes
guc_tables = custom_target('guc_tables',
input: files('../../backend/utils/misc/guc_parameters.dat'),
output: ['guc_tables.inc.c'],
depend_files: catalog_pm,
command: [perl, files('../../backend/utils/misc/gen_guc_tables.pl'), '@INPUT@', '@OUTPUT@'])
generated_headers += guc_tables
if dtrace.found()
probes_tmp = custom_target('probes.h.tmp',
input: files('../../backend/utils/probes.d'),

@ -364,8 +364,8 @@ pg_timezone_initialize(void)
* We may not yet know where PGSHAREDIR is (in particular this is true in
* an EXEC_BACKEND subprocess). So use "GMT", which pg_tzset forces to be
* interpreted without reference to the filesystem. This corresponds to
* the bootstrap default for these variables in guc_tables.c, although in
* principle it could be different.
* the bootstrap default for these variables in guc_parameters.dat,
* although in principle it could be different.
*/
session_timezone = pg_tzset("GMT");
log_timezone = session_timezone;

Loading…
Cancel
Save