autogenerating headers & bki stuff

Started by Robert Haasover 16 years ago30 messages
#1Robert Haas
robertmhaas@gmail.com
1 attachment(s)

As some of you have probably gathered from a couple of recent patches
that I've posted, I've been taking a look at the scripts we use to
generate various derived files based on the catalog headers, and I
think there's room for improvement. First, as discussed on previous
threads, it seems needlessly complex to have both perl and
shell-script implementations of genbki and Gen_fmgrtab. Second,
there's a fair amount of duplicated data that could be auto-generated,
but currently isn't.

The attached patch merges all of the logic currently in genbki.sh and
Gen_fmgrtab.{sh,pl} into a single script called gen_catalog.pl. It
then extends that logic to generate all of the Anum_* and Natts_*
constants, as well as the Schema_pg_* declarations for the bootstrap
tables. (I don't see a clean, easy way to generate Schema_pg_index,
since there are no DATA() lines for that table in pg_attribute.h; but
the others are all straightforward.) It also adds a fair amount of
error checking to what we currently have in place.

In order to avoid create a build-time dependency on Perl for
non-Windows platforms, this patch makes all of the things generated by
gen_catalog.pl into distprep targets. This should be OK, since none
of them depend on architecture or configuration.

I have not made any attempt to fix the MSVC build to work with this,
but there should be some stuff that can be simplified there as well
(in particular, the Perl reimplementation of genbki).

Love it? Hate it? Comments appreciated.

Thanks,

...Robert

Attachments:

gen_catalog-v1.patchtext/x-diff; charset=US-ASCII; name=gen_catalog-v1.patchDownload
*** a/src/Makefile.global.in
--- b/src/Makefile.global.in
***************
*** 517,522 **** $(top_builddir)/src/interfaces/ecpg/include/ecpg_config.h: $(top_builddir)/src/i
--- 517,599 ----
  $(top_builddir)/config.status: $(top_srcdir)/configure
  	cd $(top_builddir) && ./config.status --recheck
  
+ # Note: there are some undocumented dependencies on the ordering in which
+ # the catalog header files are assembled into postgres.bki.  In particular,
+ # indexing.h had better be last, and toasting.h just before it.
+ 
+ POSTGRES_BKI_SRCS = $(addprefix $(top_srcdir)/src/include/catalog/,\
+ 	pg_proc.h pg_type.h pg_attribute.h pg_class.h \
+ 	pg_attrdef.h pg_constraint.h pg_inherits.h pg_index.h pg_operator.h \
+ 	pg_opfamily.h pg_opclass.h pg_am.h pg_amop.h pg_amproc.h \
+ 	pg_language.h pg_largeobject.h pg_aggregate.h pg_statistic.h \
+ 	pg_rewrite.h pg_trigger.h pg_listener.h pg_description.h pg_cast.h \
+ 	pg_enum.h pg_namespace.h pg_conversion.h pg_depend.h \
+ 	pg_database.h pg_tablespace.h pg_pltemplate.h \
+ 	pg_authid.h pg_auth_members.h pg_shdepend.h pg_shdescription.h \
+ 	pg_ts_config.h pg_ts_config_map.h pg_ts_dict.h \
+ 	pg_ts_parser.h pg_ts_template.h \
+ 	pg_foreign_data_wrapper.h pg_foreign_server.h pg_user_mapping.h \
+ 	toasting.h indexing.h \
+     )
+ 
+ # Generated header files need dependencies here to ensure that everything
+ # which depends on them gets rebuilt when necessary.  Note that it's important
+ # we match the dependencies shown in the subdirectory makefiles!
+ ifneq ($(subdir),src/backend/parser)
+ $(top_srcdir)/src/backend/parser/gram.h: $(top_srcdir)/src/backend/parser/gram.y
+ 	$(MAKE) -C $(top_builddir)/src/backend/parser gram.h
+ endif
+ 
+ ifneq ($(subdir),src/backend/catalog)
+ # Same logic as pg_config.h and ecpg_config.h
+ $(top_srcdir)/src/backend/catalog/anum.h: $(top_srcdir)/src/backend/catalog/stamp-h;
+ 
+ $(top_srcdir)/src/backend/catalog/fmgroids.h: $(top_srcdir)/src/backend/catalog/stamp-h ;
+ 
+ $(top_srcdir)/src/backend/catalog/schemapg.h: $(top_srcdir)/src/backend/catalog/stamp-h;
+ 
+ $(top_srcdir)/src/backend/catalog/stamp-h: $(top_srcdir)/src/backend/catalog/gen_catalog.pl $(POSTGRES_BKI_SRCS)
+ 	$(MAKE) -C $(top_builddir)/src/backend/catalog stamp-h
+ endif
+ 
+ ifneq ($(subdir),src/backend/utils)
+ $(top_builddir)/src/backend/utils/probes.h: $(top_srcdir)/src/backend/utils/probes.d
+ 	$(MAKE) -C $(top_builddir)/src/backend/utils probes.h
+ endif
+ 
+ # Make symlinks for these headers in the include directory. That way
+ # we can cut down on the -I options. Also, a symlink is automatically
+ # up to date when we update the base file.
+ #
+ # The point of the prereqdir incantation in some of the rules below is to force
+ # the symlink to use an absolute path rather than a relative path.  For headers
+ # which are generated by make distprep, the copy within src/backend will be in
+ # the source tree, and the copy in src/include will be in the build tree.
+ 
+ $(top_builddir)/src/include/parser/gram.h: $(top_srcdir)/src/backend/parser/gram.h
+ 	prereqdir=`cd $(dir $<) >/dev/null && pwd` && \
+ 	  cd $(dir $@) && rm -f $(notdir $@) && \
+ 	  $(LN_S) "$$prereqdir/$(notdir $<)" .
+ 
+ $(top_builddir)/src/include/catalog/anum.h: $(top_srcdir)/src/backend/catalog/anum.h
+ 	prereqdir=`cd $(dir $<) >/dev/null && pwd` && \
+ 	  cd $(dir $@) && rm -f $(notdir $@) && \
+ 	  $(LN_S) "$$prereqdir/$(notdir $<)" .
+ 
+ $(top_builddir)/src/include/utils/fmgroids.h: $(top_srcdir)/src/backend/catalog/fmgroids.h
+ 	prereqdir=`cd $(dir $<) >/dev/null && pwd` && \
+ 	  cd $(dir $@) && rm -f $(notdir $@) && \
+ 	  $(LN_S) "$$prereqdir/$(notdir $<)" .
+ 
+ $(top_builddir)/src/include/catalog/schemapg.h: $(top_srcdir)/src/backend/catalog/schemapg.h
+ 	prereqdir=`cd $(dir $<) >/dev/null && pwd` && \
+ 	  cd $(dir $@) && rm -f $(notdir $@) && \
+ 	  $(LN_S) "$$prereqdir/$(notdir $<)" .
+ 
+ $(top_builddir)/src/include/utils/probes.h: $(top_builddir)/src/backend/utils/probes.h
+ 	cd $(dir $@) && rm -f $(notdir $@) && \
+ 	    $(LN_S) ../../../src/backend/utils/probes.h .
+ 
  endif # not PGXS
  
  
*** a/src/backend/Makefile
--- b/src/backend/Makefile
***************
*** 105,150 **** endif
  endif # aix
  
  # Update the commonly used headers before building the subdirectories
! $(SUBDIRS:%=%-recursive): $(top_builddir)/src/include/parser/gram.h $(top_builddir)/src/include/utils/fmgroids.h $(top_builddir)/src/include/utils/probes.h
! 
  
  # The postgres.o target is needed by the rule in Makefile.global that
  # creates the exports file when MAKE_EXPORTS = true.
  postgres.o: $(OBJS)
  	$(CC) $(LDREL) $(LDFLAGS) $(call expand_subsys,$^) $(LIBS) -o $@
  
- 
- # The following targets are specified in make commands that appear in
- # the make files in our subdirectories. Note that it's important we
- # match the dependencies shown in the subdirectory makefiles!
- 
- $(srcdir)/parser/gram.h: parser/gram.y
- 	$(MAKE) -C parser gram.h
- 
- utils/fmgroids.h: utils/Gen_fmgrtab.sh $(top_srcdir)/src/include/catalog/pg_proc.h
- 	$(MAKE) -C utils fmgroids.h
- 
- utils/probes.h: utils/probes.d
- 	$(MAKE) -C utils probes.h
- 
- # Make symlinks for these headers in the include directory. That way
- # we can cut down on the -I options. Also, a symlink is automatically
- # up to date when we update the base file.
- 
- $(top_builddir)/src/include/parser/gram.h: $(srcdir)/parser/gram.h
- 	prereqdir=`cd $(dir $<) >/dev/null && pwd` && \
- 	  cd $(dir $@) && rm -f $(notdir $@) && \
- 	  $(LN_S) "$$prereqdir/$(notdir $<)" .
- 
- $(top_builddir)/src/include/utils/fmgroids.h: utils/fmgroids.h
- 	cd $(dir $@) && rm -f $(notdir $@) && \
- 	    $(LN_S) ../../../$(subdir)/utils/fmgroids.h .
- 
- $(top_builddir)/src/include/utils/probes.h: utils/probes.h
- 	cd $(dir $@) && rm -f $(notdir $@) && \
- 	    $(LN_S) ../../../$(subdir)/utils/probes.h .
- 
- 
  ifeq ($(PORTNAME), solaris)
  utils/probes.o: utils/probes.d $(SUBDIROBJS)
  	$(DTRACE) $(DTRACEFLAGS) -C -G -s $(call expand_subsys,$^) -o $@
--- 105,117 ----
  endif # aix
  
  # Update the commonly used headers before building the subdirectories
! $(SUBDIRS:%=%-recursive): $(top_builddir)/src/include/parser/gram.h $(top_builddir)/src/include/utils/fmgroids.h $(top_builddir)/src/include/catalog/anum.h $(top_builddir)/src/include/utils/probes.h $(top_builddir)/src/include/catalog/schemapg.h
  
  # The postgres.o target is needed by the rule in Makefile.global that
  # creates the exports file when MAKE_EXPORTS = true.
  postgres.o: $(OBJS)
  	$(CC) $(LDREL) $(LDFLAGS) $(call expand_subsys,$^) $(LIBS) -o $@
  
  ifeq ($(PORTNAME), solaris)
  utils/probes.o: utils/probes.d $(SUBDIROBJS)
  	$(DTRACE) $(DTRACEFLAGS) -C -G -s $(call expand_subsys,$^) -o $@
***************
*** 157,162 **** distprep:
--- 124,131 ----
  	$(MAKE) -C parser	gram.c gram.h scan.c
  	$(MAKE) -C bootstrap	bootparse.c bootscanner.c
  	$(MAKE) -C utils/misc	guc-file.c
+ 	$(MAKE) -C catalog	postgres.bki postgres.description \
+ 		postgres.shdescription anum.h fmgroids.h fmgrtab.c schemapg.h
  
  
  ##########################################################################
*** a/src/backend/access/common/reloptions.c
--- b/src/backend/access/common/reloptions.c
***************
*** 19,24 ****
--- 19,25 ----
  #include "access/hash.h"
  #include "access/nbtree.h"
  #include "access/reloptions.h"
+ #include "catalog/anum.h"
  #include "catalog/pg_type.h"
  #include "commands/defrem.h"
  #include "nodes/makefuncs.h"
*** /dev/null
--- b/src/backend/catalog/.cvsignore
***************
*** 0 ****
--- 1,2 ----
+ fmgrtab.c
+ fmgroids.h
*** a/src/backend/catalog/Makefile
--- b/src/backend/catalog/Makefile
***************
*** 10,54 **** subdir = src/backend/catalog
  top_builddir = ../../..
  include $(top_builddir)/src/Makefile.global
  
! OBJS = catalog.o dependency.o heap.o index.o indexing.o namespace.o aclchk.o \
!        pg_aggregate.o pg_constraint.o pg_conversion.o pg_depend.o pg_enum.o \
!        pg_inherits.o pg_largeobject.o pg_namespace.o pg_operator.o pg_proc.o \
!        pg_shdepend.o pg_type.o storage.o toasting.o
  
  BKIFILES = postgres.bki postgres.description postgres.shdescription
  
  include $(top_srcdir)/src/backend/common.mk
  
! all: $(BKIFILES)
! 
! # Note: there are some undocumented dependencies on the ordering in which
! # the catalog header files are assembled into postgres.bki.  In particular,
! # indexing.h had better be last, and toasting.h just before it.
! 
! POSTGRES_BKI_SRCS = $(addprefix $(top_srcdir)/src/include/catalog/,\
! 	pg_proc.h pg_type.h pg_attribute.h pg_class.h \
! 	pg_attrdef.h pg_constraint.h pg_inherits.h pg_index.h pg_operator.h \
! 	pg_opfamily.h pg_opclass.h pg_am.h pg_amop.h pg_amproc.h \
! 	pg_language.h pg_largeobject.h pg_aggregate.h pg_statistic.h \
! 	pg_rewrite.h pg_trigger.h pg_listener.h pg_description.h pg_cast.h \
! 	pg_enum.h pg_namespace.h pg_conversion.h pg_depend.h \
! 	pg_database.h pg_tablespace.h pg_pltemplate.h \
! 	pg_authid.h pg_auth_members.h pg_shdepend.h pg_shdescription.h \
! 	pg_ts_config.h pg_ts_config_map.h pg_ts_dict.h \
! 	pg_ts_parser.h pg_ts_template.h \
! 	pg_foreign_data_wrapper.h pg_foreign_server.h pg_user_mapping.h \
! 	toasting.h indexing.h \
!     )
  
  pg_includes = $(sort -I$(top_srcdir)/src/include -I$(top_builddir)/src/include)
  
! # see explanation in ../parser/Makefile
! postgres.description: postgres.bki ;
  
! postgres.shdescription: postgres.bki ;
  
! postgres.bki: genbki.sh $(POSTGRES_BKI_SRCS) $(top_builddir)/src/include/pg_config_manual.h
! 	AWK='$(AWK)' $(SHELL) $< $(pg_includes) --set-version=$(VERSION) -o postgres $(POSTGRES_BKI_SRCS)
  
  .PHONY: install-data
  install-data: $(BKIFILES) installdirs
--- 10,47 ----
  top_builddir = ../../..
  include $(top_builddir)/src/Makefile.global
  
! OBJS = catalog.o dependency.o fmgrtab.o heap.o index.o indexing.o namespace.o \
! 	   aclchk.o pg_aggregate.o pg_constraint.o pg_conversion.o pg_depend.o \
! 	   pg_enum.o pg_inherits.o pg_largeobject.o pg_namespace.o pg_operator.o \
! 	   pg_proc.o pg_shdepend.o pg_type.o storage.o toasting.o
  
  BKIFILES = postgres.bki postgres.description postgres.shdescription
  
  include $(top_srcdir)/src/backend/common.mk
  
! all: $(addprefix $(srcdir)/, $(BKIFILES) anum.h fmgroids.h fmgrtab.c schemapg.h)
  
  pg_includes = $(sort -I$(top_srcdir)/src/include -I$(top_builddir)/src/include)
  
! # see src/backend/parser/Makefile for notes on dependency chaining for multiple
! # output files; see src/Makefile.global.in for notes on how stamp-h files are
! # used
! $(srcdir)/postgres.bki: $(srcdir)/stamp-h ;
  
! $(srcdir)/postgres.description: $(srcdir)/stamp-h ;
  
! $(srcdir)/postgres.shdescription: $(srcdir)/stamp-h ;
! 
! $(srcdir)/anum.h: $(srcdir)/stamp-h ;
! 
! $(srcdir)/fmgroids.h: $(srcdir)/stamp-h ;
! 
! $(srcdir)/fmgrtab.c: $(srcdir)/stamp-h ;
! 
! $(srcdir)/schemapg.h: $(srcdir)/stamp-h ;
! 
! $(srcdir)/stamp-h: gen_catalog.pl $(POSTGRES_BKI_SRCS) $(top_builddir)/src/include/pg_config_manual.h
! 	$(PERL) $< $(pg_includes) -o $(srcdir) --set-version=$(VERSION) $(POSTGRES_BKI_SRCS)
  
  .PHONY: install-data
  install-data: $(BKIFILES) installdirs
***************
*** 66,70 **** installdirs:
  uninstall-data:
  	rm -f $(addprefix '$(DESTDIR)$(datadir)'/, $(BKIFILES) system_views.sql information_schema.sql sql_features.txt)
  
! clean:
! 	rm -f $(BKIFILES)
--- 59,64 ----
  uninstall-data:
  	rm -f $(addprefix '$(DESTDIR)$(datadir)'/, $(BKIFILES) system_views.sql information_schema.sql sql_features.txt)
  
! # postgres.bki, postgres.description, postgres.shdescription, anum.h,
! # fmgroids.h, fmgrtab.c, and schemapg.h are in the distribution tarball, so
! # they are not cleaned here.
*** a/src/backend/catalog/aclchk.c
--- b/src/backend/catalog/aclchk.c
***************
*** 21,26 ****
--- 21,27 ----
  #include "access/heapam.h"
  #include "access/sysattr.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/catalog.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
*** a/src/backend/catalog/dependency.c
--- b/src/backend/catalog/dependency.c
***************
*** 18,23 ****
--- 18,24 ----
  #include "access/heapam.h"
  #include "access/sysattr.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/dependency.h"
  #include "catalog/heap.h"
  #include "catalog/index.h"
*** /dev/null
--- b/src/backend/catalog/gen_catalog.pl
***************
*** 0 ****
--- 1,594 ----
+ #!/usr/bin/perl
+ 
+ #
+ # gen_catalog.pl
+ #
+ # Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
+ # Portions Copyright (c) 1994, Regents of the University of California
+ #
+ 
+ use strict;
+ use warnings;
+ 
+ #
+ # The purpose of this script is to generate as many of the files derived from
+ # the catalogs as possible in one script.  Since this script is written in
+ # Perl, it can be used under either Windows or UNIX-ish systems.  On the flip
+ # side, because none of what we generate here depends on architecture or
+ # configuration, we can build it all at distprep time so that, on UNIX, it
+ # is possible to build from an unmodified distribution tarball without Perl.
+ #
+ # However, if any of the relevant headers are modified, or when building from
+ # CVS (or git), Perl will be required, as this script must be rerun.
+ #
+ my @OUTPUT = (
+ 	[ 'postgres.bki', \*BKI ],
+ 	[ 'postgres.description', \*DESCR ],
+ 	[ 'postgres.shdescription', \*SHDESCR ],
+ 	[ 'anum.h', \*ANUM ],
+ 	[ 'fmgroids.h', \*FMGROIDS ],
+ 	[ 'fmgrtab.c', \*FMGRTAB ],
+ 	[ 'schemapg.h', \*SCHEMAPG ],
+ );
+ 
+ #
+ # There are a few types which are given one name in the C source, but a
+ # different name at the SQL level.  These are enumerated here.
+ #
+ my %RENAME_ATTTYPE = (
+ 	'Oid' => 'oid',
+ 	'NameData' => 'name',
+ 	'TransactionId' => 'xid'
+ );
+ 
+ #
+ # Argument parsing.  We could use GetOpt::Long or similar here, but doing it
+ # this way avoids depending on any outside modules.
+ #
+ my @include_path;
+ my @input_file;
+ my $output_path = '';
+ my $major_version;
+ while (@ARGV) {
+ 	my $arg = shift @ARGV;
+ 	if ($arg !~ /^-/) {
+ 		push @input_file, $arg;
+ 	}
+ 	elsif ($arg =~ /^-o/) {
+ 		$output_path = length($arg) > 2 ? substr($arg, 2) : shift @ARGV;
+ 	}
+ 	elsif ($arg =~ /^-I/) {
+ 		push @include_path, length($arg) > 2 ? substr($arg, 2) : shift @ARGV;
+ 	}
+ 	elsif ($arg =~ /^--set-version=(.*)$/) {
+ 		$major_version = $1;
+ 		# Remove minor version information, if any.
+ 		if ($major_version =~ /^(\d+.\d+)/) {
+ 			$major_version = $1;
+ 		}
+ 	}
+ 	else {
+ 		usage();
+ 	}
+ }
+ 
+ # Sanity check arguments.
+ die "No input files.\n" if ! @input_file;
+ die "No include path; you must specify -I at least once.\n" if ! @include_path;
+ die "No version specified.\n" if !defined $major_version;
+ 
+ #
+ # CAUTION: be wary about what symbols you substitute into the .bki file here!
+ # It's okay to substitute things that are expected to be really constant
+ # within a given Postgres release, such as fixed OIDs.  Do not substitute
+ # anything that could depend on platform or configuration.  (The right place
+ # to handle those sorts of things is in initdb.c's bootstrap_template1().)
+ #
+ my $BOOTSTRAP_SUPERUSERID =
+ 	find_defined_symbol('pg_authid.h', 'BOOTSTRAP_SUPERUSERID');
+ my $PG_CATALOG_NAMESPACE =
+ 	find_defined_symbol('pg_namespace.h', 'PG_CATALOG_NAMESPACE');
+ my $INTERNAL_LANGUAGE_ID =
+ 	find_defined_symbol('pg_language.h', 'INTERNALlanguageId');
+ 
+ # Make sure output_path ends in a slash.
+ if ($output_path ne '' && substr($output_path, -1) ne '/') {
+ 	$output_path .= '/';
+ }
+ 
+ # Open temporary output files.
+ for my $output (@OUTPUT) {
+ 	my $temp_name = $output_path . $output->[0] . '.tmp';
+ 	# We avoid using the three-argument form of open() here, because it is
+ 	# only supported in Perl 5.6 and higher.
+ 	open($output->[1], ">$temp_name") || die "$temp_name: $!";
+ }
+ 
+ # Opening boilerplate for postgres.bki
+ print BKI "# PostgreSQL $major_version\n";
+ 
+ # Opening boilerplate for fmgroids.h
+ print FMGROIDS <<EOM;
+ /*-------------------------------------------------------------------------
+  *
+  * fmgroids.h
+  *    Macros that define the OIDs of built-in functions.
+  *
+  * These macros can be used to avoid a catalog lookup when a specific
+  * fmgr-callable function needs to be referenced.
+  *
+  * Portions Copyright (c) 1996-2009, 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 $0
+  *	from pg_proc.h
+  *
+  *-------------------------------------------------------------------------
+  */
+ #ifndef FMGROIDS_H
+ #define FMGROIDS_H
+ 
+ /*
+  *	Constant macros for the OIDs of entries in pg_proc.
+  *
+  *	NOTE: macros are named after the prosrc value, ie the actual C name
+  *	of the implementing function, not the proname which may be overloaded.
+  *	For example, we want to be able to assign different macro names to both
+  *	char_text() and name_text() even though these both appear with proname
+  *	'text'.  If the same C function appears in more than one pg_proc entry,
+  *	its equivalent macro will be defined with the lowest OID among those
+  *	entries.
+  */
+ EOM
+ 
+ # Opening boilerplate for fmgrtab.c
+ print FMGRTAB <<EOM;
+ /*-------------------------------------------------------------------------
+  *
+  * fmgrtab.c
+  *    The function manager's table of internal functions.
+  *
+  * Portions Copyright (c) 1996-2009, 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 $0
+  *	from pg_proc.h
+  *
+  *-------------------------------------------------------------------------
+  */
+ 
+ #include "postgres.h"
+ 
+ #include "utils/fmgrtab.h"
+ 
+ EOM
+ 
+ # Opening boilerplate for anum.h
+ print ANUM <<EOM;
+ /*-------------------------------------------------------------------------
+  *
+  * anum.h
+  *    Macros that define the number of attributes in each system catalog
+  *    table and the attribute number for each column name.
+  *
+  * Portions Copyright (c) 1996-2009, 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 $0
+  *
+  *-------------------------------------------------------------------------
+  */
+ #ifndef ANUM_H
+ #define ANUM_H
+ 
+ EOM
+ 
+ # Opening boilerplate for schemapg.h
+ print SCHEMAPG <<EOM;
+ /*-------------------------------------------------------------------------
+  *
+  * schemapg.h
+  *    Schema_pg_xxx macros for use by relcache.c
+  *
+  * Portions Copyright (c) 1996-2009, 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 $0
+  *
+  *-------------------------------------------------------------------------
+  */
+ #ifndef SCHEMAPG_H
+ #define SCHEMAPG_H
+ 
+ EOM
+ 
+ # Main part of the work: read and process each header file.
+ my (@fmgr, %schema_pg, %catalog_name);
+ for my $input_file (@input_file)
+ {
+ 	process_input_file($input_file);
+ }
+ 
+ # We're going to iterate over this array twice and it needs to be in sorted
+ # order both times.
+ @fmgr = sort { $a->{'oid'} <=> $b->{'oid'} } @fmgr;
+ 
+ # Emit fmgr #define's and extern's, but only one per prosrc value.
+ my %fmgr_seenit;
+ foreach my $s (@fmgr) {
+ 	next if $fmgr_seenit{$s->{'prosrc'}};
+ 	$fmgr_seenit{$s->{'prosrc'}} = 1;
+ 	print FMGROIDS "#define F_" . uc($s->{'prosrc'}) . " $s->{oid}\n";
+ 	print FMGRTAB "extern Datum " . $s->{'prosrc'} . " (PG_FUNCTION_ARGS);\n";
+ }
+ 
+ # Emit fmgr_builtins table.
+ print FMGRTAB "\nconst FmgrBuiltin fmgr_builtins[] = {\n";
+ my %bmap;
+ $bmap{'t'} = 'true';
+ $bmap{'f'} = 'false';
+ foreach my $s (@fmgr) {
+     print FMGRTAB join('',
+ 		'  { ', $s->{'oid'}, ', "', $s->{'prosrc'}, '", ', $s->{'nargs'},
+ 		', ', $bmap{$s->{'strict'}}, ', ', $bmap{$s->{'retset'}}, ', ',
+ 		$s->{'prosrc'}, " },\n");
+ }
+ 
+ # Emit Schema_pg_xxx declarations.
+ while (my ($oid, $entry_list) = each %schema_pg) {
+ 	my $catalog = $catalog_name{$oid};
+ 	die "catalog with oid $oid not found" if !defined $catalog;
+ 	print SCHEMAPG "#define Schema_$catalog \\\n",
+ 		join(", \\\n", @$entry_list), "\n\n";
+ }
+ 
+ # Closing boilerplate for fmgroids.h
+ print FMGROIDS "\n#endif /* FMGROIDS_H */\n";
+ 
+ # Closing boilerplate for fmgrtab.c
+ print FMGRTAB <<EOM;
+   /* dummy entry is easier than getting rid of comma after last real one */
+   /* (not that there has ever been anything wrong with *having* a
+      comma after the last field in an array initializer) */
+   { 0, NULL, 0, false, false, NULL }
+ };
+ 
+ /* Note fmgr_nbuiltins excludes the dummy entry */
+ const int fmgr_nbuiltins = (sizeof(fmgr_builtins) / sizeof(FmgrBuiltin)) - 1;
+ EOM
+ 
+ # Closing boilerplate for anum.h
+ print ANUM "#endif /* ANUM_H */\n";
+ 
+ # Closing boilerplate for schemapg.h
+ print SCHEMAPG "#endif /* SCHEMAPG_H */\n";
+ 
+ # Close output files.
+ for my $output (@OUTPUT) {
+ 	my $temp_name = $output_path . $output->[0] . '.tmp';
+ 	close($output->[1]) || die "close: $temp_name: $!";
+ }
+ 
+ # Rename temporary files to final names, if anything has changed.
+ for my $output (@OUTPUT) {
+ 	my $temp_name = $output_path . $output->[0] . '.tmp';
+ 	my $final_name = $output_path . $output->[0];
+ 	if (-e $final_name && -s $temp_name == -s $final_name) {
+ 		open(TN, "<$temp_name") || die "$temp_name: $!";
+ 		if (open(FN, "<$temp_name")) {
+ 			local $/ = undef;
+ 			my $tn = <TN>;
+ 			my $fn = <FN>;
+ 			close(FN);
+ 			if ($tn eq $fn) {
+ 				print "$output->[0] unchanged, not replacing\n";
+ 				close(TN);
+ 				unlink($temp_name) || die "unlink: $temp_name: $!";
+ 				next;
+ 			}
+ 		}
+ 		close(TN);
+ 	}
+ 	rename($temp_name, $final_name) || die "rename: $temp_name: $!";
+ }
+ 
+ # Update timestamp file.  Makefile system uses this to avoid unnecessary
+ # rebuilds.
+ open(STAMP, ">$output_path/stamp-h") || die "stamp-h: $!";
+ close(STAMP);
+ 
+ exit 0;
+ 
+ #
+ # Read and process a single input file.
+ #
+ sub process_input_file {
+ 	my ($input_file) = @_;
+ 	open(INPUT_FILE, "<$input_file") || die "$input_file: $!";
+ 
+ 	# State we need to keep track of while scanning the file.
+ 	my ($oid, $catalog, $is_bootstrap, $declaring_attributes, $reln_open);
+ 	my (@bki_attr, @attname, %attname_to_attnum, %attname_to_atttype);
+ 
+ 	# Scan the input file.
+ 	while (<INPUT_FILE>) {
+ 		# Strip C-style comments.
+ 		s;/\*(.|\n)*\*/;;g;
+ 		if (m;/\*;) {
+ 			my $next_line = <INPUT_FILE>;
+ 			die "$input_file: ends within C-style comment\n"
+ 				if !defined $next_line;
+ 			$_ .= $next_line;
+ 			redo;
+ 		}
+ 
+ 		# Strip useless whitespace and trailing semicolons.
+ 		chomp;
+ 		s/^\s+//;
+ 		s/;\s*$//;
+ 		s/\s+/ /g;
+ 
+ 		#
+ 		# DATA lines are passed through to postgres.bki after stripping off
+ 		# the DATA( and the ) on the end.  Remember the OID for use by
+ 		# DESCR() and SHDESCR().
+ 		#
+ 		# In addition, when processing pg_proc.h, we extract all of the
+ 		# "internal" functions and save them so that we can eventually write
+ 		# them out to fmgroids.h and fmgrtab.h.
+ 		#
+ 		if (/^DATA\((insert(\s+OID\s+=\s+(\d+))?\s+\((.*)\))\s*\)$/) {
+ 			my ($data, $field_data) = ($1, $4);
+ 			# Save the OID, if any, for reference by a subsequent DESCR() or
+ 			# SHDESCR() declaration.
+ 			$oid = $3;
+ 			# Pass the (almost) raw data through to postgres.bki.
+ 			$data =~ s/\bPGUID\b/$BOOTSTRAP_SUPERUSERID/g;
+ 			$data =~ s/\bPGNSP\b/$PG_CATALOG_NAMESPACE/g;
+ 			print BKI $data, "\n";
+ 			# To construct fmgroids.h and fmgrtab.c, we need to inspect some
+ 			# of the individual data fields.  Just splitting on whitespace
+ 			# won't work, because some quoted fields might contain internal
+ 			# whitespace.  We handle this by folding them all to a simple
+ 			# "xxx". Fortunately, this script doesn't need to look at any
+ 			# fields that might need quoting, so this simple hack is
+ 			# sufficient.
+ 			if (defined $catalog) {
+ 				$field_data =~ s/^\s+//;
+ 				$field_data =~ s/"[^"]*"/"xxx"/g;
+ 				my @p = split /\s+/, $field_data;
+ 				# Emit fmgr declarations for non-internal functions.
+ 				if ($catalog eq 'pg_proc'
+ 					&& $p[$attname_to_attnum{'prolang'}-1] eq '12') {
+ 				    push @fmgr, {
+ 				        'oid'     => $oid,
+ 				        'proname' => $p[$attname_to_attnum{'proname'}-1],
+ 				        'strict'  => $p[$attname_to_attnum{'proisstrict'}-1],
+ 				        'retset'  => $p[$attname_to_attnum{'proretset'}-1],
+ 				        'nargs'   => $p[$attname_to_attnum{'pronargs'}-1],
+ 				        'prosrc'  => $p[$attname_to_attnum{'prosrc'}-1],
+ 					};
+ 				}
+ 				# Emit Schema_pg info for non-system attributes.
+ 				elsif ($catalog eq 'pg_attribute'
+ 					&& $p[$attname_to_attnum{'attnum'}-1] > 0) {
+ 					if (@attname != @p) {
+ 						die sprintf "catalog has %d attributes, DATA() has "
+ 							. "%d entries\n", 0+@attname, 0+@p;
+ 					}
+ 					my @cvalue;
+ 					for (my $i = 0; $i < @p; ++$i) {
+ 						my $attname = $attname[$i];
+ 						my $atttype = $attname_to_atttype{$attname};
+ 						if (grep { $atttype eq $_ } qw(oid int2 int4)) {
+ 							push @cvalue, $p[$i];
+ 						}
+ 						elsif ($atttype eq 'aclitem[]') {
+ 							if ($p[$i] ne '_null_') {
+ 								die "can't handle non-null aclitem[]: $p[$i]";
+ 							}
+ 							push @cvalue, '{ 0 }';
+ 						}
+ 						elsif ($atttype eq 'bool') {
+ 							if ($p[$i] eq 't') {
+ 								push @cvalue, 'true';
+ 							}
+ 							elsif ($p[$i] eq 'f') {
+ 								push @cvalue, 'false';
+ 							}
+ 							else {
+ 								# May be a constant, like FLOAT4PASSBYVAL.
+ 								push @cvalue, $p[$i];
+ 							}
+ 						}
+ 						elsif ($atttype eq 'char') {
+ 							push @cvalue, "'$p[$i]'";
+ 						}
+ 						elsif ($atttype eq 'name') {
+ 							push @cvalue, "{\"$p[$i]\"}";
+ 						}
+ 						else {
+ 							die "unhandled type $atttype";
+ 						}
+ 					}
+ 				    my $attrelid = $p[$attname_to_attnum{'attrelid'}-1];
+ 					push @{$schema_pg{$attrelid}},
+ 						"{ " . join(", ", @cvalue) . " }";
+ 				}
+ 			}
+ 		}
+ 		# DESCR() and SHDESCR() lines apply to the most recent catalog
+ 		# and OID.
+ 		elsif (/^DESCR\(\"(.*)\"\)$/) {
+ 			my $data = $1;
+ 			if (!defined $catalog) {
+ 				die "DESCR() does not apply to any catalog ($input_file)";
+ 			}
+ 			elsif (!defined $oid) {
+ 				die "DESCR() does not apply to any oid ($input_file)";
+ 			}
+ 			elsif ($data ne '') {
+ 				printf DESCR "%d\t%s\t0\t%s\n", $oid, $catalog, $data;
+ 			}
+ 		}
+ 		elsif (/^SHDESCR\(\"(.*)\"\)$/) {
+ 			my $data = $1;
+ 			if (!defined $catalog) {
+ 				die "SHDESCR() does not apply to any catalog ($input_file)";
+ 			}
+ 			elsif (!defined $oid) {
+ 				die "SHDESCR() does not apply to any oid ($input_file)";
+ 			}
+ 			elsif ($data ne '') {
+ 				printf SHDESCR "%d\t%s\t%s\n", $oid, $catalog, $data;
+ 			}
+ 		}
+ 		elsif (/^DECLARE_(UNIQUE_)?INDEX\((\s*[\w+]*),\s*(\d+),\s*(.*)\)/) {
+ 			my ($is_unique, $iname, $oid, $data) = ($1, $2, $3, $4);
+ 			# close catalog before declaring index
+ 			if ($reln_open) {
+ 				$reln_open = 0;
+ 				print BKI "close $catalog\n";
+ 			}
+ 			printf BKI "declare %sindex %s %s %s\n",
+ 				$is_unique ? "unique " : "", $iname, $oid, $data;
+ 		}
+ 		elsif (/^DECLARE_TOAST\((\s*[\w+]*),\s*(\d+),\s*(\d+)\)/) {
+ 			my ($toastname, $toastoid, $indexoid) = ($1, $2, $3);
+ 			# close catalog before declaring toast
+ 			if ($reln_open) {
+ 				$reln_open = 0;
+ 				print BKI "close $catalog\n";
+ 			}
+ 			print BKI "declare toast $toastoid $indexoid on $toastname\n";
+ 		}
+ 		elsif (/^BUILD_INDICES/) {
+ 			print BKI "build indices\n";
+ 		}
+ 		elsif (/^CATALOG\(([^,]*),(.*)\)/) {
+ 			my ($catname, $catoid) = ($1, $2);
+ 			# close catalog before declaring next catalog
+ 			if ($reln_open) {
+ 				$reln_open = 0;
+ 				print BKI "close $catalog\n";
+ 			}
+ 			$catalog = $catname;
+ 			$is_bootstrap = /BKI_BOOTSTRAP/;
+ 			print BKI "create " . ($is_bootstrap ? 'bootstrap ' : '')
+ 				. (/BKI_SHARED_RELATION/ ? 'shared_relation ' : '')
+ 				. (/BKI_WITHOUT_OIDS/ ? 'without_oids ' : '')
+ 				. $catalog . ' ' . $catoid . "\n";
+ 			$declaring_attributes = 1;
+ 			undef %attname_to_attnum;
+ 			undef %attname_to_atttype;
+ 			undef @attname;
+ 			$catalog_name{$catoid} = $catname;
+ 		}
+ 		elsif ($declaring_attributes) {
+ 			if ($_ =~ /^{|^$/) {
+ 				;							# just ignore it
+ 			}
+ 			elsif ($_ =~ /^}/)	{
+ 				print BKI " (\n", join(" ,\n", @bki_attr), "\n )\n";
+ 				printf ANUM "#define Natts_%s\t\t%d\n\n",
+ 					$catalog, 0+@bki_attr;
+ 				if (! $is_bootstrap) {
+ 					print BKI "open $catalog\n";
+ 				}
+ 				undef $declaring_attributes;
+ 				$reln_open = 1;
+ 			}
+ 			else {
+ 				my @datafields = split /\s+/, $_;
+ 				my $atttype = $datafields[0];
+ 				my $attname;
+ 				if (exists $RENAME_ATTTYPE{$atttype}) {
+ 					$atttype = $RENAME_ATTTYPE{$atttype};
+ 				}
+ 		        if ($datafields[1] =~ /(.*)\[.*\]/) {   # array attribute
+ 	                $attname = $1;
+ 	                $atttype .= "[]";  					# variable-length only
+ 				}
+ 				else {
+ 					$attname = $datafields[1];
+ 				}
+ 				push @bki_attr, " $attname = $atttype";
+ 				printf ANUM "#define Anum_%s_%s\t\t%d\n",
+ 					$catalog, $attname, 0+@bki_attr;
+ 				push @attname, $attname;
+ 				$attname_to_attnum{$attname} = 0+@bki_attr;
+ 				$attname_to_atttype{$attname} = $atttype;
+ 			}
+ 		}
+ 		elsif (/^(DATA|CATALOG|DECLARE_(INDEX|UNIQUE_INDEX|TOAST))/) {
+ 			die "malformed $1 line ($input_file)";
+ 		}
+ 	}
+ 	if ($reln_open) {
+ 		print BKI "close $catalog\n";
+ 	}
+ 	close(INPUT_FILE);
+ }
+ 
+ #
+ # Find a symbol defined in a particular header file and extract the value.
+ #
+ sub find_defined_symbol {
+ 	my ($catalog_header, $symbol) = @_;
+ 	for my $path (@include_path) {
+ 		my $file = $path . '/catalog/' . $catalog_header;
+ 		next if ! -f $file;
+ 		# We avoid using the three-argument form of open() here, because it is
+ 		# only supported in Perl 5.6 and higher.
+ 		open(FIND_DEFINED_SYMBOL, "<$file") || die "$file: $!";
+ 		while (<FIND_DEFINED_SYMBOL>) {
+ 			if (/^#define\s+\Q$symbol\E\s+(\S+)/) {
+ 				return $1;
+ 			}
+ 		}
+ 		close(FIND_DEFINED_SYMBOL);
+ 		die "$file: no definition found for $symbol\n";
+ 	}
+ 	die "$catalog_header: not found in any include directory\n";
+ }
+ 
+ #
+ # Display usage message and exit.
+ #
+ sub usage
+ {
+ 	die <<EOM;
+ Usage: genbki.pl [options] header...
+ 
+ Options:
+ 	-I				path to include files
+ 	--bki			prefix for BKI output files
+ 	--set-version	PostgreSQL version number for initdb cross-check
+ 
+ genbki.pl generates .bki files from specially formatted .h files.  These .bki
+ files are used to initialize the postgres template database.
+ 
+ Report bugs to <pgsql-bugs\@postgresql.org>.
+ EOM
+ }
*** a/src/backend/catalog/genbki.sh
--- /dev/null
***************
*** 1,430 ****
- #! /bin/sh
- #-------------------------------------------------------------------------
- #
- # genbki.sh--
- #    shell script which generates .bki files from specially formatted .h
- #    files.  These .bki files are used to initialize the postgres template
- #    database.
- #
- # Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
- # Portions Copyright (c) 1994, Regents of the University of California
- #
- #
- # IDENTIFICATION
- #    $PostgreSQL$
- #
- # NOTES
- #    non-essential whitespace is removed from the generated file.
- #    if this is ever a problem, then the sed script at the very
- #    end can be changed into another awk script or something smarter.
- #
- #-------------------------------------------------------------------------
- 
- : ${AWK='awk'}
- 
- CMDNAME=`basename $0`
- 
- INCLUDE_DIRS=
- OUTPUT_PREFIX=
- INFILES=
- major_version=
- 
- #
- # Process command line switches.
- #
- while [ $# -gt 0 ]
- do
-     case $1 in
-         -I)
-             INCLUDE_DIRS="$INCLUDE_DIRS $2"
-             shift;;
-         -I*)
-             arg=`echo $1 | sed -e 's/^-I//'`
-             INCLUDE_DIRS="$INCLUDE_DIRS $arg"
-             ;;
-         -o)
-             OUTPUT_PREFIX="$2"
-             shift;;
-         -o*)
-             OUTPUT_PREFIX=`echo $1 | sed -e 's/^-o//'`
-             ;;
-         --set-version=*)
-             arg=`expr x"$1" : x"--set-version=\(.*\)"`
-             major_version=`expr x"$arg" : x'\([0-9][0-9]*\.[0-9][0-9]*\)'`
-             ;;
-         --help)
-             echo "$CMDNAME generates system catalog bootstrapping files."
-             echo
-             echo "Usage:"
-             echo "  $CMDNAME [ -I dir ] --set-version=VERSION -o prefix files..."
-             echo
-             echo "Options:"
-             echo "  -I  path to include files"
-             echo "  -o  prefix of output files"
-             echo "  --set-version  PostgreSQL version number for initdb cross-check"
-             echo
-             echo "The environment variable AWK determines which Awk program"
-             echo "to use. The default is \`awk'."
-             echo
-             echo "Report bugs to <pgsql-bugs@postgresql.org>."
-             exit 0
-             ;;
-         -*)
-             echo "$CMDNAME: invalid option: $1"
-             exit 1
-             ;;
-         *)
-             INFILES="$INFILES $1"
-             ;;
-     esac
-     shift
- done
- 
- if [ x"$INFILES" = x"" ] ; then
-     echo "$CMDNAME: no input files" 1>&2
-     exit 1
- fi
- 
- if [ x"$OUTPUT_PREFIX" = x"" ] ; then
-     echo "$CMDNAME: no output prefix specified" 1>&2
-     exit 1
- fi
- 
- if [ x"$INCLUDE_DIRS" = x"" ] ; then
-     echo "$CMDNAME: path to include directory unknown" 1>&2
-     exit 1
- fi
- 
- if [ x"$major_version" = x"" ] ; then
-     echo "$CMDNAME: invalid or no version number specified" 1>&2
-     exit 1
- fi
- 
- 
- TMPFILE="genbkitmp$$.c"
- 
- trap "rm -f $TMPFILE ${OUTPUT_PREFIX}.bki.$$ ${OUTPUT_PREFIX}.description.$$ ${OUTPUT_PREFIX}.shdescription.$$" 0 1 2 3 15
- 
- 
- # CAUTION: be wary about what symbols you substitute into the .bki file here!
- # It's okay to substitute things that are expected to be really constant
- # within a given Postgres release, such as fixed OIDs.  Do not substitute
- # anything that could depend on platform or configuration.  (The right place
- # to handle those sorts of things is in initdb.c's bootstrap_template1().)
- 
- # Get BOOTSTRAP_SUPERUSERID from catalog/pg_authid.h
- for dir in $INCLUDE_DIRS; do
-     if [ -f "$dir/catalog/pg_authid.h" ]; then
-         BOOTSTRAP_SUPERUSERID=`grep '^#define[ 	]*BOOTSTRAP_SUPERUSERID' $dir/catalog/pg_authid.h | $AWK '{ print $3 }'`
-         break
-     fi
- done
- 
- # Get PG_CATALOG_NAMESPACE from catalog/pg_namespace.h
- for dir in $INCLUDE_DIRS; do
-     if [ -f "$dir/catalog/pg_namespace.h" ]; then
-         PG_CATALOG_NAMESPACE=`grep '^#define[ 	]*PG_CATALOG_NAMESPACE' $dir/catalog/pg_namespace.h | $AWK '{ print $3 }'`
-         break
-     fi
- done
- 
- touch ${OUTPUT_PREFIX}.description.$$
- touch ${OUTPUT_PREFIX}.shdescription.$$
- 
- # ----------------
- # 	Strip comments and other trash from .h
- #
- #	Put multi-line start/end comments on a separate line
- #
- #	Rename datatypes that have different names in .h files than in SQL
- #
- #	Substitute values of configuration constants
- # ----------------
- #
- cat $INFILES | \
- sed -e 's;/\*.*\*/;;g' \
-     -e 's;/\*;\
- /*\
- ;g' \
-     -e 's;\*/;\
- */\
- ;g' | # we must run a new sed here to see the newlines we added
- sed -e "s/;[ 	]*$//g" \
-     -e "s/^[ 	]*//" \
-     -e "s/[ 	]Oid/ oid/g" \
-     -e "s/^Oid/oid/g" \
-     -e "s/(Oid/(oid/g" \
-     -e "s/[ 	]NameData/ name/g" \
-     -e "s/^NameData/name/g" \
-     -e "s/(NameData/(name/g" \
-     -e "s/[ 	]TransactionId/ xid/g" \
-     -e "s/^TransactionId/xid/g" \
-     -e "s/(TransactionId/(xid/g" \
-     -e "s/PGUID/$BOOTSTRAP_SUPERUSERID/g" \
-     -e "s/PGNSP/$PG_CATALOG_NAMESPACE/g" \
- | $AWK '
- # ----------------
- #	now use awk to process remaining .h file..
- #
- #	nc is the number of catalogs
- #	inside is a variable set to 1 when we are scanning the
- #	   contents of a catalog definition.
- #	reln_open is a flag indicating when we are processing DATA lines.
- #	   (i.e. have a relation open and need to close it)
- #	oid is the most recently seen oid, or 0 if none in the last DATA line.
- # ----------------
- BEGIN {
- 	inside = 0;
- 	bootstrap = "";
- 	shared_relation = "";
- 	without_oids = "";
- 	nc = 0;
- 	reln_open = 0;
- 	comment_level = 0;
- 	oid = 0;
- }
- 
- # ----------------
- # Anything in a /* .. */ block should be ignored.
- # Blank lines also go.
- # Note that any /* */ comment on a line by itself was removed from the line
- # by the sed above.
- # ----------------
- /^\/\*/           { comment_level += 1; next; }
- /^\*\//           { comment_level -= 1; next; }
- comment_level > 0 { next; }
- 
- /^[ 	]*$/      { next; }
- 
- # ----------------
- #	DATA() statements are basically passed right through after
- #	stripping off the DATA( and the ) on the end.
- #	Remember the OID for use by DESCR() and SHDESCR().
- # ----------------
- /^DATA\(/ {
- 	data = substr($0, 6, length($0) - 6);
- 	oid = 0;
- 	nf = split(data, datafields);
- 	if (nf >= 4 && datafields[1] == "insert" && datafields[2] == "OID" && datafields[3] == "=")
- 	{
- 		oid = datafields[4];
- 	}
- 	print data;
- 	next;
- }
- 
- /^DESCR\(/ {
- 	if (oid != 0)
- 	{
- 		data = substr($0, 8, length($0) - 9);
- 		if (data != "")
- 			printf "%d\t%s\t0\t%s\n", oid, catalog, data >>descriptionfile;
- 	}
- 	next;
- }
- 
- /^SHDESCR\(/ {
- 	if (oid != 0)
- 	{
- 		data = substr($0, 10, length($0) - 11);
- 		if (data != "")
- 			printf "%d\t%s\t%s\n", oid, catalog, data >>shdescriptionfile;
- 	}
- 	next;
- }
- 
- /^DECLARE_INDEX\(/ {
- # ----
- #  end any prior catalog data insertions before starting a define index
- # ----
- 	if (reln_open == 1) {
- 		print "close " catalog;
- 		reln_open = 0;
- 	}
- 
- 	data = substr($0, 15, length($0) - 15);
- 	pos = index(data, ",");
- 	iname = substr(data, 1, pos-1);
- 	data = substr(data, pos+1, length(data)-pos);
- 	pos = index(data, ",");
- 	oid = substr(data, 1, pos-1);
- 	data = substr(data, pos+1, length(data)-pos);
- 
- 	print "declare index " iname " " oid " " data
- }
- 
- /^DECLARE_UNIQUE_INDEX\(/ {
- # ----
- #  end any prior catalog data insertions before starting a define unique index
- # ----
- 	if (reln_open == 1) {
- 		print "close " catalog;
- 		reln_open = 0;
- 	}
- 
- 	data = substr($0, 22, length($0) - 22);
- 	pos = index(data, ",");
- 	iname = substr(data, 1, pos-1);
- 	data = substr(data, pos+1, length(data)-pos);
- 	pos = index(data, ",");
- 	oid = substr(data, 1, pos-1);
- 	data = substr(data, pos+1, length(data)-pos);
- 
- 	print "declare unique index " iname " " oid " " data
- }
- 
- /^DECLARE_TOAST\(/ {
- # ----
- #  end any prior catalog data insertions before starting a define toast
- # ----
- 	if (reln_open == 1) {
- 		print "close " catalog;
- 		reln_open = 0;
- 	}
- 
- 	data = substr($0, 15, length($0) - 15);
- 	pos = index(data, ",");
- 	tname = substr(data, 1, pos-1);
- 	data = substr(data, pos+1, length(data)-pos);
- 	pos = index(data, ",");
- 	toastoid = substr(data, 1, pos-1);
- 	data = substr(data, pos+1, length(data)-pos);
- 	# previous commands already removed the trailing );
- 	indexoid = data;
- 
- 	print "declare toast " toastoid " " indexoid " on " tname
- }
- 
- /^BUILD_INDICES/	{ print "build indices"; }
- 	
- # ----------------
- #	CATALOG() definitions take some more work.
- # ----------------
- /^CATALOG\(/ { 
- # ----
- #  end any prior catalog data insertions before starting a new one..
- # ----
- 	if (reln_open == 1) {
- 		print "close " catalog;
- 		reln_open = 0;
- 	}
- 
- # ----
- #  get the name and properties of the new catalog
- # ----
- 	pos = index($1,")");
- 	catalogandoid = substr($1,9,pos-9);
- 	pos = index(catalogandoid, ",");
- 	catalog = substr(catalogandoid, 1, pos-1);
- 	oid = substr(catalogandoid, pos+1, length(catalogandoid)-pos);
- 
- 	if ($0 ~ /BKI_BOOTSTRAP/) {
- 		bootstrap = "bootstrap ";
- 	}
- 	if ($0 ~ /BKI_SHARED_RELATION/) {
- 		shared_relation = "shared_relation ";
- 	}
- 	if ($0 ~ /BKI_WITHOUT_OIDS/) {
- 		without_oids = "without_oids ";
- 	}
- 
-         i = 1;
- 	inside = 1;
-         nc++;
- 	next;
- }
- 
- # ----------------
- #	process the columns of the catalog definition
- #
- #	attname[ x ] contains the attribute name for attribute x
- #	atttype[ x ] contains the attribute type fot attribute x
- # ----------------
- inside == 1 {
- # ----
- #  ignore a leading brace line..
- # ----
-         if ($1 ~ /\{/)
- 		next;
- 
- # ----
- #  if this is the last line, then output the bki catalog stuff.
- # ----
- 	if ($1 ~ /}/) {
- 		print "create " bootstrap shared_relation without_oids catalog " " oid;
- 		print "\t(";
- 
- 		for (j=1; j<i-1; j++) {
- 			print "\t " attname[ j ] " = " atttype[ j ] " ,";
- 		}
- 		print "\t " attname[ j ] " = " atttype[ j ] ;
- 		print "\t)";
- 
- 		if (bootstrap == "") {
- 			print "open " catalog;
- 		}
- 
- 		i = 1;
- 		reln_open = 1;
- 		inside = 0;
- 		bootstrap = "";
- 		shared_relation = "";
- 		without_oids = "";
- 		next;
- 	}
- 
- # ----
- #  we are inside the catalog definition, so keep sucking up
- #  attribute names and types
- # ----
- 	if ($2 ~ /\[.*\]/) {			# array attribute
- 		idlen = index($2,"[") - 1;
- 		atttype[ i ] = $1 "[]";		# variable-length only..
- 		attname[ i ] = substr($2,1,idlen);
- 	} else {
- 		atttype[ i ] = $1;
- 		attname[ i ] = $2;
- 	}
- 	i++;
- 	next;
- }
- 
- END {
- 	if (reln_open == 1) {
- 		print "close " catalog;
- 		reln_open = 0;
- 	}
- }
- ' "descriptionfile=${OUTPUT_PREFIX}.description.$$" "shdescriptionfile=${OUTPUT_PREFIX}.shdescription.$$" > $TMPFILE || exit
- 
- echo "# PostgreSQL $major_version" >${OUTPUT_PREFIX}.bki.$$
- 
- sed -e '/^[ 	]*$/d' \
-     -e 's/[ 	][ 	]*/ /g' $TMPFILE >>${OUTPUT_PREFIX}.bki.$$ || exit
- 
- #
- # Sanity check: if one of the sed/awk/etc commands fails, we'll probably
- # end up with a .bki file that is empty or just a few lines.  Cross-check
- # that the files are of reasonable size.  The numbers here are arbitrary,
- # but are much smaller than the actual expected sizes as of Postgres 7.2.
- #
- if [ `wc -c < ${OUTPUT_PREFIX}.bki.$$` -lt 100000 ]; then
-     echo "$CMDNAME: something seems to be wrong with the .bki file" >&2
-     exit 1
- fi
- if [ `wc -c < ${OUTPUT_PREFIX}.description.$$` -lt 10000 ]; then
-     echo "$CMDNAME: something seems to be wrong with the .description file" >&2
-     exit 1
- fi
- if [ `wc -c < ${OUTPUT_PREFIX}.shdescription.$$` -lt 10 ]; then
-     echo "$CMDNAME: something seems to be wrong with the .shdescription file" >&2
-     exit 1
- fi
- 
- # Looks good, commit ...
- 
- mv ${OUTPUT_PREFIX}.bki.$$ ${OUTPUT_PREFIX}.bki || exit
- mv ${OUTPUT_PREFIX}.description.$$ ${OUTPUT_PREFIX}.description || exit
- mv ${OUTPUT_PREFIX}.shdescription.$$ ${OUTPUT_PREFIX}.shdescription || exit
- 
- exit 0
--- 0 ----
*** a/src/backend/catalog/heap.c
--- b/src/backend/catalog/heap.c
***************
*** 34,39 ****
--- 34,40 ----
  #include "access/sysattr.h"
  #include "access/transam.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/catalog.h"
  #include "catalog/dependency.h"
  #include "catalog/heap.h"
*** a/src/backend/catalog/index.c
--- b/src/backend/catalog/index.c
***************
*** 30,35 ****
--- 30,36 ----
  #include "access/transam.h"
  #include "access/xact.h"
  #include "bootstrap/bootstrap.h"
+ #include "catalog/anum.h"
  #include "catalog/catalog.h"
  #include "catalog/dependency.h"
  #include "catalog/heap.h"
*** a/src/backend/catalog/pg_aggregate.c
--- b/src/backend/catalog/pg_aggregate.c
***************
*** 15,20 ****
--- 15,21 ----
  #include "postgres.h"
  
  #include "access/heapam.h"
+ #include "catalog/anum.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_aggregate.h"
*** a/src/backend/catalog/pg_constraint.c
--- b/src/backend/catalog/pg_constraint.c
***************
*** 16,21 ****
--- 16,22 ----
  
  #include "access/genam.h"
  #include "access/heapam.h"
+ #include "catalog/anum.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_constraint.h"
*** a/src/backend/catalog/pg_conversion.c
--- b/src/backend/catalog/pg_conversion.c
***************
*** 16,21 ****
--- 16,22 ----
  
  #include "access/heapam.h"
  #include "access/sysattr.h"
+ #include "catalog/anum.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_conversion.h"
*** a/src/backend/catalog/pg_depend.c
--- b/src/backend/catalog/pg_depend.c
***************
*** 16,21 ****
--- 16,22 ----
  
  #include "access/genam.h"
  #include "access/heapam.h"
+ #include "catalog/anum.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_constraint.h"
*** a/src/backend/catalog/pg_enum.c
--- b/src/backend/catalog/pg_enum.c
***************
*** 15,20 ****
--- 15,21 ----
  
  #include "access/genam.h"
  #include "access/heapam.h"
+ #include "catalog/anum.h"
  #include "catalog/catalog.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_enum.h"
*** a/src/backend/catalog/pg_inherits.c
--- b/src/backend/catalog/pg_inherits.c
***************
*** 20,25 ****
--- 20,26 ----
  #include "postgres.h"
  
  #include "access/heapam.h"
+ #include "catalog/anum.h"
  #include "catalog/pg_class.h"
  #include "catalog/pg_inherits.h"
  #include "catalog/pg_inherits_fn.h"
*** a/src/backend/catalog/pg_largeobject.c
--- b/src/backend/catalog/pg_largeobject.c
***************
*** 16,21 ****
--- 16,22 ----
  
  #include "access/genam.h"
  #include "access/heapam.h"
+ #include "catalog/anum.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_largeobject.h"
  #include "utils/builtins.h"
*** a/src/backend/catalog/pg_namespace.c
--- b/src/backend/catalog/pg_namespace.c
***************
*** 15,20 ****
--- 15,21 ----
  #include "postgres.h"
  
  #include "access/heapam.h"
+ #include "catalog/anum.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_namespace.h"
*** a/src/backend/catalog/pg_operator.c
--- b/src/backend/catalog/pg_operator.c
***************
*** 19,24 ****
--- 19,25 ----
  
  #include "access/heapam.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
  #include "catalog/namespace.h"
*** a/src/backend/catalog/pg_proc.c
--- b/src/backend/catalog/pg_proc.c
***************
*** 16,21 ****
--- 16,22 ----
  
  #include "access/heapam.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_language.h"
*** a/src/backend/catalog/pg_shdepend.c
--- b/src/backend/catalog/pg_shdepend.c
***************
*** 17,22 ****
--- 17,23 ----
  #include "access/genam.h"
  #include "access/heapam.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/catalog.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
*** a/src/backend/catalog/pg_type.c
--- b/src/backend/catalog/pg_type.c
***************
*** 16,21 ****
--- 16,22 ----
  
  #include "access/heapam.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_namespace.h"
*** a/src/backend/commands/async.c
--- b/src/backend/commands/async.c
***************
*** 89,94 ****
--- 89,95 ----
  #include "access/heapam.h"
  #include "access/twophase_rmgr.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/pg_listener.h"
  #include "commands/async.h"
  #include "libpq/libpq.h"
***************
*** 486,493 **** Exec_Listen(Relation lRel, const char *relname)
  
  	namestrcpy(&condname, relname);
  	values[Anum_pg_listener_relname - 1] = NameGetDatum(&condname);
! 	values[Anum_pg_listener_pid - 1] = Int32GetDatum(MyProcPid);
! 	values[Anum_pg_listener_notify - 1] = Int32GetDatum(0);		/* no notifies pending */
  
  	tuple = heap_form_tuple(RelationGetDescr(lRel), values, nulls);
  
--- 487,494 ----
  
  	namestrcpy(&condname, relname);
  	values[Anum_pg_listener_relname - 1] = NameGetDatum(&condname);
! 	values[Anum_pg_listener_listenerpid - 1] = Int32GetDatum(MyProcPid);
! 	values[Anum_pg_listener_notification - 1] = Int32GetDatum(0);		/* no notifies pending */
  
  	tuple = heap_form_tuple(RelationGetDescr(lRel), values, nulls);
  
***************
*** 567,573 **** Exec_UnlistenAll(Relation lRel)
  
  	/* Find and delete all entries with my listenerPID */
  	ScanKeyInit(&key[0],
! 				Anum_pg_listener_pid,
  				BTEqualStrategyNumber, F_INT4EQ,
  				Int32GetDatum(MyProcPid));
  	scan = heap_beginscan(lRel, SnapshotNow, 1, key);
--- 568,574 ----
  
  	/* Find and delete all entries with my listenerPID */
  	ScanKeyInit(&key[0],
! 				Anum_pg_listener_listenerpid,
  				BTEqualStrategyNumber, F_INT4EQ,
  				Int32GetDatum(MyProcPid));
  	scan = heap_beginscan(lRel, SnapshotNow, 1, key);
***************
*** 598,606 **** Send_Notify(Relation lRel)
  	/* preset data to update notify column to MyProcPid */
  	memset(nulls, false, sizeof(nulls));
  	memset(repl, false, sizeof(repl));
! 	repl[Anum_pg_listener_notify - 1] = true;
  	memset(value, 0, sizeof(value));
! 	value[Anum_pg_listener_notify - 1] = Int32GetDatum(MyProcPid);
  
  	scan = heap_beginscan(lRel, SnapshotNow, 0, NULL);
  
--- 599,607 ----
  	/* preset data to update notify column to MyProcPid */
  	memset(nulls, false, sizeof(nulls));
  	memset(repl, false, sizeof(repl));
! 	repl[Anum_pg_listener_notification - 1] = true;
  	memset(value, 0, sizeof(value));
! 	value[Anum_pg_listener_notification - 1] = Int32GetDatum(MyProcPid);
  
  	scan = heap_beginscan(lRel, SnapshotNow, 0, NULL);
  
***************
*** 978,984 **** ProcessIncomingNotify(void)
  
  	/* Scan only entries with my listenerPID */
  	ScanKeyInit(&key[0],
! 				Anum_pg_listener_pid,
  				BTEqualStrategyNumber, F_INT4EQ,
  				Int32GetDatum(MyProcPid));
  	scan = heap_beginscan(lRel, SnapshotNow, 1, key);
--- 979,985 ----
  
  	/* Scan only entries with my listenerPID */
  	ScanKeyInit(&key[0],
! 				Anum_pg_listener_listenerpid,
  				BTEqualStrategyNumber, F_INT4EQ,
  				Int32GetDatum(MyProcPid));
  	scan = heap_beginscan(lRel, SnapshotNow, 1, key);
***************
*** 986,994 **** ProcessIncomingNotify(void)
  	/* Prepare data for rewriting 0 into notification field */
  	memset(nulls, false, sizeof(nulls));
  	memset(repl, false, sizeof(repl));
! 	repl[Anum_pg_listener_notify - 1] = true;
  	memset(value, 0, sizeof(value));
! 	value[Anum_pg_listener_notify - 1] = Int32GetDatum(0);
  
  	while ((lTuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
  	{
--- 987,995 ----
  	/* Prepare data for rewriting 0 into notification field */
  	memset(nulls, false, sizeof(nulls));
  	memset(repl, false, sizeof(repl));
! 	repl[Anum_pg_listener_notification - 1] = true;
  	memset(value, 0, sizeof(value));
! 	value[Anum_pg_listener_notification - 1] = Int32GetDatum(0);
  
  	while ((lTuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
  	{
*** a/src/backend/commands/cluster.c
--- b/src/backend/commands/cluster.c
***************
*** 23,28 ****
--- 23,29 ----
  #include "access/rewriteheap.h"
  #include "access/transam.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/catalog.h"
  #include "catalog/dependency.h"
  #include "catalog/heap.h"
*** a/src/backend/commands/comment.c
--- b/src/backend/commands/comment.c
***************
*** 16,21 ****
--- 16,22 ----
  
  #include "access/genam.h"
  #include "access/heapam.h"
+ #include "catalog/anum.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_authid.h"
  #include "catalog/pg_cast.h"
*** a/src/backend/commands/dbcommands.c
--- b/src/backend/commands/dbcommands.c
***************
*** 28,33 ****
--- 28,34 ----
  #include "access/heapam.h"
  #include "access/xact.h"
  #include "access/xlogutils.h"
+ #include "catalog/anum.h"
  #include "catalog/catalog.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
*** a/src/backend/commands/foreigncmds.c
--- b/src/backend/commands/foreigncmds.c
***************
*** 15,20 ****
--- 15,21 ----
  
  #include "access/heapam.h"
  #include "access/reloptions.h"
+ #include "catalog/anum.h"
  #include "catalog/catalog.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
*** a/src/backend/commands/functioncmds.c
--- b/src/backend/commands/functioncmds.c
***************
*** 35,40 ****
--- 35,41 ----
  #include "access/genam.h"
  #include "access/heapam.h"
  #include "access/sysattr.h"
+ #include "catalog/anum.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_aggregate.h"
*** a/src/backend/commands/indexcmds.c
--- b/src/backend/commands/indexcmds.c
***************
*** 20,25 ****
--- 20,26 ----
  #include "access/reloptions.h"
  #include "access/transam.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/catalog.h"
  #include "catalog/heap.h"
  #include "catalog/index.h"
*** a/src/backend/commands/opclasscmds.c
--- b/src/backend/commands/opclasscmds.c
***************
*** 20,25 ****
--- 20,26 ----
  #include "access/genam.h"
  #include "access/heapam.h"
  #include "access/sysattr.h"
+ #include "catalog/anum.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_amop.h"
*** a/src/backend/commands/proclang.c
--- b/src/backend/commands/proclang.c
***************
*** 15,20 ****
--- 15,21 ----
  
  #include "access/genam.h"
  #include "access/heapam.h"
+ #include "catalog/anum.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_authid.h"
*** a/src/backend/commands/schemacmds.c
--- b/src/backend/commands/schemacmds.c
***************
*** 16,21 ****
--- 16,22 ----
  
  #include "access/heapam.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/catalog.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
*** a/src/backend/commands/tablecmds.c
--- b/src/backend/commands/tablecmds.c
***************
*** 20,25 ****
--- 20,26 ----
  #include "access/relscan.h"
  #include "access/sysattr.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/catalog.h"
  #include "catalog/dependency.h"
  #include "catalog/heap.h"
*** a/src/backend/commands/tablespace.c
--- b/src/backend/commands/tablespace.c
***************
*** 51,56 ****
--- 51,57 ----
  #include "access/heapam.h"
  #include "access/sysattr.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/catalog.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
*** a/src/backend/commands/trigger.c
--- b/src/backend/commands/trigger.c
***************
*** 17,22 ****
--- 17,23 ----
  #include "access/heapam.h"
  #include "access/sysattr.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/catalog.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
*** a/src/backend/commands/tsearchcmds.c
--- b/src/backend/commands/tsearchcmds.c
***************
*** 20,25 ****
--- 20,26 ----
  #include "access/heapam.h"
  #include "access/genam.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
  #include "catalog/namespace.h"
*** a/src/backend/commands/typecmds.c
--- b/src/backend/commands/typecmds.c
***************
*** 34,39 ****
--- 34,40 ----
  #include "access/genam.h"
  #include "access/heapam.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/catalog.h"
  #include "catalog/dependency.h"
  #include "catalog/heap.h"
*** a/src/backend/commands/user.c
--- b/src/backend/commands/user.c
***************
*** 15,20 ****
--- 15,21 ----
  #include "access/genam.h"
  #include "access/heapam.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_auth_members.h"
*** a/src/backend/commands/vacuum.c
--- b/src/backend/commands/vacuum.c
***************
*** 29,34 ****
--- 29,35 ----
  #include "access/visibilitymap.h"
  #include "access/xact.h"
  #include "access/xlog.h"
+ #include "catalog/anum.h"
  #include "catalog/namespace.h"
  #include "catalog/pg_database.h"
  #include "catalog/pg_namespace.h"
*** a/src/backend/executor/functions.c
--- b/src/backend/executor/functions.c
***************
*** 15,20 ****
--- 15,21 ----
  #include "postgres.h"
  
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/pg_proc.h"
  #include "catalog/pg_type.h"
  #include "commands/trigger.h"
*** a/src/backend/executor/nodeAgg.c
--- b/src/backend/executor/nodeAgg.c
***************
*** 68,73 ****
--- 68,74 ----
  
  #include "postgres.h"
  
+ #include "catalog/anum.h"
  #include "catalog/pg_aggregate.h"
  #include "catalog/pg_proc.h"
  #include "catalog/pg_type.h"
*** a/src/backend/executor/nodeWindowAgg.c
--- b/src/backend/executor/nodeWindowAgg.c
***************
*** 33,38 ****
--- 33,39 ----
   */
  #include "postgres.h"
  
+ #include "catalog/anum.h"
  #include "catalog/pg_aggregate.h"
  #include "catalog/pg_proc.h"
  #include "catalog/pg_type.h"
*** a/src/backend/foreign/foreign.c
--- b/src/backend/foreign/foreign.c
***************
*** 13,18 ****
--- 13,19 ----
  #include "postgres.h"
  
  #include "access/reloptions.h"
+ #include "catalog/anum.h"
  #include "catalog/namespace.h"
  #include "catalog/pg_foreign_data_wrapper.h"
  #include "catalog/pg_foreign_server.h"
*** a/src/backend/optimizer/util/clauses.c
--- b/src/backend/optimizer/util/clauses.c
***************
*** 19,24 ****
--- 19,25 ----
  
  #include "postgres.h"
  
+ #include "catalog/anum.h"
  #include "catalog/pg_aggregate.h"
  #include "catalog/pg_language.h"
  #include "catalog/pg_operator.h"
*** a/src/backend/parser/parse_func.c
--- b/src/backend/parser/parse_func.c
***************
*** 14,19 ****
--- 14,20 ----
   */
  #include "postgres.h"
  
+ #include "catalog/anum.h"
  #include "catalog/pg_proc.h"
  #include "catalog/pg_type.h"
  #include "funcapi.h"
*** a/src/backend/parser/parse_utilcmd.c
--- b/src/backend/parser/parse_utilcmd.c
***************
*** 29,34 ****
--- 29,35 ----
  #include "access/genam.h"
  #include "access/heapam.h"
  #include "access/reloptions.h"
+ #include "catalog/anum.h"
  #include "catalog/dependency.h"
  #include "catalog/heap.h"
  #include "catalog/index.h"
*** a/src/backend/postmaster/autovacuum.c
--- b/src/backend/postmaster/autovacuum.c
***************
*** 72,77 ****
--- 72,78 ----
  #include "access/reloptions.h"
  #include "access/transam.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
  #include "catalog/namespace.h"
*** a/src/backend/rewrite/rewriteDefine.c
--- b/src/backend/rewrite/rewriteDefine.c
***************
*** 15,20 ****
--- 15,21 ----
  #include "postgres.h"
  
  #include "access/heapam.h"
+ #include "catalog/anum.h"
  #include "catalog/catalog.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
*** a/src/backend/storage/large_object/inv_api.c
--- b/src/backend/storage/large_object/inv_api.c
***************
*** 34,39 ****
--- 34,40 ----
  #include "access/heapam.h"
  #include "access/tuptoaster.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/catalog.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_largeobject.h"
*** a/src/backend/utils/.cvsignore
--- /dev/null
***************
*** 1,2 ****
- fmgrtab.c
- fmgroids.h
--- 0 ----
*** a/src/backend/utils/Gen_fmgrtab.pl
--- /dev/null
***************
*** 1,194 ****
- #! /usr/bin/perl -w
- #-------------------------------------------------------------------------
- #
- # Gen_fmgrtab.pl
- #    Perl equivalent of Gen_fmgrtab.sh
- #
- # Usage: perl Gen_fmgrtab.pl path-to-pg_proc.h
- #
- # The reason for implementing this functionality twice is that we don't
- # require people to have perl to build from a tarball, but on the other
- # hand Windows can't deal with shell scripts.
- #
- # Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
- # Portions Copyright (c) 1994, Regents of the University of California
- #
- #
- # IDENTIFICATION
- #    $PostgreSQL$
- #
- #-------------------------------------------------------------------------
- 
- use strict;
- use warnings;
- 
- # Collect arguments
- my $infile = shift;
- defined($infile) || die "$0: missing required argument: pg_proc.h\n";
- 
- # Note: see Gen_fmgrtab.sh for detailed commentary on what this is doing
- 
- # Collect column numbers for pg_proc columns we need
- my ($proname, $prolang, $proisstrict, $proretset, $pronargs, $prosrc);
- 
- open(I, $infile) || die "Could not open $infile: $!";
- while (<I>)
- {
-     if (m/#define Anum_pg_proc_proname\s+(\d+)/) {
- 	$proname = $1;
-     }
-     if (m/#define Anum_pg_proc_prolang\s+(\d+)/) {
- 	$prolang = $1;
-     }
-     if (m/#define Anum_pg_proc_proisstrict\s+(\d+)/) {
- 	$proisstrict = $1;
-     }
-     if (m/#define Anum_pg_proc_proretset\s+(\d+)/) {
- 	$proretset = $1;
-     }
-     if (m/#define Anum_pg_proc_pronargs\s+(\d+)/) {
- 	$pronargs = $1;
-     }
-     if (m/#define Anum_pg_proc_prosrc\s+(\d+)/) {
- 	$prosrc = $1;
-     }
- }
- close(I);
- 
- # Collect the raw data
- my @fmgr = ();
- 
- open(I, $infile) || die "Could not open $infile: $!";
- while (<I>)
- {
-     next unless (/^DATA/);
-     s/^[^O]*OID[^=]*=[ \t]*//;
-     s/\(//;
-     s/"[^"]*"/"xxx"/g;
-     my @p = split;
-     next if ($p[$prolang] ne "12");
-     push @fmgr,
-       {
-         oid     => $p[0],
-         proname => $p[$proname],
-         strict  => $p[$proisstrict],
-         retset  => $p[$proretset],
-         nargs   => $p[$pronargs],
-         prosrc  => $p[$prosrc],
-       };
- }
- close(I);
- 
- # Emit headers for both files
- open(H, '>', "$$-fmgroids.h") || die "Could not open $$-fmgroids.h: $!";
- print H 
- qq|/*-------------------------------------------------------------------------
-  *
-  * fmgroids.h
-  *    Macros that define the OIDs of built-in functions.
-  *
-  * These macros can be used to avoid a catalog lookup when a specific
-  * fmgr-callable function needs to be referenced.
-  *
-  * Portions Copyright (c) 1996-2009, 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 $0
-  *	from $infile
-  *
-  *-------------------------------------------------------------------------
-  */
- #ifndef FMGROIDS_H
- #define FMGROIDS_H
- 
- /*
-  *	Constant macros for the OIDs of entries in pg_proc.
-  *
-  *	NOTE: macros are named after the prosrc value, ie the actual C name
-  *	of the implementing function, not the proname which may be overloaded.
-  *	For example, we want to be able to assign different macro names to both
-  *	char_text() and name_text() even though these both appear with proname
-  *	'text'.  If the same C function appears in more than one pg_proc entry,
-  *	its equivalent macro will be defined with the lowest OID among those
-  *	entries.
-  */
- |;
- 
- open(T, '>', "$$-fmgrtab.c") || die "Could not open $$-fmgrtab.c: $!";
- print T
- qq|/*-------------------------------------------------------------------------
-  *
-  * fmgrtab.c
-  *    The function manager's table of internal functions.
-  *
-  * Portions Copyright (c) 1996-2009, 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 $0
-  *	from $infile
-  *
-  *-------------------------------------------------------------------------
-  */
- 
- #include "postgres.h"
- 
- #include "utils/fmgrtab.h"
- 
- |;
- 
- # Emit #define's and extern's -- only one per prosrc value
- my %seenit;
- foreach my $s (sort {$a->{oid} <=> $b->{oid}} @fmgr)
- {
-     next if $seenit{$s->{prosrc}};
-     $seenit{$s->{prosrc}} = 1;
-     print H "#define F_" . uc $s->{prosrc} . " $s->{oid}\n";
-     print T "extern Datum $s->{prosrc} (PG_FUNCTION_ARGS);\n";
- }
- 
- # Create the fmgr_builtins table
- print T "\nconst FmgrBuiltin fmgr_builtins[] = {\n";
- my %bmap;
- $bmap{'t'} = 'true';
- $bmap{'f'} = 'false';
- foreach my $s (sort {$a->{oid} <=> $b->{oid}} @fmgr)
- {
-     print T
- 	"  { $s->{oid}, \"$s->{prosrc}\", $s->{nargs}, $bmap{$s->{strict}}, $bmap{$s->{retset}}, $s->{prosrc} },\n";
- }
- 
- # And add the file footers.
- print H "\n#endif /* FMGROIDS_H */\n";
- close(H);
- 
- print T
- qq|  /* dummy entry is easier than getting rid of comma after last real one */
-   /* (not that there has ever been anything wrong with *having* a
-      comma after the last field in an array initializer) */
-   { 0, NULL, 0, false, false, NULL }
- };
- 
- /* Note fmgr_nbuiltins excludes the dummy entry */
- const int fmgr_nbuiltins = (sizeof(fmgr_builtins) / sizeof(FmgrBuiltin)) - 1;
- |;
- 
- close(T);
- 
- # Finally, rename the completed files into place.
- rename "$$-fmgroids.h", "fmgroids.h"
-     || die "Could not rename $$-fmgroids.h to fmgroids.h: $!";
- rename "$$-fmgrtab.c", "fmgrtab.c"
-     || die "Could not rename $$-fmgrtab.c to fmgrtab.c: $!";
- 
- exit 0;
--- 0 ----
*** a/src/backend/utils/Gen_fmgrtab.sh
--- /dev/null
***************
*** 1,253 ****
- #! /bin/sh
- #-------------------------------------------------------------------------
- #
- # Gen_fmgrtab.sh
- #    shell script to generate fmgroids.h and fmgrtab.c from pg_proc.h
- #
- # NOTE: if you change this, you need to fix Gen_fmgrtab.pl too!
- #
- # Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
- # Portions Copyright (c) 1994, Regents of the University of California
- #
- #
- # IDENTIFICATION
- #    $PostgreSQL$
- #
- #-------------------------------------------------------------------------
- 
- CMDNAME=`basename $0`
- 
- if [ x"$AWK" = x"" ]; then
- 	AWK=awk
- fi
- 
- cleanup(){
-     [ x"$noclean" != x"t" ] && rm -f "$SORTEDFILE" "$$-$OIDSFILE" "$$-$TABLEFILE"
- }
- 
- noclean=
- 
- #
- # Process command line switches.
- #
- while [ $# -gt 0 ]
- do
-     case $1 in
-         --noclean)
-             noclean=t
-             ;;
-         --help)
-             echo "$CMDNAME generates fmgroids.h and fmgrtab.c from pg_proc.h."
-             echo
-             echo "Usage:"
-             echo "  $CMDNAME inputfile"
-             echo
-             echo "The environment variable AWK determines which Awk program"
-             echo "to use. The default is \`awk'."
-             echo
-             echo "Report bugs to <pgsql-bugs@postgresql.org>."
-             exit 0
-             ;;
-         -*)
-             echo "$CMDNAME: invalid option: $1"
-             exit 1
-             ;;
-         *)
-             INFILE=$1
-             ;;
-     esac
-     shift
- done
- 
- 
- if [ x"$INFILE" = x ] ; then
-     echo "$CMDNAME: no input file"
-     exit 1
- fi
- 
- SORTEDFILE="$$-fmgr.data"
- OIDSFILE=fmgroids.h
- TABLEFILE=fmgrtab.c
- 
- 
- trap 'echo "Caught signal." ; cleanup ; exit 1' 1 2 15
- 
- #
- # Collect the column numbers of the pg_proc columns we need.  Because we will
- # be looking at data that includes the OID as the first column, add one to
- # each column number.
- #
- proname=`egrep '^#define Anum_pg_proc_proname[ 	]' $INFILE | $AWK '{print $3+1}'`
- prolang=`egrep '^#define Anum_pg_proc_prolang[ 	]' $INFILE | $AWK '{print $3+1}'`
- proisstrict=`egrep '^#define Anum_pg_proc_proisstrict[ 	]' $INFILE | $AWK '{print $3+1}'`
- proretset=`egrep '^#define Anum_pg_proc_proretset[ 	]' $INFILE | $AWK '{print $3+1}'`
- pronargs=`egrep '^#define Anum_pg_proc_pronargs[ 	]' $INFILE | $AWK '{print $3+1}'`
- prosrc=`egrep '^#define Anum_pg_proc_prosrc[ 	]' $INFILE | $AWK '{print $3+1}'`
- 
- #
- # Generate the file containing raw pg_proc data.  We do three things here:
- # 1. Strip off the DATA macro call, leaving procedure OID as $1
- # and all the pg_proc field values as $2, $3, etc on each line.
- # 2. Fold quoted fields to simple "xxx".  We need this because such fields
- # may contain whitespace, which would confuse awk's counting of fields.
- # Fortunately, this script doesn't need to look at any fields that might
- # need quoting, so this simple hack is sufficient.
- # 3. Select out just the rows for internal-language procedures.
- #
- # Note assumption here that INTERNALlanguageId == 12.
- #
- egrep '^DATA' $INFILE | \
- sed 	-e 's/^[^O]*OID[^=]*=[ 	]*//' \
- 	-e 's/(//' \
- 	-e 's/"[^"]*"/"xxx"/g' | \
- $AWK "\$$prolang == \"12\" { print }" | \
- sort -n > $SORTEDFILE
- 
- if [ $? -ne 0 ]; then
-     cleanup
-     echo "$CMDNAME failed"
-     exit 1
- fi
- 
- 
- cpp_define=`echo $OIDSFILE | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ | sed -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g'`
- 
- #
- # Generate fmgroids.h
- #
- cat > "$$-$OIDSFILE" <<FuNkYfMgRsTuFf
- /*-------------------------------------------------------------------------
-  *
-  * $OIDSFILE
-  *    Macros that define the OIDs of built-in functions.
-  *
-  * These macros can be used to avoid a catalog lookup when a specific
-  * fmgr-callable function needs to be referenced.
-  *
-  * Portions Copyright (c) 1996-2009, 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 $CMDNAME
-  *	from $INFILE
-  *
-  *-------------------------------------------------------------------------
-  */
- #ifndef $cpp_define
- #define $cpp_define
- 
- /*
-  *	Constant macros for the OIDs of entries in pg_proc.
-  *
-  *	NOTE: macros are named after the prosrc value, ie the actual C name
-  *	of the implementing function, not the proname which may be overloaded.
-  *	For example, we want to be able to assign different macro names to both
-  *	char_text() and name_text() even though these both appear with proname
-  *	'text'.  If the same C function appears in more than one pg_proc entry,
-  *	its equivalent macro will be defined with the lowest OID among those
-  *	entries.
-  */
- FuNkYfMgRsTuFf
- 
- tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' < $SORTEDFILE | \
- $AWK "{ if (seenit[\$$prosrc]++ == 0)
- 	printf \"#define F_%s %s\\n\", \$$prosrc, \$1; }" >> "$$-$OIDSFILE"
- 
- if [ $? -ne 0 ]; then
-     cleanup
-     echo "$CMDNAME failed"
-     exit 1
- fi
- 
- cat >> "$$-$OIDSFILE" <<FuNkYfMgRsTuFf
- 
- #endif /* $cpp_define */
- FuNkYfMgRsTuFf
- 
- #
- # Generate fmgr's built-in-function table.
- #
- # Print out the function declarations, then the table that refers to them.
- #
- cat > "$$-$TABLEFILE" <<FuNkYfMgRtAbStUfF
- /*-------------------------------------------------------------------------
-  *
-  * $TABLEFILE
-  *    The function manager's table of internal functions.
-  *
-  * Portions Copyright (c) 1996-2009, 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 $CMDNAME
-  *	from $INFILE
-  *
-  *-------------------------------------------------------------------------
-  */
- 
- #include "postgres.h"
- 
- #include "utils/fmgrtab.h"
- 
- FuNkYfMgRtAbStUfF
- 
- $AWK "{ if (seenit[\$$prosrc]++ == 0)
- 	print \"extern Datum\", \$$prosrc, \"(PG_FUNCTION_ARGS);\"; }" $SORTEDFILE >> "$$-$TABLEFILE"
- 
- if [ $? -ne 0 ]; then
-     cleanup
-     echo "$CMDNAME failed"
-     exit 1
- fi
- 
- 
- cat >> "$$-$TABLEFILE" <<FuNkYfMgRtAbStUfF
- 
- const FmgrBuiltin fmgr_builtins[] = {
- FuNkYfMgRtAbStUfF
- 
- # Note: using awk arrays to translate from pg_proc values to fmgrtab values
- # may seem tedious, but avoid the temptation to write a quick x?y:z
- # conditional expression instead.  Not all awks have conditional expressions.
- 
- $AWK "BEGIN {
-     Bool[\"t\"] = \"true\";
-     Bool[\"f\"] = \"false\";
- }
- { printf (\"  { %d, \\\"%s\\\", %d, %s, %s, %s },\\n\"),
- 	\$1, \$$prosrc, \$$pronargs, Bool[\$$proisstrict], Bool[\$$proretset], \$$prosrc ;
- }" $SORTEDFILE >> "$$-$TABLEFILE"
- 
- if [ $? -ne 0 ]; then
-     cleanup
-     echo "$CMDNAME failed"
-     exit 1
- fi
- 
- cat >> "$$-$TABLEFILE" <<FuNkYfMgRtAbStUfF
-   /* dummy entry is easier than getting rid of comma after last real one */
-   /* (not that there has ever been anything wrong with *having* a
-      comma after the last field in an array initializer) */
-   { 0, NULL, 0, false, false, NULL }
- };
- 
- /* Note fmgr_nbuiltins excludes the dummy entry */
- const int fmgr_nbuiltins = (sizeof(fmgr_builtins) / sizeof(FmgrBuiltin)) - 1;
- FuNkYfMgRtAbStUfF
- 
- # We use the temporary files to avoid problems with concurrent runs
- # (which can happen during parallel make).
- mv "$$-$OIDSFILE" $OIDSFILE
- mv "$$-$TABLEFILE" $TABLEFILE
- 
- cleanup
- exit 0
--- 0 ----
*** a/src/backend/utils/Makefile
--- b/src/backend/utils/Makefile
***************
*** 8,24 **** subdir = src/backend/utils
  top_builddir = ../../..
  include $(top_builddir)/src/Makefile.global
  
- OBJS        = fmgrtab.o
  SUBDIRS     = adt cache error fmgr hash init mb misc mmgr resowner sort time
  
  include $(top_srcdir)/src/backend/common.mk
  
! all: fmgroids.h probes.h
! 
! $(SUBDIRS:%=%-recursive): fmgroids.h
! 
! fmgroids.h fmgrtab.c: Gen_fmgrtab.sh $(top_srcdir)/src/include/catalog/pg_proc.h
! 	AWK='$(AWK)' $(SHELL) $< $(top_srcdir)/src/include/catalog/pg_proc.h
  
  ifneq ($(enable_dtrace), yes)
  probes.h: Gen_dummy_probes.sed
--- 8,18 ----
  top_builddir = ../../..
  include $(top_builddir)/src/Makefile.global
  
  SUBDIRS     = adt cache error fmgr hash init mb misc mmgr resowner sort time
  
  include $(top_srcdir)/src/backend/common.mk
  
! all: probes.h
  
  ifneq ($(enable_dtrace), yes)
  probes.h: Gen_dummy_probes.sed
***************
*** 35,38 **** endif
  
  
  clean:
! 	rm -f fmgroids.h fmgrtab.c probes.h
--- 29,32 ----
  
  
  clean:
! 	rm -f probes.h
*** a/src/backend/utils/adt/regproc.c
--- b/src/backend/utils/adt/regproc.c
***************
*** 23,28 ****
--- 23,29 ----
  
  #include "access/genam.h"
  #include "access/heapam.h"
+ #include "catalog/anum.h"
  #include "catalog/indexing.h"
  #include "catalog/namespace.h"
  #include "catalog/pg_class.h"
*** a/src/backend/utils/adt/ri_triggers.c
--- b/src/backend/utils/adt/ri_triggers.c
***************
*** 31,36 ****
--- 31,37 ----
  #include "postgres.h"
  
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/pg_constraint.h"
  #include "catalog/pg_operator.h"
  #include "catalog/pg_type.h"
*** a/src/backend/utils/adt/ruleutils.c
--- b/src/backend/utils/adt/ruleutils.c
***************
*** 20,25 ****
--- 20,26 ----
  
  #include "access/genam.h"
  #include "access/sysattr.h"
+ #include "catalog/anum.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_authid.h"
*** a/src/backend/utils/cache/lsyscache.c
--- b/src/backend/utils/cache/lsyscache.c
***************
*** 18,23 ****
--- 18,24 ----
  #include "access/hash.h"
  #include "access/nbtree.h"
  #include "bootstrap/bootstrap.h"
+ #include "catalog/anum.h"
  #include "catalog/pg_amop.h"
  #include "catalog/pg_amproc.h"
  #include "catalog/pg_constraint.h"
*** a/src/backend/utils/cache/relcache.c
--- b/src/backend/utils/cache/relcache.c
***************
*** 34,39 ****
--- 34,40 ----
  #include "access/reloptions.h"
  #include "access/sysattr.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/catalog.h"
  #include "catalog/index.h"
  #include "catalog/indexing.h"
***************
*** 48,53 ****
--- 49,55 ----
  #include "catalog/pg_proc.h"
  #include "catalog/pg_rewrite.h"
  #include "catalog/pg_type.h"
+ #include "catalog/schemapg.h"
  #include "commands/trigger.h"
  #include "miscadmin.h"
  #include "optimizer/clauses.h"
*** a/src/backend/utils/cache/syscache.c
--- b/src/backend/utils/cache/syscache.c
***************
*** 21,26 ****
--- 21,27 ----
  #include "postgres.h"
  
  #include "access/sysattr.h"
+ #include "catalog/anum.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_aggregate.h"
  #include "catalog/pg_amop.h"
*** a/src/backend/utils/cache/ts_cache.c
--- b/src/backend/utils/cache/ts_cache.c
***************
*** 29,34 ****
--- 29,35 ----
  #include "access/genam.h"
  #include "access/heapam.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/indexing.h"
  #include "catalog/namespace.h"
  #include "catalog/pg_ts_config.h"
*** a/src/backend/utils/fmgr/fmgr.c
--- b/src/backend/utils/fmgr/fmgr.c
***************
*** 16,21 ****
--- 16,22 ----
  #include "postgres.h"
  
  #include "access/tuptoaster.h"
+ #include "catalog/anum.h"
  #include "catalog/pg_language.h"
  #include "catalog/pg_proc.h"
  #include "executor/functions.h"
*** a/src/backend/utils/fmgr/funcapi.c
--- b/src/backend/utils/fmgr/funcapi.c
***************
*** 14,19 ****
--- 14,20 ----
  #include "postgres.h"
  
  #include "access/heapam.h"
+ #include "catalog/anum.h"
  #include "catalog/namespace.h"
  #include "catalog/pg_proc.h"
  #include "catalog/pg_type.h"
*** a/src/backend/utils/init/flatfiles.c
--- b/src/backend/utils/init/flatfiles.c
***************
*** 37,42 ****
--- 37,43 ----
  #include "access/twophase_rmgr.h"
  #include "access/xact.h"
  #include "access/xlogutils.h"
+ #include "catalog/anum.h"
  #include "catalog/catalog.h"
  #include "catalog/pg_auth_members.h"
  #include "catalog/pg_authid.h"
*** a/src/backend/utils/init/miscinit.c
--- b/src/backend/utils/init/miscinit.c
***************
*** 29,34 ****
--- 29,35 ----
  #include <utime.h>
  #endif
  
+ #include "catalog/anum.h"
  #include "catalog/pg_authid.h"
  #include "mb/pg_wchar.h"
  #include "miscadmin.h"
*** a/src/backend/utils/init/postinit.c
--- b/src/backend/utils/init/postinit.c
***************
*** 20,25 ****
--- 20,26 ----
  
  #include "access/heapam.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/catalog.h"
  #include "catalog/namespace.h"
  #include "catalog/pg_authid.h"
*** a/src/include/catalog/pg_aggregate.h
--- b/src/include/catalog/pg_aggregate.h
***************
*** 55,74 **** CATALOG(pg_aggregate,2600) BKI_WITHOUT_OIDS
  typedef FormData_pg_aggregate *Form_pg_aggregate;
  
  /* ----------------
-  *		compiler constants for pg_aggregate
-  * ----------------
-  */
- 
- #define Natts_pg_aggregate				6
- #define Anum_pg_aggregate_aggfnoid		1
- #define Anum_pg_aggregate_aggtransfn	2
- #define Anum_pg_aggregate_aggfinalfn	3
- #define Anum_pg_aggregate_aggsortop		4
- #define Anum_pg_aggregate_aggtranstype	5
- #define Anum_pg_aggregate_agginitval	6
- 
- 
- /* ----------------
   * initial contents of pg_aggregate
   * ---------------
   */
--- 55,60 ----
*** a/src/include/catalog/pg_am.h
--- b/src/include/catalog/pg_am.h
***************
*** 73,110 **** CATALOG(pg_am,2601)
  typedef FormData_pg_am *Form_pg_am;
  
  /* ----------------
-  *		compiler constants for pg_am
-  * ----------------
-  */
- #define Natts_pg_am						26
- #define Anum_pg_am_amname				1
- #define Anum_pg_am_amstrategies			2
- #define Anum_pg_am_amsupport			3
- #define Anum_pg_am_amcanorder			4
- #define Anum_pg_am_amcanbackward		5
- #define Anum_pg_am_amcanunique			6
- #define Anum_pg_am_amcanmulticol		7
- #define Anum_pg_am_amoptionalkey		8
- #define Anum_pg_am_amindexnulls			9
- #define Anum_pg_am_amsearchnulls		10
- #define Anum_pg_am_amstorage			11
- #define Anum_pg_am_amclusterable		12
- #define Anum_pg_am_amkeytype			13
- #define Anum_pg_am_aminsert				14
- #define Anum_pg_am_ambeginscan			15
- #define Anum_pg_am_amgettuple			16
- #define Anum_pg_am_amgetbitmap			17
- #define Anum_pg_am_amrescan				18
- #define Anum_pg_am_amendscan			19
- #define Anum_pg_am_ammarkpos			20
- #define Anum_pg_am_amrestrpos			21
- #define Anum_pg_am_ambuild				22
- #define Anum_pg_am_ambulkdelete			23
- #define Anum_pg_am_amvacuumcleanup		24
- #define Anum_pg_am_amcostestimate		25
- #define Anum_pg_am_amoptions			26
- 
- /* ----------------
   *		initial contents of pg_am
   * ----------------
   */
--- 73,78 ----
*** a/src/include/catalog/pg_amop.h
--- b/src/include/catalog/pg_amop.h
***************
*** 67,84 **** CATALOG(pg_amop,2602)
  typedef FormData_pg_amop *Form_pg_amop;
  
  /* ----------------
-  *		compiler constants for pg_amop
-  * ----------------
-  */
- #define Natts_pg_amop					6
- #define Anum_pg_amop_amopfamily			1
- #define Anum_pg_amop_amoplefttype		2
- #define Anum_pg_amop_amoprighttype		3
- #define Anum_pg_amop_amopstrategy		4
- #define Anum_pg_amop_amopopr			5
- #define Anum_pg_amop_amopmethod			6
- 
- /* ----------------
   *		initial contents of pg_amop
   * ----------------
   */
--- 67,72 ----
*** a/src/include/catalog/pg_amproc.h
--- b/src/include/catalog/pg_amproc.h
***************
*** 59,75 **** CATALOG(pg_amproc,2603)
  typedef FormData_pg_amproc *Form_pg_amproc;
  
  /* ----------------
-  *		compiler constants for pg_amproc
-  * ----------------
-  */
- #define Natts_pg_amproc					5
- #define Anum_pg_amproc_amprocfamily		1
- #define Anum_pg_amproc_amproclefttype	2
- #define Anum_pg_amproc_amprocrighttype	3
- #define Anum_pg_amproc_amprocnum		4
- #define Anum_pg_amproc_amproc			5
- 
- /* ----------------
   *		initial contents of pg_amproc
   * ----------------
   */
--- 59,64 ----
*** a/src/include/catalog/pg_attrdef.h
--- b/src/include/catalog/pg_attrdef.h
***************
*** 43,56 **** CATALOG(pg_attrdef,2604)
   */
  typedef FormData_pg_attrdef *Form_pg_attrdef;
  
- /* ----------------
-  *		compiler constants for pg_attrdef
-  * ----------------
-  */
- #define Natts_pg_attrdef				4
- #define Anum_pg_attrdef_adrelid			1
- #define Anum_pg_attrdef_adnum			2
- #define Anum_pg_attrdef_adbin			3
- #define Anum_pg_attrdef_adsrc			4
- 
  #endif   /* PG_ATTRDEF_H */
--- 43,46 ----
*** a/src/include/catalog/pg_attribute.h
--- b/src/include/catalog/pg_attribute.h
***************
*** 172,203 **** CATALOG(pg_attribute,1249) BKI_BOOTSTRAP BKI_WITHOUT_OIDS
  typedef FormData_pg_attribute *Form_pg_attribute;
  
  /* ----------------
-  *		compiler constants for pg_attribute
-  * ----------------
-  */
- 
- #define Natts_pg_attribute				18
- #define Anum_pg_attribute_attrelid		1
- #define Anum_pg_attribute_attname		2
- #define Anum_pg_attribute_atttypid		3
- #define Anum_pg_attribute_attstattarget 4
- #define Anum_pg_attribute_attlen		5
- #define Anum_pg_attribute_attnum		6
- #define Anum_pg_attribute_attndims		7
- #define Anum_pg_attribute_attcacheoff	8
- #define Anum_pg_attribute_atttypmod		9
- #define Anum_pg_attribute_attbyval		10
- #define Anum_pg_attribute_attstorage	11
- #define Anum_pg_attribute_attalign		12
- #define Anum_pg_attribute_attnotnull	13
- #define Anum_pg_attribute_atthasdef		14
- #define Anum_pg_attribute_attisdropped	15
- #define Anum_pg_attribute_attislocal	16
- #define Anum_pg_attribute_attinhcount	17
- #define Anum_pg_attribute_attacl		18
- 
- 
- /* ----------------
   *		initial contents of pg_attribute
   *
   * NOTE: only "bootstrapped" relations need to be declared here.
--- 172,177 ----
***************
*** 211,245 **** typedef FormData_pg_attribute *Form_pg_attribute;
   *		pg_type
   * ----------------
   */
- #define Schema_pg_type \
- { 1247, {"typname"},	   19, -1, NAMEDATALEN, 1, 0, -1, -1, false, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typnamespace"},  26, -1,	4,	2, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typowner"},	   26, -1,	4,	3, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typlen"},		   21, -1,	2,	4, 0, -1, -1, true, 'p', 's', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typbyval"},	   16, -1,	1,	5, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typtype"},	   18, -1,	1,	6, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typcategory"},   18, -1,	1,	7, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typispreferred"},16, -1,	1,	8, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typisdefined"},  16, -1,	1,	9, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typdelim"},	   18, -1,	1, 10, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typrelid"},	   26, -1,	4, 11, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typelem"},	   26, -1,	4, 12, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typarray"},	   26, -1,	4, 13, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typinput"},	   24, -1,	4, 14, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typoutput"},	   24, -1,	4, 15, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typreceive"},    24, -1,	4, 16, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typsend"},	   24, -1,	4, 17, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typmodin"},	   24, -1,	4, 18, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typmodout"},	   24, -1,	4, 19, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typanalyze"},    24, -1,	4, 20, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typalign"},	   18, -1,	1, 21, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typstorage"},    18, -1,	1, 22, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typnotnull"},    16, -1,	1, 23, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typbasetype"},   26, -1,	4, 24, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typtypmod"},	   23, -1,	4, 25, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typndims"},	   23, -1,	4, 26, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typdefaultbin"}, 25, -1, -1, 27, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }, \
- { 1247, {"typdefault"},    25, -1, -1, 28, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }
  
  DATA(insert ( 1247 typname			19 -1 NAMEDATALEN	1 0 -1 -1 f p c t f f t 0 _null_));
  DATA(insert ( 1247 typnamespace		26 -1 4   2 0 -1 -1 t p i t f f t 0 _null_));
--- 185,190 ----
***************
*** 281,312 **** DATA(insert ( 1247 tableoid			26 0  4  -7 0 -1 -1 t p i t f f t 0 _null_));
   *		pg_proc
   * ----------------
   */
- #define Schema_pg_proc \
- { 1255, {"proname"},			19, -1, NAMEDATALEN,  1, 0, -1, -1, false, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1255, {"pronamespace"},		26, -1, 4,	2, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1255, {"proowner"},			26, -1, 4,	3, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1255, {"prolang"},			26, -1, 4,	4, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1255, {"procost"},		   700, -1, 4,	5, 0, -1, -1, FLOAT4PASSBYVAL, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1255, {"prorows"},		   700, -1, 4,	6, 0, -1, -1, FLOAT4PASSBYVAL, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1255, {"provariadic"},		26, -1, 4,	7, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1255, {"proisagg"},			16, -1, 1,	8, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1255, {"proiswindow"},		16, -1, 1,	9, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1255, {"prosecdef"},			16, -1, 1, 10, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1255, {"proisstrict"},		16, -1, 1, 11, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1255, {"proretset"},			16, -1, 1, 12, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1255, {"provolatile"},		18, -1, 1, 13, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1255, {"pronargs"},			21, -1, 2, 14, 0, -1, -1, true, 'p', 's', true, false, false, true, 0, { 0 } }, \
- { 1255, {"pronargdefaults"},	21, -1, 2, 15, 0, -1, -1, true, 'p', 's', true, false, false, true, 0, { 0 } }, \
- { 1255, {"prorettype"},			26, -1, 4, 16, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1255, {"proargtypes"},		30, -1, -1, 17, 1, -1, -1, false, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1255, {"proallargtypes"},   1028, -1, -1, 18, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }, \
- { 1255, {"proargmodes"},	  1002, -1, -1, 19, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }, \
- { 1255, {"proargnames"},	  1009, -1, -1, 20, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }, \
- { 1255, {"proargdefaults"},		25, -1, -1, 21, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }, \
- { 1255, {"prosrc"},				25, -1, -1, 22, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }, \
- { 1255, {"probin"},				17, -1, -1, 23, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }, \
- { 1255, {"proconfig"},		  1009, -1, -1, 24, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }, \
- { 1255, {"proacl"},			  1034, -1, -1, 25, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }
  
  DATA(insert ( 1255 proname			19 -1 NAMEDATALEN	1 0 -1 -1 f p c t f f t 0 _null_));
  DATA(insert ( 1255 pronamespace		26 -1 4   2 0 -1 -1 t p i t f f t 0 _null_));
--- 226,231 ----
***************
*** 345,369 **** DATA(insert ( 1255 tableoid			26 0  4  -7 0 -1 -1 t p i t f f t 0 _null_));
   *		pg_attribute
   * ----------------
   */
- #define Schema_pg_attribute \
- { 1249, {"attrelid"},	  26, -1,	4,	1, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attname"},	  19, -1, NAMEDATALEN,	2, 0, -1, -1, false, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1249, {"atttypid"},	  26, -1,	4,	3, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attstattarget"}, 23, -1,	4,	4, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attlen"},		  21, -1,	2,	5, 0, -1, -1, true, 'p', 's', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attnum"},		  21, -1,	2,	6, 0, -1, -1, true, 'p', 's', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attndims"},	  23, -1,	4,	7, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attcacheoff"},  23, -1,	4,	8, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1249, {"atttypmod"},	  23, -1,	4,	9, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attbyval"},	  16, -1,	1, 10, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attstorage"},   18, -1,	1, 11, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attalign"},	  18, -1,	1, 12, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attnotnull"},   16, -1,	1, 13, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1249, {"atthasdef"},	  16, -1,	1, 14, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attisdropped"}, 16, -1,	1, 15, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attislocal"},   16, -1,	1, 16, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attinhcount"},  23, -1,	4, 17, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attacl"},		1034, -1,  -1, 18, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }
  
  DATA(insert ( 1249 attrelid			26 -1  4   1 0 -1 -1 t p i t f f t 0 _null_));
  DATA(insert ( 1249 attname			19 -1 NAMEDATALEN  2 0 -1 -1 f p c t f f t 0 _null_));
--- 264,269 ----
***************
*** 395,426 **** DATA(insert ( 1249 tableoid			26 0  4  -7 0 -1 -1 t p i t f f t 0 _null_));
   *		pg_class
   * ----------------
   */
- #define Schema_pg_class \
- { 1259, {"relname"},	   19, -1, NAMEDATALEN, 1, 0, -1, -1, false, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relnamespace"},  26, -1,	4,	2, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1259, {"reltype"},	   26, -1,	4,	3, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relowner"},	   26, -1,	4,	4, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relam"},		   26, -1,	4,	5, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relfilenode"},   26, -1,	4,	6, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1259, {"reltablespace"}, 26, -1,	4,	7, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relpages"},	   23, -1,	4,	8, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1259, {"reltuples"},	   700, -1, 4,	9, 0, -1, -1, FLOAT4PASSBYVAL, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1259, {"reltoastrelid"}, 26, -1,	4, 10, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1259, {"reltoastidxid"}, 26, -1,	4, 11, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relhasindex"},   16, -1,	1, 12, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relisshared"},   16, -1,	1, 13, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relistemp"},	   16, -1,	1, 14, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relkind"},	   18, -1,	1, 15, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relnatts"},	   21, -1,	2, 16, 0, -1, -1, true, 'p', 's', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relchecks"},	   21, -1,	2, 17, 0, -1, -1, true, 'p', 's', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relhasoids"},    16, -1,	1, 18, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relhaspkey"},    16, -1,	1, 19, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relhasrules"},   16, -1,	1, 20, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relhastriggers"},16, -1,	1, 21, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relhassubclass"},16, -1,	1, 22, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relfrozenxid"},  28, -1,	4, 23, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relacl"},		 1034, -1, -1, 24, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }, \
- { 1259, {"reloptions"},  1009, -1, -1, 25, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }
  
  DATA(insert ( 1259 relname			19 -1 NAMEDATALEN	1 0 -1 -1 f p c t f f t 0 _null_));
  DATA(insert ( 1259 relnamespace		26 -1 4   2 0 -1 -1 t p i t f f t 0 _null_));
--- 295,300 ----
***************
*** 460,466 **** DATA(insert ( 1259 tableoid			26 0  4  -7 0 -1 -1 t p i t f f t 0 _null_));
   *
   * pg_index is not bootstrapped in the same way as the other relations that
   * have hardwired pg_attribute entries in this file.  However, we do need
!  * a "Schema_xxx" macro for it --- see relcache.c.
   * ----------------
   */
  #define Schema_pg_index \
--- 334,342 ----
   *
   * pg_index is not bootstrapped in the same way as the other relations that
   * have hardwired pg_attribute entries in this file.  However, we do need
!  * a "Schema_xxx" macro for it --- see relcache.c.  But since there are no
!  * DATA() statements for pg_index in this file (or anywhere else), this
!  * can't be automatically generated, so we hard-code it here.
   * ----------------
   */
  #define Schema_pg_index \
*** a/src/include/catalog/pg_auth_members.h
--- b/src/include/catalog/pg_auth_members.h
***************
*** 43,56 **** CATALOG(pg_auth_members,1261) BKI_SHARED_RELATION BKI_WITHOUT_OIDS
   */
  typedef FormData_pg_auth_members *Form_pg_auth_members;
  
- /* ----------------
-  *		compiler constants for pg_auth_members
-  * ----------------
-  */
- #define Natts_pg_auth_members				4
- #define Anum_pg_auth_members_roleid			1
- #define Anum_pg_auth_members_member			2
- #define Anum_pg_auth_members_grantor		3
- #define Anum_pg_auth_members_admin_option	4
- 
  #endif   /* PG_AUTH_MEMBERS_H */
--- 43,46 ----
*** a/src/include/catalog/pg_authid.h
--- b/src/include/catalog/pg_authid.h
***************
*** 69,91 **** CATALOG(pg_authid,1260) BKI_SHARED_RELATION
  typedef FormData_pg_authid *Form_pg_authid;
  
  /* ----------------
-  *		compiler constants for pg_authid
-  * ----------------
-  */
- #define Natts_pg_authid					11
- #define Anum_pg_authid_rolname			1
- #define Anum_pg_authid_rolsuper			2
- #define Anum_pg_authid_rolinherit		3
- #define Anum_pg_authid_rolcreaterole	4
- #define Anum_pg_authid_rolcreatedb		5
- #define Anum_pg_authid_rolcatupdate		6
- #define Anum_pg_authid_rolcanlogin		7
- #define Anum_pg_authid_rolconnlimit		8
- #define Anum_pg_authid_rolpassword		9
- #define Anum_pg_authid_rolvaliduntil	10
- #define Anum_pg_authid_rolconfig		11
- 
- /* ----------------
   *		initial contents of pg_authid
   *
   * The uppercase quantities will be replaced at initdb time with
--- 69,74 ----
*** a/src/include/catalog/pg_cast.h
--- b/src/include/catalog/pg_cast.h
***************
*** 71,87 **** typedef enum CoercionMethod
  
  
  /* ----------------
-  *		compiler constants for pg_cast
-  * ----------------
-  */
- #define Natts_pg_cast				5
- #define Anum_pg_cast_castsource		1
- #define Anum_pg_cast_casttarget		2
- #define Anum_pg_cast_castfunc		3
- #define Anum_pg_cast_castcontext	4
- #define Anum_pg_cast_castmethod		5
- 
- /* ----------------
   *		initial contents of pg_cast
   *
   * Note: this table has OIDs, but we don't bother to assign them manually,
--- 71,76 ----
*** a/src/include/catalog/pg_class.h
--- b/src/include/catalog/pg_class.h
***************
*** 82,119 **** CATALOG(pg_class,1259) BKI_BOOTSTRAP
  typedef FormData_pg_class *Form_pg_class;
  
  /* ----------------
-  *		compiler constants for pg_class
-  * ----------------
-  */
- 
- #define Natts_pg_class					25
- #define Anum_pg_class_relname			1
- #define Anum_pg_class_relnamespace		2
- #define Anum_pg_class_reltype			3
- #define Anum_pg_class_relowner			4
- #define Anum_pg_class_relam				5
- #define Anum_pg_class_relfilenode		6
- #define Anum_pg_class_reltablespace		7
- #define Anum_pg_class_relpages			8
- #define Anum_pg_class_reltuples			9
- #define Anum_pg_class_reltoastrelid		10
- #define Anum_pg_class_reltoastidxid		11
- #define Anum_pg_class_relhasindex		12
- #define Anum_pg_class_relisshared		13
- #define Anum_pg_class_relistemp			14
- #define Anum_pg_class_relkind			15
- #define Anum_pg_class_relnatts			16
- #define Anum_pg_class_relchecks			17
- #define Anum_pg_class_relhasoids		18
- #define Anum_pg_class_relhaspkey		19
- #define Anum_pg_class_relhasrules		20
- #define Anum_pg_class_relhastriggers	21
- #define Anum_pg_class_relhassubclass	22
- #define Anum_pg_class_relfrozenxid		23
- #define Anum_pg_class_relacl			24
- #define Anum_pg_class_reloptions		25
- 
- /* ----------------
   *		initial contents of pg_class
   *
   * NOTE: only "bootstrapped" relations need to be declared here.  Be sure that
--- 82,87 ----
*** a/src/include/catalog/pg_constraint.h
--- b/src/include/catalog/pg_constraint.h
***************
*** 127,159 **** CATALOG(pg_constraint,2606)
   */
  typedef FormData_pg_constraint *Form_pg_constraint;
  
- /* ----------------
-  *		compiler constants for pg_constraint
-  * ----------------
-  */
- #define Natts_pg_constraint					20
- #define Anum_pg_constraint_conname			1
- #define Anum_pg_constraint_connamespace		2
- #define Anum_pg_constraint_contype			3
- #define Anum_pg_constraint_condeferrable	4
- #define Anum_pg_constraint_condeferred		5
- #define Anum_pg_constraint_conrelid			6
- #define Anum_pg_constraint_contypid			7
- #define Anum_pg_constraint_confrelid		8
- #define Anum_pg_constraint_confupdtype		9
- #define Anum_pg_constraint_confdeltype		10
- #define Anum_pg_constraint_confmatchtype	11
- #define Anum_pg_constraint_conislocal		12
- #define Anum_pg_constraint_coninhcount		13
- #define Anum_pg_constraint_conkey			14
- #define Anum_pg_constraint_confkey			15
- #define Anum_pg_constraint_conpfeqop		16
- #define Anum_pg_constraint_conppeqop		17
- #define Anum_pg_constraint_conffeqop		18
- #define Anum_pg_constraint_conbin			19
- #define Anum_pg_constraint_consrc			20
- 
- 
  /* Valid values for contype */
  #define CONSTRAINT_CHECK			'c'
  #define CONSTRAINT_FOREIGN			'f'
--- 127,132 ----
*** a/src/include/catalog/pg_conversion.h
--- b/src/include/catalog/pg_conversion.h
***************
*** 56,75 **** CATALOG(pg_conversion,2607)
  typedef FormData_pg_conversion *Form_pg_conversion;
  
  /* ----------------
-  *		compiler constants for pg_conversion
-  * ----------------
-  */
- 
- #define Natts_pg_conversion				7
- #define Anum_pg_conversion_conname		1
- #define Anum_pg_conversion_connamespace 2
- #define Anum_pg_conversion_conowner		3
- #define Anum_pg_conversion_conforencoding		4
- #define Anum_pg_conversion_contoencoding		5
- #define Anum_pg_conversion_conproc		6
- #define Anum_pg_conversion_condefault	7
- 
- /* ----------------
   * initial contents of pg_conversion
   * ---------------
   */
--- 56,61 ----
*** a/src/include/catalog/pg_database.h
--- b/src/include/catalog/pg_database.h
***************
*** 52,76 **** CATALOG(pg_database,1262) BKI_SHARED_RELATION
   */
  typedef FormData_pg_database *Form_pg_database;
  
- /* ----------------
-  *		compiler constants for pg_database
-  * ----------------
-  */
- #define Natts_pg_database				13
- #define Anum_pg_database_datname		1
- #define Anum_pg_database_datdba			2
- #define Anum_pg_database_encoding		3
- #define Anum_pg_database_datcollate		4
- #define Anum_pg_database_datctype		5
- #define Anum_pg_database_datistemplate	6
- #define Anum_pg_database_datallowconn	7
- #define Anum_pg_database_datconnlimit	8
- #define Anum_pg_database_datlastsysoid	9
- #define Anum_pg_database_datfrozenxid	10
- #define Anum_pg_database_dattablespace	11
- #define Anum_pg_database_datconfig		12
- #define Anum_pg_database_datacl			13
- 
  DATA(insert OID = 1 (  template1 PGUID ENCODING "LC_COLLATE" "LC_CTYPE" t t -1 0 0 1663 _null_ _null_));
  SHDESCR("default template database");
  #define TemplateDbOid			1
--- 52,57 ----
*** a/src/include/catalog/pg_depend.h
--- b/src/include/catalog/pg_depend.h
***************
*** 60,79 **** CATALOG(pg_depend,2608) BKI_WITHOUT_OIDS
   */
  typedef FormData_pg_depend *Form_pg_depend;
  
- /* ----------------
-  *		compiler constants for pg_depend
-  * ----------------
-  */
- #define Natts_pg_depend				7
- #define Anum_pg_depend_classid		1
- #define Anum_pg_depend_objid		2
- #define Anum_pg_depend_objsubid		3
- #define Anum_pg_depend_refclassid	4
- #define Anum_pg_depend_refobjid		5
- #define Anum_pg_depend_refobjsubid	6
- #define Anum_pg_depend_deptype		7
- 
- 
  /*
   * pg_depend has no preloaded contents; system-defined dependencies are
   * loaded into it during a late stage of the initdb process.
--- 60,65 ----
*** a/src/include/catalog/pg_description.h
--- b/src/include/catalog/pg_description.h
***************
*** 61,76 **** CATALOG(pg_description,2609) BKI_WITHOUT_OIDS
  typedef FormData_pg_description *Form_pg_description;
  
  /* ----------------
-  *		compiler constants for pg_description
-  * ----------------
-  */
- #define Natts_pg_description			4
- #define Anum_pg_description_objoid		1
- #define Anum_pg_description_classoid	2
- #define Anum_pg_description_objsubid	3
- #define Anum_pg_description_description 4
- 
- /* ----------------
   *		initial contents of pg_description
   * ----------------
   */
--- 61,66 ----
*** a/src/include/catalog/pg_enum.h
--- b/src/include/catalog/pg_enum.h
***************
*** 45,58 **** CATALOG(pg_enum,3501)
  typedef FormData_pg_enum *Form_pg_enum;
  
  /* ----------------
-  *		compiler constants for pg_enum
-  * ----------------
-  */
- #define Natts_pg_enum					2
- #define Anum_pg_enum_enumtypid			1
- #define Anum_pg_enum_enumlabel			2
- 
- /* ----------------
   *		pg_enum has no initial contents
   * ----------------
   */
--- 45,50 ----
*** a/src/include/catalog/pg_foreign_data_wrapper.h
--- b/src/include/catalog/pg_foreign_data_wrapper.h
***************
*** 47,62 **** CATALOG(pg_foreign_data_wrapper,2328)
   */
  typedef FormData_pg_foreign_data_wrapper *Form_pg_foreign_data_wrapper;
  
- /* ----------------
-  *		compiler constants for pg_fdw
-  * ----------------
-  */
- 
- #define Natts_pg_foreign_data_wrapper				5
- #define Anum_pg_foreign_data_wrapper_fdwname		1
- #define Anum_pg_foreign_data_wrapper_fdwowner		2
- #define Anum_pg_foreign_data_wrapper_fdwvalidator	3
- #define Anum_pg_foreign_data_wrapper_fdwacl			4
- #define Anum_pg_foreign_data_wrapper_fdwoptions		5
- 
  #endif   /* PG_FOREIGN_DATA_WRAPPER_H */
--- 47,50 ----
*** a/src/include/catalog/pg_foreign_server.h
--- b/src/include/catalog/pg_foreign_server.h
***************
*** 48,65 **** CATALOG(pg_foreign_server,1417)
   */
  typedef FormData_pg_foreign_server *Form_pg_foreign_server;
  
- /* ----------------
-  *		compiler constants for pg_foreign_server
-  * ----------------
-  */
- 
- #define Natts_pg_foreign_server					7
- #define Anum_pg_foreign_server_srvname			1
- #define Anum_pg_foreign_server_srvowner			2
- #define Anum_pg_foreign_server_srvfdw			3
- #define Anum_pg_foreign_server_srvtype			4
- #define Anum_pg_foreign_server_srvversion		5
- #define Anum_pg_foreign_server_srvacl			6
- #define Anum_pg_foreign_server_srvoptions		7
- 
  #endif   /* PG_FOREIGN_SERVER_H */
--- 48,51 ----
*** a/src/include/catalog/pg_index.h
--- b/src/include/catalog/pg_index.h
***************
*** 58,83 **** CATALOG(pg_index,2610) BKI_WITHOUT_OIDS
   */
  typedef FormData_pg_index *Form_pg_index;
  
- /* ----------------
-  *		compiler constants for pg_index
-  * ----------------
-  */
- #define Natts_pg_index					14
- #define Anum_pg_index_indexrelid		1
- #define Anum_pg_index_indrelid			2
- #define Anum_pg_index_indnatts			3
- #define Anum_pg_index_indisunique		4
- #define Anum_pg_index_indisprimary		5
- #define Anum_pg_index_indisclustered	6
- #define Anum_pg_index_indisvalid		7
- #define Anum_pg_index_indcheckxmin		8
- #define Anum_pg_index_indisready		9
- #define Anum_pg_index_indkey			10
- #define Anum_pg_index_indclass			11
- #define Anum_pg_index_indoption			12
- #define Anum_pg_index_indexprs			13
- #define Anum_pg_index_indpred			14
- 
  /*
   * Index AMs that support ordered scans must support these two indoption
   * bits.  Otherwise, the content of the per-column indoption fields is
--- 58,63 ----
*** a/src/include/catalog/pg_inherits.h
--- b/src/include/catalog/pg_inherits.h
***************
*** 43,57 **** CATALOG(pg_inherits,2611) BKI_WITHOUT_OIDS
  typedef FormData_pg_inherits *Form_pg_inherits;
  
  /* ----------------
-  *		compiler constants for pg_inherits
-  * ----------------
-  */
- #define Natts_pg_inherits				3
- #define Anum_pg_inherits_inhrelid		1
- #define Anum_pg_inherits_inhparent		2
- #define Anum_pg_inherits_inhseqno		3
- 
- /* ----------------
   *		pg_inherits has no initial contents
   * ----------------
   */
--- 43,48 ----
*** a/src/include/catalog/pg_language.h
--- b/src/include/catalog/pg_language.h
***************
*** 47,65 **** CATALOG(pg_language,2612)
  typedef FormData_pg_language *Form_pg_language;
  
  /* ----------------
-  *		compiler constants for pg_language
-  * ----------------
-  */
- #define Natts_pg_language				7
- #define Anum_pg_language_lanname		1
- #define Anum_pg_language_lanowner		2
- #define Anum_pg_language_lanispl		3
- #define Anum_pg_language_lanpltrusted	4
- #define Anum_pg_language_lanplcallfoid	5
- #define Anum_pg_language_lanvalidator	6
- #define Anum_pg_language_lanacl			7
- 
- /* ----------------
   *		initial contents of pg_language
   * ----------------
   */
--- 47,52 ----
*** a/src/include/catalog/pg_largeobject.h
--- b/src/include/catalog/pg_largeobject.h
***************
*** 42,56 **** CATALOG(pg_largeobject,2613) BKI_WITHOUT_OIDS
   */
  typedef FormData_pg_largeobject *Form_pg_largeobject;
  
- /* ----------------
-  *		compiler constants for pg_largeobject
-  * ----------------
-  */
- #define Natts_pg_largeobject			3
- #define Anum_pg_largeobject_loid		1
- #define Anum_pg_largeobject_pageno		2
- #define Anum_pg_largeobject_data		3
- 
  extern void LargeObjectCreate(Oid loid);
  extern void LargeObjectDrop(Oid loid);
  extern bool LargeObjectExists(Oid loid);
--- 42,47 ----
*** a/src/include/catalog/pg_listener.h
--- b/src/include/catalog/pg_listener.h
***************
*** 43,57 **** CATALOG(pg_listener,2614) BKI_WITHOUT_OIDS
  typedef FormData_pg_listener *Form_pg_listener;
  
  /* ----------------
-  *		compiler constants for pg_listener
-  * ----------------
-  */
- #define Natts_pg_listener						3
- #define Anum_pg_listener_relname				1
- #define Anum_pg_listener_pid					2
- #define Anum_pg_listener_notify					3
- 
- /* ----------------
   *		initial contents of pg_listener are NOTHING.
   * ----------------
   */
--- 43,48 ----
*** a/src/include/catalog/pg_namespace.h
--- b/src/include/catalog/pg_namespace.h
***************
*** 48,64 **** CATALOG(pg_namespace,2615)
  typedef FormData_pg_namespace *Form_pg_namespace;
  
  /* ----------------
-  *		compiler constants for pg_namespace
-  * ----------------
-  */
- 
- #define Natts_pg_namespace				3
- #define Anum_pg_namespace_nspname		1
- #define Anum_pg_namespace_nspowner		2
- #define Anum_pg_namespace_nspacl		3
- 
- 
- /* ----------------
   * initial contents of pg_namespace
   * ---------------
   */
--- 48,53 ----
*** a/src/include/catalog/pg_opclass.h
--- b/src/include/catalog/pg_opclass.h
***************
*** 68,87 **** CATALOG(pg_opclass,2616)
  typedef FormData_pg_opclass *Form_pg_opclass;
  
  /* ----------------
-  *		compiler constants for pg_opclass
-  * ----------------
-  */
- #define Natts_pg_opclass				8
- #define Anum_pg_opclass_opcmethod		1
- #define Anum_pg_opclass_opcname			2
- #define Anum_pg_opclass_opcnamespace	3
- #define Anum_pg_opclass_opcowner		4
- #define Anum_pg_opclass_opcfamily		5
- #define Anum_pg_opclass_opcintype		6
- #define Anum_pg_opclass_opcdefault		7
- #define Anum_pg_opclass_opckeytype		8
- 
- /* ----------------
   *		initial contents of pg_opclass
   *
   * Note: we hard-wire an OID only for a few entries that have to be explicitly
--- 68,73 ----
*** a/src/include/catalog/pg_operator.h
--- b/src/include/catalog/pg_operator.h
***************
*** 58,84 **** CATALOG(pg_operator,2617)
  typedef FormData_pg_operator *Form_pg_operator;
  
  /* ----------------
-  *		compiler constants for pg_operator
-  * ----------------
-  */
- 
- #define Natts_pg_operator				14
- #define Anum_pg_operator_oprname		1
- #define Anum_pg_operator_oprnamespace	2
- #define Anum_pg_operator_oprowner		3
- #define Anum_pg_operator_oprkind		4
- #define Anum_pg_operator_oprcanmerge	5
- #define Anum_pg_operator_oprcanhash		6
- #define Anum_pg_operator_oprleft		7
- #define Anum_pg_operator_oprright		8
- #define Anum_pg_operator_oprresult		9
- #define Anum_pg_operator_oprcom			10
- #define Anum_pg_operator_oprnegate		11
- #define Anum_pg_operator_oprcode		12
- #define Anum_pg_operator_oprrest		13
- #define Anum_pg_operator_oprjoin		14
- 
- /* ----------------
   *		initial contents of pg_operator
   * ----------------
   */
--- 58,63 ----
*** a/src/include/catalog/pg_opfamily.h
--- b/src/include/catalog/pg_opfamily.h
***************
*** 44,59 **** CATALOG(pg_opfamily,2753)
  typedef FormData_pg_opfamily *Form_pg_opfamily;
  
  /* ----------------
-  *		compiler constants for pg_opfamily
-  * ----------------
-  */
- #define Natts_pg_opfamily				4
- #define Anum_pg_opfamily_opfmethod		1
- #define Anum_pg_opfamily_opfname		2
- #define Anum_pg_opfamily_opfnamespace	3
- #define Anum_pg_opfamily_opfowner		4
- 
- /* ----------------
   *		initial contents of pg_opfamily
   * ----------------
   */
--- 44,49 ----
*** a/src/include/catalog/pg_pltemplate.h
--- b/src/include/catalog/pg_pltemplate.h
***************
*** 47,66 **** CATALOG(pg_pltemplate,1136) BKI_SHARED_RELATION BKI_WITHOUT_OIDS
  typedef FormData_pg_pltemplate *Form_pg_pltemplate;
  
  /* ----------------
-  *		compiler constants for pg_pltemplate
-  * ----------------
-  */
- #define Natts_pg_pltemplate					7
- #define Anum_pg_pltemplate_tmplname			1
- #define Anum_pg_pltemplate_tmpltrusted		2
- #define Anum_pg_pltemplate_tmpldbacreate	3
- #define Anum_pg_pltemplate_tmplhandler		4
- #define Anum_pg_pltemplate_tmplvalidator	5
- #define Anum_pg_pltemplate_tmpllibrary		6
- #define Anum_pg_pltemplate_tmplacl			7
- 
- 
- /* ----------------
   *		initial contents of pg_pltemplate
   * ----------------
   */
--- 47,52 ----
*** a/src/include/catalog/pg_proc.h
--- b/src/include/catalog/pg_proc.h
***************
*** 10,18 ****
   * $PostgreSQL$
   *
   * NOTES
!  *	  The script catalog/genbki.sh reads this file and generates .bki
!  *	  information from the DATA() statements.  utils/Gen_fmgrtab.sh
!  *	  generates fmgroids.h and fmgrtab.c the same way.
   *
   *	  XXX do NOT break up DATA() statements into multiple lines!
   *		  the scripts are not as smart as you might think...
--- 10,18 ----
   * $PostgreSQL$
   *
   * NOTES
!  *	  The script catalog/gen_catalog.pl reads this file and generates .bki
!  *	  information from the DATA() statements; it also generates fmgroids.h
!  *	  and fmgrtab.c.
   *
   *	  XXX do NOT break up DATA() statements into multiple lines!
   *		  the scripts are not as smart as you might think...
***************
*** 72,108 **** CATALOG(pg_proc,1255) BKI_BOOTSTRAP
  typedef FormData_pg_proc *Form_pg_proc;
  
  /* ----------------
-  *		compiler constants for pg_proc
-  * ----------------
-  */
- #define Natts_pg_proc					25
- #define Anum_pg_proc_proname			1
- #define Anum_pg_proc_pronamespace		2
- #define Anum_pg_proc_proowner			3
- #define Anum_pg_proc_prolang			4
- #define Anum_pg_proc_procost			5
- #define Anum_pg_proc_prorows			6
- #define Anum_pg_proc_provariadic		7
- #define Anum_pg_proc_proisagg			8
- #define Anum_pg_proc_proiswindow		9
- #define Anum_pg_proc_prosecdef			10
- #define Anum_pg_proc_proisstrict		11
- #define Anum_pg_proc_proretset			12
- #define Anum_pg_proc_provolatile		13
- #define Anum_pg_proc_pronargs			14
- #define Anum_pg_proc_pronargdefaults	15
- #define Anum_pg_proc_prorettype			16
- #define Anum_pg_proc_proargtypes		17
- #define Anum_pg_proc_proallargtypes		18
- #define Anum_pg_proc_proargmodes		19
- #define Anum_pg_proc_proargnames		20
- #define Anum_pg_proc_proargdefaults		21
- #define Anum_pg_proc_prosrc				22
- #define Anum_pg_proc_probin				23
- #define Anum_pg_proc_proconfig			24
- #define Anum_pg_proc_proacl				25
- 
- /* ----------------
   *		initial contents of pg_proc
   * ----------------
   */
--- 72,77 ----
*** a/src/include/catalog/pg_rewrite.h
--- b/src/include/catalog/pg_rewrite.h
***************
*** 52,69 **** CATALOG(pg_rewrite,2618)
   */
  typedef FormData_pg_rewrite *Form_pg_rewrite;
  
- /* ----------------
-  *		compiler constants for pg_rewrite
-  * ----------------
-  */
- #define Natts_pg_rewrite				8
- #define Anum_pg_rewrite_rulename		1
- #define Anum_pg_rewrite_ev_class		2
- #define Anum_pg_rewrite_ev_attr			3
- #define Anum_pg_rewrite_ev_type			4
- #define Anum_pg_rewrite_ev_enabled		5
- #define Anum_pg_rewrite_is_instead		6
- #define Anum_pg_rewrite_ev_qual			7
- #define Anum_pg_rewrite_ev_action		8
- 
  #endif   /* PG_REWRITE_H */
--- 52,55 ----
*** a/src/include/catalog/pg_shdepend.h
--- b/src/include/catalog/pg_shdepend.h
***************
*** 63,82 **** CATALOG(pg_shdepend,1214) BKI_SHARED_RELATION BKI_WITHOUT_OIDS
   */
  typedef FormData_pg_shdepend *Form_pg_shdepend;
  
- /* ----------------
-  *		compiler constants for pg_shdepend
-  * ----------------
-  */
- #define Natts_pg_shdepend			7
- #define Anum_pg_shdepend_dbid		1
- #define Anum_pg_shdepend_classid	2
- #define Anum_pg_shdepend_objid		3
- #define Anum_pg_shdepend_objsubid	4
- #define Anum_pg_shdepend_refclassid 5
- #define Anum_pg_shdepend_refobjid	6
- #define Anum_pg_shdepend_deptype	7
- 
- 
  /*
   * pg_shdepend has no preloaded contents; system-defined dependencies are
   * loaded into it during a late stage of the initdb process.
--- 63,68 ----
*** a/src/include/catalog/pg_shdescription.h
--- b/src/include/catalog/pg_shdescription.h
***************
*** 53,67 **** CATALOG(pg_shdescription,2396) BKI_SHARED_RELATION BKI_WITHOUT_OIDS
  typedef FormData_pg_shdescription *Form_pg_shdescription;
  
  /* ----------------
-  *		compiler constants for pg_shdescription
-  * ----------------
-  */
- #define Natts_pg_shdescription			3
- #define Anum_pg_shdescription_objoid		1
- #define Anum_pg_shdescription_classoid	2
- #define Anum_pg_shdescription_description 3
- 
- /* ----------------
   *		initial contents of pg_shdescription
   * ----------------
   */
--- 53,58 ----
***************
*** 69,75 **** typedef FormData_pg_shdescription *Form_pg_shdescription;
  /*
   *	Because the contents of this table are taken from the other *.h files,
   *	there is no initialization here.  The initial contents are extracted
!  *	by genbki.sh and loaded during initdb.
   */
  
  #endif   /* PG_SHDESCRIPTION_H */
--- 60,66 ----
  /*
   *	Because the contents of this table are taken from the other *.h files,
   *	there is no initialization here.  The initial contents are extracted
!  *	by gen_catalog.pl and loaded during initdb.
   */
  
  #endif   /* PG_SHDESCRIPTION_H */
*** a/src/include/catalog/pg_tablespace.h
--- b/src/include/catalog/pg_tablespace.h
***************
*** 43,59 **** CATALOG(pg_tablespace,1213) BKI_SHARED_RELATION
   */
  typedef FormData_pg_tablespace *Form_pg_tablespace;
  
- /* ----------------
-  *		compiler constants for pg_tablespace
-  * ----------------
-  */
- 
- #define Natts_pg_tablespace				4
- #define Anum_pg_tablespace_spcname		1
- #define Anum_pg_tablespace_spcowner		2
- #define Anum_pg_tablespace_spclocation	3
- #define Anum_pg_tablespace_spcacl		4
- 
  DATA(insert OID = 1663 ( pg_default PGUID "" _null_ ));
  DATA(insert OID = 1664 ( pg_global	PGUID "" _null_ ));
  
--- 43,48 ----
*** a/src/include/catalog/pg_trigger.h
--- b/src/include/catalog/pg_trigger.h
***************
*** 63,88 **** CATALOG(pg_trigger,2620)
   */
  typedef FormData_pg_trigger *Form_pg_trigger;
  
- /* ----------------
-  *		compiler constants for pg_trigger
-  * ----------------
-  */
- #define Natts_pg_trigger				14
- #define Anum_pg_trigger_tgrelid			1
- #define Anum_pg_trigger_tgname			2
- #define Anum_pg_trigger_tgfoid			3
- #define Anum_pg_trigger_tgtype			4
- #define Anum_pg_trigger_tgenabled		5
- #define Anum_pg_trigger_tgisconstraint	6
- #define Anum_pg_trigger_tgconstrname	7
- #define Anum_pg_trigger_tgconstrrelid	8
- #define Anum_pg_trigger_tgconstraint	9
- #define Anum_pg_trigger_tgdeferrable	10
- #define Anum_pg_trigger_tginitdeferred	11
- #define Anum_pg_trigger_tgnargs			12
- #define Anum_pg_trigger_tgattr			13
- #define Anum_pg_trigger_tgargs			14
- 
  /* Bits within tgtype */
  #define TRIGGER_TYPE_ROW				(1 << 0)
  #define TRIGGER_TYPE_BEFORE				(1 << 1)
--- 63,68 ----
*** a/src/include/catalog/pg_ts_config.h
--- b/src/include/catalog/pg_ts_config.h
***************
*** 41,56 **** CATALOG(pg_ts_config,3602)
  typedef FormData_pg_ts_config *Form_pg_ts_config;
  
  /* ----------------
-  *		compiler constants for pg_ts_config
-  * ----------------
-  */
- #define Natts_pg_ts_config				4
- #define Anum_pg_ts_config_cfgname		1
- #define Anum_pg_ts_config_cfgnamespace	2
- #define Anum_pg_ts_config_cfgowner		3
- #define Anum_pg_ts_config_cfgparser		4
- 
- /* ----------------
   *		initial contents of pg_ts_config
   * ----------------
   */
--- 41,46 ----
*** a/src/include/catalog/pg_ts_config_map.h
--- b/src/include/catalog/pg_ts_config_map.h
***************
*** 41,56 **** CATALOG(pg_ts_config_map,3603) BKI_WITHOUT_OIDS
  typedef FormData_pg_ts_config_map *Form_pg_ts_config_map;
  
  /* ----------------
-  *		compiler constants for pg_ts_config_map
-  * ----------------
-  */
- #define Natts_pg_ts_config_map				4
- #define Anum_pg_ts_config_map_mapcfg		1
- #define Anum_pg_ts_config_map_maptokentype	2
- #define Anum_pg_ts_config_map_mapseqno		3
- #define Anum_pg_ts_config_map_mapdict		4
- 
- /* ----------------
   *		initial contents of pg_ts_config_map
   * ----------------
   */
--- 41,46 ----
*** a/src/include/catalog/pg_ts_dict.h
--- b/src/include/catalog/pg_ts_dict.h
***************
*** 42,58 **** CATALOG(pg_ts_dict,3600)
  typedef FormData_pg_ts_dict *Form_pg_ts_dict;
  
  /* ----------------
-  *		compiler constants for pg_ts_dict
-  * ----------------
-  */
- #define Natts_pg_ts_dict				5
- #define Anum_pg_ts_dict_dictname		1
- #define Anum_pg_ts_dict_dictnamespace	2
- #define Anum_pg_ts_dict_dictowner		3
- #define Anum_pg_ts_dict_dicttemplate	4
- #define Anum_pg_ts_dict_dictinitoption	5
- 
- /* ----------------
   *		initial contents of pg_ts_dict
   * ----------------
   */
--- 42,47 ----
*** a/src/include/catalog/pg_ts_parser.h
--- b/src/include/catalog/pg_ts_parser.h
***************
*** 44,62 **** CATALOG(pg_ts_parser,3601)
  typedef FormData_pg_ts_parser *Form_pg_ts_parser;
  
  /* ----------------
-  *		compiler constants for pg_ts_parser
-  * ----------------
-  */
- #define Natts_pg_ts_parser					7
- #define Anum_pg_ts_parser_prsname			1
- #define Anum_pg_ts_parser_prsnamespace		2
- #define Anum_pg_ts_parser_prsstart			3
- #define Anum_pg_ts_parser_prstoken			4
- #define Anum_pg_ts_parser_prsend			5
- #define Anum_pg_ts_parser_prsheadline		6
- #define Anum_pg_ts_parser_prslextype		7
- 
- /* ----------------
   *		initial contents of pg_ts_parser
   * ----------------
   */
--- 44,49 ----
*** a/src/include/catalog/pg_ts_template.h
--- b/src/include/catalog/pg_ts_template.h
***************
*** 41,56 **** CATALOG(pg_ts_template,3764)
  typedef FormData_pg_ts_template *Form_pg_ts_template;
  
  /* ----------------
-  *		compiler constants for pg_ts_template
-  * ----------------
-  */
- #define Natts_pg_ts_template				4
- #define Anum_pg_ts_template_tmplname		1
- #define Anum_pg_ts_template_tmplnamespace	2
- #define Anum_pg_ts_template_tmplinit		3
- #define Anum_pg_ts_template_tmpllexize		4
- 
- /* ----------------
   *		initial contents of pg_ts_template
   * ----------------
   */
--- 41,46 ----
*** a/src/include/catalog/pg_type.h
--- b/src/include/catalog/pg_type.h
***************
*** 220,260 **** CATALOG(pg_type,1247) BKI_BOOTSTRAP
  typedef FormData_pg_type *Form_pg_type;
  
  /* ----------------
-  *		compiler constants for pg_type
-  * ----------------
-  */
- #define Natts_pg_type					28
- #define Anum_pg_type_typname			1
- #define Anum_pg_type_typnamespace		2
- #define Anum_pg_type_typowner			3
- #define Anum_pg_type_typlen				4
- #define Anum_pg_type_typbyval			5
- #define Anum_pg_type_typtype			6
- #define Anum_pg_type_typcategory		7
- #define Anum_pg_type_typispreferred		8
- #define Anum_pg_type_typisdefined		9
- #define Anum_pg_type_typdelim			10
- #define Anum_pg_type_typrelid			11
- #define Anum_pg_type_typelem			12
- #define Anum_pg_type_typarray			13
- #define Anum_pg_type_typinput			14
- #define Anum_pg_type_typoutput			15
- #define Anum_pg_type_typreceive			16
- #define Anum_pg_type_typsend			17
- #define Anum_pg_type_typmodin			18
- #define Anum_pg_type_typmodout			19
- #define Anum_pg_type_typanalyze			20
- #define Anum_pg_type_typalign			21
- #define Anum_pg_type_typstorage			22
- #define Anum_pg_type_typnotnull			23
- #define Anum_pg_type_typbasetype		24
- #define Anum_pg_type_typtypmod			25
- #define Anum_pg_type_typndims			26
- #define Anum_pg_type_typdefaultbin		27
- #define Anum_pg_type_typdefault			28
- 
- 
- /* ----------------
   *		initial contents of pg_type
   * ----------------
   */
--- 220,225 ----
*** a/src/include/catalog/pg_user_mapping.h
--- b/src/include/catalog/pg_user_mapping.h
***************
*** 46,59 **** CATALOG(pg_user_mapping,1418)
   */
  typedef FormData_pg_user_mapping *Form_pg_user_mapping;
  
- /* ----------------
-  *		compiler constants for pg_user_mapping
-  * ----------------
-  */
- 
- #define Natts_pg_user_mapping				3
- #define Anum_pg_user_mapping_umuser			1
- #define Anum_pg_user_mapping_umserver		2
- #define Anum_pg_user_mapping_umoptions		3
- 
  #endif   /* PG_USER_MAPPING_H */
--- 46,49 ----
*** a/src/pl/plpgsql/src/pl_comp.c
--- b/src/pl/plpgsql/src/pl_comp.c
***************
*** 19,24 ****
--- 19,25 ----
  
  #include "pl_gram.h"
  
+ #include "catalog/anum.h"
  #include "catalog/namespace.h"
  #include "catalog/pg_attrdef.h"
  #include "catalog/pg_attribute.h"
#2Robert Haas
robertmhaas@gmail.com
In reply to: Robert Haas (#1)
1 attachment(s)
Re: autogenerating headers & bki stuff

On Mon, Jun 29, 2009 at 11:59 PM, Robert Haas<robertmhaas@gmail.com> wrote:

As some of you have probably gathered from a couple of recent patches
that I've posted, I've been taking a look at the scripts we use to
generate various derived files based on the catalog headers, and I
think there's room for improvement.  First, as discussed on previous
threads, it seems needlessly complex to have both perl and
shell-script implementations of genbki and Gen_fmgrtab.   Second,
there's a fair amount of duplicated data that could be auto-generated,
but currently isn't.

The attached patch merges all of the logic currently in genbki.sh and
Gen_fmgrtab.{sh,pl} into a single script called gen_catalog.pl.  It
then extends that logic to generate all of the Anum_* and Natts_*
constants, as well as the Schema_pg_* declarations for the bootstrap
tables.  (I don't see a clean, easy way to generate Schema_pg_index,
since there are no DATA() lines for that table in pg_attribute.h; but
the others are all straightforward.)  It also adds a fair amount of
error checking to what we currently have in place.

In order to avoid create a build-time dependency on Perl for
non-Windows platforms, this patch makes all of the things generated by
gen_catalog.pl into distprep targets.  This should be OK, since none
of them depend on architecture or configuration.

I have not made any attempt to fix the MSVC build to work with this,
but there should be some stuff that can be simplified there as well
(in particular, the Perl reimplementation of genbki).

Updated to CVS HEAD. Peter's commit of my related patch "pg_listener
attribute number #defines" introduced a minor conflict.

...Robert

Attachments:

gen_catalog-v2.patchtext/x-diff; charset=US-ASCII; name=gen_catalog-v2.patchDownload
*** a/src/Makefile.global.in
--- b/src/Makefile.global.in
***************
*** 517,522 **** $(top_builddir)/src/interfaces/ecpg/include/ecpg_config.h: $(top_builddir)/src/i
--- 517,599 ----
  $(top_builddir)/config.status: $(top_srcdir)/configure
  	cd $(top_builddir) && ./config.status --recheck
  
+ # Note: there are some undocumented dependencies on the ordering in which
+ # the catalog header files are assembled into postgres.bki.  In particular,
+ # indexing.h had better be last, and toasting.h just before it.
+ 
+ POSTGRES_BKI_SRCS = $(addprefix $(top_srcdir)/src/include/catalog/,\
+ 	pg_proc.h pg_type.h pg_attribute.h pg_class.h \
+ 	pg_attrdef.h pg_constraint.h pg_inherits.h pg_index.h pg_operator.h \
+ 	pg_opfamily.h pg_opclass.h pg_am.h pg_amop.h pg_amproc.h \
+ 	pg_language.h pg_largeobject.h pg_aggregate.h pg_statistic.h \
+ 	pg_rewrite.h pg_trigger.h pg_listener.h pg_description.h pg_cast.h \
+ 	pg_enum.h pg_namespace.h pg_conversion.h pg_depend.h \
+ 	pg_database.h pg_tablespace.h pg_pltemplate.h \
+ 	pg_authid.h pg_auth_members.h pg_shdepend.h pg_shdescription.h \
+ 	pg_ts_config.h pg_ts_config_map.h pg_ts_dict.h \
+ 	pg_ts_parser.h pg_ts_template.h \
+ 	pg_foreign_data_wrapper.h pg_foreign_server.h pg_user_mapping.h \
+ 	toasting.h indexing.h \
+     )
+ 
+ # Generated header files need dependencies here to ensure that everything
+ # which depends on them gets rebuilt when necessary.  Note that it's important
+ # we match the dependencies shown in the subdirectory makefiles!
+ ifneq ($(subdir),src/backend/parser)
+ $(top_srcdir)/src/backend/parser/gram.h: $(top_srcdir)/src/backend/parser/gram.y
+ 	$(MAKE) -C $(top_builddir)/src/backend/parser gram.h
+ endif
+ 
+ ifneq ($(subdir),src/backend/catalog)
+ # Same logic as pg_config.h and ecpg_config.h
+ $(top_srcdir)/src/backend/catalog/anum.h: $(top_srcdir)/src/backend/catalog/stamp-h;
+ 
+ $(top_srcdir)/src/backend/catalog/fmgroids.h: $(top_srcdir)/src/backend/catalog/stamp-h ;
+ 
+ $(top_srcdir)/src/backend/catalog/schemapg.h: $(top_srcdir)/src/backend/catalog/stamp-h;
+ 
+ $(top_srcdir)/src/backend/catalog/stamp-h: $(top_srcdir)/src/backend/catalog/gen_catalog.pl $(POSTGRES_BKI_SRCS)
+ 	$(MAKE) -C $(top_builddir)/src/backend/catalog stamp-h
+ endif
+ 
+ ifneq ($(subdir),src/backend/utils)
+ $(top_builddir)/src/backend/utils/probes.h: $(top_srcdir)/src/backend/utils/probes.d
+ 	$(MAKE) -C $(top_builddir)/src/backend/utils probes.h
+ endif
+ 
+ # Make symlinks for these headers in the include directory. That way
+ # we can cut down on the -I options. Also, a symlink is automatically
+ # up to date when we update the base file.
+ #
+ # The point of the prereqdir incantation in some of the rules below is to force
+ # the symlink to use an absolute path rather than a relative path.  For headers
+ # which are generated by make distprep, the copy within src/backend will be in
+ # the source tree, and the copy in src/include will be in the build tree.
+ 
+ $(top_builddir)/src/include/parser/gram.h: $(top_srcdir)/src/backend/parser/gram.h
+ 	prereqdir=`cd $(dir $<) >/dev/null && pwd` && \
+ 	  cd $(dir $@) && rm -f $(notdir $@) && \
+ 	  $(LN_S) "$$prereqdir/$(notdir $<)" .
+ 
+ $(top_builddir)/src/include/catalog/anum.h: $(top_srcdir)/src/backend/catalog/anum.h
+ 	prereqdir=`cd $(dir $<) >/dev/null && pwd` && \
+ 	  cd $(dir $@) && rm -f $(notdir $@) && \
+ 	  $(LN_S) "$$prereqdir/$(notdir $<)" .
+ 
+ $(top_builddir)/src/include/utils/fmgroids.h: $(top_srcdir)/src/backend/catalog/fmgroids.h
+ 	prereqdir=`cd $(dir $<) >/dev/null && pwd` && \
+ 	  cd $(dir $@) && rm -f $(notdir $@) && \
+ 	  $(LN_S) "$$prereqdir/$(notdir $<)" .
+ 
+ $(top_builddir)/src/include/catalog/schemapg.h: $(top_srcdir)/src/backend/catalog/schemapg.h
+ 	prereqdir=`cd $(dir $<) >/dev/null && pwd` && \
+ 	  cd $(dir $@) && rm -f $(notdir $@) && \
+ 	  $(LN_S) "$$prereqdir/$(notdir $<)" .
+ 
+ $(top_builddir)/src/include/utils/probes.h: $(top_builddir)/src/backend/utils/probes.h
+ 	cd $(dir $@) && rm -f $(notdir $@) && \
+ 	    $(LN_S) ../../../src/backend/utils/probes.h .
+ 
  endif # not PGXS
  
  
*** a/src/backend/Makefile
--- b/src/backend/Makefile
***************
*** 105,150 **** endif
  endif # aix
  
  # Update the commonly used headers before building the subdirectories
! $(SUBDIRS:%=%-recursive): $(top_builddir)/src/include/parser/gram.h $(top_builddir)/src/include/utils/fmgroids.h $(top_builddir)/src/include/utils/probes.h
! 
  
  # The postgres.o target is needed by the rule in Makefile.global that
  # creates the exports file when MAKE_EXPORTS = true.
  postgres.o: $(OBJS)
  	$(CC) $(LDREL) $(LDFLAGS) $(call expand_subsys,$^) $(LIBS) -o $@
  
- 
- # The following targets are specified in make commands that appear in
- # the make files in our subdirectories. Note that it's important we
- # match the dependencies shown in the subdirectory makefiles!
- 
- $(srcdir)/parser/gram.h: parser/gram.y
- 	$(MAKE) -C parser gram.h
- 
- utils/fmgroids.h: utils/Gen_fmgrtab.sh $(top_srcdir)/src/include/catalog/pg_proc.h
- 	$(MAKE) -C utils fmgroids.h
- 
- utils/probes.h: utils/probes.d
- 	$(MAKE) -C utils probes.h
- 
- # Make symlinks for these headers in the include directory. That way
- # we can cut down on the -I options. Also, a symlink is automatically
- # up to date when we update the base file.
- 
- $(top_builddir)/src/include/parser/gram.h: $(srcdir)/parser/gram.h
- 	prereqdir=`cd $(dir $<) >/dev/null && pwd` && \
- 	  cd $(dir $@) && rm -f $(notdir $@) && \
- 	  $(LN_S) "$$prereqdir/$(notdir $<)" .
- 
- $(top_builddir)/src/include/utils/fmgroids.h: utils/fmgroids.h
- 	cd $(dir $@) && rm -f $(notdir $@) && \
- 	    $(LN_S) ../../../$(subdir)/utils/fmgroids.h .
- 
- $(top_builddir)/src/include/utils/probes.h: utils/probes.h
- 	cd $(dir $@) && rm -f $(notdir $@) && \
- 	    $(LN_S) ../../../$(subdir)/utils/probes.h .
- 
- 
  ifeq ($(PORTNAME), solaris)
  utils/probes.o: utils/probes.d $(SUBDIROBJS)
  	$(DTRACE) $(DTRACEFLAGS) -C -G -s $(call expand_subsys,$^) -o $@
--- 105,117 ----
  endif # aix
  
  # Update the commonly used headers before building the subdirectories
! $(SUBDIRS:%=%-recursive): $(top_builddir)/src/include/parser/gram.h $(top_builddir)/src/include/utils/fmgroids.h $(top_builddir)/src/include/catalog/anum.h $(top_builddir)/src/include/utils/probes.h $(top_builddir)/src/include/catalog/schemapg.h
  
  # The postgres.o target is needed by the rule in Makefile.global that
  # creates the exports file when MAKE_EXPORTS = true.
  postgres.o: $(OBJS)
  	$(CC) $(LDREL) $(LDFLAGS) $(call expand_subsys,$^) $(LIBS) -o $@
  
  ifeq ($(PORTNAME), solaris)
  utils/probes.o: utils/probes.d $(SUBDIROBJS)
  	$(DTRACE) $(DTRACEFLAGS) -C -G -s $(call expand_subsys,$^) -o $@
***************
*** 157,162 **** distprep:
--- 124,131 ----
  	$(MAKE) -C parser	gram.c gram.h scan.c
  	$(MAKE) -C bootstrap	bootparse.c bootscanner.c
  	$(MAKE) -C utils/misc	guc-file.c
+ 	$(MAKE) -C catalog	postgres.bki postgres.description \
+ 		postgres.shdescription anum.h fmgroids.h fmgrtab.c schemapg.h
  
  
  ##########################################################################
*** a/src/backend/access/common/reloptions.c
--- b/src/backend/access/common/reloptions.c
***************
*** 19,24 ****
--- 19,25 ----
  #include "access/hash.h"
  #include "access/nbtree.h"
  #include "access/reloptions.h"
+ #include "catalog/anum.h"
  #include "catalog/pg_type.h"
  #include "commands/defrem.h"
  #include "nodes/makefuncs.h"
*** /dev/null
--- b/src/backend/catalog/.cvsignore
***************
*** 0 ****
--- 1,2 ----
+ fmgrtab.c
+ fmgroids.h
*** a/src/backend/catalog/Makefile
--- b/src/backend/catalog/Makefile
***************
*** 10,54 **** subdir = src/backend/catalog
  top_builddir = ../../..
  include $(top_builddir)/src/Makefile.global
  
! OBJS = catalog.o dependency.o heap.o index.o indexing.o namespace.o aclchk.o \
!        pg_aggregate.o pg_constraint.o pg_conversion.o pg_depend.o pg_enum.o \
!        pg_inherits.o pg_largeobject.o pg_namespace.o pg_operator.o pg_proc.o \
!        pg_shdepend.o pg_type.o storage.o toasting.o
  
  BKIFILES = postgres.bki postgres.description postgres.shdescription
  
  include $(top_srcdir)/src/backend/common.mk
  
! all: $(BKIFILES)
! 
! # Note: there are some undocumented dependencies on the ordering in which
! # the catalog header files are assembled into postgres.bki.  In particular,
! # indexing.h had better be last, and toasting.h just before it.
! 
! POSTGRES_BKI_SRCS = $(addprefix $(top_srcdir)/src/include/catalog/,\
! 	pg_proc.h pg_type.h pg_attribute.h pg_class.h \
! 	pg_attrdef.h pg_constraint.h pg_inherits.h pg_index.h pg_operator.h \
! 	pg_opfamily.h pg_opclass.h pg_am.h pg_amop.h pg_amproc.h \
! 	pg_language.h pg_largeobject.h pg_aggregate.h pg_statistic.h \
! 	pg_rewrite.h pg_trigger.h pg_listener.h pg_description.h pg_cast.h \
! 	pg_enum.h pg_namespace.h pg_conversion.h pg_depend.h \
! 	pg_database.h pg_tablespace.h pg_pltemplate.h \
! 	pg_authid.h pg_auth_members.h pg_shdepend.h pg_shdescription.h \
! 	pg_ts_config.h pg_ts_config_map.h pg_ts_dict.h \
! 	pg_ts_parser.h pg_ts_template.h \
! 	pg_foreign_data_wrapper.h pg_foreign_server.h pg_user_mapping.h \
! 	toasting.h indexing.h \
!     )
  
  pg_includes = $(sort -I$(top_srcdir)/src/include -I$(top_builddir)/src/include)
  
! # see explanation in ../parser/Makefile
! postgres.description: postgres.bki ;
  
! postgres.shdescription: postgres.bki ;
  
! postgres.bki: genbki.sh $(POSTGRES_BKI_SRCS) $(top_builddir)/src/include/pg_config_manual.h
! 	AWK='$(AWK)' $(SHELL) $< $(pg_includes) --set-version=$(VERSION) -o postgres $(POSTGRES_BKI_SRCS)
  
  .PHONY: install-data
  install-data: $(BKIFILES) installdirs
--- 10,47 ----
  top_builddir = ../../..
  include $(top_builddir)/src/Makefile.global
  
! OBJS = catalog.o dependency.o fmgrtab.o heap.o index.o indexing.o namespace.o \
! 	   aclchk.o pg_aggregate.o pg_constraint.o pg_conversion.o pg_depend.o \
! 	   pg_enum.o pg_inherits.o pg_largeobject.o pg_namespace.o pg_operator.o \
! 	   pg_proc.o pg_shdepend.o pg_type.o storage.o toasting.o
  
  BKIFILES = postgres.bki postgres.description postgres.shdescription
  
  include $(top_srcdir)/src/backend/common.mk
  
! all: $(addprefix $(srcdir)/, $(BKIFILES) anum.h fmgroids.h fmgrtab.c schemapg.h)
  
  pg_includes = $(sort -I$(top_srcdir)/src/include -I$(top_builddir)/src/include)
  
! # see src/backend/parser/Makefile for notes on dependency chaining for multiple
! # output files; see src/Makefile.global.in for notes on how stamp-h files are
! # used
! $(srcdir)/postgres.bki: $(srcdir)/stamp-h ;
  
! $(srcdir)/postgres.description: $(srcdir)/stamp-h ;
  
! $(srcdir)/postgres.shdescription: $(srcdir)/stamp-h ;
! 
! $(srcdir)/anum.h: $(srcdir)/stamp-h ;
! 
! $(srcdir)/fmgroids.h: $(srcdir)/stamp-h ;
! 
! $(srcdir)/fmgrtab.c: $(srcdir)/stamp-h ;
! 
! $(srcdir)/schemapg.h: $(srcdir)/stamp-h ;
! 
! $(srcdir)/stamp-h: gen_catalog.pl $(POSTGRES_BKI_SRCS) $(top_builddir)/src/include/pg_config_manual.h
! 	$(PERL) $< $(pg_includes) -o $(srcdir) --set-version=$(VERSION) $(POSTGRES_BKI_SRCS)
  
  .PHONY: install-data
  install-data: $(BKIFILES) installdirs
***************
*** 66,70 **** installdirs:
  uninstall-data:
  	rm -f $(addprefix '$(DESTDIR)$(datadir)'/, $(BKIFILES) system_views.sql information_schema.sql sql_features.txt)
  
! clean:
! 	rm -f $(BKIFILES)
--- 59,64 ----
  uninstall-data:
  	rm -f $(addprefix '$(DESTDIR)$(datadir)'/, $(BKIFILES) system_views.sql information_schema.sql sql_features.txt)
  
! # postgres.bki, postgres.description, postgres.shdescription, anum.h,
! # fmgroids.h, fmgrtab.c, and schemapg.h are in the distribution tarball, so
! # they are not cleaned here.
*** a/src/backend/catalog/aclchk.c
--- b/src/backend/catalog/aclchk.c
***************
*** 21,26 ****
--- 21,27 ----
  #include "access/heapam.h"
  #include "access/sysattr.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/catalog.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
*** a/src/backend/catalog/dependency.c
--- b/src/backend/catalog/dependency.c
***************
*** 18,23 ****
--- 18,24 ----
  #include "access/heapam.h"
  #include "access/sysattr.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/dependency.h"
  #include "catalog/heap.h"
  #include "catalog/index.h"
*** /dev/null
--- b/src/backend/catalog/gen_catalog.pl
***************
*** 0 ****
--- 1,594 ----
+ #!/usr/bin/perl
+ 
+ #
+ # gen_catalog.pl
+ #
+ # Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
+ # Portions Copyright (c) 1994, Regents of the University of California
+ #
+ 
+ use strict;
+ use warnings;
+ 
+ #
+ # The purpose of this script is to generate as many of the files derived from
+ # the catalogs as possible in one script.  Since this script is written in
+ # Perl, it can be used under either Windows or UNIX-ish systems.  On the flip
+ # side, because none of what we generate here depends on architecture or
+ # configuration, we can build it all at distprep time so that, on UNIX, it
+ # is possible to build from an unmodified distribution tarball without Perl.
+ #
+ # However, if any of the relevant headers are modified, or when building from
+ # CVS (or git), Perl will be required, as this script must be rerun.
+ #
+ my @OUTPUT = (
+ 	[ 'postgres.bki', \*BKI ],
+ 	[ 'postgres.description', \*DESCR ],
+ 	[ 'postgres.shdescription', \*SHDESCR ],
+ 	[ 'anum.h', \*ANUM ],
+ 	[ 'fmgroids.h', \*FMGROIDS ],
+ 	[ 'fmgrtab.c', \*FMGRTAB ],
+ 	[ 'schemapg.h', \*SCHEMAPG ],
+ );
+ 
+ #
+ # There are a few types which are given one name in the C source, but a
+ # different name at the SQL level.  These are enumerated here.
+ #
+ my %RENAME_ATTTYPE = (
+ 	'Oid' => 'oid',
+ 	'NameData' => 'name',
+ 	'TransactionId' => 'xid'
+ );
+ 
+ #
+ # Argument parsing.  We could use GetOpt::Long or similar here, but doing it
+ # this way avoids depending on any outside modules.
+ #
+ my @include_path;
+ my @input_file;
+ my $output_path = '';
+ my $major_version;
+ while (@ARGV) {
+ 	my $arg = shift @ARGV;
+ 	if ($arg !~ /^-/) {
+ 		push @input_file, $arg;
+ 	}
+ 	elsif ($arg =~ /^-o/) {
+ 		$output_path = length($arg) > 2 ? substr($arg, 2) : shift @ARGV;
+ 	}
+ 	elsif ($arg =~ /^-I/) {
+ 		push @include_path, length($arg) > 2 ? substr($arg, 2) : shift @ARGV;
+ 	}
+ 	elsif ($arg =~ /^--set-version=(.*)$/) {
+ 		$major_version = $1;
+ 		# Remove minor version information, if any.
+ 		if ($major_version =~ /^(\d+.\d+)/) {
+ 			$major_version = $1;
+ 		}
+ 	}
+ 	else {
+ 		usage();
+ 	}
+ }
+ 
+ # Sanity check arguments.
+ die "No input files.\n" if ! @input_file;
+ die "No include path; you must specify -I at least once.\n" if ! @include_path;
+ die "No version specified.\n" if !defined $major_version;
+ 
+ #
+ # CAUTION: be wary about what symbols you substitute into the .bki file here!
+ # It's okay to substitute things that are expected to be really constant
+ # within a given Postgres release, such as fixed OIDs.  Do not substitute
+ # anything that could depend on platform or configuration.  (The right place
+ # to handle those sorts of things is in initdb.c's bootstrap_template1().)
+ #
+ my $BOOTSTRAP_SUPERUSERID =
+ 	find_defined_symbol('pg_authid.h', 'BOOTSTRAP_SUPERUSERID');
+ my $PG_CATALOG_NAMESPACE =
+ 	find_defined_symbol('pg_namespace.h', 'PG_CATALOG_NAMESPACE');
+ my $INTERNAL_LANGUAGE_ID =
+ 	find_defined_symbol('pg_language.h', 'INTERNALlanguageId');
+ 
+ # Make sure output_path ends in a slash.
+ if ($output_path ne '' && substr($output_path, -1) ne '/') {
+ 	$output_path .= '/';
+ }
+ 
+ # Open temporary output files.
+ for my $output (@OUTPUT) {
+ 	my $temp_name = $output_path . $output->[0] . '.tmp';
+ 	# We avoid using the three-argument form of open() here, because it is
+ 	# only supported in Perl 5.6 and higher.
+ 	open($output->[1], ">$temp_name") || die "$temp_name: $!";
+ }
+ 
+ # Opening boilerplate for postgres.bki
+ print BKI "# PostgreSQL $major_version\n";
+ 
+ # Opening boilerplate for fmgroids.h
+ print FMGROIDS <<EOM;
+ /*-------------------------------------------------------------------------
+  *
+  * fmgroids.h
+  *    Macros that define the OIDs of built-in functions.
+  *
+  * These macros can be used to avoid a catalog lookup when a specific
+  * fmgr-callable function needs to be referenced.
+  *
+  * Portions Copyright (c) 1996-2009, 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 $0
+  *	from pg_proc.h
+  *
+  *-------------------------------------------------------------------------
+  */
+ #ifndef FMGROIDS_H
+ #define FMGROIDS_H
+ 
+ /*
+  *	Constant macros for the OIDs of entries in pg_proc.
+  *
+  *	NOTE: macros are named after the prosrc value, ie the actual C name
+  *	of the implementing function, not the proname which may be overloaded.
+  *	For example, we want to be able to assign different macro names to both
+  *	char_text() and name_text() even though these both appear with proname
+  *	'text'.  If the same C function appears in more than one pg_proc entry,
+  *	its equivalent macro will be defined with the lowest OID among those
+  *	entries.
+  */
+ EOM
+ 
+ # Opening boilerplate for fmgrtab.c
+ print FMGRTAB <<EOM;
+ /*-------------------------------------------------------------------------
+  *
+  * fmgrtab.c
+  *    The function manager's table of internal functions.
+  *
+  * Portions Copyright (c) 1996-2009, 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 $0
+  *	from pg_proc.h
+  *
+  *-------------------------------------------------------------------------
+  */
+ 
+ #include "postgres.h"
+ 
+ #include "utils/fmgrtab.h"
+ 
+ EOM
+ 
+ # Opening boilerplate for anum.h
+ print ANUM <<EOM;
+ /*-------------------------------------------------------------------------
+  *
+  * anum.h
+  *    Macros that define the number of attributes in each system catalog
+  *    table and the attribute number for each column name.
+  *
+  * Portions Copyright (c) 1996-2009, 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 $0
+  *
+  *-------------------------------------------------------------------------
+  */
+ #ifndef ANUM_H
+ #define ANUM_H
+ 
+ EOM
+ 
+ # Opening boilerplate for schemapg.h
+ print SCHEMAPG <<EOM;
+ /*-------------------------------------------------------------------------
+  *
+  * schemapg.h
+  *    Schema_pg_xxx macros for use by relcache.c
+  *
+  * Portions Copyright (c) 1996-2009, 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 $0
+  *
+  *-------------------------------------------------------------------------
+  */
+ #ifndef SCHEMAPG_H
+ #define SCHEMAPG_H
+ 
+ EOM
+ 
+ # Main part of the work: read and process each header file.
+ my (@fmgr, %schema_pg, %catalog_name);
+ for my $input_file (@input_file)
+ {
+ 	process_input_file($input_file);
+ }
+ 
+ # We're going to iterate over this array twice and it needs to be in sorted
+ # order both times.
+ @fmgr = sort { $a->{'oid'} <=> $b->{'oid'} } @fmgr;
+ 
+ # Emit fmgr #define's and extern's, but only one per prosrc value.
+ my %fmgr_seenit;
+ foreach my $s (@fmgr) {
+ 	next if $fmgr_seenit{$s->{'prosrc'}};
+ 	$fmgr_seenit{$s->{'prosrc'}} = 1;
+ 	print FMGROIDS "#define F_" . uc($s->{'prosrc'}) . " $s->{oid}\n";
+ 	print FMGRTAB "extern Datum " . $s->{'prosrc'} . " (PG_FUNCTION_ARGS);\n";
+ }
+ 
+ # Emit fmgr_builtins table.
+ print FMGRTAB "\nconst FmgrBuiltin fmgr_builtins[] = {\n";
+ my %bmap;
+ $bmap{'t'} = 'true';
+ $bmap{'f'} = 'false';
+ foreach my $s (@fmgr) {
+     print FMGRTAB join('',
+ 		'  { ', $s->{'oid'}, ', "', $s->{'prosrc'}, '", ', $s->{'nargs'},
+ 		', ', $bmap{$s->{'strict'}}, ', ', $bmap{$s->{'retset'}}, ', ',
+ 		$s->{'prosrc'}, " },\n");
+ }
+ 
+ # Emit Schema_pg_xxx declarations.
+ while (my ($oid, $entry_list) = each %schema_pg) {
+ 	my $catalog = $catalog_name{$oid};
+ 	die "catalog with oid $oid not found" if !defined $catalog;
+ 	print SCHEMAPG "#define Schema_$catalog \\\n",
+ 		join(", \\\n", @$entry_list), "\n\n";
+ }
+ 
+ # Closing boilerplate for fmgroids.h
+ print FMGROIDS "\n#endif /* FMGROIDS_H */\n";
+ 
+ # Closing boilerplate for fmgrtab.c
+ print FMGRTAB <<EOM;
+   /* dummy entry is easier than getting rid of comma after last real one */
+   /* (not that there has ever been anything wrong with *having* a
+      comma after the last field in an array initializer) */
+   { 0, NULL, 0, false, false, NULL }
+ };
+ 
+ /* Note fmgr_nbuiltins excludes the dummy entry */
+ const int fmgr_nbuiltins = (sizeof(fmgr_builtins) / sizeof(FmgrBuiltin)) - 1;
+ EOM
+ 
+ # Closing boilerplate for anum.h
+ print ANUM "#endif /* ANUM_H */\n";
+ 
+ # Closing boilerplate for schemapg.h
+ print SCHEMAPG "#endif /* SCHEMAPG_H */\n";
+ 
+ # Close output files.
+ for my $output (@OUTPUT) {
+ 	my $temp_name = $output_path . $output->[0] . '.tmp';
+ 	close($output->[1]) || die "close: $temp_name: $!";
+ }
+ 
+ # Rename temporary files to final names, if anything has changed.
+ for my $output (@OUTPUT) {
+ 	my $temp_name = $output_path . $output->[0] . '.tmp';
+ 	my $final_name = $output_path . $output->[0];
+ 	if (-e $final_name && -s $temp_name == -s $final_name) {
+ 		open(TN, "<$temp_name") || die "$temp_name: $!";
+ 		if (open(FN, "<$temp_name")) {
+ 			local $/ = undef;
+ 			my $tn = <TN>;
+ 			my $fn = <FN>;
+ 			close(FN);
+ 			if ($tn eq $fn) {
+ 				print "$output->[0] unchanged, not replacing\n";
+ 				close(TN);
+ 				unlink($temp_name) || die "unlink: $temp_name: $!";
+ 				next;
+ 			}
+ 		}
+ 		close(TN);
+ 	}
+ 	rename($temp_name, $final_name) || die "rename: $temp_name: $!";
+ }
+ 
+ # Update timestamp file.  Makefile system uses this to avoid unnecessary
+ # rebuilds.
+ open(STAMP, ">$output_path/stamp-h") || die "stamp-h: $!";
+ close(STAMP);
+ 
+ exit 0;
+ 
+ #
+ # Read and process a single input file.
+ #
+ sub process_input_file {
+ 	my ($input_file) = @_;
+ 	open(INPUT_FILE, "<$input_file") || die "$input_file: $!";
+ 
+ 	# State we need to keep track of while scanning the file.
+ 	my ($oid, $catalog, $is_bootstrap, $declaring_attributes, $reln_open);
+ 	my (@bki_attr, @attname, %attname_to_attnum, %attname_to_atttype);
+ 
+ 	# Scan the input file.
+ 	while (<INPUT_FILE>) {
+ 		# Strip C-style comments.
+ 		s;/\*(.|\n)*\*/;;g;
+ 		if (m;/\*;) {
+ 			my $next_line = <INPUT_FILE>;
+ 			die "$input_file: ends within C-style comment\n"
+ 				if !defined $next_line;
+ 			$_ .= $next_line;
+ 			redo;
+ 		}
+ 
+ 		# Strip useless whitespace and trailing semicolons.
+ 		chomp;
+ 		s/^\s+//;
+ 		s/;\s*$//;
+ 		s/\s+/ /g;
+ 
+ 		#
+ 		# DATA lines are passed through to postgres.bki after stripping off
+ 		# the DATA( and the ) on the end.  Remember the OID for use by
+ 		# DESCR() and SHDESCR().
+ 		#
+ 		# In addition, when processing pg_proc.h, we extract all of the
+ 		# "internal" functions and save them so that we can eventually write
+ 		# them out to fmgroids.h and fmgrtab.h.
+ 		#
+ 		if (/^DATA\((insert(\s+OID\s+=\s+(\d+))?\s+\((.*)\))\s*\)$/) {
+ 			my ($data, $field_data) = ($1, $4);
+ 			# Save the OID, if any, for reference by a subsequent DESCR() or
+ 			# SHDESCR() declaration.
+ 			$oid = $3;
+ 			# Pass the (almost) raw data through to postgres.bki.
+ 			$data =~ s/\bPGUID\b/$BOOTSTRAP_SUPERUSERID/g;
+ 			$data =~ s/\bPGNSP\b/$PG_CATALOG_NAMESPACE/g;
+ 			print BKI $data, "\n";
+ 			# To construct fmgroids.h and fmgrtab.c, we need to inspect some
+ 			# of the individual data fields.  Just splitting on whitespace
+ 			# won't work, because some quoted fields might contain internal
+ 			# whitespace.  We handle this by folding them all to a simple
+ 			# "xxx". Fortunately, this script doesn't need to look at any
+ 			# fields that might need quoting, so this simple hack is
+ 			# sufficient.
+ 			if (defined $catalog) {
+ 				$field_data =~ s/^\s+//;
+ 				$field_data =~ s/"[^"]*"/"xxx"/g;
+ 				my @p = split /\s+/, $field_data;
+ 				# Emit fmgr declarations for non-internal functions.
+ 				if ($catalog eq 'pg_proc'
+ 					&& $p[$attname_to_attnum{'prolang'}-1] eq '12') {
+ 				    push @fmgr, {
+ 				        'oid'     => $oid,
+ 				        'proname' => $p[$attname_to_attnum{'proname'}-1],
+ 				        'strict'  => $p[$attname_to_attnum{'proisstrict'}-1],
+ 				        'retset'  => $p[$attname_to_attnum{'proretset'}-1],
+ 				        'nargs'   => $p[$attname_to_attnum{'pronargs'}-1],
+ 				        'prosrc'  => $p[$attname_to_attnum{'prosrc'}-1],
+ 					};
+ 				}
+ 				# Emit Schema_pg info for non-system attributes.
+ 				elsif ($catalog eq 'pg_attribute'
+ 					&& $p[$attname_to_attnum{'attnum'}-1] > 0) {
+ 					if (@attname != @p) {
+ 						die sprintf "catalog has %d attributes, DATA() has "
+ 							. "%d entries\n", 0+@attname, 0+@p;
+ 					}
+ 					my @cvalue;
+ 					for (my $i = 0; $i < @p; ++$i) {
+ 						my $attname = $attname[$i];
+ 						my $atttype = $attname_to_atttype{$attname};
+ 						if (grep { $atttype eq $_ } qw(oid int2 int4)) {
+ 							push @cvalue, $p[$i];
+ 						}
+ 						elsif ($atttype eq 'aclitem[]') {
+ 							if ($p[$i] ne '_null_') {
+ 								die "can't handle non-null aclitem[]: $p[$i]";
+ 							}
+ 							push @cvalue, '{ 0 }';
+ 						}
+ 						elsif ($atttype eq 'bool') {
+ 							if ($p[$i] eq 't') {
+ 								push @cvalue, 'true';
+ 							}
+ 							elsif ($p[$i] eq 'f') {
+ 								push @cvalue, 'false';
+ 							}
+ 							else {
+ 								# May be a constant, like FLOAT4PASSBYVAL.
+ 								push @cvalue, $p[$i];
+ 							}
+ 						}
+ 						elsif ($atttype eq 'char') {
+ 							push @cvalue, "'$p[$i]'";
+ 						}
+ 						elsif ($atttype eq 'name') {
+ 							push @cvalue, "{\"$p[$i]\"}";
+ 						}
+ 						else {
+ 							die "unhandled type $atttype";
+ 						}
+ 					}
+ 				    my $attrelid = $p[$attname_to_attnum{'attrelid'}-1];
+ 					push @{$schema_pg{$attrelid}},
+ 						"{ " . join(", ", @cvalue) . " }";
+ 				}
+ 			}
+ 		}
+ 		# DESCR() and SHDESCR() lines apply to the most recent catalog
+ 		# and OID.
+ 		elsif (/^DESCR\(\"(.*)\"\)$/) {
+ 			my $data = $1;
+ 			if (!defined $catalog) {
+ 				die "DESCR() does not apply to any catalog ($input_file)";
+ 			}
+ 			elsif (!defined $oid) {
+ 				die "DESCR() does not apply to any oid ($input_file)";
+ 			}
+ 			elsif ($data ne '') {
+ 				printf DESCR "%d\t%s\t0\t%s\n", $oid, $catalog, $data;
+ 			}
+ 		}
+ 		elsif (/^SHDESCR\(\"(.*)\"\)$/) {
+ 			my $data = $1;
+ 			if (!defined $catalog) {
+ 				die "SHDESCR() does not apply to any catalog ($input_file)";
+ 			}
+ 			elsif (!defined $oid) {
+ 				die "SHDESCR() does not apply to any oid ($input_file)";
+ 			}
+ 			elsif ($data ne '') {
+ 				printf SHDESCR "%d\t%s\t%s\n", $oid, $catalog, $data;
+ 			}
+ 		}
+ 		elsif (/^DECLARE_(UNIQUE_)?INDEX\((\s*[\w+]*),\s*(\d+),\s*(.*)\)/) {
+ 			my ($is_unique, $iname, $oid, $data) = ($1, $2, $3, $4);
+ 			# close catalog before declaring index
+ 			if ($reln_open) {
+ 				$reln_open = 0;
+ 				print BKI "close $catalog\n";
+ 			}
+ 			printf BKI "declare %sindex %s %s %s\n",
+ 				$is_unique ? "unique " : "", $iname, $oid, $data;
+ 		}
+ 		elsif (/^DECLARE_TOAST\((\s*[\w+]*),\s*(\d+),\s*(\d+)\)/) {
+ 			my ($toastname, $toastoid, $indexoid) = ($1, $2, $3);
+ 			# close catalog before declaring toast
+ 			if ($reln_open) {
+ 				$reln_open = 0;
+ 				print BKI "close $catalog\n";
+ 			}
+ 			print BKI "declare toast $toastoid $indexoid on $toastname\n";
+ 		}
+ 		elsif (/^BUILD_INDICES/) {
+ 			print BKI "build indices\n";
+ 		}
+ 		elsif (/^CATALOG\(([^,]*),(.*)\)/) {
+ 			my ($catname, $catoid) = ($1, $2);
+ 			# close catalog before declaring next catalog
+ 			if ($reln_open) {
+ 				$reln_open = 0;
+ 				print BKI "close $catalog\n";
+ 			}
+ 			$catalog = $catname;
+ 			$is_bootstrap = /BKI_BOOTSTRAP/;
+ 			print BKI "create " . ($is_bootstrap ? 'bootstrap ' : '')
+ 				. (/BKI_SHARED_RELATION/ ? 'shared_relation ' : '')
+ 				. (/BKI_WITHOUT_OIDS/ ? 'without_oids ' : '')
+ 				. $catalog . ' ' . $catoid . "\n";
+ 			$declaring_attributes = 1;
+ 			undef %attname_to_attnum;
+ 			undef %attname_to_atttype;
+ 			undef @attname;
+ 			$catalog_name{$catoid} = $catname;
+ 		}
+ 		elsif ($declaring_attributes) {
+ 			if ($_ =~ /^{|^$/) {
+ 				;							# just ignore it
+ 			}
+ 			elsif ($_ =~ /^}/)	{
+ 				print BKI " (\n", join(" ,\n", @bki_attr), "\n )\n";
+ 				printf ANUM "#define Natts_%s\t\t%d\n\n",
+ 					$catalog, 0+@bki_attr;
+ 				if (! $is_bootstrap) {
+ 					print BKI "open $catalog\n";
+ 				}
+ 				undef $declaring_attributes;
+ 				$reln_open = 1;
+ 			}
+ 			else {
+ 				my @datafields = split /\s+/, $_;
+ 				my $atttype = $datafields[0];
+ 				my $attname;
+ 				if (exists $RENAME_ATTTYPE{$atttype}) {
+ 					$atttype = $RENAME_ATTTYPE{$atttype};
+ 				}
+ 		        if ($datafields[1] =~ /(.*)\[.*\]/) {   # array attribute
+ 	                $attname = $1;
+ 	                $atttype .= "[]";  					# variable-length only
+ 				}
+ 				else {
+ 					$attname = $datafields[1];
+ 				}
+ 				push @bki_attr, " $attname = $atttype";
+ 				printf ANUM "#define Anum_%s_%s\t\t%d\n",
+ 					$catalog, $attname, 0+@bki_attr;
+ 				push @attname, $attname;
+ 				$attname_to_attnum{$attname} = 0+@bki_attr;
+ 				$attname_to_atttype{$attname} = $atttype;
+ 			}
+ 		}
+ 		elsif (/^(DATA|CATALOG|DECLARE_(INDEX|UNIQUE_INDEX|TOAST))/) {
+ 			die "malformed $1 line ($input_file)";
+ 		}
+ 	}
+ 	if ($reln_open) {
+ 		print BKI "close $catalog\n";
+ 	}
+ 	close(INPUT_FILE);
+ }
+ 
+ #
+ # Find a symbol defined in a particular header file and extract the value.
+ #
+ sub find_defined_symbol {
+ 	my ($catalog_header, $symbol) = @_;
+ 	for my $path (@include_path) {
+ 		my $file = $path . '/catalog/' . $catalog_header;
+ 		next if ! -f $file;
+ 		# We avoid using the three-argument form of open() here, because it is
+ 		# only supported in Perl 5.6 and higher.
+ 		open(FIND_DEFINED_SYMBOL, "<$file") || die "$file: $!";
+ 		while (<FIND_DEFINED_SYMBOL>) {
+ 			if (/^#define\s+\Q$symbol\E\s+(\S+)/) {
+ 				return $1;
+ 			}
+ 		}
+ 		close(FIND_DEFINED_SYMBOL);
+ 		die "$file: no definition found for $symbol\n";
+ 	}
+ 	die "$catalog_header: not found in any include directory\n";
+ }
+ 
+ #
+ # Display usage message and exit.
+ #
+ sub usage
+ {
+ 	die <<EOM;
+ Usage: genbki.pl [options] header...
+ 
+ Options:
+ 	-I				path to include files
+ 	--bki			prefix for BKI output files
+ 	--set-version	PostgreSQL version number for initdb cross-check
+ 
+ genbki.pl generates .bki files from specially formatted .h files.  These .bki
+ files are used to initialize the postgres template database.
+ 
+ Report bugs to <pgsql-bugs\@postgresql.org>.
+ EOM
+ }
*** a/src/backend/catalog/genbki.sh
--- /dev/null
***************
*** 1,430 ****
- #! /bin/sh
- #-------------------------------------------------------------------------
- #
- # genbki.sh--
- #    shell script which generates .bki files from specially formatted .h
- #    files.  These .bki files are used to initialize the postgres template
- #    database.
- #
- # Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
- # Portions Copyright (c) 1994, Regents of the University of California
- #
- #
- # IDENTIFICATION
- #    $PostgreSQL$
- #
- # NOTES
- #    non-essential whitespace is removed from the generated file.
- #    if this is ever a problem, then the sed script at the very
- #    end can be changed into another awk script or something smarter.
- #
- #-------------------------------------------------------------------------
- 
- : ${AWK='awk'}
- 
- CMDNAME=`basename $0`
- 
- INCLUDE_DIRS=
- OUTPUT_PREFIX=
- INFILES=
- major_version=
- 
- #
- # Process command line switches.
- #
- while [ $# -gt 0 ]
- do
-     case $1 in
-         -I)
-             INCLUDE_DIRS="$INCLUDE_DIRS $2"
-             shift;;
-         -I*)
-             arg=`echo $1 | sed -e 's/^-I//'`
-             INCLUDE_DIRS="$INCLUDE_DIRS $arg"
-             ;;
-         -o)
-             OUTPUT_PREFIX="$2"
-             shift;;
-         -o*)
-             OUTPUT_PREFIX=`echo $1 | sed -e 's/^-o//'`
-             ;;
-         --set-version=*)
-             arg=`expr x"$1" : x"--set-version=\(.*\)"`
-             major_version=`expr x"$arg" : x'\([0-9][0-9]*\.[0-9][0-9]*\)'`
-             ;;
-         --help)
-             echo "$CMDNAME generates system catalog bootstrapping files."
-             echo
-             echo "Usage:"
-             echo "  $CMDNAME [ -I dir ] --set-version=VERSION -o prefix files..."
-             echo
-             echo "Options:"
-             echo "  -I  path to include files"
-             echo "  -o  prefix of output files"
-             echo "  --set-version  PostgreSQL version number for initdb cross-check"
-             echo
-             echo "The environment variable AWK determines which Awk program"
-             echo "to use. The default is \`awk'."
-             echo
-             echo "Report bugs to <pgsql-bugs@postgresql.org>."
-             exit 0
-             ;;
-         -*)
-             echo "$CMDNAME: invalid option: $1"
-             exit 1
-             ;;
-         *)
-             INFILES="$INFILES $1"
-             ;;
-     esac
-     shift
- done
- 
- if [ x"$INFILES" = x"" ] ; then
-     echo "$CMDNAME: no input files" 1>&2
-     exit 1
- fi
- 
- if [ x"$OUTPUT_PREFIX" = x"" ] ; then
-     echo "$CMDNAME: no output prefix specified" 1>&2
-     exit 1
- fi
- 
- if [ x"$INCLUDE_DIRS" = x"" ] ; then
-     echo "$CMDNAME: path to include directory unknown" 1>&2
-     exit 1
- fi
- 
- if [ x"$major_version" = x"" ] ; then
-     echo "$CMDNAME: invalid or no version number specified" 1>&2
-     exit 1
- fi
- 
- 
- TMPFILE="genbkitmp$$.c"
- 
- trap "rm -f $TMPFILE ${OUTPUT_PREFIX}.bki.$$ ${OUTPUT_PREFIX}.description.$$ ${OUTPUT_PREFIX}.shdescription.$$" 0 1 2 3 15
- 
- 
- # CAUTION: be wary about what symbols you substitute into the .bki file here!
- # It's okay to substitute things that are expected to be really constant
- # within a given Postgres release, such as fixed OIDs.  Do not substitute
- # anything that could depend on platform or configuration.  (The right place
- # to handle those sorts of things is in initdb.c's bootstrap_template1().)
- 
- # Get BOOTSTRAP_SUPERUSERID from catalog/pg_authid.h
- for dir in $INCLUDE_DIRS; do
-     if [ -f "$dir/catalog/pg_authid.h" ]; then
-         BOOTSTRAP_SUPERUSERID=`grep '^#define[ 	]*BOOTSTRAP_SUPERUSERID' $dir/catalog/pg_authid.h | $AWK '{ print $3 }'`
-         break
-     fi
- done
- 
- # Get PG_CATALOG_NAMESPACE from catalog/pg_namespace.h
- for dir in $INCLUDE_DIRS; do
-     if [ -f "$dir/catalog/pg_namespace.h" ]; then
-         PG_CATALOG_NAMESPACE=`grep '^#define[ 	]*PG_CATALOG_NAMESPACE' $dir/catalog/pg_namespace.h | $AWK '{ print $3 }'`
-         break
-     fi
- done
- 
- touch ${OUTPUT_PREFIX}.description.$$
- touch ${OUTPUT_PREFIX}.shdescription.$$
- 
- # ----------------
- # 	Strip comments and other trash from .h
- #
- #	Put multi-line start/end comments on a separate line
- #
- #	Rename datatypes that have different names in .h files than in SQL
- #
- #	Substitute values of configuration constants
- # ----------------
- #
- cat $INFILES | \
- sed -e 's;/\*.*\*/;;g' \
-     -e 's;/\*;\
- /*\
- ;g' \
-     -e 's;\*/;\
- */\
- ;g' | # we must run a new sed here to see the newlines we added
- sed -e "s/;[ 	]*$//g" \
-     -e "s/^[ 	]*//" \
-     -e "s/[ 	]Oid/ oid/g" \
-     -e "s/^Oid/oid/g" \
-     -e "s/(Oid/(oid/g" \
-     -e "s/[ 	]NameData/ name/g" \
-     -e "s/^NameData/name/g" \
-     -e "s/(NameData/(name/g" \
-     -e "s/[ 	]TransactionId/ xid/g" \
-     -e "s/^TransactionId/xid/g" \
-     -e "s/(TransactionId/(xid/g" \
-     -e "s/PGUID/$BOOTSTRAP_SUPERUSERID/g" \
-     -e "s/PGNSP/$PG_CATALOG_NAMESPACE/g" \
- | $AWK '
- # ----------------
- #	now use awk to process remaining .h file..
- #
- #	nc is the number of catalogs
- #	inside is a variable set to 1 when we are scanning the
- #	   contents of a catalog definition.
- #	reln_open is a flag indicating when we are processing DATA lines.
- #	   (i.e. have a relation open and need to close it)
- #	oid is the most recently seen oid, or 0 if none in the last DATA line.
- # ----------------
- BEGIN {
- 	inside = 0;
- 	bootstrap = "";
- 	shared_relation = "";
- 	without_oids = "";
- 	nc = 0;
- 	reln_open = 0;
- 	comment_level = 0;
- 	oid = 0;
- }
- 
- # ----------------
- # Anything in a /* .. */ block should be ignored.
- # Blank lines also go.
- # Note that any /* */ comment on a line by itself was removed from the line
- # by the sed above.
- # ----------------
- /^\/\*/           { comment_level += 1; next; }
- /^\*\//           { comment_level -= 1; next; }
- comment_level > 0 { next; }
- 
- /^[ 	]*$/      { next; }
- 
- # ----------------
- #	DATA() statements are basically passed right through after
- #	stripping off the DATA( and the ) on the end.
- #	Remember the OID for use by DESCR() and SHDESCR().
- # ----------------
- /^DATA\(/ {
- 	data = substr($0, 6, length($0) - 6);
- 	oid = 0;
- 	nf = split(data, datafields);
- 	if (nf >= 4 && datafields[1] == "insert" && datafields[2] == "OID" && datafields[3] == "=")
- 	{
- 		oid = datafields[4];
- 	}
- 	print data;
- 	next;
- }
- 
- /^DESCR\(/ {
- 	if (oid != 0)
- 	{
- 		data = substr($0, 8, length($0) - 9);
- 		if (data != "")
- 			printf "%d\t%s\t0\t%s\n", oid, catalog, data >>descriptionfile;
- 	}
- 	next;
- }
- 
- /^SHDESCR\(/ {
- 	if (oid != 0)
- 	{
- 		data = substr($0, 10, length($0) - 11);
- 		if (data != "")
- 			printf "%d\t%s\t%s\n", oid, catalog, data >>shdescriptionfile;
- 	}
- 	next;
- }
- 
- /^DECLARE_INDEX\(/ {
- # ----
- #  end any prior catalog data insertions before starting a define index
- # ----
- 	if (reln_open == 1) {
- 		print "close " catalog;
- 		reln_open = 0;
- 	}
- 
- 	data = substr($0, 15, length($0) - 15);
- 	pos = index(data, ",");
- 	iname = substr(data, 1, pos-1);
- 	data = substr(data, pos+1, length(data)-pos);
- 	pos = index(data, ",");
- 	oid = substr(data, 1, pos-1);
- 	data = substr(data, pos+1, length(data)-pos);
- 
- 	print "declare index " iname " " oid " " data
- }
- 
- /^DECLARE_UNIQUE_INDEX\(/ {
- # ----
- #  end any prior catalog data insertions before starting a define unique index
- # ----
- 	if (reln_open == 1) {
- 		print "close " catalog;
- 		reln_open = 0;
- 	}
- 
- 	data = substr($0, 22, length($0) - 22);
- 	pos = index(data, ",");
- 	iname = substr(data, 1, pos-1);
- 	data = substr(data, pos+1, length(data)-pos);
- 	pos = index(data, ",");
- 	oid = substr(data, 1, pos-1);
- 	data = substr(data, pos+1, length(data)-pos);
- 
- 	print "declare unique index " iname " " oid " " data
- }
- 
- /^DECLARE_TOAST\(/ {
- # ----
- #  end any prior catalog data insertions before starting a define toast
- # ----
- 	if (reln_open == 1) {
- 		print "close " catalog;
- 		reln_open = 0;
- 	}
- 
- 	data = substr($0, 15, length($0) - 15);
- 	pos = index(data, ",");
- 	tname = substr(data, 1, pos-1);
- 	data = substr(data, pos+1, length(data)-pos);
- 	pos = index(data, ",");
- 	toastoid = substr(data, 1, pos-1);
- 	data = substr(data, pos+1, length(data)-pos);
- 	# previous commands already removed the trailing );
- 	indexoid = data;
- 
- 	print "declare toast " toastoid " " indexoid " on " tname
- }
- 
- /^BUILD_INDICES/	{ print "build indices"; }
- 	
- # ----------------
- #	CATALOG() definitions take some more work.
- # ----------------
- /^CATALOG\(/ { 
- # ----
- #  end any prior catalog data insertions before starting a new one..
- # ----
- 	if (reln_open == 1) {
- 		print "close " catalog;
- 		reln_open = 0;
- 	}
- 
- # ----
- #  get the name and properties of the new catalog
- # ----
- 	pos = index($1,")");
- 	catalogandoid = substr($1,9,pos-9);
- 	pos = index(catalogandoid, ",");
- 	catalog = substr(catalogandoid, 1, pos-1);
- 	oid = substr(catalogandoid, pos+1, length(catalogandoid)-pos);
- 
- 	if ($0 ~ /BKI_BOOTSTRAP/) {
- 		bootstrap = "bootstrap ";
- 	}
- 	if ($0 ~ /BKI_SHARED_RELATION/) {
- 		shared_relation = "shared_relation ";
- 	}
- 	if ($0 ~ /BKI_WITHOUT_OIDS/) {
- 		without_oids = "without_oids ";
- 	}
- 
-         i = 1;
- 	inside = 1;
-         nc++;
- 	next;
- }
- 
- # ----------------
- #	process the columns of the catalog definition
- #
- #	attname[ x ] contains the attribute name for attribute x
- #	atttype[ x ] contains the attribute type fot attribute x
- # ----------------
- inside == 1 {
- # ----
- #  ignore a leading brace line..
- # ----
-         if ($1 ~ /\{/)
- 		next;
- 
- # ----
- #  if this is the last line, then output the bki catalog stuff.
- # ----
- 	if ($1 ~ /}/) {
- 		print "create " bootstrap shared_relation without_oids catalog " " oid;
- 		print "\t(";
- 
- 		for (j=1; j<i-1; j++) {
- 			print "\t " attname[ j ] " = " atttype[ j ] " ,";
- 		}
- 		print "\t " attname[ j ] " = " atttype[ j ] ;
- 		print "\t)";
- 
- 		if (bootstrap == "") {
- 			print "open " catalog;
- 		}
- 
- 		i = 1;
- 		reln_open = 1;
- 		inside = 0;
- 		bootstrap = "";
- 		shared_relation = "";
- 		without_oids = "";
- 		next;
- 	}
- 
- # ----
- #  we are inside the catalog definition, so keep sucking up
- #  attribute names and types
- # ----
- 	if ($2 ~ /\[.*\]/) {			# array attribute
- 		idlen = index($2,"[") - 1;
- 		atttype[ i ] = $1 "[]";		# variable-length only..
- 		attname[ i ] = substr($2,1,idlen);
- 	} else {
- 		atttype[ i ] = $1;
- 		attname[ i ] = $2;
- 	}
- 	i++;
- 	next;
- }
- 
- END {
- 	if (reln_open == 1) {
- 		print "close " catalog;
- 		reln_open = 0;
- 	}
- }
- ' "descriptionfile=${OUTPUT_PREFIX}.description.$$" "shdescriptionfile=${OUTPUT_PREFIX}.shdescription.$$" > $TMPFILE || exit
- 
- echo "# PostgreSQL $major_version" >${OUTPUT_PREFIX}.bki.$$
- 
- sed -e '/^[ 	]*$/d' \
-     -e 's/[ 	][ 	]*/ /g' $TMPFILE >>${OUTPUT_PREFIX}.bki.$$ || exit
- 
- #
- # Sanity check: if one of the sed/awk/etc commands fails, we'll probably
- # end up with a .bki file that is empty or just a few lines.  Cross-check
- # that the files are of reasonable size.  The numbers here are arbitrary,
- # but are much smaller than the actual expected sizes as of Postgres 7.2.
- #
- if [ `wc -c < ${OUTPUT_PREFIX}.bki.$$` -lt 100000 ]; then
-     echo "$CMDNAME: something seems to be wrong with the .bki file" >&2
-     exit 1
- fi
- if [ `wc -c < ${OUTPUT_PREFIX}.description.$$` -lt 10000 ]; then
-     echo "$CMDNAME: something seems to be wrong with the .description file" >&2
-     exit 1
- fi
- if [ `wc -c < ${OUTPUT_PREFIX}.shdescription.$$` -lt 10 ]; then
-     echo "$CMDNAME: something seems to be wrong with the .shdescription file" >&2
-     exit 1
- fi
- 
- # Looks good, commit ...
- 
- mv ${OUTPUT_PREFIX}.bki.$$ ${OUTPUT_PREFIX}.bki || exit
- mv ${OUTPUT_PREFIX}.description.$$ ${OUTPUT_PREFIX}.description || exit
- mv ${OUTPUT_PREFIX}.shdescription.$$ ${OUTPUT_PREFIX}.shdescription || exit
- 
- exit 0
--- 0 ----
*** a/src/backend/catalog/heap.c
--- b/src/backend/catalog/heap.c
***************
*** 34,39 ****
--- 34,40 ----
  #include "access/sysattr.h"
  #include "access/transam.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/catalog.h"
  #include "catalog/dependency.h"
  #include "catalog/heap.h"
*** a/src/backend/catalog/index.c
--- b/src/backend/catalog/index.c
***************
*** 30,35 ****
--- 30,36 ----
  #include "access/transam.h"
  #include "access/xact.h"
  #include "bootstrap/bootstrap.h"
+ #include "catalog/anum.h"
  #include "catalog/catalog.h"
  #include "catalog/dependency.h"
  #include "catalog/heap.h"
*** a/src/backend/catalog/pg_aggregate.c
--- b/src/backend/catalog/pg_aggregate.c
***************
*** 15,20 ****
--- 15,21 ----
  #include "postgres.h"
  
  #include "access/heapam.h"
+ #include "catalog/anum.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_aggregate.h"
*** a/src/backend/catalog/pg_constraint.c
--- b/src/backend/catalog/pg_constraint.c
***************
*** 16,21 ****
--- 16,22 ----
  
  #include "access/genam.h"
  #include "access/heapam.h"
+ #include "catalog/anum.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_constraint.h"
*** a/src/backend/catalog/pg_conversion.c
--- b/src/backend/catalog/pg_conversion.c
***************
*** 16,21 ****
--- 16,22 ----
  
  #include "access/heapam.h"
  #include "access/sysattr.h"
+ #include "catalog/anum.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_conversion.h"
*** a/src/backend/catalog/pg_depend.c
--- b/src/backend/catalog/pg_depend.c
***************
*** 16,21 ****
--- 16,22 ----
  
  #include "access/genam.h"
  #include "access/heapam.h"
+ #include "catalog/anum.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_constraint.h"
*** a/src/backend/catalog/pg_enum.c
--- b/src/backend/catalog/pg_enum.c
***************
*** 15,20 ****
--- 15,21 ----
  
  #include "access/genam.h"
  #include "access/heapam.h"
+ #include "catalog/anum.h"
  #include "catalog/catalog.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_enum.h"
*** a/src/backend/catalog/pg_inherits.c
--- b/src/backend/catalog/pg_inherits.c
***************
*** 20,25 ****
--- 20,26 ----
  #include "postgres.h"
  
  #include "access/heapam.h"
+ #include "catalog/anum.h"
  #include "catalog/pg_class.h"
  #include "catalog/pg_inherits.h"
  #include "catalog/pg_inherits_fn.h"
*** a/src/backend/catalog/pg_largeobject.c
--- b/src/backend/catalog/pg_largeobject.c
***************
*** 16,21 ****
--- 16,22 ----
  
  #include "access/genam.h"
  #include "access/heapam.h"
+ #include "catalog/anum.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_largeobject.h"
  #include "utils/builtins.h"
*** a/src/backend/catalog/pg_namespace.c
--- b/src/backend/catalog/pg_namespace.c
***************
*** 15,20 ****
--- 15,21 ----
  #include "postgres.h"
  
  #include "access/heapam.h"
+ #include "catalog/anum.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_namespace.h"
*** a/src/backend/catalog/pg_operator.c
--- b/src/backend/catalog/pg_operator.c
***************
*** 19,24 ****
--- 19,25 ----
  
  #include "access/heapam.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
  #include "catalog/namespace.h"
*** a/src/backend/catalog/pg_proc.c
--- b/src/backend/catalog/pg_proc.c
***************
*** 16,21 ****
--- 16,22 ----
  
  #include "access/heapam.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_language.h"
*** a/src/backend/catalog/pg_shdepend.c
--- b/src/backend/catalog/pg_shdepend.c
***************
*** 17,22 ****
--- 17,23 ----
  #include "access/genam.h"
  #include "access/heapam.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/catalog.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
*** a/src/backend/catalog/pg_type.c
--- b/src/backend/catalog/pg_type.c
***************
*** 16,21 ****
--- 16,22 ----
  
  #include "access/heapam.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_namespace.h"
*** a/src/backend/commands/async.c
--- b/src/backend/commands/async.c
***************
*** 89,94 ****
--- 89,95 ----
  #include "access/heapam.h"
  #include "access/twophase_rmgr.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/pg_listener.h"
  #include "commands/async.h"
  #include "libpq/libpq.h"
*** a/src/backend/commands/cluster.c
--- b/src/backend/commands/cluster.c
***************
*** 23,28 ****
--- 23,29 ----
  #include "access/rewriteheap.h"
  #include "access/transam.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/catalog.h"
  #include "catalog/dependency.h"
  #include "catalog/heap.h"
*** a/src/backend/commands/comment.c
--- b/src/backend/commands/comment.c
***************
*** 16,21 ****
--- 16,22 ----
  
  #include "access/genam.h"
  #include "access/heapam.h"
+ #include "catalog/anum.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_authid.h"
  #include "catalog/pg_cast.h"
*** a/src/backend/commands/dbcommands.c
--- b/src/backend/commands/dbcommands.c
***************
*** 28,33 ****
--- 28,34 ----
  #include "access/heapam.h"
  #include "access/xact.h"
  #include "access/xlogutils.h"
+ #include "catalog/anum.h"
  #include "catalog/catalog.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
*** a/src/backend/commands/foreigncmds.c
--- b/src/backend/commands/foreigncmds.c
***************
*** 15,20 ****
--- 15,21 ----
  
  #include "access/heapam.h"
  #include "access/reloptions.h"
+ #include "catalog/anum.h"
  #include "catalog/catalog.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
*** a/src/backend/commands/functioncmds.c
--- b/src/backend/commands/functioncmds.c
***************
*** 35,40 ****
--- 35,41 ----
  #include "access/genam.h"
  #include "access/heapam.h"
  #include "access/sysattr.h"
+ #include "catalog/anum.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_aggregate.h"
*** a/src/backend/commands/indexcmds.c
--- b/src/backend/commands/indexcmds.c
***************
*** 20,25 ****
--- 20,26 ----
  #include "access/reloptions.h"
  #include "access/transam.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/catalog.h"
  #include "catalog/heap.h"
  #include "catalog/index.h"
*** a/src/backend/commands/opclasscmds.c
--- b/src/backend/commands/opclasscmds.c
***************
*** 20,25 ****
--- 20,26 ----
  #include "access/genam.h"
  #include "access/heapam.h"
  #include "access/sysattr.h"
+ #include "catalog/anum.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_amop.h"
*** a/src/backend/commands/proclang.c
--- b/src/backend/commands/proclang.c
***************
*** 15,20 ****
--- 15,21 ----
  
  #include "access/genam.h"
  #include "access/heapam.h"
+ #include "catalog/anum.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_authid.h"
*** a/src/backend/commands/schemacmds.c
--- b/src/backend/commands/schemacmds.c
***************
*** 16,21 ****
--- 16,22 ----
  
  #include "access/heapam.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/catalog.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
*** a/src/backend/commands/tablecmds.c
--- b/src/backend/commands/tablecmds.c
***************
*** 20,25 ****
--- 20,26 ----
  #include "access/relscan.h"
  #include "access/sysattr.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/catalog.h"
  #include "catalog/dependency.h"
  #include "catalog/heap.h"
*** a/src/backend/commands/tablespace.c
--- b/src/backend/commands/tablespace.c
***************
*** 51,56 ****
--- 51,57 ----
  #include "access/heapam.h"
  #include "access/sysattr.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/catalog.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
*** a/src/backend/commands/trigger.c
--- b/src/backend/commands/trigger.c
***************
*** 17,22 ****
--- 17,23 ----
  #include "access/heapam.h"
  #include "access/sysattr.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/catalog.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
*** a/src/backend/commands/tsearchcmds.c
--- b/src/backend/commands/tsearchcmds.c
***************
*** 20,25 ****
--- 20,26 ----
  #include "access/heapam.h"
  #include "access/genam.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
  #include "catalog/namespace.h"
*** a/src/backend/commands/typecmds.c
--- b/src/backend/commands/typecmds.c
***************
*** 34,39 ****
--- 34,40 ----
  #include "access/genam.h"
  #include "access/heapam.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/catalog.h"
  #include "catalog/dependency.h"
  #include "catalog/heap.h"
*** a/src/backend/commands/user.c
--- b/src/backend/commands/user.c
***************
*** 15,20 ****
--- 15,21 ----
  #include "access/genam.h"
  #include "access/heapam.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_auth_members.h"
*** a/src/backend/commands/vacuum.c
--- b/src/backend/commands/vacuum.c
***************
*** 29,34 ****
--- 29,35 ----
  #include "access/visibilitymap.h"
  #include "access/xact.h"
  #include "access/xlog.h"
+ #include "catalog/anum.h"
  #include "catalog/namespace.h"
  #include "catalog/pg_database.h"
  #include "catalog/pg_namespace.h"
*** a/src/backend/executor/functions.c
--- b/src/backend/executor/functions.c
***************
*** 15,20 ****
--- 15,21 ----
  #include "postgres.h"
  
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/pg_proc.h"
  #include "catalog/pg_type.h"
  #include "commands/trigger.h"
*** a/src/backend/executor/nodeAgg.c
--- b/src/backend/executor/nodeAgg.c
***************
*** 68,73 ****
--- 68,74 ----
  
  #include "postgres.h"
  
+ #include "catalog/anum.h"
  #include "catalog/pg_aggregate.h"
  #include "catalog/pg_proc.h"
  #include "catalog/pg_type.h"
*** a/src/backend/executor/nodeWindowAgg.c
--- b/src/backend/executor/nodeWindowAgg.c
***************
*** 33,38 ****
--- 33,39 ----
   */
  #include "postgres.h"
  
+ #include "catalog/anum.h"
  #include "catalog/pg_aggregate.h"
  #include "catalog/pg_proc.h"
  #include "catalog/pg_type.h"
*** a/src/backend/foreign/foreign.c
--- b/src/backend/foreign/foreign.c
***************
*** 13,18 ****
--- 13,19 ----
  #include "postgres.h"
  
  #include "access/reloptions.h"
+ #include "catalog/anum.h"
  #include "catalog/namespace.h"
  #include "catalog/pg_foreign_data_wrapper.h"
  #include "catalog/pg_foreign_server.h"
*** a/src/backend/optimizer/util/clauses.c
--- b/src/backend/optimizer/util/clauses.c
***************
*** 19,24 ****
--- 19,25 ----
  
  #include "postgres.h"
  
+ #include "catalog/anum.h"
  #include "catalog/pg_aggregate.h"
  #include "catalog/pg_language.h"
  #include "catalog/pg_operator.h"
*** a/src/backend/parser/parse_func.c
--- b/src/backend/parser/parse_func.c
***************
*** 14,19 ****
--- 14,20 ----
   */
  #include "postgres.h"
  
+ #include "catalog/anum.h"
  #include "catalog/pg_proc.h"
  #include "catalog/pg_type.h"
  #include "funcapi.h"
*** a/src/backend/parser/parse_utilcmd.c
--- b/src/backend/parser/parse_utilcmd.c
***************
*** 29,34 ****
--- 29,35 ----
  #include "access/genam.h"
  #include "access/heapam.h"
  #include "access/reloptions.h"
+ #include "catalog/anum.h"
  #include "catalog/dependency.h"
  #include "catalog/heap.h"
  #include "catalog/index.h"
*** a/src/backend/postmaster/autovacuum.c
--- b/src/backend/postmaster/autovacuum.c
***************
*** 72,77 ****
--- 72,78 ----
  #include "access/reloptions.h"
  #include "access/transam.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
  #include "catalog/namespace.h"
*** a/src/backend/rewrite/rewriteDefine.c
--- b/src/backend/rewrite/rewriteDefine.c
***************
*** 15,20 ****
--- 15,21 ----
  #include "postgres.h"
  
  #include "access/heapam.h"
+ #include "catalog/anum.h"
  #include "catalog/catalog.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
*** a/src/backend/storage/large_object/inv_api.c
--- b/src/backend/storage/large_object/inv_api.c
***************
*** 34,39 ****
--- 34,40 ----
  #include "access/heapam.h"
  #include "access/tuptoaster.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/catalog.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_largeobject.h"
*** a/src/backend/utils/.cvsignore
--- /dev/null
***************
*** 1,2 ****
- fmgrtab.c
- fmgroids.h
--- 0 ----
*** a/src/backend/utils/Gen_fmgrtab.pl
--- /dev/null
***************
*** 1,194 ****
- #! /usr/bin/perl -w
- #-------------------------------------------------------------------------
- #
- # Gen_fmgrtab.pl
- #    Perl equivalent of Gen_fmgrtab.sh
- #
- # Usage: perl Gen_fmgrtab.pl path-to-pg_proc.h
- #
- # The reason for implementing this functionality twice is that we don't
- # require people to have perl to build from a tarball, but on the other
- # hand Windows can't deal with shell scripts.
- #
- # Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
- # Portions Copyright (c) 1994, Regents of the University of California
- #
- #
- # IDENTIFICATION
- #    $PostgreSQL$
- #
- #-------------------------------------------------------------------------
- 
- use strict;
- use warnings;
- 
- # Collect arguments
- my $infile = shift;
- defined($infile) || die "$0: missing required argument: pg_proc.h\n";
- 
- # Note: see Gen_fmgrtab.sh for detailed commentary on what this is doing
- 
- # Collect column numbers for pg_proc columns we need
- my ($proname, $prolang, $proisstrict, $proretset, $pronargs, $prosrc);
- 
- open(I, $infile) || die "Could not open $infile: $!";
- while (<I>)
- {
-     if (m/#define Anum_pg_proc_proname\s+(\d+)/) {
- 	$proname = $1;
-     }
-     if (m/#define Anum_pg_proc_prolang\s+(\d+)/) {
- 	$prolang = $1;
-     }
-     if (m/#define Anum_pg_proc_proisstrict\s+(\d+)/) {
- 	$proisstrict = $1;
-     }
-     if (m/#define Anum_pg_proc_proretset\s+(\d+)/) {
- 	$proretset = $1;
-     }
-     if (m/#define Anum_pg_proc_pronargs\s+(\d+)/) {
- 	$pronargs = $1;
-     }
-     if (m/#define Anum_pg_proc_prosrc\s+(\d+)/) {
- 	$prosrc = $1;
-     }
- }
- close(I);
- 
- # Collect the raw data
- my @fmgr = ();
- 
- open(I, $infile) || die "Could not open $infile: $!";
- while (<I>)
- {
-     next unless (/^DATA/);
-     s/^[^O]*OID[^=]*=[ \t]*//;
-     s/\(//;
-     s/"[^"]*"/"xxx"/g;
-     my @p = split;
-     next if ($p[$prolang] ne "12");
-     push @fmgr,
-       {
-         oid     => $p[0],
-         proname => $p[$proname],
-         strict  => $p[$proisstrict],
-         retset  => $p[$proretset],
-         nargs   => $p[$pronargs],
-         prosrc  => $p[$prosrc],
-       };
- }
- close(I);
- 
- # Emit headers for both files
- open(H, '>', "$$-fmgroids.h") || die "Could not open $$-fmgroids.h: $!";
- print H 
- qq|/*-------------------------------------------------------------------------
-  *
-  * fmgroids.h
-  *    Macros that define the OIDs of built-in functions.
-  *
-  * These macros can be used to avoid a catalog lookup when a specific
-  * fmgr-callable function needs to be referenced.
-  *
-  * Portions Copyright (c) 1996-2009, 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 $0
-  *	from $infile
-  *
-  *-------------------------------------------------------------------------
-  */
- #ifndef FMGROIDS_H
- #define FMGROIDS_H
- 
- /*
-  *	Constant macros for the OIDs of entries in pg_proc.
-  *
-  *	NOTE: macros are named after the prosrc value, ie the actual C name
-  *	of the implementing function, not the proname which may be overloaded.
-  *	For example, we want to be able to assign different macro names to both
-  *	char_text() and name_text() even though these both appear with proname
-  *	'text'.  If the same C function appears in more than one pg_proc entry,
-  *	its equivalent macro will be defined with the lowest OID among those
-  *	entries.
-  */
- |;
- 
- open(T, '>', "$$-fmgrtab.c") || die "Could not open $$-fmgrtab.c: $!";
- print T
- qq|/*-------------------------------------------------------------------------
-  *
-  * fmgrtab.c
-  *    The function manager's table of internal functions.
-  *
-  * Portions Copyright (c) 1996-2009, 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 $0
-  *	from $infile
-  *
-  *-------------------------------------------------------------------------
-  */
- 
- #include "postgres.h"
- 
- #include "utils/fmgrtab.h"
- 
- |;
- 
- # Emit #define's and extern's -- only one per prosrc value
- my %seenit;
- foreach my $s (sort {$a->{oid} <=> $b->{oid}} @fmgr)
- {
-     next if $seenit{$s->{prosrc}};
-     $seenit{$s->{prosrc}} = 1;
-     print H "#define F_" . uc $s->{prosrc} . " $s->{oid}\n";
-     print T "extern Datum $s->{prosrc} (PG_FUNCTION_ARGS);\n";
- }
- 
- # Create the fmgr_builtins table
- print T "\nconst FmgrBuiltin fmgr_builtins[] = {\n";
- my %bmap;
- $bmap{'t'} = 'true';
- $bmap{'f'} = 'false';
- foreach my $s (sort {$a->{oid} <=> $b->{oid}} @fmgr)
- {
-     print T
- 	"  { $s->{oid}, \"$s->{prosrc}\", $s->{nargs}, $bmap{$s->{strict}}, $bmap{$s->{retset}}, $s->{prosrc} },\n";
- }
- 
- # And add the file footers.
- print H "\n#endif /* FMGROIDS_H */\n";
- close(H);
- 
- print T
- qq|  /* dummy entry is easier than getting rid of comma after last real one */
-   /* (not that there has ever been anything wrong with *having* a
-      comma after the last field in an array initializer) */
-   { 0, NULL, 0, false, false, NULL }
- };
- 
- /* Note fmgr_nbuiltins excludes the dummy entry */
- const int fmgr_nbuiltins = (sizeof(fmgr_builtins) / sizeof(FmgrBuiltin)) - 1;
- |;
- 
- close(T);
- 
- # Finally, rename the completed files into place.
- rename "$$-fmgroids.h", "fmgroids.h"
-     || die "Could not rename $$-fmgroids.h to fmgroids.h: $!";
- rename "$$-fmgrtab.c", "fmgrtab.c"
-     || die "Could not rename $$-fmgrtab.c to fmgrtab.c: $!";
- 
- exit 0;
--- 0 ----
*** a/src/backend/utils/Gen_fmgrtab.sh
--- /dev/null
***************
*** 1,253 ****
- #! /bin/sh
- #-------------------------------------------------------------------------
- #
- # Gen_fmgrtab.sh
- #    shell script to generate fmgroids.h and fmgrtab.c from pg_proc.h
- #
- # NOTE: if you change this, you need to fix Gen_fmgrtab.pl too!
- #
- # Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
- # Portions Copyright (c) 1994, Regents of the University of California
- #
- #
- # IDENTIFICATION
- #    $PostgreSQL$
- #
- #-------------------------------------------------------------------------
- 
- CMDNAME=`basename $0`
- 
- if [ x"$AWK" = x"" ]; then
- 	AWK=awk
- fi
- 
- cleanup(){
-     [ x"$noclean" != x"t" ] && rm -f "$SORTEDFILE" "$$-$OIDSFILE" "$$-$TABLEFILE"
- }
- 
- noclean=
- 
- #
- # Process command line switches.
- #
- while [ $# -gt 0 ]
- do
-     case $1 in
-         --noclean)
-             noclean=t
-             ;;
-         --help)
-             echo "$CMDNAME generates fmgroids.h and fmgrtab.c from pg_proc.h."
-             echo
-             echo "Usage:"
-             echo "  $CMDNAME inputfile"
-             echo
-             echo "The environment variable AWK determines which Awk program"
-             echo "to use. The default is \`awk'."
-             echo
-             echo "Report bugs to <pgsql-bugs@postgresql.org>."
-             exit 0
-             ;;
-         -*)
-             echo "$CMDNAME: invalid option: $1"
-             exit 1
-             ;;
-         *)
-             INFILE=$1
-             ;;
-     esac
-     shift
- done
- 
- 
- if [ x"$INFILE" = x ] ; then
-     echo "$CMDNAME: no input file"
-     exit 1
- fi
- 
- SORTEDFILE="$$-fmgr.data"
- OIDSFILE=fmgroids.h
- TABLEFILE=fmgrtab.c
- 
- 
- trap 'echo "Caught signal." ; cleanup ; exit 1' 1 2 15
- 
- #
- # Collect the column numbers of the pg_proc columns we need.  Because we will
- # be looking at data that includes the OID as the first column, add one to
- # each column number.
- #
- proname=`egrep '^#define Anum_pg_proc_proname[ 	]' $INFILE | $AWK '{print $3+1}'`
- prolang=`egrep '^#define Anum_pg_proc_prolang[ 	]' $INFILE | $AWK '{print $3+1}'`
- proisstrict=`egrep '^#define Anum_pg_proc_proisstrict[ 	]' $INFILE | $AWK '{print $3+1}'`
- proretset=`egrep '^#define Anum_pg_proc_proretset[ 	]' $INFILE | $AWK '{print $3+1}'`
- pronargs=`egrep '^#define Anum_pg_proc_pronargs[ 	]' $INFILE | $AWK '{print $3+1}'`
- prosrc=`egrep '^#define Anum_pg_proc_prosrc[ 	]' $INFILE | $AWK '{print $3+1}'`
- 
- #
- # Generate the file containing raw pg_proc data.  We do three things here:
- # 1. Strip off the DATA macro call, leaving procedure OID as $1
- # and all the pg_proc field values as $2, $3, etc on each line.
- # 2. Fold quoted fields to simple "xxx".  We need this because such fields
- # may contain whitespace, which would confuse awk's counting of fields.
- # Fortunately, this script doesn't need to look at any fields that might
- # need quoting, so this simple hack is sufficient.
- # 3. Select out just the rows for internal-language procedures.
- #
- # Note assumption here that INTERNALlanguageId == 12.
- #
- egrep '^DATA' $INFILE | \
- sed 	-e 's/^[^O]*OID[^=]*=[ 	]*//' \
- 	-e 's/(//' \
- 	-e 's/"[^"]*"/"xxx"/g' | \
- $AWK "\$$prolang == \"12\" { print }" | \
- sort -n > $SORTEDFILE
- 
- if [ $? -ne 0 ]; then
-     cleanup
-     echo "$CMDNAME failed"
-     exit 1
- fi
- 
- 
- cpp_define=`echo $OIDSFILE | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ | sed -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g'`
- 
- #
- # Generate fmgroids.h
- #
- cat > "$$-$OIDSFILE" <<FuNkYfMgRsTuFf
- /*-------------------------------------------------------------------------
-  *
-  * $OIDSFILE
-  *    Macros that define the OIDs of built-in functions.
-  *
-  * These macros can be used to avoid a catalog lookup when a specific
-  * fmgr-callable function needs to be referenced.
-  *
-  * Portions Copyright (c) 1996-2009, 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 $CMDNAME
-  *	from $INFILE
-  *
-  *-------------------------------------------------------------------------
-  */
- #ifndef $cpp_define
- #define $cpp_define
- 
- /*
-  *	Constant macros for the OIDs of entries in pg_proc.
-  *
-  *	NOTE: macros are named after the prosrc value, ie the actual C name
-  *	of the implementing function, not the proname which may be overloaded.
-  *	For example, we want to be able to assign different macro names to both
-  *	char_text() and name_text() even though these both appear with proname
-  *	'text'.  If the same C function appears in more than one pg_proc entry,
-  *	its equivalent macro will be defined with the lowest OID among those
-  *	entries.
-  */
- FuNkYfMgRsTuFf
- 
- tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' < $SORTEDFILE | \
- $AWK "{ if (seenit[\$$prosrc]++ == 0)
- 	printf \"#define F_%s %s\\n\", \$$prosrc, \$1; }" >> "$$-$OIDSFILE"
- 
- if [ $? -ne 0 ]; then
-     cleanup
-     echo "$CMDNAME failed"
-     exit 1
- fi
- 
- cat >> "$$-$OIDSFILE" <<FuNkYfMgRsTuFf
- 
- #endif /* $cpp_define */
- FuNkYfMgRsTuFf
- 
- #
- # Generate fmgr's built-in-function table.
- #
- # Print out the function declarations, then the table that refers to them.
- #
- cat > "$$-$TABLEFILE" <<FuNkYfMgRtAbStUfF
- /*-------------------------------------------------------------------------
-  *
-  * $TABLEFILE
-  *    The function manager's table of internal functions.
-  *
-  * Portions Copyright (c) 1996-2009, 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 $CMDNAME
-  *	from $INFILE
-  *
-  *-------------------------------------------------------------------------
-  */
- 
- #include "postgres.h"
- 
- #include "utils/fmgrtab.h"
- 
- FuNkYfMgRtAbStUfF
- 
- $AWK "{ if (seenit[\$$prosrc]++ == 0)
- 	print \"extern Datum\", \$$prosrc, \"(PG_FUNCTION_ARGS);\"; }" $SORTEDFILE >> "$$-$TABLEFILE"
- 
- if [ $? -ne 0 ]; then
-     cleanup
-     echo "$CMDNAME failed"
-     exit 1
- fi
- 
- 
- cat >> "$$-$TABLEFILE" <<FuNkYfMgRtAbStUfF
- 
- const FmgrBuiltin fmgr_builtins[] = {
- FuNkYfMgRtAbStUfF
- 
- # Note: using awk arrays to translate from pg_proc values to fmgrtab values
- # may seem tedious, but avoid the temptation to write a quick x?y:z
- # conditional expression instead.  Not all awks have conditional expressions.
- 
- $AWK "BEGIN {
-     Bool[\"t\"] = \"true\";
-     Bool[\"f\"] = \"false\";
- }
- { printf (\"  { %d, \\\"%s\\\", %d, %s, %s, %s },\\n\"),
- 	\$1, \$$prosrc, \$$pronargs, Bool[\$$proisstrict], Bool[\$$proretset], \$$prosrc ;
- }" $SORTEDFILE >> "$$-$TABLEFILE"
- 
- if [ $? -ne 0 ]; then
-     cleanup
-     echo "$CMDNAME failed"
-     exit 1
- fi
- 
- cat >> "$$-$TABLEFILE" <<FuNkYfMgRtAbStUfF
-   /* dummy entry is easier than getting rid of comma after last real one */
-   /* (not that there has ever been anything wrong with *having* a
-      comma after the last field in an array initializer) */
-   { 0, NULL, 0, false, false, NULL }
- };
- 
- /* Note fmgr_nbuiltins excludes the dummy entry */
- const int fmgr_nbuiltins = (sizeof(fmgr_builtins) / sizeof(FmgrBuiltin)) - 1;
- FuNkYfMgRtAbStUfF
- 
- # We use the temporary files to avoid problems with concurrent runs
- # (which can happen during parallel make).
- mv "$$-$OIDSFILE" $OIDSFILE
- mv "$$-$TABLEFILE" $TABLEFILE
- 
- cleanup
- exit 0
--- 0 ----
*** a/src/backend/utils/Makefile
--- b/src/backend/utils/Makefile
***************
*** 8,24 **** subdir = src/backend/utils
  top_builddir = ../../..
  include $(top_builddir)/src/Makefile.global
  
- OBJS        = fmgrtab.o
  SUBDIRS     = adt cache error fmgr hash init mb misc mmgr resowner sort time
  
  include $(top_srcdir)/src/backend/common.mk
  
! all: fmgroids.h probes.h
! 
! $(SUBDIRS:%=%-recursive): fmgroids.h
! 
! fmgroids.h fmgrtab.c: Gen_fmgrtab.sh $(top_srcdir)/src/include/catalog/pg_proc.h
! 	AWK='$(AWK)' $(SHELL) $< $(top_srcdir)/src/include/catalog/pg_proc.h
  
  ifneq ($(enable_dtrace), yes)
  probes.h: Gen_dummy_probes.sed
--- 8,18 ----
  top_builddir = ../../..
  include $(top_builddir)/src/Makefile.global
  
  SUBDIRS     = adt cache error fmgr hash init mb misc mmgr resowner sort time
  
  include $(top_srcdir)/src/backend/common.mk
  
! all: probes.h
  
  ifneq ($(enable_dtrace), yes)
  probes.h: Gen_dummy_probes.sed
***************
*** 35,38 **** endif
  
  
  clean:
! 	rm -f fmgroids.h fmgrtab.c probes.h
--- 29,32 ----
  
  
  clean:
! 	rm -f probes.h
*** a/src/backend/utils/adt/regproc.c
--- b/src/backend/utils/adt/regproc.c
***************
*** 23,28 ****
--- 23,29 ----
  
  #include "access/genam.h"
  #include "access/heapam.h"
+ #include "catalog/anum.h"
  #include "catalog/indexing.h"
  #include "catalog/namespace.h"
  #include "catalog/pg_class.h"
*** a/src/backend/utils/adt/ri_triggers.c
--- b/src/backend/utils/adt/ri_triggers.c
***************
*** 31,36 ****
--- 31,37 ----
  #include "postgres.h"
  
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/pg_constraint.h"
  #include "catalog/pg_operator.h"
  #include "catalog/pg_type.h"
*** a/src/backend/utils/adt/ruleutils.c
--- b/src/backend/utils/adt/ruleutils.c
***************
*** 20,25 ****
--- 20,26 ----
  
  #include "access/genam.h"
  #include "access/sysattr.h"
+ #include "catalog/anum.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_authid.h"
*** a/src/backend/utils/cache/lsyscache.c
--- b/src/backend/utils/cache/lsyscache.c
***************
*** 18,23 ****
--- 18,24 ----
  #include "access/hash.h"
  #include "access/nbtree.h"
  #include "bootstrap/bootstrap.h"
+ #include "catalog/anum.h"
  #include "catalog/pg_amop.h"
  #include "catalog/pg_amproc.h"
  #include "catalog/pg_constraint.h"
*** a/src/backend/utils/cache/relcache.c
--- b/src/backend/utils/cache/relcache.c
***************
*** 34,39 ****
--- 34,40 ----
  #include "access/reloptions.h"
  #include "access/sysattr.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/catalog.h"
  #include "catalog/index.h"
  #include "catalog/indexing.h"
***************
*** 48,53 ****
--- 49,55 ----
  #include "catalog/pg_proc.h"
  #include "catalog/pg_rewrite.h"
  #include "catalog/pg_type.h"
+ #include "catalog/schemapg.h"
  #include "commands/trigger.h"
  #include "miscadmin.h"
  #include "optimizer/clauses.h"
*** a/src/backend/utils/cache/syscache.c
--- b/src/backend/utils/cache/syscache.c
***************
*** 21,26 ****
--- 21,27 ----
  #include "postgres.h"
  
  #include "access/sysattr.h"
+ #include "catalog/anum.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_aggregate.h"
  #include "catalog/pg_amop.h"
*** a/src/backend/utils/cache/ts_cache.c
--- b/src/backend/utils/cache/ts_cache.c
***************
*** 29,34 ****
--- 29,35 ----
  #include "access/genam.h"
  #include "access/heapam.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/indexing.h"
  #include "catalog/namespace.h"
  #include "catalog/pg_ts_config.h"
*** a/src/backend/utils/fmgr/fmgr.c
--- b/src/backend/utils/fmgr/fmgr.c
***************
*** 16,21 ****
--- 16,22 ----
  #include "postgres.h"
  
  #include "access/tuptoaster.h"
+ #include "catalog/anum.h"
  #include "catalog/pg_language.h"
  #include "catalog/pg_proc.h"
  #include "executor/functions.h"
*** a/src/backend/utils/fmgr/funcapi.c
--- b/src/backend/utils/fmgr/funcapi.c
***************
*** 14,19 ****
--- 14,20 ----
  #include "postgres.h"
  
  #include "access/heapam.h"
+ #include "catalog/anum.h"
  #include "catalog/namespace.h"
  #include "catalog/pg_proc.h"
  #include "catalog/pg_type.h"
*** a/src/backend/utils/init/flatfiles.c
--- b/src/backend/utils/init/flatfiles.c
***************
*** 37,42 ****
--- 37,43 ----
  #include "access/twophase_rmgr.h"
  #include "access/xact.h"
  #include "access/xlogutils.h"
+ #include "catalog/anum.h"
  #include "catalog/catalog.h"
  #include "catalog/pg_auth_members.h"
  #include "catalog/pg_authid.h"
*** a/src/backend/utils/init/miscinit.c
--- b/src/backend/utils/init/miscinit.c
***************
*** 29,34 ****
--- 29,35 ----
  #include <utime.h>
  #endif
  
+ #include "catalog/anum.h"
  #include "catalog/pg_authid.h"
  #include "mb/pg_wchar.h"
  #include "miscadmin.h"
*** a/src/backend/utils/init/postinit.c
--- b/src/backend/utils/init/postinit.c
***************
*** 20,25 ****
--- 20,26 ----
  
  #include "access/heapam.h"
  #include "access/xact.h"
+ #include "catalog/anum.h"
  #include "catalog/catalog.h"
  #include "catalog/namespace.h"
  #include "catalog/pg_authid.h"
*** a/src/include/catalog/pg_aggregate.h
--- b/src/include/catalog/pg_aggregate.h
***************
*** 55,74 **** CATALOG(pg_aggregate,2600) BKI_WITHOUT_OIDS
  typedef FormData_pg_aggregate *Form_pg_aggregate;
  
  /* ----------------
-  *		compiler constants for pg_aggregate
-  * ----------------
-  */
- 
- #define Natts_pg_aggregate				6
- #define Anum_pg_aggregate_aggfnoid		1
- #define Anum_pg_aggregate_aggtransfn	2
- #define Anum_pg_aggregate_aggfinalfn	3
- #define Anum_pg_aggregate_aggsortop		4
- #define Anum_pg_aggregate_aggtranstype	5
- #define Anum_pg_aggregate_agginitval	6
- 
- 
- /* ----------------
   * initial contents of pg_aggregate
   * ---------------
   */
--- 55,60 ----
*** a/src/include/catalog/pg_am.h
--- b/src/include/catalog/pg_am.h
***************
*** 73,110 **** CATALOG(pg_am,2601)
  typedef FormData_pg_am *Form_pg_am;
  
  /* ----------------
-  *		compiler constants for pg_am
-  * ----------------
-  */
- #define Natts_pg_am						26
- #define Anum_pg_am_amname				1
- #define Anum_pg_am_amstrategies			2
- #define Anum_pg_am_amsupport			3
- #define Anum_pg_am_amcanorder			4
- #define Anum_pg_am_amcanbackward		5
- #define Anum_pg_am_amcanunique			6
- #define Anum_pg_am_amcanmulticol		7
- #define Anum_pg_am_amoptionalkey		8
- #define Anum_pg_am_amindexnulls			9
- #define Anum_pg_am_amsearchnulls		10
- #define Anum_pg_am_amstorage			11
- #define Anum_pg_am_amclusterable		12
- #define Anum_pg_am_amkeytype			13
- #define Anum_pg_am_aminsert				14
- #define Anum_pg_am_ambeginscan			15
- #define Anum_pg_am_amgettuple			16
- #define Anum_pg_am_amgetbitmap			17
- #define Anum_pg_am_amrescan				18
- #define Anum_pg_am_amendscan			19
- #define Anum_pg_am_ammarkpos			20
- #define Anum_pg_am_amrestrpos			21
- #define Anum_pg_am_ambuild				22
- #define Anum_pg_am_ambulkdelete			23
- #define Anum_pg_am_amvacuumcleanup		24
- #define Anum_pg_am_amcostestimate		25
- #define Anum_pg_am_amoptions			26
- 
- /* ----------------
   *		initial contents of pg_am
   * ----------------
   */
--- 73,78 ----
*** a/src/include/catalog/pg_amop.h
--- b/src/include/catalog/pg_amop.h
***************
*** 67,84 **** CATALOG(pg_amop,2602)
  typedef FormData_pg_amop *Form_pg_amop;
  
  /* ----------------
-  *		compiler constants for pg_amop
-  * ----------------
-  */
- #define Natts_pg_amop					6
- #define Anum_pg_amop_amopfamily			1
- #define Anum_pg_amop_amoplefttype		2
- #define Anum_pg_amop_amoprighttype		3
- #define Anum_pg_amop_amopstrategy		4
- #define Anum_pg_amop_amopopr			5
- #define Anum_pg_amop_amopmethod			6
- 
- /* ----------------
   *		initial contents of pg_amop
   * ----------------
   */
--- 67,72 ----
*** a/src/include/catalog/pg_amproc.h
--- b/src/include/catalog/pg_amproc.h
***************
*** 59,75 **** CATALOG(pg_amproc,2603)
  typedef FormData_pg_amproc *Form_pg_amproc;
  
  /* ----------------
-  *		compiler constants for pg_amproc
-  * ----------------
-  */
- #define Natts_pg_amproc					5
- #define Anum_pg_amproc_amprocfamily		1
- #define Anum_pg_amproc_amproclefttype	2
- #define Anum_pg_amproc_amprocrighttype	3
- #define Anum_pg_amproc_amprocnum		4
- #define Anum_pg_amproc_amproc			5
- 
- /* ----------------
   *		initial contents of pg_amproc
   * ----------------
   */
--- 59,64 ----
*** a/src/include/catalog/pg_attrdef.h
--- b/src/include/catalog/pg_attrdef.h
***************
*** 43,56 **** CATALOG(pg_attrdef,2604)
   */
  typedef FormData_pg_attrdef *Form_pg_attrdef;
  
- /* ----------------
-  *		compiler constants for pg_attrdef
-  * ----------------
-  */
- #define Natts_pg_attrdef				4
- #define Anum_pg_attrdef_adrelid			1
- #define Anum_pg_attrdef_adnum			2
- #define Anum_pg_attrdef_adbin			3
- #define Anum_pg_attrdef_adsrc			4
- 
  #endif   /* PG_ATTRDEF_H */
--- 43,46 ----
*** a/src/include/catalog/pg_attribute.h
--- b/src/include/catalog/pg_attribute.h
***************
*** 172,203 **** CATALOG(pg_attribute,1249) BKI_BOOTSTRAP BKI_WITHOUT_OIDS
  typedef FormData_pg_attribute *Form_pg_attribute;
  
  /* ----------------
-  *		compiler constants for pg_attribute
-  * ----------------
-  */
- 
- #define Natts_pg_attribute				18
- #define Anum_pg_attribute_attrelid		1
- #define Anum_pg_attribute_attname		2
- #define Anum_pg_attribute_atttypid		3
- #define Anum_pg_attribute_attstattarget 4
- #define Anum_pg_attribute_attlen		5
- #define Anum_pg_attribute_attnum		6
- #define Anum_pg_attribute_attndims		7
- #define Anum_pg_attribute_attcacheoff	8
- #define Anum_pg_attribute_atttypmod		9
- #define Anum_pg_attribute_attbyval		10
- #define Anum_pg_attribute_attstorage	11
- #define Anum_pg_attribute_attalign		12
- #define Anum_pg_attribute_attnotnull	13
- #define Anum_pg_attribute_atthasdef		14
- #define Anum_pg_attribute_attisdropped	15
- #define Anum_pg_attribute_attislocal	16
- #define Anum_pg_attribute_attinhcount	17
- #define Anum_pg_attribute_attacl		18
- 
- 
- /* ----------------
   *		initial contents of pg_attribute
   *
   * NOTE: only "bootstrapped" relations need to be declared here.
--- 172,177 ----
***************
*** 211,245 **** typedef FormData_pg_attribute *Form_pg_attribute;
   *		pg_type
   * ----------------
   */
- #define Schema_pg_type \
- { 1247, {"typname"},	   19, -1, NAMEDATALEN, 1, 0, -1, -1, false, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typnamespace"},  26, -1,	4,	2, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typowner"},	   26, -1,	4,	3, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typlen"},		   21, -1,	2,	4, 0, -1, -1, true, 'p', 's', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typbyval"},	   16, -1,	1,	5, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typtype"},	   18, -1,	1,	6, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typcategory"},   18, -1,	1,	7, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typispreferred"},16, -1,	1,	8, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typisdefined"},  16, -1,	1,	9, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typdelim"},	   18, -1,	1, 10, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typrelid"},	   26, -1,	4, 11, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typelem"},	   26, -1,	4, 12, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typarray"},	   26, -1,	4, 13, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typinput"},	   24, -1,	4, 14, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typoutput"},	   24, -1,	4, 15, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typreceive"},    24, -1,	4, 16, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typsend"},	   24, -1,	4, 17, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typmodin"},	   24, -1,	4, 18, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typmodout"},	   24, -1,	4, 19, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typanalyze"},    24, -1,	4, 20, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typalign"},	   18, -1,	1, 21, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typstorage"},    18, -1,	1, 22, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typnotnull"},    16, -1,	1, 23, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typbasetype"},   26, -1,	4, 24, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typtypmod"},	   23, -1,	4, 25, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typndims"},	   23, -1,	4, 26, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typdefaultbin"}, 25, -1, -1, 27, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }, \
- { 1247, {"typdefault"},    25, -1, -1, 28, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }
  
  DATA(insert ( 1247 typname			19 -1 NAMEDATALEN	1 0 -1 -1 f p c t f f t 0 _null_));
  DATA(insert ( 1247 typnamespace		26 -1 4   2 0 -1 -1 t p i t f f t 0 _null_));
--- 185,190 ----
***************
*** 281,312 **** DATA(insert ( 1247 tableoid			26 0  4  -7 0 -1 -1 t p i t f f t 0 _null_));
   *		pg_proc
   * ----------------
   */
- #define Schema_pg_proc \
- { 1255, {"proname"},			19, -1, NAMEDATALEN,  1, 0, -1, -1, false, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1255, {"pronamespace"},		26, -1, 4,	2, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1255, {"proowner"},			26, -1, 4,	3, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1255, {"prolang"},			26, -1, 4,	4, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1255, {"procost"},		   700, -1, 4,	5, 0, -1, -1, FLOAT4PASSBYVAL, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1255, {"prorows"},		   700, -1, 4,	6, 0, -1, -1, FLOAT4PASSBYVAL, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1255, {"provariadic"},		26, -1, 4,	7, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1255, {"proisagg"},			16, -1, 1,	8, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1255, {"proiswindow"},		16, -1, 1,	9, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1255, {"prosecdef"},			16, -1, 1, 10, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1255, {"proisstrict"},		16, -1, 1, 11, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1255, {"proretset"},			16, -1, 1, 12, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1255, {"provolatile"},		18, -1, 1, 13, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1255, {"pronargs"},			21, -1, 2, 14, 0, -1, -1, true, 'p', 's', true, false, false, true, 0, { 0 } }, \
- { 1255, {"pronargdefaults"},	21, -1, 2, 15, 0, -1, -1, true, 'p', 's', true, false, false, true, 0, { 0 } }, \
- { 1255, {"prorettype"},			26, -1, 4, 16, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1255, {"proargtypes"},		30, -1, -1, 17, 1, -1, -1, false, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1255, {"proallargtypes"},   1028, -1, -1, 18, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }, \
- { 1255, {"proargmodes"},	  1002, -1, -1, 19, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }, \
- { 1255, {"proargnames"},	  1009, -1, -1, 20, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }, \
- { 1255, {"proargdefaults"},		25, -1, -1, 21, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }, \
- { 1255, {"prosrc"},				25, -1, -1, 22, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }, \
- { 1255, {"probin"},				17, -1, -1, 23, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }, \
- { 1255, {"proconfig"},		  1009, -1, -1, 24, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }, \
- { 1255, {"proacl"},			  1034, -1, -1, 25, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }
  
  DATA(insert ( 1255 proname			19 -1 NAMEDATALEN	1 0 -1 -1 f p c t f f t 0 _null_));
  DATA(insert ( 1255 pronamespace		26 -1 4   2 0 -1 -1 t p i t f f t 0 _null_));
--- 226,231 ----
***************
*** 345,369 **** DATA(insert ( 1255 tableoid			26 0  4  -7 0 -1 -1 t p i t f f t 0 _null_));
   *		pg_attribute
   * ----------------
   */
- #define Schema_pg_attribute \
- { 1249, {"attrelid"},	  26, -1,	4,	1, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attname"},	  19, -1, NAMEDATALEN,	2, 0, -1, -1, false, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1249, {"atttypid"},	  26, -1,	4,	3, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attstattarget"}, 23, -1,	4,	4, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attlen"},		  21, -1,	2,	5, 0, -1, -1, true, 'p', 's', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attnum"},		  21, -1,	2,	6, 0, -1, -1, true, 'p', 's', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attndims"},	  23, -1,	4,	7, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attcacheoff"},  23, -1,	4,	8, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1249, {"atttypmod"},	  23, -1,	4,	9, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attbyval"},	  16, -1,	1, 10, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attstorage"},   18, -1,	1, 11, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attalign"},	  18, -1,	1, 12, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attnotnull"},   16, -1,	1, 13, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1249, {"atthasdef"},	  16, -1,	1, 14, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attisdropped"}, 16, -1,	1, 15, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attislocal"},   16, -1,	1, 16, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attinhcount"},  23, -1,	4, 17, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attacl"},		1034, -1,  -1, 18, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }
  
  DATA(insert ( 1249 attrelid			26 -1  4   1 0 -1 -1 t p i t f f t 0 _null_));
  DATA(insert ( 1249 attname			19 -1 NAMEDATALEN  2 0 -1 -1 f p c t f f t 0 _null_));
--- 264,269 ----
***************
*** 395,426 **** DATA(insert ( 1249 tableoid			26 0  4  -7 0 -1 -1 t p i t f f t 0 _null_));
   *		pg_class
   * ----------------
   */
- #define Schema_pg_class \
- { 1259, {"relname"},	   19, -1, NAMEDATALEN, 1, 0, -1, -1, false, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relnamespace"},  26, -1,	4,	2, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1259, {"reltype"},	   26, -1,	4,	3, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relowner"},	   26, -1,	4,	4, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relam"},		   26, -1,	4,	5, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relfilenode"},   26, -1,	4,	6, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1259, {"reltablespace"}, 26, -1,	4,	7, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relpages"},	   23, -1,	4,	8, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1259, {"reltuples"},	   700, -1, 4,	9, 0, -1, -1, FLOAT4PASSBYVAL, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1259, {"reltoastrelid"}, 26, -1,	4, 10, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1259, {"reltoastidxid"}, 26, -1,	4, 11, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relhasindex"},   16, -1,	1, 12, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relisshared"},   16, -1,	1, 13, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relistemp"},	   16, -1,	1, 14, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relkind"},	   18, -1,	1, 15, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relnatts"},	   21, -1,	2, 16, 0, -1, -1, true, 'p', 's', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relchecks"},	   21, -1,	2, 17, 0, -1, -1, true, 'p', 's', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relhasoids"},    16, -1,	1, 18, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relhaspkey"},    16, -1,	1, 19, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relhasrules"},   16, -1,	1, 20, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relhastriggers"},16, -1,	1, 21, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relhassubclass"},16, -1,	1, 22, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relfrozenxid"},  28, -1,	4, 23, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relacl"},		 1034, -1, -1, 24, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }, \
- { 1259, {"reloptions"},  1009, -1, -1, 25, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }
  
  DATA(insert ( 1259 relname			19 -1 NAMEDATALEN	1 0 -1 -1 f p c t f f t 0 _null_));
  DATA(insert ( 1259 relnamespace		26 -1 4   2 0 -1 -1 t p i t f f t 0 _null_));
--- 295,300 ----
***************
*** 460,466 **** DATA(insert ( 1259 tableoid			26 0  4  -7 0 -1 -1 t p i t f f t 0 _null_));
   *
   * pg_index is not bootstrapped in the same way as the other relations that
   * have hardwired pg_attribute entries in this file.  However, we do need
!  * a "Schema_xxx" macro for it --- see relcache.c.
   * ----------------
   */
  #define Schema_pg_index \
--- 334,342 ----
   *
   * pg_index is not bootstrapped in the same way as the other relations that
   * have hardwired pg_attribute entries in this file.  However, we do need
!  * a "Schema_xxx" macro for it --- see relcache.c.  But since there are no
!  * DATA() statements for pg_index in this file (or anywhere else), this
!  * can't be automatically generated, so we hard-code it here.
   * ----------------
   */
  #define Schema_pg_index \
*** a/src/include/catalog/pg_auth_members.h
--- b/src/include/catalog/pg_auth_members.h
***************
*** 43,56 **** CATALOG(pg_auth_members,1261) BKI_SHARED_RELATION BKI_WITHOUT_OIDS
   */
  typedef FormData_pg_auth_members *Form_pg_auth_members;
  
- /* ----------------
-  *		compiler constants for pg_auth_members
-  * ----------------
-  */
- #define Natts_pg_auth_members				4
- #define Anum_pg_auth_members_roleid			1
- #define Anum_pg_auth_members_member			2
- #define Anum_pg_auth_members_grantor		3
- #define Anum_pg_auth_members_admin_option	4
- 
  #endif   /* PG_AUTH_MEMBERS_H */
--- 43,46 ----
*** a/src/include/catalog/pg_authid.h
--- b/src/include/catalog/pg_authid.h
***************
*** 69,91 **** CATALOG(pg_authid,1260) BKI_SHARED_RELATION
  typedef FormData_pg_authid *Form_pg_authid;
  
  /* ----------------
-  *		compiler constants for pg_authid
-  * ----------------
-  */
- #define Natts_pg_authid					11
- #define Anum_pg_authid_rolname			1
- #define Anum_pg_authid_rolsuper			2
- #define Anum_pg_authid_rolinherit		3
- #define Anum_pg_authid_rolcreaterole	4
- #define Anum_pg_authid_rolcreatedb		5
- #define Anum_pg_authid_rolcatupdate		6
- #define Anum_pg_authid_rolcanlogin		7
- #define Anum_pg_authid_rolconnlimit		8
- #define Anum_pg_authid_rolpassword		9
- #define Anum_pg_authid_rolvaliduntil	10
- #define Anum_pg_authid_rolconfig		11
- 
- /* ----------------
   *		initial contents of pg_authid
   *
   * The uppercase quantities will be replaced at initdb time with
--- 69,74 ----
*** a/src/include/catalog/pg_cast.h
--- b/src/include/catalog/pg_cast.h
***************
*** 71,87 **** typedef enum CoercionMethod
  
  
  /* ----------------
-  *		compiler constants for pg_cast
-  * ----------------
-  */
- #define Natts_pg_cast				5
- #define Anum_pg_cast_castsource		1
- #define Anum_pg_cast_casttarget		2
- #define Anum_pg_cast_castfunc		3
- #define Anum_pg_cast_castcontext	4
- #define Anum_pg_cast_castmethod		5
- 
- /* ----------------
   *		initial contents of pg_cast
   *
   * Note: this table has OIDs, but we don't bother to assign them manually,
--- 71,76 ----
*** a/src/include/catalog/pg_class.h
--- b/src/include/catalog/pg_class.h
***************
*** 82,119 **** CATALOG(pg_class,1259) BKI_BOOTSTRAP
  typedef FormData_pg_class *Form_pg_class;
  
  /* ----------------
-  *		compiler constants for pg_class
-  * ----------------
-  */
- 
- #define Natts_pg_class					25
- #define Anum_pg_class_relname			1
- #define Anum_pg_class_relnamespace		2
- #define Anum_pg_class_reltype			3
- #define Anum_pg_class_relowner			4
- #define Anum_pg_class_relam				5
- #define Anum_pg_class_relfilenode		6
- #define Anum_pg_class_reltablespace		7
- #define Anum_pg_class_relpages			8
- #define Anum_pg_class_reltuples			9
- #define Anum_pg_class_reltoastrelid		10
- #define Anum_pg_class_reltoastidxid		11
- #define Anum_pg_class_relhasindex		12
- #define Anum_pg_class_relisshared		13
- #define Anum_pg_class_relistemp			14
- #define Anum_pg_class_relkind			15
- #define Anum_pg_class_relnatts			16
- #define Anum_pg_class_relchecks			17
- #define Anum_pg_class_relhasoids		18
- #define Anum_pg_class_relhaspkey		19
- #define Anum_pg_class_relhasrules		20
- #define Anum_pg_class_relhastriggers	21
- #define Anum_pg_class_relhassubclass	22
- #define Anum_pg_class_relfrozenxid		23
- #define Anum_pg_class_relacl			24
- #define Anum_pg_class_reloptions		25
- 
- /* ----------------
   *		initial contents of pg_class
   *
   * NOTE: only "bootstrapped" relations need to be declared here.  Be sure that
--- 82,87 ----
*** a/src/include/catalog/pg_constraint.h
--- b/src/include/catalog/pg_constraint.h
***************
*** 127,159 **** CATALOG(pg_constraint,2606)
   */
  typedef FormData_pg_constraint *Form_pg_constraint;
  
- /* ----------------
-  *		compiler constants for pg_constraint
-  * ----------------
-  */
- #define Natts_pg_constraint					20
- #define Anum_pg_constraint_conname			1
- #define Anum_pg_constraint_connamespace		2
- #define Anum_pg_constraint_contype			3
- #define Anum_pg_constraint_condeferrable	4
- #define Anum_pg_constraint_condeferred		5
- #define Anum_pg_constraint_conrelid			6
- #define Anum_pg_constraint_contypid			7
- #define Anum_pg_constraint_confrelid		8
- #define Anum_pg_constraint_confupdtype		9
- #define Anum_pg_constraint_confdeltype		10
- #define Anum_pg_constraint_confmatchtype	11
- #define Anum_pg_constraint_conislocal		12
- #define Anum_pg_constraint_coninhcount		13
- #define Anum_pg_constraint_conkey			14
- #define Anum_pg_constraint_confkey			15
- #define Anum_pg_constraint_conpfeqop		16
- #define Anum_pg_constraint_conppeqop		17
- #define Anum_pg_constraint_conffeqop		18
- #define Anum_pg_constraint_conbin			19
- #define Anum_pg_constraint_consrc			20
- 
- 
  /* Valid values for contype */
  #define CONSTRAINT_CHECK			'c'
  #define CONSTRAINT_FOREIGN			'f'
--- 127,132 ----
*** a/src/include/catalog/pg_conversion.h
--- b/src/include/catalog/pg_conversion.h
***************
*** 56,75 **** CATALOG(pg_conversion,2607)
  typedef FormData_pg_conversion *Form_pg_conversion;
  
  /* ----------------
-  *		compiler constants for pg_conversion
-  * ----------------
-  */
- 
- #define Natts_pg_conversion				7
- #define Anum_pg_conversion_conname		1
- #define Anum_pg_conversion_connamespace 2
- #define Anum_pg_conversion_conowner		3
- #define Anum_pg_conversion_conforencoding		4
- #define Anum_pg_conversion_contoencoding		5
- #define Anum_pg_conversion_conproc		6
- #define Anum_pg_conversion_condefault	7
- 
- /* ----------------
   * initial contents of pg_conversion
   * ---------------
   */
--- 56,61 ----
*** a/src/include/catalog/pg_database.h
--- b/src/include/catalog/pg_database.h
***************
*** 52,76 **** CATALOG(pg_database,1262) BKI_SHARED_RELATION
   */
  typedef FormData_pg_database *Form_pg_database;
  
- /* ----------------
-  *		compiler constants for pg_database
-  * ----------------
-  */
- #define Natts_pg_database				13
- #define Anum_pg_database_datname		1
- #define Anum_pg_database_datdba			2
- #define Anum_pg_database_encoding		3
- #define Anum_pg_database_datcollate		4
- #define Anum_pg_database_datctype		5
- #define Anum_pg_database_datistemplate	6
- #define Anum_pg_database_datallowconn	7
- #define Anum_pg_database_datconnlimit	8
- #define Anum_pg_database_datlastsysoid	9
- #define Anum_pg_database_datfrozenxid	10
- #define Anum_pg_database_dattablespace	11
- #define Anum_pg_database_datconfig		12
- #define Anum_pg_database_datacl			13
- 
  DATA(insert OID = 1 (  template1 PGUID ENCODING "LC_COLLATE" "LC_CTYPE" t t -1 0 0 1663 _null_ _null_));
  SHDESCR("default template database");
  #define TemplateDbOid			1
--- 52,57 ----
*** a/src/include/catalog/pg_depend.h
--- b/src/include/catalog/pg_depend.h
***************
*** 60,79 **** CATALOG(pg_depend,2608) BKI_WITHOUT_OIDS
   */
  typedef FormData_pg_depend *Form_pg_depend;
  
- /* ----------------
-  *		compiler constants for pg_depend
-  * ----------------
-  */
- #define Natts_pg_depend				7
- #define Anum_pg_depend_classid		1
- #define Anum_pg_depend_objid		2
- #define Anum_pg_depend_objsubid		3
- #define Anum_pg_depend_refclassid	4
- #define Anum_pg_depend_refobjid		5
- #define Anum_pg_depend_refobjsubid	6
- #define Anum_pg_depend_deptype		7
- 
- 
  /*
   * pg_depend has no preloaded contents; system-defined dependencies are
   * loaded into it during a late stage of the initdb process.
--- 60,65 ----
*** a/src/include/catalog/pg_description.h
--- b/src/include/catalog/pg_description.h
***************
*** 61,76 **** CATALOG(pg_description,2609) BKI_WITHOUT_OIDS
  typedef FormData_pg_description *Form_pg_description;
  
  /* ----------------
-  *		compiler constants for pg_description
-  * ----------------
-  */
- #define Natts_pg_description			4
- #define Anum_pg_description_objoid		1
- #define Anum_pg_description_classoid	2
- #define Anum_pg_description_objsubid	3
- #define Anum_pg_description_description 4
- 
- /* ----------------
   *		initial contents of pg_description
   * ----------------
   */
--- 61,66 ----
*** a/src/include/catalog/pg_enum.h
--- b/src/include/catalog/pg_enum.h
***************
*** 45,58 **** CATALOG(pg_enum,3501)
  typedef FormData_pg_enum *Form_pg_enum;
  
  /* ----------------
-  *		compiler constants for pg_enum
-  * ----------------
-  */
- #define Natts_pg_enum					2
- #define Anum_pg_enum_enumtypid			1
- #define Anum_pg_enum_enumlabel			2
- 
- /* ----------------
   *		pg_enum has no initial contents
   * ----------------
   */
--- 45,50 ----
*** a/src/include/catalog/pg_foreign_data_wrapper.h
--- b/src/include/catalog/pg_foreign_data_wrapper.h
***************
*** 47,62 **** CATALOG(pg_foreign_data_wrapper,2328)
   */
  typedef FormData_pg_foreign_data_wrapper *Form_pg_foreign_data_wrapper;
  
- /* ----------------
-  *		compiler constants for pg_fdw
-  * ----------------
-  */
- 
- #define Natts_pg_foreign_data_wrapper				5
- #define Anum_pg_foreign_data_wrapper_fdwname		1
- #define Anum_pg_foreign_data_wrapper_fdwowner		2
- #define Anum_pg_foreign_data_wrapper_fdwvalidator	3
- #define Anum_pg_foreign_data_wrapper_fdwacl			4
- #define Anum_pg_foreign_data_wrapper_fdwoptions		5
- 
  #endif   /* PG_FOREIGN_DATA_WRAPPER_H */
--- 47,50 ----
*** a/src/include/catalog/pg_foreign_server.h
--- b/src/include/catalog/pg_foreign_server.h
***************
*** 48,65 **** CATALOG(pg_foreign_server,1417)
   */
  typedef FormData_pg_foreign_server *Form_pg_foreign_server;
  
- /* ----------------
-  *		compiler constants for pg_foreign_server
-  * ----------------
-  */
- 
- #define Natts_pg_foreign_server					7
- #define Anum_pg_foreign_server_srvname			1
- #define Anum_pg_foreign_server_srvowner			2
- #define Anum_pg_foreign_server_srvfdw			3
- #define Anum_pg_foreign_server_srvtype			4
- #define Anum_pg_foreign_server_srvversion		5
- #define Anum_pg_foreign_server_srvacl			6
- #define Anum_pg_foreign_server_srvoptions		7
- 
  #endif   /* PG_FOREIGN_SERVER_H */
--- 48,51 ----
*** a/src/include/catalog/pg_index.h
--- b/src/include/catalog/pg_index.h
***************
*** 58,83 **** CATALOG(pg_index,2610) BKI_WITHOUT_OIDS
   */
  typedef FormData_pg_index *Form_pg_index;
  
- /* ----------------
-  *		compiler constants for pg_index
-  * ----------------
-  */
- #define Natts_pg_index					14
- #define Anum_pg_index_indexrelid		1
- #define Anum_pg_index_indrelid			2
- #define Anum_pg_index_indnatts			3
- #define Anum_pg_index_indisunique		4
- #define Anum_pg_index_indisprimary		5
- #define Anum_pg_index_indisclustered	6
- #define Anum_pg_index_indisvalid		7
- #define Anum_pg_index_indcheckxmin		8
- #define Anum_pg_index_indisready		9
- #define Anum_pg_index_indkey			10
- #define Anum_pg_index_indclass			11
- #define Anum_pg_index_indoption			12
- #define Anum_pg_index_indexprs			13
- #define Anum_pg_index_indpred			14
- 
  /*
   * Index AMs that support ordered scans must support these two indoption
   * bits.  Otherwise, the content of the per-column indoption fields is
--- 58,63 ----
*** a/src/include/catalog/pg_inherits.h
--- b/src/include/catalog/pg_inherits.h
***************
*** 43,57 **** CATALOG(pg_inherits,2611) BKI_WITHOUT_OIDS
  typedef FormData_pg_inherits *Form_pg_inherits;
  
  /* ----------------
-  *		compiler constants for pg_inherits
-  * ----------------
-  */
- #define Natts_pg_inherits				3
- #define Anum_pg_inherits_inhrelid		1
- #define Anum_pg_inherits_inhparent		2
- #define Anum_pg_inherits_inhseqno		3
- 
- /* ----------------
   *		pg_inherits has no initial contents
   * ----------------
   */
--- 43,48 ----
*** a/src/include/catalog/pg_language.h
--- b/src/include/catalog/pg_language.h
***************
*** 47,65 **** CATALOG(pg_language,2612)
  typedef FormData_pg_language *Form_pg_language;
  
  /* ----------------
-  *		compiler constants for pg_language
-  * ----------------
-  */
- #define Natts_pg_language				7
- #define Anum_pg_language_lanname		1
- #define Anum_pg_language_lanowner		2
- #define Anum_pg_language_lanispl		3
- #define Anum_pg_language_lanpltrusted	4
- #define Anum_pg_language_lanplcallfoid	5
- #define Anum_pg_language_lanvalidator	6
- #define Anum_pg_language_lanacl			7
- 
- /* ----------------
   *		initial contents of pg_language
   * ----------------
   */
--- 47,52 ----
*** a/src/include/catalog/pg_largeobject.h
--- b/src/include/catalog/pg_largeobject.h
***************
*** 42,56 **** CATALOG(pg_largeobject,2613) BKI_WITHOUT_OIDS
   */
  typedef FormData_pg_largeobject *Form_pg_largeobject;
  
- /* ----------------
-  *		compiler constants for pg_largeobject
-  * ----------------
-  */
- #define Natts_pg_largeobject			3
- #define Anum_pg_largeobject_loid		1
- #define Anum_pg_largeobject_pageno		2
- #define Anum_pg_largeobject_data		3
- 
  extern void LargeObjectCreate(Oid loid);
  extern void LargeObjectDrop(Oid loid);
  extern bool LargeObjectExists(Oid loid);
--- 42,47 ----
*** a/src/include/catalog/pg_listener.h
--- b/src/include/catalog/pg_listener.h
***************
*** 43,57 **** CATALOG(pg_listener,2614) BKI_WITHOUT_OIDS
  typedef FormData_pg_listener *Form_pg_listener;
  
  /* ----------------
-  *		compiler constants for pg_listener
-  * ----------------
-  */
- #define Natts_pg_listener						3
- #define Anum_pg_listener_relname				1
- #define Anum_pg_listener_listenerpid			2
- #define Anum_pg_listener_notification			3
- 
- /* ----------------
   *		initial contents of pg_listener are NOTHING.
   * ----------------
   */
--- 43,48 ----
*** a/src/include/catalog/pg_namespace.h
--- b/src/include/catalog/pg_namespace.h
***************
*** 48,64 **** CATALOG(pg_namespace,2615)
  typedef FormData_pg_namespace *Form_pg_namespace;
  
  /* ----------------
-  *		compiler constants for pg_namespace
-  * ----------------
-  */
- 
- #define Natts_pg_namespace				3
- #define Anum_pg_namespace_nspname		1
- #define Anum_pg_namespace_nspowner		2
- #define Anum_pg_namespace_nspacl		3
- 
- 
- /* ----------------
   * initial contents of pg_namespace
   * ---------------
   */
--- 48,53 ----
*** a/src/include/catalog/pg_opclass.h
--- b/src/include/catalog/pg_opclass.h
***************
*** 68,87 **** CATALOG(pg_opclass,2616)
  typedef FormData_pg_opclass *Form_pg_opclass;
  
  /* ----------------
-  *		compiler constants for pg_opclass
-  * ----------------
-  */
- #define Natts_pg_opclass				8
- #define Anum_pg_opclass_opcmethod		1
- #define Anum_pg_opclass_opcname			2
- #define Anum_pg_opclass_opcnamespace	3
- #define Anum_pg_opclass_opcowner		4
- #define Anum_pg_opclass_opcfamily		5
- #define Anum_pg_opclass_opcintype		6
- #define Anum_pg_opclass_opcdefault		7
- #define Anum_pg_opclass_opckeytype		8
- 
- /* ----------------
   *		initial contents of pg_opclass
   *
   * Note: we hard-wire an OID only for a few entries that have to be explicitly
--- 68,73 ----
*** a/src/include/catalog/pg_operator.h
--- b/src/include/catalog/pg_operator.h
***************
*** 58,84 **** CATALOG(pg_operator,2617)
  typedef FormData_pg_operator *Form_pg_operator;
  
  /* ----------------
-  *		compiler constants for pg_operator
-  * ----------------
-  */
- 
- #define Natts_pg_operator				14
- #define Anum_pg_operator_oprname		1
- #define Anum_pg_operator_oprnamespace	2
- #define Anum_pg_operator_oprowner		3
- #define Anum_pg_operator_oprkind		4
- #define Anum_pg_operator_oprcanmerge	5
- #define Anum_pg_operator_oprcanhash		6
- #define Anum_pg_operator_oprleft		7
- #define Anum_pg_operator_oprright		8
- #define Anum_pg_operator_oprresult		9
- #define Anum_pg_operator_oprcom			10
- #define Anum_pg_operator_oprnegate		11
- #define Anum_pg_operator_oprcode		12
- #define Anum_pg_operator_oprrest		13
- #define Anum_pg_operator_oprjoin		14
- 
- /* ----------------
   *		initial contents of pg_operator
   * ----------------
   */
--- 58,63 ----
*** a/src/include/catalog/pg_opfamily.h
--- b/src/include/catalog/pg_opfamily.h
***************
*** 44,59 **** CATALOG(pg_opfamily,2753)
  typedef FormData_pg_opfamily *Form_pg_opfamily;
  
  /* ----------------
-  *		compiler constants for pg_opfamily
-  * ----------------
-  */
- #define Natts_pg_opfamily				4
- #define Anum_pg_opfamily_opfmethod		1
- #define Anum_pg_opfamily_opfname		2
- #define Anum_pg_opfamily_opfnamespace	3
- #define Anum_pg_opfamily_opfowner		4
- 
- /* ----------------
   *		initial contents of pg_opfamily
   * ----------------
   */
--- 44,49 ----
*** a/src/include/catalog/pg_pltemplate.h
--- b/src/include/catalog/pg_pltemplate.h
***************
*** 47,66 **** CATALOG(pg_pltemplate,1136) BKI_SHARED_RELATION BKI_WITHOUT_OIDS
  typedef FormData_pg_pltemplate *Form_pg_pltemplate;
  
  /* ----------------
-  *		compiler constants for pg_pltemplate
-  * ----------------
-  */
- #define Natts_pg_pltemplate					7
- #define Anum_pg_pltemplate_tmplname			1
- #define Anum_pg_pltemplate_tmpltrusted		2
- #define Anum_pg_pltemplate_tmpldbacreate	3
- #define Anum_pg_pltemplate_tmplhandler		4
- #define Anum_pg_pltemplate_tmplvalidator	5
- #define Anum_pg_pltemplate_tmpllibrary		6
- #define Anum_pg_pltemplate_tmplacl			7
- 
- 
- /* ----------------
   *		initial contents of pg_pltemplate
   * ----------------
   */
--- 47,52 ----
*** a/src/include/catalog/pg_proc.h
--- b/src/include/catalog/pg_proc.h
***************
*** 10,18 ****
   * $PostgreSQL$
   *
   * NOTES
!  *	  The script catalog/genbki.sh reads this file and generates .bki
!  *	  information from the DATA() statements.  utils/Gen_fmgrtab.sh
!  *	  generates fmgroids.h and fmgrtab.c the same way.
   *
   *	  XXX do NOT break up DATA() statements into multiple lines!
   *		  the scripts are not as smart as you might think...
--- 10,18 ----
   * $PostgreSQL$
   *
   * NOTES
!  *	  The script catalog/gen_catalog.pl reads this file and generates .bki
!  *	  information from the DATA() statements; it also generates fmgroids.h
!  *	  and fmgrtab.c.
   *
   *	  XXX do NOT break up DATA() statements into multiple lines!
   *		  the scripts are not as smart as you might think...
***************
*** 72,108 **** CATALOG(pg_proc,1255) BKI_BOOTSTRAP
  typedef FormData_pg_proc *Form_pg_proc;
  
  /* ----------------
-  *		compiler constants for pg_proc
-  * ----------------
-  */
- #define Natts_pg_proc					25
- #define Anum_pg_proc_proname			1
- #define Anum_pg_proc_pronamespace		2
- #define Anum_pg_proc_proowner			3
- #define Anum_pg_proc_prolang			4
- #define Anum_pg_proc_procost			5
- #define Anum_pg_proc_prorows			6
- #define Anum_pg_proc_provariadic		7
- #define Anum_pg_proc_proisagg			8
- #define Anum_pg_proc_proiswindow		9
- #define Anum_pg_proc_prosecdef			10
- #define Anum_pg_proc_proisstrict		11
- #define Anum_pg_proc_proretset			12
- #define Anum_pg_proc_provolatile		13
- #define Anum_pg_proc_pronargs			14
- #define Anum_pg_proc_pronargdefaults	15
- #define Anum_pg_proc_prorettype			16
- #define Anum_pg_proc_proargtypes		17
- #define Anum_pg_proc_proallargtypes		18
- #define Anum_pg_proc_proargmodes		19
- #define Anum_pg_proc_proargnames		20
- #define Anum_pg_proc_proargdefaults		21
- #define Anum_pg_proc_prosrc				22
- #define Anum_pg_proc_probin				23
- #define Anum_pg_proc_proconfig			24
- #define Anum_pg_proc_proacl				25
- 
- /* ----------------
   *		initial contents of pg_proc
   * ----------------
   */
--- 72,77 ----
*** a/src/include/catalog/pg_rewrite.h
--- b/src/include/catalog/pg_rewrite.h
***************
*** 52,69 **** CATALOG(pg_rewrite,2618)
   */
  typedef FormData_pg_rewrite *Form_pg_rewrite;
  
- /* ----------------
-  *		compiler constants for pg_rewrite
-  * ----------------
-  */
- #define Natts_pg_rewrite				8
- #define Anum_pg_rewrite_rulename		1
- #define Anum_pg_rewrite_ev_class		2
- #define Anum_pg_rewrite_ev_attr			3
- #define Anum_pg_rewrite_ev_type			4
- #define Anum_pg_rewrite_ev_enabled		5
- #define Anum_pg_rewrite_is_instead		6
- #define Anum_pg_rewrite_ev_qual			7
- #define Anum_pg_rewrite_ev_action		8
- 
  #endif   /* PG_REWRITE_H */
--- 52,55 ----
*** a/src/include/catalog/pg_shdepend.h
--- b/src/include/catalog/pg_shdepend.h
***************
*** 63,82 **** CATALOG(pg_shdepend,1214) BKI_SHARED_RELATION BKI_WITHOUT_OIDS
   */
  typedef FormData_pg_shdepend *Form_pg_shdepend;
  
- /* ----------------
-  *		compiler constants for pg_shdepend
-  * ----------------
-  */
- #define Natts_pg_shdepend			7
- #define Anum_pg_shdepend_dbid		1
- #define Anum_pg_shdepend_classid	2
- #define Anum_pg_shdepend_objid		3
- #define Anum_pg_shdepend_objsubid	4
- #define Anum_pg_shdepend_refclassid 5
- #define Anum_pg_shdepend_refobjid	6
- #define Anum_pg_shdepend_deptype	7
- 
- 
  /*
   * pg_shdepend has no preloaded contents; system-defined dependencies are
   * loaded into it during a late stage of the initdb process.
--- 63,68 ----
*** a/src/include/catalog/pg_shdescription.h
--- b/src/include/catalog/pg_shdescription.h
***************
*** 53,67 **** CATALOG(pg_shdescription,2396) BKI_SHARED_RELATION BKI_WITHOUT_OIDS
  typedef FormData_pg_shdescription *Form_pg_shdescription;
  
  /* ----------------
-  *		compiler constants for pg_shdescription
-  * ----------------
-  */
- #define Natts_pg_shdescription			3
- #define Anum_pg_shdescription_objoid		1
- #define Anum_pg_shdescription_classoid	2
- #define Anum_pg_shdescription_description 3
- 
- /* ----------------
   *		initial contents of pg_shdescription
   * ----------------
   */
--- 53,58 ----
***************
*** 69,75 **** typedef FormData_pg_shdescription *Form_pg_shdescription;
  /*
   *	Because the contents of this table are taken from the other *.h files,
   *	there is no initialization here.  The initial contents are extracted
!  *	by genbki.sh and loaded during initdb.
   */
  
  #endif   /* PG_SHDESCRIPTION_H */
--- 60,66 ----
  /*
   *	Because the contents of this table are taken from the other *.h files,
   *	there is no initialization here.  The initial contents are extracted
!  *	by gen_catalog.pl and loaded during initdb.
   */
  
  #endif   /* PG_SHDESCRIPTION_H */
*** a/src/include/catalog/pg_tablespace.h
--- b/src/include/catalog/pg_tablespace.h
***************
*** 43,59 **** CATALOG(pg_tablespace,1213) BKI_SHARED_RELATION
   */
  typedef FormData_pg_tablespace *Form_pg_tablespace;
  
- /* ----------------
-  *		compiler constants for pg_tablespace
-  * ----------------
-  */
- 
- #define Natts_pg_tablespace				4
- #define Anum_pg_tablespace_spcname		1
- #define Anum_pg_tablespace_spcowner		2
- #define Anum_pg_tablespace_spclocation	3
- #define Anum_pg_tablespace_spcacl		4
- 
  DATA(insert OID = 1663 ( pg_default PGUID "" _null_ ));
  DATA(insert OID = 1664 ( pg_global	PGUID "" _null_ ));
  
--- 43,48 ----
*** a/src/include/catalog/pg_trigger.h
--- b/src/include/catalog/pg_trigger.h
***************
*** 63,88 **** CATALOG(pg_trigger,2620)
   */
  typedef FormData_pg_trigger *Form_pg_trigger;
  
- /* ----------------
-  *		compiler constants for pg_trigger
-  * ----------------
-  */
- #define Natts_pg_trigger				14
- #define Anum_pg_trigger_tgrelid			1
- #define Anum_pg_trigger_tgname			2
- #define Anum_pg_trigger_tgfoid			3
- #define Anum_pg_trigger_tgtype			4
- #define Anum_pg_trigger_tgenabled		5
- #define Anum_pg_trigger_tgisconstraint	6
- #define Anum_pg_trigger_tgconstrname	7
- #define Anum_pg_trigger_tgconstrrelid	8
- #define Anum_pg_trigger_tgconstraint	9
- #define Anum_pg_trigger_tgdeferrable	10
- #define Anum_pg_trigger_tginitdeferred	11
- #define Anum_pg_trigger_tgnargs			12
- #define Anum_pg_trigger_tgattr			13
- #define Anum_pg_trigger_tgargs			14
- 
  /* Bits within tgtype */
  #define TRIGGER_TYPE_ROW				(1 << 0)
  #define TRIGGER_TYPE_BEFORE				(1 << 1)
--- 63,68 ----
*** a/src/include/catalog/pg_ts_config.h
--- b/src/include/catalog/pg_ts_config.h
***************
*** 41,56 **** CATALOG(pg_ts_config,3602)
  typedef FormData_pg_ts_config *Form_pg_ts_config;
  
  /* ----------------
-  *		compiler constants for pg_ts_config
-  * ----------------
-  */
- #define Natts_pg_ts_config				4
- #define Anum_pg_ts_config_cfgname		1
- #define Anum_pg_ts_config_cfgnamespace	2
- #define Anum_pg_ts_config_cfgowner		3
- #define Anum_pg_ts_config_cfgparser		4
- 
- /* ----------------
   *		initial contents of pg_ts_config
   * ----------------
   */
--- 41,46 ----
*** a/src/include/catalog/pg_ts_config_map.h
--- b/src/include/catalog/pg_ts_config_map.h
***************
*** 41,56 **** CATALOG(pg_ts_config_map,3603) BKI_WITHOUT_OIDS
  typedef FormData_pg_ts_config_map *Form_pg_ts_config_map;
  
  /* ----------------
-  *		compiler constants for pg_ts_config_map
-  * ----------------
-  */
- #define Natts_pg_ts_config_map				4
- #define Anum_pg_ts_config_map_mapcfg		1
- #define Anum_pg_ts_config_map_maptokentype	2
- #define Anum_pg_ts_config_map_mapseqno		3
- #define Anum_pg_ts_config_map_mapdict		4
- 
- /* ----------------
   *		initial contents of pg_ts_config_map
   * ----------------
   */
--- 41,46 ----
*** a/src/include/catalog/pg_ts_dict.h
--- b/src/include/catalog/pg_ts_dict.h
***************
*** 42,58 **** CATALOG(pg_ts_dict,3600)
  typedef FormData_pg_ts_dict *Form_pg_ts_dict;
  
  /* ----------------
-  *		compiler constants for pg_ts_dict
-  * ----------------
-  */
- #define Natts_pg_ts_dict				5
- #define Anum_pg_ts_dict_dictname		1
- #define Anum_pg_ts_dict_dictnamespace	2
- #define Anum_pg_ts_dict_dictowner		3
- #define Anum_pg_ts_dict_dicttemplate	4
- #define Anum_pg_ts_dict_dictinitoption	5
- 
- /* ----------------
   *		initial contents of pg_ts_dict
   * ----------------
   */
--- 42,47 ----
*** a/src/include/catalog/pg_ts_parser.h
--- b/src/include/catalog/pg_ts_parser.h
***************
*** 44,62 **** CATALOG(pg_ts_parser,3601)
  typedef FormData_pg_ts_parser *Form_pg_ts_parser;
  
  /* ----------------
-  *		compiler constants for pg_ts_parser
-  * ----------------
-  */
- #define Natts_pg_ts_parser					7
- #define Anum_pg_ts_parser_prsname			1
- #define Anum_pg_ts_parser_prsnamespace		2
- #define Anum_pg_ts_parser_prsstart			3
- #define Anum_pg_ts_parser_prstoken			4
- #define Anum_pg_ts_parser_prsend			5
- #define Anum_pg_ts_parser_prsheadline		6
- #define Anum_pg_ts_parser_prslextype		7
- 
- /* ----------------
   *		initial contents of pg_ts_parser
   * ----------------
   */
--- 44,49 ----
*** a/src/include/catalog/pg_ts_template.h
--- b/src/include/catalog/pg_ts_template.h
***************
*** 41,56 **** CATALOG(pg_ts_template,3764)
  typedef FormData_pg_ts_template *Form_pg_ts_template;
  
  /* ----------------
-  *		compiler constants for pg_ts_template
-  * ----------------
-  */
- #define Natts_pg_ts_template				4
- #define Anum_pg_ts_template_tmplname		1
- #define Anum_pg_ts_template_tmplnamespace	2
- #define Anum_pg_ts_template_tmplinit		3
- #define Anum_pg_ts_template_tmpllexize		4
- 
- /* ----------------
   *		initial contents of pg_ts_template
   * ----------------
   */
--- 41,46 ----
*** a/src/include/catalog/pg_type.h
--- b/src/include/catalog/pg_type.h
***************
*** 220,260 **** CATALOG(pg_type,1247) BKI_BOOTSTRAP
  typedef FormData_pg_type *Form_pg_type;
  
  /* ----------------
-  *		compiler constants for pg_type
-  * ----------------
-  */
- #define Natts_pg_type					28
- #define Anum_pg_type_typname			1
- #define Anum_pg_type_typnamespace		2
- #define Anum_pg_type_typowner			3
- #define Anum_pg_type_typlen				4
- #define Anum_pg_type_typbyval			5
- #define Anum_pg_type_typtype			6
- #define Anum_pg_type_typcategory		7
- #define Anum_pg_type_typispreferred		8
- #define Anum_pg_type_typisdefined		9
- #define Anum_pg_type_typdelim			10
- #define Anum_pg_type_typrelid			11
- #define Anum_pg_type_typelem			12
- #define Anum_pg_type_typarray			13
- #define Anum_pg_type_typinput			14
- #define Anum_pg_type_typoutput			15
- #define Anum_pg_type_typreceive			16
- #define Anum_pg_type_typsend			17
- #define Anum_pg_type_typmodin			18
- #define Anum_pg_type_typmodout			19
- #define Anum_pg_type_typanalyze			20
- #define Anum_pg_type_typalign			21
- #define Anum_pg_type_typstorage			22
- #define Anum_pg_type_typnotnull			23
- #define Anum_pg_type_typbasetype		24
- #define Anum_pg_type_typtypmod			25
- #define Anum_pg_type_typndims			26
- #define Anum_pg_type_typdefaultbin		27
- #define Anum_pg_type_typdefault			28
- 
- 
- /* ----------------
   *		initial contents of pg_type
   * ----------------
   */
--- 220,225 ----
*** a/src/include/catalog/pg_user_mapping.h
--- b/src/include/catalog/pg_user_mapping.h
***************
*** 46,59 **** CATALOG(pg_user_mapping,1418)
   */
  typedef FormData_pg_user_mapping *Form_pg_user_mapping;
  
- /* ----------------
-  *		compiler constants for pg_user_mapping
-  * ----------------
-  */
- 
- #define Natts_pg_user_mapping				3
- #define Anum_pg_user_mapping_umuser			1
- #define Anum_pg_user_mapping_umserver		2
- #define Anum_pg_user_mapping_umoptions		3
- 
  #endif   /* PG_USER_MAPPING_H */
--- 46,49 ----
*** a/src/pl/plpgsql/src/pl_comp.c
--- b/src/pl/plpgsql/src/pl_comp.c
***************
*** 19,24 ****
--- 19,25 ----
  
  #include "pl_gram.h"
  
+ #include "catalog/anum.h"
  #include "catalog/namespace.h"
  #include "catalog/pg_attrdef.h"
  #include "catalog/pg_attribute.h"
#3Peter Eisentraut
peter_e@gmx.net
In reply to: Robert Haas (#1)
Re: autogenerating headers & bki stuff

On Tuesday 30 June 2009 06:59:51 Robert Haas wrote:

The attached patch merges all of the logic currently in genbki.sh and
Gen_fmgrtab.{sh,pl} into a single script called gen_catalog.pl. It
then extends that logic to generate all of the Anum_* and Natts_*
constants, as well as the Schema_pg_* declarations for the bootstrap
tables.

I see a potential problem with the introduction of the catalog/anum.h header,
to hold the Anum_... defines. This looks like it could be a significant break
in the backend API, as evidenced by the fact that plperl and dblink no longer
compile with this change.

I think a less invasive change would be to include anum.h into all the
catalog/pg_*.h headers, so that the external interface stays the same.

#4Robert Haas
robertmhaas@gmail.com
In reply to: Peter Eisentraut (#3)
Re: autogenerating headers & bki stuff

On Sat, Jul 25, 2009 at 3:21 AM, Peter Eisentraut<peter_e@gmx.net> wrote:

On Tuesday 30 June 2009 06:59:51 Robert Haas wrote:

The attached patch merges all of the logic currently in genbki.sh and
Gen_fmgrtab.{sh,pl} into a single script called gen_catalog.pl.  It
then extends that logic to generate all of the Anum_* and Natts_*
constants, as well as the Schema_pg_* declarations for the bootstrap
tables.

I see a potential problem with the introduction of the catalog/anum.h header,
to hold the Anum_... defines.  This looks like it could be a significant break
in the backend API, as evidenced by the fact that plperl and dblink no longer
compile with this change.

I think a less invasive change would be to include anum.h into all the
catalog/pg_*.h headers, so that the external interface stays the same.

Gah. I wish a toplevel make would build "contrib".

Anyway, yeah, we could do that. The downsides to that approach are:

1. Changing a catalog definition in a way that actually affects the
contents of anum.h will force more things to be recompiled (note that
there are guards against useless rebuilds of anum.h), and

2. If we do that, we'll probably be stuck with it forever, and it
seems like a bit of a hack.

...Robert

#5Tom Lane
tgl@sss.pgh.pa.us
In reply to: Robert Haas (#4)
Re: autogenerating headers & bki stuff

Robert Haas <robertmhaas@gmail.com> writes:

On Sat, Jul 25, 2009 at 3:21 AM, Peter Eisentraut<peter_e@gmx.net> wrote:

I think a less invasive change would be to include anum.h into all the
catalog/pg_*.h headers, so that the external interface stays the same.

Gah. I wish a toplevel make would build "contrib".

Anyway, yeah, we could do that. The downsides to that approach are:

I didn't realize this change was intending to throw all the Anum_
constants into a single header file. I am strongly against that
on namespace pollution grounds, quite aside from the massive #include
restructuring it'd require. And then there's the fact that any change
in such a file would force rebuild of just about the entire backend.

I do not see any virtue in autogenerating the Anum_ constants anyway.
Yeah, manually updating them is a bit of a pain, but it's only a tiny
part of the work that's normally involved in changing a system catalog.
In any case, practically all of the benefit involved could be gotten
by just not having to mess with the numerical values of the individual
constants. Which we could do by setting them up as enums instead of
macros, along the lines of
http://archives.postgresql.org/pgsql-committers/2008-05/msg00080.php

regards, tom lane

#6Robert Haas
robertmhaas@gmail.com
In reply to: Tom Lane (#5)
Re: autogenerating headers & bki stuff

On Sat, Jul 25, 2009 at 10:56 AM, Tom Lane<tgl@sss.pgh.pa.us> wrote:

Robert Haas <robertmhaas@gmail.com> writes:

On Sat, Jul 25, 2009 at 3:21 AM, Peter Eisentraut<peter_e@gmx.net> wrote:

I think a less invasive change would be to include anum.h into all the
catalog/pg_*.h headers, so that the external interface stays the same.

Gah.  I wish a toplevel make would build "contrib".

Anyway, yeah, we could do that.  The downsides to that approach are:

I didn't realize this change was intending to throw all the Anum_
constants into a single header file.  I am strongly against that
on namespace pollution grounds,

I don't really understand this objection. The reason why namespace
pollution is bad is because there's a risk that someone might be using
one of the names used for some other purpose, but the chances that
someone who is using a Anum_pg_* or Natts_pg_* constant also needs a
similarly named constant for some purpose other than referencing the
PostgreSQL catalogs seems so as nearly zero as makes no difference.

The hypothetical scenario in which this is a problem goes something
like this: someone is counting on the fact that if they include
"catalog/pg_foo.h", then Anum_pg_foo_* and Natts_pg_foo will be
defined appropriately for reference to PostgreSQL backend catalogs,
but they are also counting on the fact that Anum_pg_bar_* and
Natts_pg_bar (for some value of bar that collides with a system
catalog name) are not defined and that they can use those constants
for their own internal purposes. When they port their code to PG 8.5,
they are forced into changing the naming of those constants, because
it's no longer possible to just get the pg_foo constants without the
pg_bar constants. If anyone is really doing this, I submit that it's
a horribly bad idea and they ought to stop right away whether this
patch gets committed or not.

quite aside from the massive #include
restructuring it'd require.

This is all done in the patch (with the exception of a handful of
loose ends that Peter found in his review) and I don't think it's all
that massive.

And then there's the fact that any change
in such a file would force rebuild of just about the entire backend.

It requires a rebuild of 56 of 547 files '*.c' files in src/backend,
which is to say 10.2% of the backend. Also, the system is set up in
such a way that the timestamp on catalog/anum.h changes only when its
contents actually change, and dependencies are not rebuilt otherwise.
So basically it'll happen when someone adds an attribute to, or
removes one from, a system catalog: the fact that the .h file was
updated in some other way is not sufficient.

I do not see any virtue in autogenerating the Anum_ constants anyway.
Yeah, manually updating them is a bit of a pain, but it's only a tiny
part of the work that's normally involved in changing a system catalog.

Well, I'd like to work on fixing some of the other problems too, but
this seems like a good place to start. Currently, if there are two
uncommitted patches that make changes to the system catalog, whichever
is committed first is 100% guaranteed to conflict with each other, and
the resolution is typically painful. Of course, fixing the Anum and
Natts declarations does not come close to fixing this problem: for
catalogs that are initialized with any data at bootstrap time, the
DATA() lines are a much bigger issue, but fixing that is going to
require a bigger hammer than can be put in place with one patch. I do
think this is a pretty good foundation on which to build, though.

In any case, practically all of the benefit involved could be gotten
by just not having to mess with the numerical values of the individual
constants.  Which we could do by setting them up as enums instead of
macros, along the lines of
http://archives.postgresql.org/pgsql-committers/2008-05/msg00080.php

I'd certainly be willing to concede that some of the benefit could be
gotten that way, but I'm not sure I agree with "practically all". The
benefits of this patch as I see them are: (1) to reduce the number of
places where a catalog change creates a merge conflict, and (2) to
eliminate the possibility of human error in setting up the Anum and
Natts declarations. The fact that I found a case where this had been
done inconsistently in pg_listener (and no one noticed for 10 years)
provides that this is not an entirely hypothetical possibility even
for committed code, and I've definitely screwed it up a few times in
my own tree, too. Replacing the declarations with enums would make
the merge conflicts involve fewer lines and maybe slightly simplify
the manual updating process, but it won't completely solve either
problem.

...Robert

#7Tom Lane
tgl@sss.pgh.pa.us
In reply to: Robert Haas (#6)
Re: autogenerating headers & bki stuff

Robert Haas <robertmhaas@gmail.com> writes:

On Sat, Jul 25, 2009 at 10:56 AM, Tom Lane<tgl@sss.pgh.pa.us> wrote:

I didn't realize this change was intending to throw all the Anum_
constants into a single header file. �I am strongly against that
on namespace pollution grounds,

I don't really understand this objection.

It's for the same reasons we don't put all of include/catalog/ into one
giant header file, or all of include/ for that matter. It's bad for
modularity, it's bad for compilation time, it's bad for rebuild time
if you're using --enable-depend.

The reason why namespace
pollution is bad is because there's a risk that someone might be using
one of the names used for some other purpose,

Uh, no, that's actually pretty much irrelevant for our purposes. As a
general rule, any two PG header files should be non-conflicting since
some .c file might need to include both. So we'd have to get rid of
conflicts anyhow. That does not make compartmentalization useless.
As a for-instance, exposing names that a given .c file doesn't really
need opens the door to typos that the compiler won't catch for you
(ie, accidentally using the wrong Anum_ constant, in this context).

[ other straw-man argumentation snipped ]

None of this impresses me at all. We should not throw a pile of
unrelated declarations into one header just to simplify the life
of an automatic script.

regards, tom lane

#8Greg Stark
gsstark@mit.edu
In reply to: Robert Haas (#6)
Re: autogenerating headers & bki stuff

On Sat, Jul 25, 2009 at 9:17 PM, Robert Haas<robertmhaas@gmail.com> wrote:

Of course, fixing the Anum and
Natts declarations does not come close to fixing this problem: for
catalogs that are initialized with any data at bootstrap time, the
DATA() lines are a much bigger issue, but fixing that is going to
require a bigger hammer than can be put in place with one patch.  I do
think this is a pretty good foundation on which to build, though.

I think addressing that would actually be fairly simple in theory.
Move a lot of those DATA lines to SQL initdb scripts. Virtually all of
pg_proc, pg_operator, pg_opclass, pg_opfamily, pg_cast, etc can be
initialized using SQL. Hardly any of the records in there are needed
for bootstrapping.

That would reduce the pain of editing this files *enormously*. The
worst part of adding new operators is making sure all the opclass
entries line up properly. And when there's an OID conflict and they
all have to be renumbered and the opclasses fixed up that's when
they're a real headache.

--
greg
http://mit.edu/~gsstark/resume.pdf

#9Tom Lane
tgl@sss.pgh.pa.us
In reply to: Greg Stark (#8)
Re: autogenerating headers & bki stuff

Greg Stark <gsstark@mit.edu> writes:

Move a lot of those DATA lines to SQL initdb scripts. Virtually all of
pg_proc, pg_operator, pg_opclass, pg_opfamily, pg_cast, etc can be
initialized using SQL. Hardly any of the records in there are needed
for bootstrapping.

It's easy to make that claim, much less easy to actually do it.

The other issue is that there will be some fraction of the entries that
unavoidably *are* needed before you can use SQL to insert the rest.
What will we do with those? Having two different representations for
essentially the same kind of data isn't much fun.

regards, tom lane

#10Tom Lane
tgl@sss.pgh.pa.us
In reply to: Tom Lane (#9)
Re: autogenerating headers & bki stuff

[ dept. of second thoughts ]

I wrote:

It's easy to make that claim, much less easy to actually do it.

Reflecting on this a bit more ... it seems to me that it's not the right
thing to set the goal as "try to get rid of as many DATA statements as
possible". The right way to think about this is to classify the stuff
we have got in DATA statements, and consider how to reduce the pain
associated with the harder-to-maintain categories.

In particular, I think Greg correctly identified the main pain point
as being the catalog entries associated with operator classes (ie,
pg_opclass, pg_opfamily, pg_amop, pg_amproc entries). So what I'm
thinking is we should consider how to migrate *all* of those entries
into CREATE OPERATOR CLASS/FAMILY commands. And I think that that might
be doable. Those entries are not needed by the system until we create
catalog indexes. So maybe we could split the current bootstrap phase
into three phases:
* create core catalogs and load DATA commands, using bki
* create operator classes, using sql script
* create indexes, using bki
* proceed on as before

I'm not nearly as excited about migrating all or even most of, say,
the pg_proc DATA lines into SQL. That simply isn't going to buy very
much in maintainability --- a patch that wants to add a new property
to all the functions is going to conflict just as much with another
patch doing the same. And it is going to cost us in places like
how do we generate the fmgr lookup table.

Thoughts?

regards, tom lane

#11Robert Haas
robertmhaas@gmail.com
In reply to: Tom Lane (#10)
Re: autogenerating headers & bki stuff

On Sat, Jul 25, 2009 at 6:40 PM, Tom Lane<tgl@sss.pgh.pa.us> wrote:

I'm not nearly as excited about migrating all or even most of, say,
the pg_proc DATA lines into SQL.  That simply isn't going to buy very
much in maintainability --- a patch that wants to add a new property
to all the functions is going to conflict just as much with another
patch doing the same.  And it is going to cost us in places like
how do we generate the fmgr lookup table.

Thoughts?

I think it would actually buy you quite a bit to migrate them to SQL,
because in SQL, default properties can generally be omitted, which
means that a patch which adds a new property to pg_proc that takes the
same value for every row doesn't actually need to touch the SQL at
all. I suspect that's a pretty common case, too: SE-PostgreSQL
modifies a whole bunch of system catalogs to add a security label
attribute, and ALTER TABLE ... ALTER COLUMN ... SET DISTINCT adds a
column to pg_attribute that defaults to 0.

I can hear you objecting that there's no possible way we can use SQL
to construct pg_attribute, and that's certainly true. But I have
another idea. What we could do is generate the BKI but using some
more sophisticated method than just writing it all out longhand in the
header files and copying it over into the bki file. The pg_attribute
entries for the bootstrap tables, for example, are mostly inferrable
from the PG_CATALOG() declarations (I think storage class and maybe
one other property might be problematic). And certainly you could
design a more human readable format for the pg_proc entries, maybe
something like:

DATA_PG_PROC(function-name, function-arg1-type-name
function-arg2-type-name,
function-return-type-name,language,definition)

To convert this into BKI, you make an initial pass through pg_type.h
and collect the OIDs of all the type names. Then you zip through
pg_proc.h and now you have enough information to map all the type
names into OIDs and generate the BKI. I'm waving my hands a little
bit here but I really don't think this is too hard, coding-wise, and
it seems like it would make it a LOT easier to edit this file...

...Robert

#12Tom Lane
tgl@sss.pgh.pa.us
In reply to: Robert Haas (#11)
Re: autogenerating headers & bki stuff

Robert Haas <robertmhaas@gmail.com> writes:

On Sat, Jul 25, 2009 at 6:40 PM, Tom Lane<tgl@sss.pgh.pa.us> wrote:

I'm not nearly as excited about migrating all or even most of, say,
the pg_proc DATA lines into SQL.

I think it would actually buy you quite a bit to migrate them to SQL,
because in SQL, default properties can generally be omitted, which
means that a patch which adds a new property to pg_proc that takes the
same value for every row doesn't actually need to touch the SQL at
all.

[ shrug... ] If you think default values would buy something in
maintainability, we could revise the BKI notation to support them,
with a lot less work and risk than what you're proposing. Perhaps
something like

DATA_DEFAULTS( pronamespace=PGNSP proowner=PGUID prolang=12 ... );

DATA( oid=1242 proname=boolin pronargs=2 ... );
DATA( oid=1243 proname=boolout pronargs=2 ... );

with the convention that any field not specified in either the
DATA macro or the current defaults would go to NULL, except OID
which would retain its current special treatment. (Hmm, I wonder
if we'd even still need the _null_ hack anymore?)

I remain unexcited about inventing contraptions that solve limited
special cases. It's just not that hard to maintain those cases
the way we're doing now, and every added processing step introduces
its own comprehension and maintenance overheads.

regards, tom lane

#13Andrew Dunstan
andrew@dunslane.net
In reply to: Tom Lane (#12)
Re: autogenerating headers & bki stuff

Tom Lane wrote:

Robert Haas <robertmhaas@gmail.com> writes:

On Sat, Jul 25, 2009 at 6:40 PM, Tom Lane<tgl@sss.pgh.pa.us> wrote:

I'm not nearly as excited about migrating all or even most of, say,
the pg_proc DATA lines into SQL.

I think it would actually buy you quite a bit to migrate them to SQL,
because in SQL, default properties can generally be omitted, which
means that a patch which adds a new property to pg_proc that takes the
same value for every row doesn't actually need to touch the SQL at
all.

[ shrug... ] If you think default values would buy something in
maintainability, we could revise the BKI notation to support them,
with a lot less work and risk than what you're proposing. Perhaps
something like

DATA_DEFAULTS( pronamespace=PGNSP proowner=PGUID prolang=12 ... );

DATA( oid=1242 proname=boolin pronargs=2 ... );
DATA( oid=1243 proname=boolout pronargs=2 ... );

with the convention that any field not specified in either the
DATA macro or the current defaults would go to NULL, except OID
which would retain its current special treatment. (Hmm, I wonder
if we'd even still need the _null_ hack anymore?)

I kinda like this. It will make it easier not only to make catalog
changes but to add entries to thinks like pg_proc (which is surely the
biggest piece of the headache).

I remain unexcited about inventing contraptions that solve limited
special cases. It's just not that hard to maintain those cases
the way we're doing now, and every added processing step introduces
its own comprehension and maintenance overheads.

Agreed.

cheers

andrew

#14Tom Lane
tgl@sss.pgh.pa.us
In reply to: Tom Lane (#10)
Re: autogenerating headers & bki stuff

I wrote:

... So maybe we could split the current bootstrap phase
into three phases:
* create core catalogs and load DATA commands, using bki
* create operator classes, using sql script
* create indexes, using bki
* proceed on as before

I experimented with that a little bit and found it doesn't seem to be
tremendously easy. A non-bootstrap-mode backend will PANIC immediately
on startup if it doesn't find the critical system indexes, so the second
step has issues. Also, there is no provision for resuming bootstrap
mode in an already-existing database, so the third step doesn't work
either. We could hack up solutions to those things, but it's not clear
that it's worth it. What seems more profitable is just to allow CREATE
OPERATOR CLASS/FAMILY to be executed while still in bootstrap mode.
There will still be some obstacles to be surmounted, no doubt (in
particular persuading these commands to run without system indexes
present) ... but we'd have to surmount those anyway.

In the spirit of not inventing single-purpose solutions, I suggest
that the BKI representation for this might be something like

BKI_EXECUTE( any old SQL command );

where the bootstrap.c code just passes the given string to the main SQL
parser, and whether it works or not is dependent on whether the
specified command has been bootstrap-mode-proofed. For the moment we'd
only bother to fix CREATE OPERATOR CLASS/FAMILY to work that way, but
the door would be open for other things if it seemed worthwhile.

regards, tom lane

#15Greg Stark
gsstark@mit.edu
In reply to: Tom Lane (#14)
Re: autogenerating headers & bki stuff

On Sun, Jul 26, 2009 at 5:48 PM, Tom Lane<tgl@sss.pgh.pa.us> wrote:

In the spirit of not inventing single-purpose solutions, I suggest
that the BKI representation for this might be something like

BKI_EXECUTE( any old SQL command );

where the bootstrap.c code just passes the given string to the main SQL
parser, and whether it works or not is dependent on whether the
specified command has been bootstrap-mode-proofed.  For the moment we'd
only bother to fix CREATE OPERATOR CLASS/FAMILY to work that way, but
the door would be open for other things if it seemed worthwhile.

I have nothing against a BKI_EXECUTE() like you propose.

But my instinct is still to go the other way. Of determining which
parts are actually necessary for bootstrapping and which parts really
aren't. I think it's valuable to have those two classes separated so
we understand when we're introducing new dependencies and when we're
varying from the well-trodden standard approaches.

It would also be valuable if we ever want to move some of these things
out to contrib modules or move other modules into the core. We might
even envision having optional components which the user could have the
optoin to decide at at initdb-time whether to include them.

AFAICT the only opclasses that need to be in the bootstrap set are
int2_ops, int4_ops, name_ops, oid_ops, and oidvector_ops.

--
greg
http://mit.edu/~gsstark/resume.pdf

#16Tom Lane
tgl@sss.pgh.pa.us
In reply to: Greg Stark (#15)
Re: autogenerating headers & bki stuff

Greg Stark <gsstark@mit.edu> writes:

AFAICT the only opclasses that need to be in the bootstrap set are
int2_ops, int4_ops, name_ops, oid_ops, and oidvector_ops.

Maybe so, but the first two are part of the integer_ops family. If
we have to continue implementing all of that through DATA statements
then we haven't done much towards making things more maintainable
or less fragile. I think we need to try to get *all* of the operator
classes out of the hand-maintained-DATA-entries collection.

The argument about optional stuff doesn't impress me. I would think
that something that's going to be optionally loaded doesn't need to be
considered during bootstrap mode at all. We can just have initdb run
some SQL scripts (or not) during its post-bootstrap phase.

regards, tom lane

#17Robert Haas
robertmhaas@gmail.com
In reply to: Tom Lane (#12)
Re: autogenerating headers & bki stuff

On Sun, Jul 26, 2009 at 11:31 AM, Tom Lane<tgl@sss.pgh.pa.us> wrote:

Robert Haas <robertmhaas@gmail.com> writes:

On Sat, Jul 25, 2009 at 6:40 PM, Tom Lane<tgl@sss.pgh.pa.us> wrote:

I'm not nearly as excited about migrating all or even most of, say,
the pg_proc DATA lines into SQL.

I think it would actually buy you quite a bit to migrate them to SQL,
because in SQL, default properties can generally be omitted, which
means that a patch which adds a new property to pg_proc that takes the
same value for every row doesn't actually need to touch the SQL at
all.

[ shrug... ]  If you think default values would buy something in
maintainability, we could revise the BKI notation to support them,
with a lot less work and risk than what you're proposing.

Really? I thought about that too, but concluded that it would be
easier to verify that a change to the BKI-generation stuff was correct
(by just diffing the generated files). I don't know how to verify
that two versions of initdb do the same thing - I assume the databases
won't be byte-for-byte identical. But that was my only concern about
it: I like the idea of expanding what can be done in BKI mode, if we
can figure out how to do it.

Perhaps
something like

DATA_DEFAULTS( pronamespace=PGNSP proowner=PGUID prolang=12 ... );

DATA( oid=1242 proname=boolin pronargs=2 ... );
DATA( oid=1243 proname=boolout pronargs=2 ... );

with the convention that any field not specified in either the
DATA macro or the current defaults would go to NULL, except OID
which would retain its current special treatment.  (Hmm, I wonder
if we'd even still need the _null_ hack anymore?)

I remain unexcited about inventing contraptions that solve limited
special cases.  It's just not that hard to maintain those cases
the way we're doing now, and every added processing step introduces
its own comprehension and maintenance overheads.

If you think that the current system is anywhere close to ideal, I
give up. To do so much as add a single line to pg_proc requires all
sort of useless manual work, like translating type names to OIDs, and
making sure that pronargs contains the correct value when the same
information is already encapsulated in both proargtypes and
proargmodes.

Introducing defaults for DATA() would bring some benefits because it
would mostly avoid the need to change every row in the file when
adding a new column. But a preprocessing script can do much more
sophisticated transformations, like computing a value for a column, or
looking up type names in another file and translating them into OIDs.
It's not even hard; it's probably a 100-line patch on top of what I
already submitted.

...Robert

#18Robert Haas
robertmhaas@gmail.com
In reply to: Tom Lane (#16)
Re: autogenerating headers & bki stuff

On Sun, Jul 26, 2009 at 1:58 PM, Tom Lane<tgl@sss.pgh.pa.us> wrote:

Greg Stark <gsstark@mit.edu> writes:

AFAICT the only opclasses that need to be in the bootstrap set are
int2_ops, int4_ops, name_ops, oid_ops, and oidvector_ops.

Maybe so, but the first two are part of the integer_ops family.  If
we have to continue implementing all of that through DATA statements
then we haven't done much towards making things more maintainable
or less fragile.  I think we need to try to get *all* of the operator
classes out of the hand-maintained-DATA-entries collection.

Is this mostly a forward-reference problem?

...Robert

#19Tom Lane
tgl@sss.pgh.pa.us
In reply to: Robert Haas (#17)
Re: autogenerating headers & bki stuff

Robert Haas <robertmhaas@gmail.com> writes:

Introducing defaults for DATA() would bring some benefits because it
would mostly avoid the need to change every row in the file when
adding a new column. But a preprocessing script can do much more
sophisticated transformations, like computing a value for a column, or
looking up type names in another file and translating them into OIDs.

Hmm. A preprocessing script that produces DATA commands might in fact
be a reasonable proposal, but it was not what I understood you to be
suggesting before.

regards, tom lane

#20Tom Lane
tgl@sss.pgh.pa.us
In reply to: Robert Haas (#18)
Re: autogenerating headers & bki stuff

Robert Haas <robertmhaas@gmail.com> writes:

On Sun, Jul 26, 2009 at 1:58 PM, Tom Lane<tgl@sss.pgh.pa.us> wrote:

I think we need to try to get *all* of the operator
classes out of the hand-maintained-DATA-entries collection.

Is this mostly a forward-reference problem?

No, I don't see that as particularly the issue. What I'm concerned
about is the prospect of different parts of the same opfamily being
represented in different notations --- that sounds pretty error-prone
to me. Greg is arguing that special-casing some minimum subset of the
opclasses is a good idea, but I disagree. I think if we can make the
idea work at all, we can migrate *all* the built-in opclasses into the
higher-level notation, and that's how I want to approach it.

regards, tom lane

#21Alvaro Herrera
alvherre@commandprompt.com
In reply to: Tom Lane (#14)
1 attachment(s)
Re: autogenerating headers & bki stuff

Tom Lane escribi�:

I experimented with that a little bit and found it doesn't seem to be
tremendously easy. A non-bootstrap-mode backend will PANIC immediately
on startup if it doesn't find the critical system indexes, so the second
step has issues. Also, there is no provision for resuming bootstrap
mode in an already-existing database, so the third step doesn't work
either.

FWIW we hacked up a sort-of-bootstrap mode in Mammoth Replicator to be
able to create our own catalogs and stuff. It's not particularly
hard nor large:

bootstrap.c | 31 ++++++!!!!!!!!!!!!!!!!!!!!!!!!!
1 file changed, 6 insertions(+), 25 modifications(!)

(This is BSD code so feel free to use it if you find it useful)

--
Alvaro Herrera http://www.CommandPrompt.com/
The PostgreSQL Company - Command Prompt, Inc.

Attachments:

bootstrap.patchtext/x-diff; charset=us-asciiDownload
*** 83_rel/src/backend/bootstrap/bootstrap.c	2008-01-09 13:04:32.000000000 -0300
--- 23trunk/src/backend/bootstrap/bootstrap.c	2009-07-26 21:12:48.000000000 -0400
***************
*** 27,36 ****
--- 27,39 ----
  #include "catalog/index.h"
  #include "catalog/pg_type.h"
  #include "libpq/pqsignal.h"
+ #include "mammoth_r/mcp_queue.h"
+ #include "mammoth_r/txlog.h"
  #include "miscadmin.h"
  #include "nodes/makefuncs.h"
  #include "postmaster/bgwriter.h"
  #include "postmaster/walwriter.h"
+ #include "postmaster/replication.h"
  #include "storage/freespace.h"
  #include "storage/ipc.h"
  #include "storage/proc.h"
***************
*** 48,54 ****
  #define ALLOC(t, c)		((t *) calloc((unsigned)(c), sizeof(t)))
  
  static void CheckerModeMain(void);
! static void BootstrapModeMain(void);
  static void bootstrap_signals(void);
  static void ShutdownAuxiliaryProcess(int code, Datum arg);
  static hashnode *AddStr(char *str, int strlength, int mderef);
--- 51,57 ----
  #define ALLOC(t, c)		((t *) calloc((unsigned)(c), sizeof(t)))
  
  static void CheckerModeMain(void);
! static void BootstrapModeMain(char *dbname);
  static void bootstrap_signals(void);
  static void ShutdownAuxiliaryProcess(int code, Datum arg);
  static hashnode *AddStr(char *str, int strlength, int mderef);
***************
*** 207,212 ****
--- 210,216 ----
  	int			flag;
  	AuxProcType auxType = CheckerProcess;
  	char	   *userDoption = NULL;
+ 	char       *dbname = NULL;
  
  	/*
  	 * initialize globals
***************
*** 313,319 ****
  		}
  	}
  
! 	if (argc != optind)
  	{
  		write_stderr("%s: invalid command-line arguments\n", progname);
  		proc_exit(1);
--- 317,325 ----
  		}
  	}
  
! 	if (auxType == MammothBootstrapProcess && argc - optind + 1)
! 		dbname = argv[optind++]; 
! 	else if (argc != optind || auxType == MammothBootstrapProcess)
  	{
  		write_stderr("%s: invalid command-line arguments\n", progname);
  		proc_exit(1);
***************
*** 337,342 ****
--- 343,350 ----
  			case WalWriterProcess:
  				statmsg = "wal writer process";
  				break;
+ 			case MammothBootstrapProcess:
+ 				statmsg = "mammoth bootstrap process";
  			default:
  				statmsg = "??? process";
  				break;
***************
*** 410,416 ****
  			bootstrap_signals();
  			BootStrapXLOG();
  			StartupXLOG();
! 			BootstrapModeMain();
  			proc_exit(1);		/* should never return */
  
  		case StartupProcess:
--- 418,432 ----
  			bootstrap_signals();
  			BootStrapXLOG();
  			StartupXLOG();
! 			BootstrapModeMain(NULL);
! 			proc_exit(1);		/* should never return */
! 
! 		case MammothBootstrapProcess:
! 			bootstrap_signals();
! 			BootstrapTXLOG();
! 			BootStrapMCPQueue();
! 			StartupXLOG();
! 			BootstrapModeMain(dbname);
  			proc_exit(1);		/* should never return */
  
  		case StartupProcess:
***************
*** 469,487 ****
   *	 commands in a special bootstrap language.
   */
  static void
! BootstrapModeMain(void)
  {
  	int			i;
  
  	Assert(!IsUnderPostmaster);
  
! 	SetProcessingMode(BootstrapProcessing);
  
  	/*
  	 * Do backend-like initialization for bootstrap mode
  	 */
  	InitProcess();
! 	InitPostgres(NULL, InvalidOid, NULL, NULL);
  
  	/* Initialize stuff for bootstrap-file processing */
  	for (i = 0; i < MAXATTR; i++)
--- 485,506 ----
   *	 commands in a special bootstrap language.
   */
  static void
! BootstrapModeMain(char *dbname)
  {
  	int			i;
  
  	Assert(!IsUnderPostmaster);
  
! 	if (dbname == NULL)
! 		SetProcessingMode(BootstrapProcessing);
! 	else
! 		SetProcessingMode(MammothBootstrapProcessing);
  
  	/*
  	 * Do backend-like initialization for bootstrap mode
  	 */
  	InitProcess();
! 	InitPostgres(dbname, InvalidOid, NULL, NULL);
  
  	/* Initialize stuff for bootstrap-file processing */
  	for (i = 0; i < MAXATTR; i++)
*** 83_rel/src/include/bootstrap/bootstrap.h	2008-01-09 13:04:49.000000000 -0300
--- 23trunk/src/include/bootstrap/bootstrap.h	2008-09-12 16:36:43.000000000 -0400
***************
*** 70,76 ****
  	BootstrapProcess,
  	StartupProcess,
  	BgWriterProcess,
! 	WalWriterProcess
  } AuxProcType;
  
  #endif   /* BOOTSTRAP_H */
--- 70,77 ----
  	BootstrapProcess,
  	StartupProcess,
  	BgWriterProcess,
! 	WalWriterProcess,
! 	MammothBootstrapProcess = 99
  } AuxProcType;
  
  #endif   /* BOOTSTRAP_H */
#22Robert Haas
robertmhaas@gmail.com
In reply to: Tom Lane (#19)
Re: autogenerating headers & bki stuff

On Sun, Jul 26, 2009 at 8:46 PM, Tom Lane<tgl@sss.pgh.pa.us> wrote:

Robert Haas <robertmhaas@gmail.com> writes:

Introducing defaults for DATA() would bring some benefits because it
would mostly avoid the need to change every row in the file when
adding a new column.  But a preprocessing script can do much more
sophisticated transformations, like computing a value for a column, or
looking up type names in another file and translating them into OIDs.

Hmm.  A preprocessing script that produces DATA commands might in fact
be a reasonable proposal, but it was not what I understood you to be
suggesting before.

OK, sorry if I was unclear. I'm not sure exactly what you mean by
producing DATA() commands; I think the output should be BKI directly.
One of the things this patch does that I think is good (however flawed
it may be otherwise) is unifies all of the stuff that needs to parse
the DATA() statements into a single script. I think this is something
we should pursue, because I think it will simplify the introduction of
any other notation we want to consider in this area (regardless of
whether it's DATA_DEFAULTS or EXEC_BKI or what have you).

Maybe I should rip out all the anum.h stuff (sniff, I'm sad, I liked
that design...) and resubmit.

...Robert

#23Peter Eisentraut
peter_e@gmx.net
In reply to: Tom Lane (#10)
Re: autogenerating headers & bki stuff

On Sunday 26 July 2009 01:40:09 Tom Lane wrote:

And it is going to cost us in places like
how do we generate the fmgr lookup table.

We rgrep the source tree for PG_FUNCTION_ARGS, extract the function name, and
put them in a list.

#24Peter Eisentraut
peter_e@gmx.net
In reply to: Tom Lane (#16)
Re: autogenerating headers & bki stuff

On Sunday 26 July 2009 20:58:30 Tom Lane wrote:

The argument about optional stuff doesn't impress me. I would think
that something that's going to be optionally loaded doesn't need to be
considered during bootstrap mode at all. We can just have initdb run
some SQL scripts (or not) during its post-bootstrap phase.

Isn't that exactly what some people are proposing? Remove the nonessential
things from the DATA() lines and put them into SQL scripts?

#25Robert Haas
robertmhaas@gmail.com
In reply to: Peter Eisentraut (#23)
Re: autogenerating headers & bki stuff

On Mon, Jul 27, 2009 at 4:17 AM, Peter Eisentraut<peter_e@gmx.net> wrote:

On Sunday 26 July 2009 01:40:09 Tom Lane wrote:

And it is going to cost us in places like
how do we generate the fmgr lookup table.

We rgrep the source tree for PG_FUNCTION_ARGS, extract the function name, and
put them in a list.

Probably parsing the SQL would be a better idea. Otherwise, the
outputs would depend on every .c file in the entire source tree.

...Robert

#26Tom Lane
tgl@sss.pgh.pa.us
In reply to: Peter Eisentraut (#24)
Re: autogenerating headers & bki stuff

Peter Eisentraut <peter_e@gmx.net> writes:

On Sunday 26 July 2009 20:58:30 Tom Lane wrote:

The argument about optional stuff doesn't impress me. I would think
that something that's going to be optionally loaded doesn't need to be
considered during bootstrap mode at all. We can just have initdb run
some SQL scripts (or not) during its post-bootstrap phase.

Isn't that exactly what some people are proposing? Remove the nonessential
things from the DATA() lines and put them into SQL scripts?

I think what "some people are proposing" is to rip inessential stuff
(say, the geometry types) out of core completely. Which I'd not be
against. The discussion at the moment is about whether to have
first-class and second-class citizens within the core set of functions;
and that I'm against. I think two notations implemented by two
different toolchains will be confusing and not help maintenance that much.

regards, tom lane

#27Robert Haas
robertmhaas@gmail.com
In reply to: Robert Haas (#22)
1 attachment(s)
Re: autogenerating headers & bki stuff

On Sun, Jul 26, 2009 at 11:05 PM, Robert Haas<robertmhaas@gmail.com> wrote:

Maybe I should rip out all the anum.h stuff (sniff, I'm sad, I liked
that design...) and resubmit.

Hearing no comments on this either way, here is a stripped down version.

...Robert

Attachments:

gen_catalog-v3.patchtext/x-diff; charset=US-ASCII; name=gen_catalog-v3.patchDownload
*** a/src/Makefile.global.in
--- b/src/Makefile.global.in
***************
*** 517,522 **** $(top_builddir)/src/interfaces/ecpg/include/ecpg_config.h: $(top_builddir)/src/i
--- 517,592 ----
  $(top_builddir)/config.status: $(top_srcdir)/configure
  	cd $(top_builddir) && ./config.status --recheck
  
+ # Note: there are some undocumented dependencies on the ordering in which
+ # the catalog header files are assembled into postgres.bki.  In particular,
+ # indexing.h had better be last, and toasting.h just before it.
+ 
+ POSTGRES_BKI_SRCS = $(addprefix $(top_srcdir)/src/include/catalog/,\
+ 	pg_proc.h pg_type.h pg_attribute.h pg_class.h \
+ 	pg_attrdef.h pg_constraint.h pg_inherits.h pg_index.h pg_operator.h \
+ 	pg_opfamily.h pg_opclass.h pg_am.h pg_amop.h pg_amproc.h \
+ 	pg_language.h pg_largeobject.h pg_aggregate.h pg_statistic.h \
+ 	pg_rewrite.h pg_trigger.h pg_listener.h pg_description.h pg_cast.h \
+ 	pg_enum.h pg_namespace.h pg_conversion.h pg_depend.h \
+ 	pg_database.h pg_tablespace.h pg_pltemplate.h \
+ 	pg_authid.h pg_auth_members.h pg_shdepend.h pg_shdescription.h \
+ 	pg_ts_config.h pg_ts_config_map.h pg_ts_dict.h \
+ 	pg_ts_parser.h pg_ts_template.h \
+ 	pg_foreign_data_wrapper.h pg_foreign_server.h pg_user_mapping.h \
+ 	toasting.h indexing.h \
+     )
+ 
+ # Generated header files need dependencies here to ensure that everything
+ # which depends on them gets rebuilt when necessary.  Note that it's important
+ # we match the dependencies shown in the subdirectory makefiles!
+ ifneq ($(subdir),src/backend/parser)
+ $(top_srcdir)/src/backend/parser/gram.h: $(top_srcdir)/src/backend/parser/gram.y
+ 	$(MAKE) -C $(top_builddir)/src/backend/parser gram.h
+ endif
+ 
+ ifneq ($(subdir),src/backend/catalog)
+ # Same logic as pg_config.h and ecpg_config.h
+ $(top_srcdir)/src/backend/catalog/fmgroids.h: $(top_srcdir)/src/backend/catalog/stamp-h ;
+ 
+ $(top_srcdir)/src/backend/catalog/schemapg.h: $(top_srcdir)/src/backend/catalog/stamp-h;
+ 
+ $(top_srcdir)/src/backend/catalog/stamp-h: $(top_srcdir)/src/backend/catalog/gen_catalog.pl $(POSTGRES_BKI_SRCS)
+ 	$(MAKE) -C $(top_builddir)/src/backend/catalog stamp-h
+ endif
+ 
+ ifneq ($(subdir),src/backend/utils)
+ $(top_builddir)/src/backend/utils/probes.h: $(top_srcdir)/src/backend/utils/probes.d
+ 	$(MAKE) -C $(top_builddir)/src/backend/utils probes.h
+ endif
+ 
+ # Make symlinks for these headers in the include directory. That way
+ # we can cut down on the -I options. Also, a symlink is automatically
+ # up to date when we update the base file.
+ #
+ # The point of the prereqdir incantation in some of the rules below is to force
+ # the symlink to use an absolute path rather than a relative path.  For headers
+ # which are generated by make distprep, the copy within src/backend will be in
+ # the source tree, and the copy in src/include will be in the build tree.
+ 
+ $(top_builddir)/src/include/parser/gram.h: $(top_srcdir)/src/backend/parser/gram.h
+ 	prereqdir=`cd $(dir $<) >/dev/null && pwd` && \
+ 	  cd $(dir $@) && rm -f $(notdir $@) && \
+ 	  $(LN_S) "$$prereqdir/$(notdir $<)" .
+ 
+ $(top_builddir)/src/include/utils/fmgroids.h: $(top_srcdir)/src/backend/catalog/fmgroids.h
+ 	prereqdir=`cd $(dir $<) >/dev/null && pwd` && \
+ 	  cd $(dir $@) && rm -f $(notdir $@) && \
+ 	  $(LN_S) "$$prereqdir/$(notdir $<)" .
+ 
+ $(top_builddir)/src/include/catalog/schemapg.h: $(top_srcdir)/src/backend/catalog/schemapg.h
+ 	prereqdir=`cd $(dir $<) >/dev/null && pwd` && \
+ 	  cd $(dir $@) && rm -f $(notdir $@) && \
+ 	  $(LN_S) "$$prereqdir/$(notdir $<)" .
+ 
+ $(top_builddir)/src/include/utils/probes.h: $(top_builddir)/src/backend/utils/probes.h
+ 	cd $(dir $@) && rm -f $(notdir $@) && \
+ 	    $(LN_S) ../../../src/backend/utils/probes.h .
+ 
  endif # not PGXS
  
  
*** a/src/backend/Makefile
--- b/src/backend/Makefile
***************
*** 105,150 **** endif
  endif # aix
  
  # Update the commonly used headers before building the subdirectories
! $(SUBDIRS:%=%-recursive): $(top_builddir)/src/include/parser/gram.h $(top_builddir)/src/include/utils/fmgroids.h $(top_builddir)/src/include/utils/probes.h
! 
  
  # The postgres.o target is needed by the rule in Makefile.global that
  # creates the exports file when MAKE_EXPORTS = true.
  postgres.o: $(OBJS)
  	$(CC) $(LDREL) $(LDFLAGS) $(call expand_subsys,$^) $(LIBS) -o $@
  
- 
- # The following targets are specified in make commands that appear in
- # the make files in our subdirectories. Note that it's important we
- # match the dependencies shown in the subdirectory makefiles!
- 
- $(srcdir)/parser/gram.h: parser/gram.y
- 	$(MAKE) -C parser gram.h
- 
- utils/fmgroids.h: utils/Gen_fmgrtab.sh $(top_srcdir)/src/include/catalog/pg_proc.h
- 	$(MAKE) -C utils fmgroids.h
- 
- utils/probes.h: utils/probes.d
- 	$(MAKE) -C utils probes.h
- 
- # Make symlinks for these headers in the include directory. That way
- # we can cut down on the -I options. Also, a symlink is automatically
- # up to date when we update the base file.
- 
- $(top_builddir)/src/include/parser/gram.h: $(srcdir)/parser/gram.h
- 	prereqdir=`cd $(dir $<) >/dev/null && pwd` && \
- 	  cd $(dir $@) && rm -f $(notdir $@) && \
- 	  $(LN_S) "$$prereqdir/$(notdir $<)" .
- 
- $(top_builddir)/src/include/utils/fmgroids.h: utils/fmgroids.h
- 	cd $(dir $@) && rm -f $(notdir $@) && \
- 	    $(LN_S) ../../../$(subdir)/utils/fmgroids.h .
- 
- $(top_builddir)/src/include/utils/probes.h: utils/probes.h
- 	cd $(dir $@) && rm -f $(notdir $@) && \
- 	    $(LN_S) ../../../$(subdir)/utils/probes.h .
- 
- 
  ifeq ($(PORTNAME), solaris)
  utils/probes.o: utils/probes.d $(SUBDIROBJS)
  	$(DTRACE) $(DTRACEFLAGS) -C -G -s $(call expand_subsys,$^) -o $@
--- 105,117 ----
  endif # aix
  
  # Update the commonly used headers before building the subdirectories
! $(SUBDIRS:%=%-recursive): $(top_builddir)/src/include/parser/gram.h $(top_builddir)/src/include/utils/fmgroids.h $(top_builddir)/src/include/utils/probes.h $(top_builddir)/src/include/catalog/schemapg.h
  
  # The postgres.o target is needed by the rule in Makefile.global that
  # creates the exports file when MAKE_EXPORTS = true.
  postgres.o: $(OBJS)
  	$(CC) $(LDREL) $(LDFLAGS) $(call expand_subsys,$^) $(LIBS) -o $@
  
  ifeq ($(PORTNAME), solaris)
  utils/probes.o: utils/probes.d $(SUBDIROBJS)
  	$(DTRACE) $(DTRACEFLAGS) -C -G -s $(call expand_subsys,$^) -o $@
***************
*** 157,162 **** distprep:
--- 124,131 ----
  	$(MAKE) -C parser	gram.c gram.h scan.c
  	$(MAKE) -C bootstrap	bootparse.c bootscanner.c
  	$(MAKE) -C utils/misc	guc-file.c
+ 	$(MAKE) -C catalog	postgres.bki postgres.description \
+ 		postgres.shdescription fmgroids.h fmgrtab.c schemapg.h
  
  
  ##########################################################################
*** /dev/null
--- b/src/backend/catalog/.cvsignore
***************
*** 0 ****
--- 1,2 ----
+ fmgrtab.c
+ fmgroids.h
*** a/src/backend/catalog/Makefile
--- b/src/backend/catalog/Makefile
***************
*** 10,54 **** subdir = src/backend/catalog
  top_builddir = ../../..
  include $(top_builddir)/src/Makefile.global
  
! OBJS = catalog.o dependency.o heap.o index.o indexing.o namespace.o aclchk.o \
!        pg_aggregate.o pg_constraint.o pg_conversion.o pg_depend.o pg_enum.o \
!        pg_inherits.o pg_largeobject.o pg_namespace.o pg_operator.o pg_proc.o \
!        pg_shdepend.o pg_type.o storage.o toasting.o
  
  BKIFILES = postgres.bki postgres.description postgres.shdescription
  
  include $(top_srcdir)/src/backend/common.mk
  
! all: $(BKIFILES)
! 
! # Note: there are some undocumented dependencies on the ordering in which
! # the catalog header files are assembled into postgres.bki.  In particular,
! # indexing.h had better be last, and toasting.h just before it.
! 
! POSTGRES_BKI_SRCS = $(addprefix $(top_srcdir)/src/include/catalog/,\
! 	pg_proc.h pg_type.h pg_attribute.h pg_class.h \
! 	pg_attrdef.h pg_constraint.h pg_inherits.h pg_index.h pg_operator.h \
! 	pg_opfamily.h pg_opclass.h pg_am.h pg_amop.h pg_amproc.h \
! 	pg_language.h pg_largeobject.h pg_aggregate.h pg_statistic.h \
! 	pg_rewrite.h pg_trigger.h pg_listener.h pg_description.h pg_cast.h \
! 	pg_enum.h pg_namespace.h pg_conversion.h pg_depend.h \
! 	pg_database.h pg_tablespace.h pg_pltemplate.h \
! 	pg_authid.h pg_auth_members.h pg_shdepend.h pg_shdescription.h \
! 	pg_ts_config.h pg_ts_config_map.h pg_ts_dict.h \
! 	pg_ts_parser.h pg_ts_template.h \
! 	pg_foreign_data_wrapper.h pg_foreign_server.h pg_user_mapping.h \
! 	toasting.h indexing.h \
!     )
  
  pg_includes = $(sort -I$(top_srcdir)/src/include -I$(top_builddir)/src/include)
  
! # see explanation in ../parser/Makefile
! postgres.description: postgres.bki ;
  
! postgres.shdescription: postgres.bki ;
  
! postgres.bki: genbki.sh $(POSTGRES_BKI_SRCS) $(top_builddir)/src/include/pg_config_manual.h
! 	AWK='$(AWK)' $(SHELL) $< $(pg_includes) --set-version=$(VERSION) -o postgres $(POSTGRES_BKI_SRCS)
  
  .PHONY: install-data
  install-data: $(BKIFILES) installdirs
--- 10,45 ----
  top_builddir = ../../..
  include $(top_builddir)/src/Makefile.global
  
! OBJS = catalog.o dependency.o fmgrtab.o heap.o index.o indexing.o namespace.o \
! 	   aclchk.o pg_aggregate.o pg_constraint.o pg_conversion.o pg_depend.o \
! 	   pg_enum.o pg_inherits.o pg_largeobject.o pg_namespace.o pg_operator.o \
! 	   pg_proc.o pg_shdepend.o pg_type.o storage.o toasting.o
  
  BKIFILES = postgres.bki postgres.description postgres.shdescription
  
  include $(top_srcdir)/src/backend/common.mk
  
! all: $(addprefix $(srcdir)/, $(BKIFILES) fmgroids.h fmgrtab.c schemapg.h)
  
  pg_includes = $(sort -I$(top_srcdir)/src/include -I$(top_builddir)/src/include)
  
! # see src/backend/parser/Makefile for notes on dependency chaining for multiple
! # output files; see src/Makefile.global.in for notes on how stamp-h files are
! # used
! $(srcdir)/postgres.bki: $(srcdir)/stamp-h ;
  
! $(srcdir)/postgres.description: $(srcdir)/stamp-h ;
  
! $(srcdir)/postgres.shdescription: $(srcdir)/stamp-h ;
! 
! $(srcdir)/fmgroids.h: $(srcdir)/stamp-h ;
! 
! $(srcdir)/fmgrtab.c: $(srcdir)/stamp-h ;
! 
! $(srcdir)/schemapg.h: $(srcdir)/stamp-h ;
! 
! $(srcdir)/stamp-h: gen_catalog.pl $(POSTGRES_BKI_SRCS) $(top_builddir)/src/include/pg_config_manual.h
! 	$(PERL) $< $(pg_includes) -o $(srcdir) --set-version=$(VERSION) $(POSTGRES_BKI_SRCS)
  
  .PHONY: install-data
  install-data: $(BKIFILES) installdirs
***************
*** 66,70 **** installdirs:
  uninstall-data:
  	rm -f $(addprefix '$(DESTDIR)$(datadir)'/, $(BKIFILES) system_views.sql information_schema.sql sql_features.txt)
  
! clean:
! 	rm -f $(BKIFILES)
--- 57,62 ----
  uninstall-data:
  	rm -f $(addprefix '$(DESTDIR)$(datadir)'/, $(BKIFILES) system_views.sql information_schema.sql sql_features.txt)
  
! # postgres.bki, postgres.description, postgres.shdescription,
! # fmgroids.h, fmgrtab.c, and schemapg.h are in the distribution tarball, so
! # they are not cleaned here.
*** /dev/null
--- b/src/backend/catalog/gen_catalog.pl
***************
*** 0 ****
--- 1,561 ----
+ #!/usr/bin/perl
+ 
+ #
+ # gen_catalog.pl
+ #
+ # Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
+ # Portions Copyright (c) 1994, Regents of the University of California
+ #
+ 
+ use strict;
+ use warnings;
+ 
+ #
+ # The purpose of this script is to generate as many of the files derived from
+ # the catalogs as possible in one script.  Since this script is written in
+ # Perl, it can be used under either Windows or UNIX-ish systems.  On the flip
+ # side, because none of what we generate here depends on architecture or
+ # configuration, we can build it all at distprep time so that, on UNIX, it
+ # is possible to build from an unmodified distribution tarball without Perl.
+ #
+ # However, if any of the relevant headers are modified, or when building from
+ # CVS (or git), Perl will be required, as this script must be rerun.
+ #
+ my @OUTPUT = (
+ 	[ 'postgres.bki', \*BKI ],
+ 	[ 'postgres.description', \*DESCR ],
+ 	[ 'postgres.shdescription', \*SHDESCR ],
+ 	[ 'fmgroids.h', \*FMGROIDS ],
+ 	[ 'fmgrtab.c', \*FMGRTAB ],
+ 	[ 'schemapg.h', \*SCHEMAPG ],
+ );
+ 
+ #
+ # There are a few types which are given one name in the C source, but a
+ # different name at the SQL level.  These are enumerated here.
+ #
+ my %RENAME_ATTTYPE = (
+ 	'Oid' => 'oid',
+ 	'NameData' => 'name',
+ 	'TransactionId' => 'xid'
+ );
+ 
+ #
+ # Argument parsing.  We could use GetOpt::Long or similar here, but doing it
+ # this way avoids depending on any outside modules.
+ #
+ my @include_path;
+ my @input_file;
+ my $output_path = '';
+ my $major_version;
+ while (@ARGV) {
+ 	my $arg = shift @ARGV;
+ 	if ($arg !~ /^-/) {
+ 		push @input_file, $arg;
+ 	}
+ 	elsif ($arg =~ /^-o/) {
+ 		$output_path = length($arg) > 2 ? substr($arg, 2) : shift @ARGV;
+ 	}
+ 	elsif ($arg =~ /^-I/) {
+ 		push @include_path, length($arg) > 2 ? substr($arg, 2) : shift @ARGV;
+ 	}
+ 	elsif ($arg =~ /^--set-version=(.*)$/) {
+ 		$major_version = $1;
+ 		# Remove minor version information, if any.
+ 		if ($major_version =~ /^(\d+.\d+)/) {
+ 			$major_version = $1;
+ 		}
+ 	}
+ 	else {
+ 		usage();
+ 	}
+ }
+ 
+ # Sanity check arguments.
+ die "No input files.\n" if ! @input_file;
+ die "No include path; you must specify -I at least once.\n" if ! @include_path;
+ die "No version specified.\n" if !defined $major_version;
+ 
+ #
+ # CAUTION: be wary about what symbols you substitute into the .bki file here!
+ # It's okay to substitute things that are expected to be really constant
+ # within a given Postgres release, such as fixed OIDs.  Do not substitute
+ # anything that could depend on platform or configuration.  (The right place
+ # to handle those sorts of things is in initdb.c's bootstrap_template1().)
+ #
+ my $BOOTSTRAP_SUPERUSERID =
+ 	find_defined_symbol('pg_authid.h', 'BOOTSTRAP_SUPERUSERID');
+ my $PG_CATALOG_NAMESPACE =
+ 	find_defined_symbol('pg_namespace.h', 'PG_CATALOG_NAMESPACE');
+ my $INTERNAL_LANGUAGE_ID =
+ 	find_defined_symbol('pg_language.h', 'INTERNALlanguageId');
+ 
+ # Make sure output_path ends in a slash.
+ if ($output_path ne '' && substr($output_path, -1) ne '/') {
+ 	$output_path .= '/';
+ }
+ 
+ # Open temporary output files.
+ for my $output (@OUTPUT) {
+ 	my $temp_name = $output_path . $output->[0] . '.tmp';
+ 	# We avoid using the three-argument form of open() here, because it is
+ 	# only supported in Perl 5.6 and higher.
+ 	open($output->[1], ">$temp_name") || die "$temp_name: $!";
+ }
+ 
+ # Opening boilerplate for postgres.bki
+ print BKI "# PostgreSQL $major_version\n";
+ 
+ # Opening boilerplate for fmgroids.h
+ print FMGROIDS <<EOM;
+ /*-------------------------------------------------------------------------
+  *
+  * fmgroids.h
+  *    Macros that define the OIDs of built-in functions.
+  *
+  * These macros can be used to avoid a catalog lookup when a specific
+  * fmgr-callable function needs to be referenced.
+  *
+  * Portions Copyright (c) 1996-2009, 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 $0
+  *	from pg_proc.h
+  *
+  *-------------------------------------------------------------------------
+  */
+ #ifndef FMGROIDS_H
+ #define FMGROIDS_H
+ 
+ /*
+  *	Constant macros for the OIDs of entries in pg_proc.
+  *
+  *	NOTE: macros are named after the prosrc value, ie the actual C name
+  *	of the implementing function, not the proname which may be overloaded.
+  *	For example, we want to be able to assign different macro names to both
+  *	char_text() and name_text() even though these both appear with proname
+  *	'text'.  If the same C function appears in more than one pg_proc entry,
+  *	its equivalent macro will be defined with the lowest OID among those
+  *	entries.
+  */
+ EOM
+ 
+ # Opening boilerplate for fmgrtab.c
+ print FMGRTAB <<EOM;
+ /*-------------------------------------------------------------------------
+  *
+  * fmgrtab.c
+  *    The function manager's table of internal functions.
+  *
+  * Portions Copyright (c) 1996-2009, 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 $0
+  *	from pg_proc.h
+  *
+  *-------------------------------------------------------------------------
+  */
+ 
+ #include "postgres.h"
+ 
+ #include "utils/fmgrtab.h"
+ 
+ EOM
+ 
+ # Opening boilerplate for schemapg.h
+ print SCHEMAPG <<EOM;
+ /*-------------------------------------------------------------------------
+  *
+  * schemapg.h
+  *    Schema_pg_xxx macros for use by relcache.c
+  *
+  * Portions Copyright (c) 1996-2009, 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 $0
+  *
+  *-------------------------------------------------------------------------
+  */
+ #ifndef SCHEMAPG_H
+ #define SCHEMAPG_H
+ 
+ EOM
+ 
+ # Main part of the work: read and process each header file.
+ my (@fmgr, %schema_pg, %catalog_name);
+ for my $input_file (@input_file)
+ {
+ 	process_input_file($input_file);
+ }
+ 
+ # We're going to iterate over this array twice and it needs to be in sorted
+ # order both times.
+ @fmgr = sort { $a->{'oid'} <=> $b->{'oid'} } @fmgr;
+ 
+ # Emit fmgr #define's and extern's, but only one per prosrc value.
+ my %fmgr_seenit;
+ foreach my $s (@fmgr) {
+ 	next if $fmgr_seenit{$s->{'prosrc'}};
+ 	$fmgr_seenit{$s->{'prosrc'}} = 1;
+ 	print FMGROIDS "#define F_" . uc($s->{'prosrc'}) . " $s->{oid}\n";
+ 	print FMGRTAB "extern Datum " . $s->{'prosrc'} . " (PG_FUNCTION_ARGS);\n";
+ }
+ 
+ # Emit fmgr_builtins table.
+ print FMGRTAB "\nconst FmgrBuiltin fmgr_builtins[] = {\n";
+ my %bmap;
+ $bmap{'t'} = 'true';
+ $bmap{'f'} = 'false';
+ foreach my $s (@fmgr) {
+     print FMGRTAB join('',
+ 		'  { ', $s->{'oid'}, ', "', $s->{'prosrc'}, '", ', $s->{'nargs'},
+ 		', ', $bmap{$s->{'strict'}}, ', ', $bmap{$s->{'retset'}}, ', ',
+ 		$s->{'prosrc'}, " },\n");
+ }
+ 
+ # Emit Schema_pg_xxx declarations.
+ while (my ($oid, $entry_list) = each %schema_pg) {
+ 	my $catalog = $catalog_name{$oid};
+ 	die "catalog with oid $oid not found" if !defined $catalog;
+ 	print SCHEMAPG "#define Schema_$catalog \\\n",
+ 		join(", \\\n", @$entry_list), "\n\n";
+ }
+ 
+ # Closing boilerplate for fmgroids.h
+ print FMGROIDS "\n#endif /* FMGROIDS_H */\n";
+ 
+ # Closing boilerplate for fmgrtab.c
+ print FMGRTAB <<EOM;
+   /* dummy entry is easier than getting rid of comma after last real one */
+   /* (not that there has ever been anything wrong with *having* a
+      comma after the last field in an array initializer) */
+   { 0, NULL, 0, false, false, NULL }
+ };
+ 
+ /* Note fmgr_nbuiltins excludes the dummy entry */
+ const int fmgr_nbuiltins = (sizeof(fmgr_builtins) / sizeof(FmgrBuiltin)) - 1;
+ EOM
+ 
+ # Closing boilerplate for schemapg.h
+ print SCHEMAPG "#endif /* SCHEMAPG_H */\n";
+ 
+ # Close output files.
+ for my $output (@OUTPUT) {
+ 	my $temp_name = $output_path . $output->[0] . '.tmp';
+ 	close($output->[1]) || die "close: $temp_name: $!";
+ }
+ 
+ # Rename temporary files to final names, if anything has changed.
+ for my $output (@OUTPUT) {
+ 	my $temp_name = $output_path . $output->[0] . '.tmp';
+ 	my $final_name = $output_path . $output->[0];
+ 	if (-e $final_name && -s $temp_name == -s $final_name) {
+ 		open(TN, "<$temp_name") || die "$temp_name: $!";
+ 		if (open(FN, "<$temp_name")) {
+ 			local $/ = undef;
+ 			my $tn = <TN>;
+ 			my $fn = <FN>;
+ 			close(FN);
+ 			if ($tn eq $fn) {
+ 				print "$output->[0] unchanged, not replacing\n";
+ 				close(TN);
+ 				unlink($temp_name) || die "unlink: $temp_name: $!";
+ 				next;
+ 			}
+ 		}
+ 		close(TN);
+ 	}
+ 	rename($temp_name, $final_name) || die "rename: $temp_name: $!";
+ }
+ 
+ # Update timestamp file.  Makefile system uses this to avoid unnecessary
+ # rebuilds.
+ open(STAMP, ">$output_path/stamp-h") || die "stamp-h: $!";
+ close(STAMP);
+ 
+ exit 0;
+ 
+ #
+ # Read and process a single input file.
+ #
+ sub process_input_file {
+ 	my ($input_file) = @_;
+ 	open(INPUT_FILE, "<$input_file") || die "$input_file: $!";
+ 
+ 	# State we need to keep track of while scanning the file.
+ 	my ($oid, $catalog, $is_bootstrap, $declaring_attributes, $reln_open);
+ 	my (@bki_attr, @attname, %attname_to_attnum, %attname_to_atttype);
+ 
+ 	# Scan the input file.
+ 	while (<INPUT_FILE>) {
+ 		# Strip C-style comments.
+ 		s;/\*(.|\n)*\*/;;g;
+ 		if (m;/\*;) {
+ 			my $next_line = <INPUT_FILE>;
+ 			die "$input_file: ends within C-style comment\n"
+ 				if !defined $next_line;
+ 			$_ .= $next_line;
+ 			redo;
+ 		}
+ 
+ 		# Strip useless whitespace and trailing semicolons.
+ 		chomp;
+ 		s/^\s+//;
+ 		s/;\s*$//;
+ 		s/\s+/ /g;
+ 
+ 		#
+ 		# DATA lines are passed through to postgres.bki after stripping off
+ 		# the DATA( and the ) on the end.  Remember the OID for use by
+ 		# DESCR() and SHDESCR().
+ 		#
+ 		# In addition, when processing pg_proc.h, we extract all of the
+ 		# "internal" functions and save them so that we can eventually write
+ 		# them out to fmgroids.h and fmgrtab.h.
+ 		#
+ 		if (/^DATA\((insert(\s+OID\s+=\s+(\d+))?\s+\((.*)\))\s*\)$/) {
+ 			my ($data, $field_data) = ($1, $4);
+ 			# Save the OID, if any, for reference by a subsequent DESCR() or
+ 			# SHDESCR() declaration.
+ 			$oid = $3;
+ 			# Pass the (almost) raw data through to postgres.bki.
+ 			$data =~ s/\bPGUID\b/$BOOTSTRAP_SUPERUSERID/g;
+ 			$data =~ s/\bPGNSP\b/$PG_CATALOG_NAMESPACE/g;
+ 			print BKI $data, "\n";
+ 			# To construct fmgroids.h and fmgrtab.c, we need to inspect some
+ 			# of the individual data fields.  Just splitting on whitespace
+ 			# won't work, because some quoted fields might contain internal
+ 			# whitespace.  We handle this by folding them all to a simple
+ 			# "xxx". Fortunately, this script doesn't need to look at any
+ 			# fields that might need quoting, so this simple hack is
+ 			# sufficient.
+ 			if (defined $catalog) {
+ 				$field_data =~ s/^\s+//;
+ 				$field_data =~ s/"[^"]*"/"xxx"/g;
+ 				my @p = split /\s+/, $field_data;
+ 				# Emit fmgr declarations for non-internal functions.
+ 				if ($catalog eq 'pg_proc'
+ 					&& $p[$attname_to_attnum{'prolang'}-1] eq '12') {
+ 				    push @fmgr, {
+ 				        'oid'     => $oid,
+ 				        'proname' => $p[$attname_to_attnum{'proname'}-1],
+ 				        'strict'  => $p[$attname_to_attnum{'proisstrict'}-1],
+ 				        'retset'  => $p[$attname_to_attnum{'proretset'}-1],
+ 				        'nargs'   => $p[$attname_to_attnum{'pronargs'}-1],
+ 				        'prosrc'  => $p[$attname_to_attnum{'prosrc'}-1],
+ 					};
+ 				}
+ 				# Emit Schema_pg info for non-system attributes.
+ 				elsif ($catalog eq 'pg_attribute'
+ 					&& $p[$attname_to_attnum{'attnum'}-1] > 0) {
+ 					if (@attname != @p) {
+ 						die sprintf "catalog has %d attributes, DATA() has "
+ 							. "%d entries\n", 0+@attname, 0+@p;
+ 					}
+ 					my @cvalue;
+ 					for (my $i = 0; $i < @p; ++$i) {
+ 						my $attname = $attname[$i];
+ 						my $atttype = $attname_to_atttype{$attname};
+ 						if (grep { $atttype eq $_ } qw(oid int2 int4 float4)) {
+ 							push @cvalue, $p[$i];
+ 						}
+ 						elsif ($atttype eq 'aclitem[]') {
+ 							if ($p[$i] ne '_null_') {
+ 								die "can't handle non-null aclitem[]: $p[$i]";
+ 							}
+ 							push @cvalue, '{ 0 }';
+ 						}
+ 						elsif ($atttype eq 'bool') {
+ 							if ($p[$i] eq 't') {
+ 								push @cvalue, 'true';
+ 							}
+ 							elsif ($p[$i] eq 'f') {
+ 								push @cvalue, 'false';
+ 							}
+ 							else {
+ 								# May be a constant, like FLOAT4PASSBYVAL.
+ 								push @cvalue, $p[$i];
+ 							}
+ 						}
+ 						elsif ($atttype eq 'char') {
+ 							push @cvalue, "'$p[$i]'";
+ 						}
+ 						elsif ($atttype eq 'name') {
+ 							push @cvalue, "{\"$p[$i]\"}";
+ 						}
+ 						else {
+ 							die "unhandled type $atttype";
+ 						}
+ 					}
+ 				    my $attrelid = $p[$attname_to_attnum{'attrelid'}-1];
+ 					push @{$schema_pg{$attrelid}},
+ 						"{ " . join(", ", @cvalue) . " }";
+ 				}
+ 			}
+ 		}
+ 		# DESCR() and SHDESCR() lines apply to the most recent catalog
+ 		# and OID.
+ 		elsif (/^DESCR\(\"(.*)\"\)$/) {
+ 			my $data = $1;
+ 			if (!defined $catalog) {
+ 				die "DESCR() does not apply to any catalog ($input_file)";
+ 			}
+ 			elsif (!defined $oid) {
+ 				die "DESCR() does not apply to any oid ($input_file)";
+ 			}
+ 			elsif ($data ne '') {
+ 				printf DESCR "%d\t%s\t0\t%s\n", $oid, $catalog, $data;
+ 			}
+ 		}
+ 		elsif (/^SHDESCR\(\"(.*)\"\)$/) {
+ 			my $data = $1;
+ 			if (!defined $catalog) {
+ 				die "SHDESCR() does not apply to any catalog ($input_file)";
+ 			}
+ 			elsif (!defined $oid) {
+ 				die "SHDESCR() does not apply to any oid ($input_file)";
+ 			}
+ 			elsif ($data ne '') {
+ 				printf SHDESCR "%d\t%s\t%s\n", $oid, $catalog, $data;
+ 			}
+ 		}
+ 		elsif (/^DECLARE_(UNIQUE_)?INDEX\((\s*[\w+]*),\s*(\d+),\s*(.*)\)/) {
+ 			my ($is_unique, $iname, $oid, $data) = ($1, $2, $3, $4);
+ 			# close catalog before declaring index
+ 			if ($reln_open) {
+ 				$reln_open = 0;
+ 				print BKI "close $catalog\n";
+ 			}
+ 			printf BKI "declare %sindex %s %s %s\n",
+ 				$is_unique ? "unique " : "", $iname, $oid, $data;
+ 		}
+ 		elsif (/^DECLARE_TOAST\((\s*[\w+]*),\s*(\d+),\s*(\d+)\)/) {
+ 			my ($toastname, $toastoid, $indexoid) = ($1, $2, $3);
+ 			# close catalog before declaring toast
+ 			if ($reln_open) {
+ 				$reln_open = 0;
+ 				print BKI "close $catalog\n";
+ 			}
+ 			print BKI "declare toast $toastoid $indexoid on $toastname\n";
+ 		}
+ 		elsif (/^BUILD_INDICES/) {
+ 			print BKI "build indices\n";
+ 		}
+ 		elsif (/^CATALOG\(([^,]*),(.*)\)/) {
+ 			my ($catname, $catoid) = ($1, $2);
+ 			# close catalog before declaring next catalog
+ 			if ($reln_open) {
+ 				$reln_open = 0;
+ 				print BKI "close $catalog\n";
+ 			}
+ 			$catalog = $catname;
+ 			$is_bootstrap = /BKI_BOOTSTRAP/;
+ 			print BKI "create " . ($is_bootstrap ? 'bootstrap ' : '')
+ 				. (/BKI_SHARED_RELATION/ ? 'shared_relation ' : '')
+ 				. (/BKI_WITHOUT_OIDS/ ? 'without_oids ' : '')
+ 				. $catalog . ' ' . $catoid . "\n";
+ 			$declaring_attributes = 1;
+ 			undef %attname_to_attnum;
+ 			undef %attname_to_atttype;
+ 			undef @attname;
+ 			$catalog_name{$catoid} = $catname;
+ 		}
+ 		elsif ($declaring_attributes) {
+ 			if ($_ =~ /^{|^$/) {
+ 				;							# just ignore it
+ 			}
+ 			elsif ($_ =~ /^}/)	{
+ 				print BKI " (\n", join(" ,\n", @bki_attr), "\n )\n";
+ 				if (! $is_bootstrap) {
+ 					print BKI "open $catalog\n";
+ 				}
+ 				undef $declaring_attributes;
+ 				$reln_open = 1;
+ 			}
+ 			else {
+ 				my @datafields = split /\s+/, $_;
+ 				my $atttype = $datafields[0];
+ 				my $attname;
+ 				if (exists $RENAME_ATTTYPE{$atttype}) {
+ 					$atttype = $RENAME_ATTTYPE{$atttype};
+ 				}
+ 		        if ($datafields[1] =~ /(.*)\[.*\]/) {   # array attribute
+ 	                $attname = $1;
+ 	                $atttype .= "[]";  					# variable-length only
+ 				}
+ 				else {
+ 					$attname = $datafields[1];
+ 				}
+ 				push @bki_attr, " $attname = $atttype";
+ 				push @attname, $attname;
+ 				$attname_to_attnum{$attname} = 0+@bki_attr;
+ 				$attname_to_atttype{$attname} = $atttype;
+ 			}
+ 		}
+ 		elsif (/^(DATA|CATALOG|DECLARE_(INDEX|UNIQUE_INDEX|TOAST))/) {
+ 			die "malformed $1 line ($input_file)";
+ 		}
+ 	}
+ 	if ($reln_open) {
+ 		print BKI "close $catalog\n";
+ 	}
+ 	close(INPUT_FILE);
+ }
+ 
+ #
+ # Find a symbol defined in a particular header file and extract the value.
+ #
+ sub find_defined_symbol {
+ 	my ($catalog_header, $symbol) = @_;
+ 	for my $path (@include_path) {
+ 		my $file = $path . '/catalog/' . $catalog_header;
+ 		next if ! -f $file;
+ 		# We avoid using the three-argument form of open() here, because it is
+ 		# only supported in Perl 5.6 and higher.
+ 		open(FIND_DEFINED_SYMBOL, "<$file") || die "$file: $!";
+ 		while (<FIND_DEFINED_SYMBOL>) {
+ 			if (/^#define\s+\Q$symbol\E\s+(\S+)/) {
+ 				return $1;
+ 			}
+ 		}
+ 		close(FIND_DEFINED_SYMBOL);
+ 		die "$file: no definition found for $symbol\n";
+ 	}
+ 	die "$catalog_header: not found in any include directory\n";
+ }
+ 
+ #
+ # Display usage message and exit.
+ #
+ sub usage
+ {
+ 	die <<EOM;
+ Usage: genbki.pl [options] header...
+ 
+ Options:
+ 	-I				path to include files
+ 	--bki			prefix for BKI output files
+ 	--set-version	PostgreSQL version number for initdb cross-check
+ 
+ genbki.pl generates .bki files from specially formatted .h files.  These .bki
+ files are used to initialize the postgres template database.
+ 
+ Report bugs to <pgsql-bugs\@postgresql.org>.
+ EOM
+ }
*** a/src/backend/catalog/genbki.sh
--- /dev/null
***************
*** 1,430 ****
- #! /bin/sh
- #-------------------------------------------------------------------------
- #
- # genbki.sh--
- #    shell script which generates .bki files from specially formatted .h
- #    files.  These .bki files are used to initialize the postgres template
- #    database.
- #
- # Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
- # Portions Copyright (c) 1994, Regents of the University of California
- #
- #
- # IDENTIFICATION
- #    $PostgreSQL$
- #
- # NOTES
- #    non-essential whitespace is removed from the generated file.
- #    if this is ever a problem, then the sed script at the very
- #    end can be changed into another awk script or something smarter.
- #
- #-------------------------------------------------------------------------
- 
- : ${AWK='awk'}
- 
- CMDNAME=`basename $0`
- 
- INCLUDE_DIRS=
- OUTPUT_PREFIX=
- INFILES=
- major_version=
- 
- #
- # Process command line switches.
- #
- while [ $# -gt 0 ]
- do
-     case $1 in
-         -I)
-             INCLUDE_DIRS="$INCLUDE_DIRS $2"
-             shift;;
-         -I*)
-             arg=`echo $1 | sed -e 's/^-I//'`
-             INCLUDE_DIRS="$INCLUDE_DIRS $arg"
-             ;;
-         -o)
-             OUTPUT_PREFIX="$2"
-             shift;;
-         -o*)
-             OUTPUT_PREFIX=`echo $1 | sed -e 's/^-o//'`
-             ;;
-         --set-version=*)
-             arg=`expr x"$1" : x"--set-version=\(.*\)"`
-             major_version=`expr x"$arg" : x'\([0-9][0-9]*\.[0-9][0-9]*\)'`
-             ;;
-         --help)
-             echo "$CMDNAME generates system catalog bootstrapping files."
-             echo
-             echo "Usage:"
-             echo "  $CMDNAME [ -I dir ] --set-version=VERSION -o prefix files..."
-             echo
-             echo "Options:"
-             echo "  -I  path to include files"
-             echo "  -o  prefix of output files"
-             echo "  --set-version  PostgreSQL version number for initdb cross-check"
-             echo
-             echo "The environment variable AWK determines which Awk program"
-             echo "to use. The default is \`awk'."
-             echo
-             echo "Report bugs to <pgsql-bugs@postgresql.org>."
-             exit 0
-             ;;
-         -*)
-             echo "$CMDNAME: invalid option: $1"
-             exit 1
-             ;;
-         *)
-             INFILES="$INFILES $1"
-             ;;
-     esac
-     shift
- done
- 
- if [ x"$INFILES" = x"" ] ; then
-     echo "$CMDNAME: no input files" 1>&2
-     exit 1
- fi
- 
- if [ x"$OUTPUT_PREFIX" = x"" ] ; then
-     echo "$CMDNAME: no output prefix specified" 1>&2
-     exit 1
- fi
- 
- if [ x"$INCLUDE_DIRS" = x"" ] ; then
-     echo "$CMDNAME: path to include directory unknown" 1>&2
-     exit 1
- fi
- 
- if [ x"$major_version" = x"" ] ; then
-     echo "$CMDNAME: invalid or no version number specified" 1>&2
-     exit 1
- fi
- 
- 
- TMPFILE="genbkitmp$$.c"
- 
- trap "rm -f $TMPFILE ${OUTPUT_PREFIX}.bki.$$ ${OUTPUT_PREFIX}.description.$$ ${OUTPUT_PREFIX}.shdescription.$$" 0 1 2 3 15
- 
- 
- # CAUTION: be wary about what symbols you substitute into the .bki file here!
- # It's okay to substitute things that are expected to be really constant
- # within a given Postgres release, such as fixed OIDs.  Do not substitute
- # anything that could depend on platform or configuration.  (The right place
- # to handle those sorts of things is in initdb.c's bootstrap_template1().)
- 
- # Get BOOTSTRAP_SUPERUSERID from catalog/pg_authid.h
- for dir in $INCLUDE_DIRS; do
-     if [ -f "$dir/catalog/pg_authid.h" ]; then
-         BOOTSTRAP_SUPERUSERID=`grep '^#define[ 	]*BOOTSTRAP_SUPERUSERID' $dir/catalog/pg_authid.h | $AWK '{ print $3 }'`
-         break
-     fi
- done
- 
- # Get PG_CATALOG_NAMESPACE from catalog/pg_namespace.h
- for dir in $INCLUDE_DIRS; do
-     if [ -f "$dir/catalog/pg_namespace.h" ]; then
-         PG_CATALOG_NAMESPACE=`grep '^#define[ 	]*PG_CATALOG_NAMESPACE' $dir/catalog/pg_namespace.h | $AWK '{ print $3 }'`
-         break
-     fi
- done
- 
- touch ${OUTPUT_PREFIX}.description.$$
- touch ${OUTPUT_PREFIX}.shdescription.$$
- 
- # ----------------
- # 	Strip comments and other trash from .h
- #
- #	Put multi-line start/end comments on a separate line
- #
- #	Rename datatypes that have different names in .h files than in SQL
- #
- #	Substitute values of configuration constants
- # ----------------
- #
- cat $INFILES | \
- sed -e 's;/\*.*\*/;;g' \
-     -e 's;/\*;\
- /*\
- ;g' \
-     -e 's;\*/;\
- */\
- ;g' | # we must run a new sed here to see the newlines we added
- sed -e "s/;[ 	]*$//g" \
-     -e "s/^[ 	]*//" \
-     -e "s/[ 	]Oid/ oid/g" \
-     -e "s/^Oid/oid/g" \
-     -e "s/(Oid/(oid/g" \
-     -e "s/[ 	]NameData/ name/g" \
-     -e "s/^NameData/name/g" \
-     -e "s/(NameData/(name/g" \
-     -e "s/[ 	]TransactionId/ xid/g" \
-     -e "s/^TransactionId/xid/g" \
-     -e "s/(TransactionId/(xid/g" \
-     -e "s/PGUID/$BOOTSTRAP_SUPERUSERID/g" \
-     -e "s/PGNSP/$PG_CATALOG_NAMESPACE/g" \
- | $AWK '
- # ----------------
- #	now use awk to process remaining .h file..
- #
- #	nc is the number of catalogs
- #	inside is a variable set to 1 when we are scanning the
- #	   contents of a catalog definition.
- #	reln_open is a flag indicating when we are processing DATA lines.
- #	   (i.e. have a relation open and need to close it)
- #	oid is the most recently seen oid, or 0 if none in the last DATA line.
- # ----------------
- BEGIN {
- 	inside = 0;
- 	bootstrap = "";
- 	shared_relation = "";
- 	without_oids = "";
- 	nc = 0;
- 	reln_open = 0;
- 	comment_level = 0;
- 	oid = 0;
- }
- 
- # ----------------
- # Anything in a /* .. */ block should be ignored.
- # Blank lines also go.
- # Note that any /* */ comment on a line by itself was removed from the line
- # by the sed above.
- # ----------------
- /^\/\*/           { comment_level += 1; next; }
- /^\*\//           { comment_level -= 1; next; }
- comment_level > 0 { next; }
- 
- /^[ 	]*$/      { next; }
- 
- # ----------------
- #	DATA() statements are basically passed right through after
- #	stripping off the DATA( and the ) on the end.
- #	Remember the OID for use by DESCR() and SHDESCR().
- # ----------------
- /^DATA\(/ {
- 	data = substr($0, 6, length($0) - 6);
- 	oid = 0;
- 	nf = split(data, datafields);
- 	if (nf >= 4 && datafields[1] == "insert" && datafields[2] == "OID" && datafields[3] == "=")
- 	{
- 		oid = datafields[4];
- 	}
- 	print data;
- 	next;
- }
- 
- /^DESCR\(/ {
- 	if (oid != 0)
- 	{
- 		data = substr($0, 8, length($0) - 9);
- 		if (data != "")
- 			printf "%d\t%s\t0\t%s\n", oid, catalog, data >>descriptionfile;
- 	}
- 	next;
- }
- 
- /^SHDESCR\(/ {
- 	if (oid != 0)
- 	{
- 		data = substr($0, 10, length($0) - 11);
- 		if (data != "")
- 			printf "%d\t%s\t%s\n", oid, catalog, data >>shdescriptionfile;
- 	}
- 	next;
- }
- 
- /^DECLARE_INDEX\(/ {
- # ----
- #  end any prior catalog data insertions before starting a define index
- # ----
- 	if (reln_open == 1) {
- 		print "close " catalog;
- 		reln_open = 0;
- 	}
- 
- 	data = substr($0, 15, length($0) - 15);
- 	pos = index(data, ",");
- 	iname = substr(data, 1, pos-1);
- 	data = substr(data, pos+1, length(data)-pos);
- 	pos = index(data, ",");
- 	oid = substr(data, 1, pos-1);
- 	data = substr(data, pos+1, length(data)-pos);
- 
- 	print "declare index " iname " " oid " " data
- }
- 
- /^DECLARE_UNIQUE_INDEX\(/ {
- # ----
- #  end any prior catalog data insertions before starting a define unique index
- # ----
- 	if (reln_open == 1) {
- 		print "close " catalog;
- 		reln_open = 0;
- 	}
- 
- 	data = substr($0, 22, length($0) - 22);
- 	pos = index(data, ",");
- 	iname = substr(data, 1, pos-1);
- 	data = substr(data, pos+1, length(data)-pos);
- 	pos = index(data, ",");
- 	oid = substr(data, 1, pos-1);
- 	data = substr(data, pos+1, length(data)-pos);
- 
- 	print "declare unique index " iname " " oid " " data
- }
- 
- /^DECLARE_TOAST\(/ {
- # ----
- #  end any prior catalog data insertions before starting a define toast
- # ----
- 	if (reln_open == 1) {
- 		print "close " catalog;
- 		reln_open = 0;
- 	}
- 
- 	data = substr($0, 15, length($0) - 15);
- 	pos = index(data, ",");
- 	tname = substr(data, 1, pos-1);
- 	data = substr(data, pos+1, length(data)-pos);
- 	pos = index(data, ",");
- 	toastoid = substr(data, 1, pos-1);
- 	data = substr(data, pos+1, length(data)-pos);
- 	# previous commands already removed the trailing );
- 	indexoid = data;
- 
- 	print "declare toast " toastoid " " indexoid " on " tname
- }
- 
- /^BUILD_INDICES/	{ print "build indices"; }
- 	
- # ----------------
- #	CATALOG() definitions take some more work.
- # ----------------
- /^CATALOG\(/ { 
- # ----
- #  end any prior catalog data insertions before starting a new one..
- # ----
- 	if (reln_open == 1) {
- 		print "close " catalog;
- 		reln_open = 0;
- 	}
- 
- # ----
- #  get the name and properties of the new catalog
- # ----
- 	pos = index($1,")");
- 	catalogandoid = substr($1,9,pos-9);
- 	pos = index(catalogandoid, ",");
- 	catalog = substr(catalogandoid, 1, pos-1);
- 	oid = substr(catalogandoid, pos+1, length(catalogandoid)-pos);
- 
- 	if ($0 ~ /BKI_BOOTSTRAP/) {
- 		bootstrap = "bootstrap ";
- 	}
- 	if ($0 ~ /BKI_SHARED_RELATION/) {
- 		shared_relation = "shared_relation ";
- 	}
- 	if ($0 ~ /BKI_WITHOUT_OIDS/) {
- 		without_oids = "without_oids ";
- 	}
- 
-         i = 1;
- 	inside = 1;
-         nc++;
- 	next;
- }
- 
- # ----------------
- #	process the columns of the catalog definition
- #
- #	attname[ x ] contains the attribute name for attribute x
- #	atttype[ x ] contains the attribute type fot attribute x
- # ----------------
- inside == 1 {
- # ----
- #  ignore a leading brace line..
- # ----
-         if ($1 ~ /\{/)
- 		next;
- 
- # ----
- #  if this is the last line, then output the bki catalog stuff.
- # ----
- 	if ($1 ~ /}/) {
- 		print "create " bootstrap shared_relation without_oids catalog " " oid;
- 		print "\t(";
- 
- 		for (j=1; j<i-1; j++) {
- 			print "\t " attname[ j ] " = " atttype[ j ] " ,";
- 		}
- 		print "\t " attname[ j ] " = " atttype[ j ] ;
- 		print "\t)";
- 
- 		if (bootstrap == "") {
- 			print "open " catalog;
- 		}
- 
- 		i = 1;
- 		reln_open = 1;
- 		inside = 0;
- 		bootstrap = "";
- 		shared_relation = "";
- 		without_oids = "";
- 		next;
- 	}
- 
- # ----
- #  we are inside the catalog definition, so keep sucking up
- #  attribute names and types
- # ----
- 	if ($2 ~ /\[.*\]/) {			# array attribute
- 		idlen = index($2,"[") - 1;
- 		atttype[ i ] = $1 "[]";		# variable-length only..
- 		attname[ i ] = substr($2,1,idlen);
- 	} else {
- 		atttype[ i ] = $1;
- 		attname[ i ] = $2;
- 	}
- 	i++;
- 	next;
- }
- 
- END {
- 	if (reln_open == 1) {
- 		print "close " catalog;
- 		reln_open = 0;
- 	}
- }
- ' "descriptionfile=${OUTPUT_PREFIX}.description.$$" "shdescriptionfile=${OUTPUT_PREFIX}.shdescription.$$" > $TMPFILE || exit
- 
- echo "# PostgreSQL $major_version" >${OUTPUT_PREFIX}.bki.$$
- 
- sed -e '/^[ 	]*$/d' \
-     -e 's/[ 	][ 	]*/ /g' $TMPFILE >>${OUTPUT_PREFIX}.bki.$$ || exit
- 
- #
- # Sanity check: if one of the sed/awk/etc commands fails, we'll probably
- # end up with a .bki file that is empty or just a few lines.  Cross-check
- # that the files are of reasonable size.  The numbers here are arbitrary,
- # but are much smaller than the actual expected sizes as of Postgres 7.2.
- #
- if [ `wc -c < ${OUTPUT_PREFIX}.bki.$$` -lt 100000 ]; then
-     echo "$CMDNAME: something seems to be wrong with the .bki file" >&2
-     exit 1
- fi
- if [ `wc -c < ${OUTPUT_PREFIX}.description.$$` -lt 10000 ]; then
-     echo "$CMDNAME: something seems to be wrong with the .description file" >&2
-     exit 1
- fi
- if [ `wc -c < ${OUTPUT_PREFIX}.shdescription.$$` -lt 10 ]; then
-     echo "$CMDNAME: something seems to be wrong with the .shdescription file" >&2
-     exit 1
- fi
- 
- # Looks good, commit ...
- 
- mv ${OUTPUT_PREFIX}.bki.$$ ${OUTPUT_PREFIX}.bki || exit
- mv ${OUTPUT_PREFIX}.description.$$ ${OUTPUT_PREFIX}.description || exit
- mv ${OUTPUT_PREFIX}.shdescription.$$ ${OUTPUT_PREFIX}.shdescription || exit
- 
- exit 0
--- 0 ----
*** a/src/backend/utils/.cvsignore
--- /dev/null
***************
*** 1,2 ****
- fmgrtab.c
- fmgroids.h
--- 0 ----
*** a/src/backend/utils/Gen_fmgrtab.pl
--- /dev/null
***************
*** 1,194 ****
- #! /usr/bin/perl -w
- #-------------------------------------------------------------------------
- #
- # Gen_fmgrtab.pl
- #    Perl equivalent of Gen_fmgrtab.sh
- #
- # Usage: perl Gen_fmgrtab.pl path-to-pg_proc.h
- #
- # The reason for implementing this functionality twice is that we don't
- # require people to have perl to build from a tarball, but on the other
- # hand Windows can't deal with shell scripts.
- #
- # Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
- # Portions Copyright (c) 1994, Regents of the University of California
- #
- #
- # IDENTIFICATION
- #    $PostgreSQL$
- #
- #-------------------------------------------------------------------------
- 
- use strict;
- use warnings;
- 
- # Collect arguments
- my $infile = shift;
- defined($infile) || die "$0: missing required argument: pg_proc.h\n";
- 
- # Note: see Gen_fmgrtab.sh for detailed commentary on what this is doing
- 
- # Collect column numbers for pg_proc columns we need
- my ($proname, $prolang, $proisstrict, $proretset, $pronargs, $prosrc);
- 
- open(I, $infile) || die "Could not open $infile: $!";
- while (<I>)
- {
-     if (m/#define Anum_pg_proc_proname\s+(\d+)/) {
- 	$proname = $1;
-     }
-     if (m/#define Anum_pg_proc_prolang\s+(\d+)/) {
- 	$prolang = $1;
-     }
-     if (m/#define Anum_pg_proc_proisstrict\s+(\d+)/) {
- 	$proisstrict = $1;
-     }
-     if (m/#define Anum_pg_proc_proretset\s+(\d+)/) {
- 	$proretset = $1;
-     }
-     if (m/#define Anum_pg_proc_pronargs\s+(\d+)/) {
- 	$pronargs = $1;
-     }
-     if (m/#define Anum_pg_proc_prosrc\s+(\d+)/) {
- 	$prosrc = $1;
-     }
- }
- close(I);
- 
- # Collect the raw data
- my @fmgr = ();
- 
- open(I, $infile) || die "Could not open $infile: $!";
- while (<I>)
- {
-     next unless (/^DATA/);
-     s/^[^O]*OID[^=]*=[ \t]*//;
-     s/\(//;
-     s/"[^"]*"/"xxx"/g;
-     my @p = split;
-     next if ($p[$prolang] ne "12");
-     push @fmgr,
-       {
-         oid     => $p[0],
-         proname => $p[$proname],
-         strict  => $p[$proisstrict],
-         retset  => $p[$proretset],
-         nargs   => $p[$pronargs],
-         prosrc  => $p[$prosrc],
-       };
- }
- close(I);
- 
- # Emit headers for both files
- open(H, '>', "$$-fmgroids.h") || die "Could not open $$-fmgroids.h: $!";
- print H 
- qq|/*-------------------------------------------------------------------------
-  *
-  * fmgroids.h
-  *    Macros that define the OIDs of built-in functions.
-  *
-  * These macros can be used to avoid a catalog lookup when a specific
-  * fmgr-callable function needs to be referenced.
-  *
-  * Portions Copyright (c) 1996-2009, 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 $0
-  *	from $infile
-  *
-  *-------------------------------------------------------------------------
-  */
- #ifndef FMGROIDS_H
- #define FMGROIDS_H
- 
- /*
-  *	Constant macros for the OIDs of entries in pg_proc.
-  *
-  *	NOTE: macros are named after the prosrc value, ie the actual C name
-  *	of the implementing function, not the proname which may be overloaded.
-  *	For example, we want to be able to assign different macro names to both
-  *	char_text() and name_text() even though these both appear with proname
-  *	'text'.  If the same C function appears in more than one pg_proc entry,
-  *	its equivalent macro will be defined with the lowest OID among those
-  *	entries.
-  */
- |;
- 
- open(T, '>', "$$-fmgrtab.c") || die "Could not open $$-fmgrtab.c: $!";
- print T
- qq|/*-------------------------------------------------------------------------
-  *
-  * fmgrtab.c
-  *    The function manager's table of internal functions.
-  *
-  * Portions Copyright (c) 1996-2009, 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 $0
-  *	from $infile
-  *
-  *-------------------------------------------------------------------------
-  */
- 
- #include "postgres.h"
- 
- #include "utils/fmgrtab.h"
- 
- |;
- 
- # Emit #define's and extern's -- only one per prosrc value
- my %seenit;
- foreach my $s (sort {$a->{oid} <=> $b->{oid}} @fmgr)
- {
-     next if $seenit{$s->{prosrc}};
-     $seenit{$s->{prosrc}} = 1;
-     print H "#define F_" . uc $s->{prosrc} . " $s->{oid}\n";
-     print T "extern Datum $s->{prosrc} (PG_FUNCTION_ARGS);\n";
- }
- 
- # Create the fmgr_builtins table
- print T "\nconst FmgrBuiltin fmgr_builtins[] = {\n";
- my %bmap;
- $bmap{'t'} = 'true';
- $bmap{'f'} = 'false';
- foreach my $s (sort {$a->{oid} <=> $b->{oid}} @fmgr)
- {
-     print T
- 	"  { $s->{oid}, \"$s->{prosrc}\", $s->{nargs}, $bmap{$s->{strict}}, $bmap{$s->{retset}}, $s->{prosrc} },\n";
- }
- 
- # And add the file footers.
- print H "\n#endif /* FMGROIDS_H */\n";
- close(H);
- 
- print T
- qq|  /* dummy entry is easier than getting rid of comma after last real one */
-   /* (not that there has ever been anything wrong with *having* a
-      comma after the last field in an array initializer) */
-   { 0, NULL, 0, false, false, NULL }
- };
- 
- /* Note fmgr_nbuiltins excludes the dummy entry */
- const int fmgr_nbuiltins = (sizeof(fmgr_builtins) / sizeof(FmgrBuiltin)) - 1;
- |;
- 
- close(T);
- 
- # Finally, rename the completed files into place.
- rename "$$-fmgroids.h", "fmgroids.h"
-     || die "Could not rename $$-fmgroids.h to fmgroids.h: $!";
- rename "$$-fmgrtab.c", "fmgrtab.c"
-     || die "Could not rename $$-fmgrtab.c to fmgrtab.c: $!";
- 
- exit 0;
--- 0 ----
*** a/src/backend/utils/Gen_fmgrtab.sh
--- /dev/null
***************
*** 1,253 ****
- #! /bin/sh
- #-------------------------------------------------------------------------
- #
- # Gen_fmgrtab.sh
- #    shell script to generate fmgroids.h and fmgrtab.c from pg_proc.h
- #
- # NOTE: if you change this, you need to fix Gen_fmgrtab.pl too!
- #
- # Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
- # Portions Copyright (c) 1994, Regents of the University of California
- #
- #
- # IDENTIFICATION
- #    $PostgreSQL$
- #
- #-------------------------------------------------------------------------
- 
- CMDNAME=`basename $0`
- 
- if [ x"$AWK" = x"" ]; then
- 	AWK=awk
- fi
- 
- cleanup(){
-     [ x"$noclean" != x"t" ] && rm -f "$SORTEDFILE" "$$-$OIDSFILE" "$$-$TABLEFILE"
- }
- 
- noclean=
- 
- #
- # Process command line switches.
- #
- while [ $# -gt 0 ]
- do
-     case $1 in
-         --noclean)
-             noclean=t
-             ;;
-         --help)
-             echo "$CMDNAME generates fmgroids.h and fmgrtab.c from pg_proc.h."
-             echo
-             echo "Usage:"
-             echo "  $CMDNAME inputfile"
-             echo
-             echo "The environment variable AWK determines which Awk program"
-             echo "to use. The default is \`awk'."
-             echo
-             echo "Report bugs to <pgsql-bugs@postgresql.org>."
-             exit 0
-             ;;
-         -*)
-             echo "$CMDNAME: invalid option: $1"
-             exit 1
-             ;;
-         *)
-             INFILE=$1
-             ;;
-     esac
-     shift
- done
- 
- 
- if [ x"$INFILE" = x ] ; then
-     echo "$CMDNAME: no input file"
-     exit 1
- fi
- 
- SORTEDFILE="$$-fmgr.data"
- OIDSFILE=fmgroids.h
- TABLEFILE=fmgrtab.c
- 
- 
- trap 'echo "Caught signal." ; cleanup ; exit 1' 1 2 15
- 
- #
- # Collect the column numbers of the pg_proc columns we need.  Because we will
- # be looking at data that includes the OID as the first column, add one to
- # each column number.
- #
- proname=`egrep '^#define Anum_pg_proc_proname[ 	]' $INFILE | $AWK '{print $3+1}'`
- prolang=`egrep '^#define Anum_pg_proc_prolang[ 	]' $INFILE | $AWK '{print $3+1}'`
- proisstrict=`egrep '^#define Anum_pg_proc_proisstrict[ 	]' $INFILE | $AWK '{print $3+1}'`
- proretset=`egrep '^#define Anum_pg_proc_proretset[ 	]' $INFILE | $AWK '{print $3+1}'`
- pronargs=`egrep '^#define Anum_pg_proc_pronargs[ 	]' $INFILE | $AWK '{print $3+1}'`
- prosrc=`egrep '^#define Anum_pg_proc_prosrc[ 	]' $INFILE | $AWK '{print $3+1}'`
- 
- #
- # Generate the file containing raw pg_proc data.  We do three things here:
- # 1. Strip off the DATA macro call, leaving procedure OID as $1
- # and all the pg_proc field values as $2, $3, etc on each line.
- # 2. Fold quoted fields to simple "xxx".  We need this because such fields
- # may contain whitespace, which would confuse awk's counting of fields.
- # Fortunately, this script doesn't need to look at any fields that might
- # need quoting, so this simple hack is sufficient.
- # 3. Select out just the rows for internal-language procedures.
- #
- # Note assumption here that INTERNALlanguageId == 12.
- #
- egrep '^DATA' $INFILE | \
- sed 	-e 's/^[^O]*OID[^=]*=[ 	]*//' \
- 	-e 's/(//' \
- 	-e 's/"[^"]*"/"xxx"/g' | \
- $AWK "\$$prolang == \"12\" { print }" | \
- sort -n > $SORTEDFILE
- 
- if [ $? -ne 0 ]; then
-     cleanup
-     echo "$CMDNAME failed"
-     exit 1
- fi
- 
- 
- cpp_define=`echo $OIDSFILE | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ | sed -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g'`
- 
- #
- # Generate fmgroids.h
- #
- cat > "$$-$OIDSFILE" <<FuNkYfMgRsTuFf
- /*-------------------------------------------------------------------------
-  *
-  * $OIDSFILE
-  *    Macros that define the OIDs of built-in functions.
-  *
-  * These macros can be used to avoid a catalog lookup when a specific
-  * fmgr-callable function needs to be referenced.
-  *
-  * Portions Copyright (c) 1996-2009, 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 $CMDNAME
-  *	from $INFILE
-  *
-  *-------------------------------------------------------------------------
-  */
- #ifndef $cpp_define
- #define $cpp_define
- 
- /*
-  *	Constant macros for the OIDs of entries in pg_proc.
-  *
-  *	NOTE: macros are named after the prosrc value, ie the actual C name
-  *	of the implementing function, not the proname which may be overloaded.
-  *	For example, we want to be able to assign different macro names to both
-  *	char_text() and name_text() even though these both appear with proname
-  *	'text'.  If the same C function appears in more than one pg_proc entry,
-  *	its equivalent macro will be defined with the lowest OID among those
-  *	entries.
-  */
- FuNkYfMgRsTuFf
- 
- tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' < $SORTEDFILE | \
- $AWK "{ if (seenit[\$$prosrc]++ == 0)
- 	printf \"#define F_%s %s\\n\", \$$prosrc, \$1; }" >> "$$-$OIDSFILE"
- 
- if [ $? -ne 0 ]; then
-     cleanup
-     echo "$CMDNAME failed"
-     exit 1
- fi
- 
- cat >> "$$-$OIDSFILE" <<FuNkYfMgRsTuFf
- 
- #endif /* $cpp_define */
- FuNkYfMgRsTuFf
- 
- #
- # Generate fmgr's built-in-function table.
- #
- # Print out the function declarations, then the table that refers to them.
- #
- cat > "$$-$TABLEFILE" <<FuNkYfMgRtAbStUfF
- /*-------------------------------------------------------------------------
-  *
-  * $TABLEFILE
-  *    The function manager's table of internal functions.
-  *
-  * Portions Copyright (c) 1996-2009, 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 $CMDNAME
-  *	from $INFILE
-  *
-  *-------------------------------------------------------------------------
-  */
- 
- #include "postgres.h"
- 
- #include "utils/fmgrtab.h"
- 
- FuNkYfMgRtAbStUfF
- 
- $AWK "{ if (seenit[\$$prosrc]++ == 0)
- 	print \"extern Datum\", \$$prosrc, \"(PG_FUNCTION_ARGS);\"; }" $SORTEDFILE >> "$$-$TABLEFILE"
- 
- if [ $? -ne 0 ]; then
-     cleanup
-     echo "$CMDNAME failed"
-     exit 1
- fi
- 
- 
- cat >> "$$-$TABLEFILE" <<FuNkYfMgRtAbStUfF
- 
- const FmgrBuiltin fmgr_builtins[] = {
- FuNkYfMgRtAbStUfF
- 
- # Note: using awk arrays to translate from pg_proc values to fmgrtab values
- # may seem tedious, but avoid the temptation to write a quick x?y:z
- # conditional expression instead.  Not all awks have conditional expressions.
- 
- $AWK "BEGIN {
-     Bool[\"t\"] = \"true\";
-     Bool[\"f\"] = \"false\";
- }
- { printf (\"  { %d, \\\"%s\\\", %d, %s, %s, %s },\\n\"),
- 	\$1, \$$prosrc, \$$pronargs, Bool[\$$proisstrict], Bool[\$$proretset], \$$prosrc ;
- }" $SORTEDFILE >> "$$-$TABLEFILE"
- 
- if [ $? -ne 0 ]; then
-     cleanup
-     echo "$CMDNAME failed"
-     exit 1
- fi
- 
- cat >> "$$-$TABLEFILE" <<FuNkYfMgRtAbStUfF
-   /* dummy entry is easier than getting rid of comma after last real one */
-   /* (not that there has ever been anything wrong with *having* a
-      comma after the last field in an array initializer) */
-   { 0, NULL, 0, false, false, NULL }
- };
- 
- /* Note fmgr_nbuiltins excludes the dummy entry */
- const int fmgr_nbuiltins = (sizeof(fmgr_builtins) / sizeof(FmgrBuiltin)) - 1;
- FuNkYfMgRtAbStUfF
- 
- # We use the temporary files to avoid problems with concurrent runs
- # (which can happen during parallel make).
- mv "$$-$OIDSFILE" $OIDSFILE
- mv "$$-$TABLEFILE" $TABLEFILE
- 
- cleanup
- exit 0
--- 0 ----
*** a/src/backend/utils/Makefile
--- b/src/backend/utils/Makefile
***************
*** 8,24 **** subdir = src/backend/utils
  top_builddir = ../../..
  include $(top_builddir)/src/Makefile.global
  
- OBJS        = fmgrtab.o
  SUBDIRS     = adt cache error fmgr hash init mb misc mmgr resowner sort time
  
  include $(top_srcdir)/src/backend/common.mk
  
! all: fmgroids.h probes.h
! 
! $(SUBDIRS:%=%-recursive): fmgroids.h
! 
! fmgroids.h fmgrtab.c: Gen_fmgrtab.sh $(top_srcdir)/src/include/catalog/pg_proc.h
! 	AWK='$(AWK)' $(SHELL) $< $(top_srcdir)/src/include/catalog/pg_proc.h
  
  ifneq ($(enable_dtrace), yes)
  probes.h: Gen_dummy_probes.sed
--- 8,18 ----
  top_builddir = ../../..
  include $(top_builddir)/src/Makefile.global
  
  SUBDIRS     = adt cache error fmgr hash init mb misc mmgr resowner sort time
  
  include $(top_srcdir)/src/backend/common.mk
  
! all: probes.h
  
  ifneq ($(enable_dtrace), yes)
  probes.h: Gen_dummy_probes.sed
***************
*** 35,38 **** endif
  
  
  clean:
! 	rm -f fmgroids.h fmgrtab.c probes.h
--- 29,32 ----
  
  
  clean:
! 	rm -f probes.h
*** a/src/backend/utils/cache/relcache.c
--- b/src/backend/utils/cache/relcache.c
***************
*** 48,53 ****
--- 48,54 ----
  #include "catalog/pg_proc.h"
  #include "catalog/pg_rewrite.h"
  #include "catalog/pg_type.h"
+ #include "catalog/schemapg.h"
  #include "commands/trigger.h"
  #include "miscadmin.h"
  #include "optimizer/clauses.h"
*** a/src/include/catalog/pg_attribute.h
--- b/src/include/catalog/pg_attribute.h
***************
*** 219,254 **** typedef FormData_pg_attribute *Form_pg_attribute;
   *		pg_type
   * ----------------
   */
- #define Schema_pg_type \
- { 1247, {"typname"},	   19, -1, 0, NAMEDATALEN, 1, 0, -1, -1, false, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typnamespace"},  26, -1, 0,	4,	2, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typowner"},	   26, -1, 0,	4,	3, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typlen"},		   21, -1, 0,	2,	4, 0, -1, -1, true, 'p', 's', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typbyval"},	   16, -1, 0,	1,	5, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typtype"},	   18, -1, 0,	1,	6, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typcategory"},   18, -1, 0,	1,	7, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typispreferred"},16, -1, 0,	1,	8, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typisdefined"},  16, -1, 0,	1,	9, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typdelim"},	   18, -1, 0,	1, 10, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typrelid"},	   26, -1, 0,	4, 11, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typelem"},	   26, -1, 0,	4, 12, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typarray"},	   26, -1, 0,	4, 13, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typinput"},	   24, -1, 0,	4, 14, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typoutput"},	   24, -1, 0,	4, 15, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typreceive"},    24, -1, 0,	4, 16, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typsend"},	   24, -1, 0,	4, 17, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typmodin"},	   24, -1, 0,	4, 18, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typmodout"},	   24, -1, 0,	4, 19, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typanalyze"},    24, -1, 0,	4, 20, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typalign"},	   18, -1, 0,	1, 21, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typstorage"},    18, -1, 0,	1, 22, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typnotnull"},    16, -1, 0,	1, 23, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typbasetype"},   26, -1, 0,	4, 24, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typtypmod"},	   23, -1, 0,	4, 25, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typndims"},	   23, -1, 0,	4, 26, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1247, {"typdefaultbin"}, 25, -1, 0, -1, 27, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }, \
- { 1247, {"typdefault"},    25, -1, 0, -1, 28, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }
- 
  DATA(insert ( 1247 typname			19 -1 0 NAMEDATALEN	1 0 -1 -1 f p c t f f t 0 _null_));
  DATA(insert ( 1247 typnamespace		26 -1 0 4   2 0 -1 -1 t p i t f f t 0 _null_));
  DATA(insert ( 1247 typowner			26 -1 0 4   3 0 -1 -1 t p i t f f t 0 _null_));
--- 219,224 ----
***************
*** 289,321 **** DATA(insert ( 1247 tableoid			26 0 0  4  -7 0 -1 -1 t p i t f f t 0 _null_));
   *		pg_proc
   * ----------------
   */
- #define Schema_pg_proc \
- { 1255, {"proname"},			19, -1, 0, NAMEDATALEN,  1, 0, -1, -1, false, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1255, {"pronamespace"},		26, -1, 0, 4,	2, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1255, {"proowner"},			26, -1, 0, 4,	3, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1255, {"prolang"},			26, -1, 0, 4,	4, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1255, {"procost"},		   700, -1, 0, 4,	5, 0, -1, -1, FLOAT4PASSBYVAL, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1255, {"prorows"},		   700, -1, 0, 4,	6, 0, -1, -1, FLOAT4PASSBYVAL, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1255, {"provariadic"},		26, -1, 0, 4,	7, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1255, {"proisagg"},			16, -1, 0, 1,	8, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1255, {"proiswindow"},		16, -1, 0, 1,	9, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1255, {"prosecdef"},			16, -1, 0, 1, 10, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1255, {"proisstrict"},		16, -1, 0, 1, 11, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1255, {"proretset"},			16, -1, 0, 1, 12, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1255, {"provolatile"},		18, -1, 0, 1, 13, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1255, {"pronargs"},			21, -1, 0, 2, 14, 0, -1, -1, true, 'p', 's', true, false, false, true, 0, { 0 } }, \
- { 1255, {"pronargdefaults"},	21, -1, 0, 2, 15, 0, -1, -1, true, 'p', 's', true, false, false, true, 0, { 0 } }, \
- { 1255, {"prorettype"},			26, -1, 0, 4, 16, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1255, {"proargtypes"},		30, -1, 0, -1, 17, 1, -1, -1, false, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1255, {"proallargtypes"},   1028, -1, 0, -1, 18, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }, \
- { 1255, {"proargmodes"},	  1002, -1, 0, -1, 19, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }, \
- { 1255, {"proargnames"},	  1009, -1, 0, -1, 20, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }, \
- { 1255, {"proargdefaults"},		25, -1, 0, -1, 21, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }, \
- { 1255, {"prosrc"},				25, -1, 0, -1, 22, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }, \
- { 1255, {"probin"},				17, -1, 0, -1, 23, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }, \
- { 1255, {"proconfig"},		  1009, -1, 0, -1, 24, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }, \
- { 1255, {"proacl"},			  1034, -1, 0, -1, 25, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }
- 
  DATA(insert ( 1255 proname			19 -1 0 NAMEDATALEN	1 0 -1 -1 f p c t f f t 0 _null_));
  DATA(insert ( 1255 pronamespace		26 -1 0 4   2 0 -1 -1 t p i t f f t 0 _null_));
  DATA(insert ( 1255 proowner			26 -1 0 4   3 0 -1 -1 t p i t f f t 0 _null_));
--- 259,264 ----
***************
*** 353,379 **** DATA(insert ( 1255 tableoid			26 0 0  4  -7 0 -1 -1 t p i t f f t 0 _null_));
   *		pg_attribute
   * ----------------
   */
- #define Schema_pg_attribute \
- { 1249, {"attrelid"},	  26, -1, 0,	4,	1, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attname"},	  19, -1, 0, NAMEDATALEN,	2, 0, -1, -1, false, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1249, {"atttypid"},	  26, -1, 0,	4,	3, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attstattarget"}, 23, -1, 0,	4,	4, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attdistinct"}, 700, -1, 0,	4,	5, 0, -1, -1, FLOAT4PASSBYVAL, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attlen"},		  21, -1, 0,	2,	6, 0, -1, -1, true, 'p', 's', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attnum"},		  21, -1, 0,	2,	7, 0, -1, -1, true, 'p', 's', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attndims"},	  23, -1, 0,	4,	8, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attcacheoff"},  23, -1, 0,	4,	9, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1249, {"atttypmod"},	  23, -1, 0,	4, 10, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attbyval"},	  16, -1, 0,	1, 11, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attstorage"},   18, -1, 0,	1, 12, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attalign"},	  18, -1, 0,	1, 13, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attnotnull"},   16, -1, 0,	1, 14, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1249, {"atthasdef"},	  16, -1, 0,	1, 15, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attisdropped"}, 16, -1, 0,	1, 16, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attislocal"},   16, -1, 0,	1, 17, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attinhcount"},  23, -1, 0,	4, 18, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1249, {"attacl"},		1034, -1, 0,  -1, 19, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }
- 
  DATA(insert ( 1249 attrelid			26 -1 0  4   1 0 -1 -1 t p i t f f t 0 _null_));
  DATA(insert ( 1249 attname			19 -1 0 NAMEDATALEN  2 0 -1 -1 f p c t f f t 0 _null_));
  DATA(insert ( 1249 atttypid			26 -1 0  4   3 0 -1 -1 t p i t f f t 0 _null_));
--- 296,301 ----
***************
*** 405,437 **** DATA(insert ( 1249 tableoid			26 0 0  4  -7 0 -1 -1 t p i t f f t 0 _null_));
   *		pg_class
   * ----------------
   */
- #define Schema_pg_class \
- { 1259, {"relname"},	   19, -1, 0, NAMEDATALEN, 1, 0, -1, -1, false, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relnamespace"},  26, -1, 0,	4,	2, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1259, {"reltype"},	   26, -1, 0,	4,	3, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relowner"},	   26, -1, 0,	4,	4, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relam"},		   26, -1, 0,	4,	5, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relfilenode"},   26, -1, 0,	4,	6, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1259, {"reltablespace"}, 26, -1, 0,	4,	7, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relpages"},	   23, -1, 0,	4,	8, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1259, {"reltuples"},	   700, -1, 0, 4,	9, 0, -1, -1, FLOAT4PASSBYVAL, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1259, {"reltoastrelid"}, 26, -1, 0,	4, 10, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1259, {"reltoastidxid"}, 26, -1, 0,	4, 11, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relhasindex"},   16, -1, 0,	1, 12, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relisshared"},   16, -1, 0,	1, 13, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relistemp"},	   16, -1, 0,	1, 14, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relkind"},	   18, -1, 0,	1, 15, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relnatts"},	   21, -1, 0,	2, 16, 0, -1, -1, true, 'p', 's', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relchecks"},	   21, -1, 0,	2, 17, 0, -1, -1, true, 'p', 's', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relhasoids"},    16, -1, 0,	1, 18, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relhaspkey"},    16, -1, 0,	1, 19, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relhasrules"},   16, -1, 0,	1, 20, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relhastriggers"},16, -1, 0,	1, 21, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relhassubclass"},16, -1, 0,	1, 22, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relfrozenxid"},  28, -1, 0,	4, 23, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0, { 0 } }, \
- { 1259, {"relacl"},		 1034, -1, 0, -1, 24, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }, \
- { 1259, {"reloptions"},  1009, -1, 0, -1, 25, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0, { 0 } }
- 
  DATA(insert ( 1259 relname			19 -1 0 NAMEDATALEN	1 0 -1 -1 f p c t f f t 0 _null_));
  DATA(insert ( 1259 relnamespace		26 -1 0 4   2 0 -1 -1 t p i t f f t 0 _null_));
  DATA(insert ( 1259 reltype			26 -1 0 4   3 0 -1 -1 t p i t f f t 0 _null_));
--- 327,332 ----
***************
*** 470,476 **** DATA(insert ( 1259 tableoid			26 0 0  4  -7 0 -1 -1 t p i t f f t 0 _null_));
   *
   * pg_index is not bootstrapped in the same way as the other relations that
   * have hardwired pg_attribute entries in this file.  However, we do need
!  * a "Schema_xxx" macro for it --- see relcache.c.
   * ----------------
   */
  #define Schema_pg_index \
--- 365,373 ----
   *
   * pg_index is not bootstrapped in the same way as the other relations that
   * have hardwired pg_attribute entries in this file.  However, we do need
!  * a "Schema_xxx" macro for it --- see relcache.c.  But since there are no
!  * DATA() statements for pg_index in this file (or anywhere else), this can't
!  * be automatically generated, so we hard-code it here.
   * ----------------
   */
  #define Schema_pg_index \
*** a/src/include/catalog/pg_proc.h
--- b/src/include/catalog/pg_proc.h
***************
*** 10,18 ****
   * $PostgreSQL$
   *
   * NOTES
!  *	  The script catalog/genbki.sh reads this file and generates .bki
!  *	  information from the DATA() statements.  utils/Gen_fmgrtab.sh
!  *	  generates fmgroids.h and fmgrtab.c the same way.
   *
   *	  XXX do NOT break up DATA() statements into multiple lines!
   *		  the scripts are not as smart as you might think...
--- 10,18 ----
   * $PostgreSQL$
   *
   * NOTES
!  *	  The script catalog/gen_catalog.pl reads this file and generates .bki
!  *	  information from the DATA() statements; it also generates fmgroids.h
!  *	  and fmgrtab.c.
   *
   *	  XXX do NOT break up DATA() statements into multiple lines!
   *		  the scripts are not as smart as you might think...
#28Peter Eisentraut
peter_e@gmx.net
In reply to: Robert Haas (#1)
Re: autogenerating headers & bki stuff

On Tuesday 30 June 2009 06:59:51 Robert Haas wrote:

The attached patch merges all of the logic currently in genbki.sh and
Gen_fmgrtab.{sh,pl} into a single script called gen_catalog.pl

I can't really convince myself to like this change. I think there is some
merit that these scripts are separate. I'm not sure what the combined script
buys us except that it is a lot bigger and does everything at once instead of
in two or three steps.

That together with the big makefile moving around makes me think that this
would cause more confusion and not much advantage.

Btw., is this stamp-h business really necessary? I guess you copied that from
pg_config.h, but the reason there is that everything depends on pg_config.h,
and rerunning configure would normally cause everything to be rebuilt. The
files we are looking at here should only change when something is edited.

#29Alvaro Herrera
alvherre@commandprompt.com
In reply to: Peter Eisentraut (#28)
Re: autogenerating headers & bki stuff

Peter Eisentraut escribi�:

On Tuesday 30 June 2009 06:59:51 Robert Haas wrote:

The attached patch merges all of the logic currently in genbki.sh and
Gen_fmgrtab.{sh,pl} into a single script called gen_catalog.pl

I can't really convince myself to like this change. I think there is some
merit that these scripts are separate. I'm not sure what the combined script
buys us except that it is a lot bigger and does everything at once instead of
in two or three steps.

Maybe we can move forward in little steps. For example it would be
excellent to have the schemapg.h file autogenerated instead of having to
edit two copies of those definitions.

I'm not sure that it buys us a lot to have all those things in a single
script. Why not have a script to generate schemapg.h, another one to
generate the bki stuff, another one to generate the fmgrtab header?
They don't seem to share a lot of code anyway (and even if they do,
surely we can add a .pm module containing common code).

--
Alvaro Herrera http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support

#30Robert Haas
robertmhaas@gmail.com
In reply to: Peter Eisentraut (#28)
Re: autogenerating headers & bki stuff

On Tue, Aug 11, 2009 at 4:52 PM, Peter Eisentraut<peter_e@gmx.net> wrote:

On Tuesday 30 June 2009 06:59:51 Robert Haas wrote:

The attached patch merges all of the logic currently in genbki.sh and
Gen_fmgrtab.{sh,pl} into a single script called gen_catalog.pl

I can't really convince myself to like this change.  I think there is some
merit that these scripts are separate.  I'm not sure what the combined script
buys us except that it is a lot bigger and does everything at once instead of
in two or three steps.

That together with the big makefile moving around makes me think that this
would cause more confusion and not much advantage.

Btw., is this stamp-h business really necessary?  I guess you copied that from
pg_config.h, but the reason there is that everything depends on pg_config.h,
and rerunning configure would normally cause everything to be rebuilt.  The
files we are looking at here should only change when something is edited.

It definitely has less appeal without the anum.h stuff.

I think there is some benefit in having a single script because it
means that if we want to add additional syntax in the future (like
BKI_EXECUTE or DATA_DEFAULTS or some kind of more human-readable
notation for functions or opclasses, all of which were discussed
upthread) there is only one place to change. But is that sufficient
reason to commit it at this point, given that we don't have a
fully-fleshed out design for any of those things? Not sure. Building
schemapg.h automatically seems definitely nice to me.

The stamp-h stuff is quite important for minimizing unnecessary
rebuilds. Without that, any change to any include/catalog/*.h file
will trigger a massive rebuild. With it, it only triggers a rebuild
if one of the outputs actually changes, and only for those portions
for which the output actually changed.

...Robert