v2-0001-Provide-script-to-renumber-OIDs.patch
text/x-patch
Filename: v2-0001-Provide-script-to-renumber-OIDs.patch
Type: text/x-patch
Part: 0
Patch
Format: format-patch
Series: patch v2-0001
Subject: Provide script to renumber OIDs.
| File | + | − |
|---|---|---|
| doc/src/sgml/bki.sgml | 16 | 0 |
| src/include/catalog/renumber_oids.pl | 193 | 0 |
From c6f5a1f6016feeb7f7ea94e504be6d23a264ca07 Mon Sep 17 00:00:00 2001
From: John Naylor <jcnaylor@gmail.com>
Date: Mon, 11 Mar 2019 01:05:15 +0800
Subject: [PATCH v2] Provide script to renumber OIDs.
Historically, It's been considered good practice to choose an OID that's
at the beginning of the range shown by the unused_oids script, but
nowadays that space is getting cramped, leading to merge conflicts.
Instead, allow developers to use high-numbered OIDs, and remap them
to a lower range at some future date.
---
doc/src/sgml/bki.sgml | 16 +++
src/include/catalog/renumber_oids.pl | 193 +++++++++++++++++++++++++++
2 files changed, 209 insertions(+)
create mode 100644 src/include/catalog/renumber_oids.pl
diff --git a/doc/src/sgml/bki.sgml b/doc/src/sgml/bki.sgml
index 3c5830bc8a..7e553dc30d 100644
--- a/doc/src/sgml/bki.sgml
+++ b/doc/src/sgml/bki.sgml
@@ -392,6 +392,22 @@
at compile time.)
</para>
+ <para>
+ For a variety of reasons, newly assigned OIDs should occupy the lower
+ end of the reserved range. Because multiple patches considered for
+ inclusion into <productname>PostgreSQL</productname> could be using
+ the same new OIDs, there is the possibilty of conflict. To mitigate
+ this, there is a convention that OIDs 8000 and over are reserved for
+ development. This reduces the effort in rebasing over the HEAD branch.
+ To enable committers to move these OIDs to the lower range easily,
+ <filename>renumber_oids.pl</filename> can map OIDs as in the following,
+ following, which maps any OIDs between 8000 and 8999, inclusive, to
+ unused OIDs starting at 2000:
+<programlisting>
+$ perl renumber_oids.pl --first-mapped-oid 8000 --last-mapped-oid 8999 --first-target-oid 2000 *.dat
+</programlisting>
+ </para>
+
<para>
The OID counter starts at 10000 at the beginning of a bootstrap run.
If a row from a source other than <filename>postgres.bki</filename>
diff --git a/src/include/catalog/renumber_oids.pl b/src/include/catalog/renumber_oids.pl
new file mode 100644
index 0000000000..79537465bc
--- /dev/null
+++ b/src/include/catalog/renumber_oids.pl
@@ -0,0 +1,193 @@
+#!/usr/bin/perl
+#----------------------------------------------------------------------
+#
+# renumber_oids.pl
+# Perl script that shifts a range of high-numbered OIDs in the given
+# catalog data file(s) to a lower range.
+#
+# Note: This does not format the output, so you will still need to
+# run reformat_dat_file.pl.
+#
+# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
+# Portions Copyright (c) 1994, Regents of the University of California
+#
+# src/include/catalog/renumber_oids.pl
+#
+#----------------------------------------------------------------------
+
+use strict;
+use warnings;
+
+use FindBin;
+use Getopt::Long;
+use Data::Dumper;
+$Data::Dumper::Terse = 1;
+
+# If you copy this script to somewhere other than src/include/catalog,
+# you'll need to modify this "use lib" or provide a suitable -I switch.
+use lib "$FindBin::RealBin/../../backend/catalog/";
+use Catalog;
+
+# Must run in src/include/catalog
+chdir $FindBin::RealBin or die "could not cd to $FindBin::RealBin: $!\n";
+
+my $FirstGenbkiObjectId =
+ Catalog::FindDefinedSymbol('access/transam.h', '..',
+ 'FirstGenbkiObjectId');
+
+# Process command line switches.
+my $output_path = '';
+my $first_mapped_oid;
+my $last_mapped_oid = $FirstGenbkiObjectId - 1;
+my $first_target_oid = 1;
+
+GetOptions(
+ 'output:s' => \$output_path,
+ 'first-mapped-oid:i' => \$first_mapped_oid,
+ 'last-mapped-oid:i' => \$last_mapped_oid,
+ 'first-target-oid:i' => \$first_target_oid) || usage();
+
+my $next_oid = $first_target_oid;
+
+# Sanity check arguments.
+die "No input files.\n" unless @ARGV;
+die "output range is higher than input range"
+ if $first_target_oid > $first_mapped_oid;
+
+# Make sure output_path ends in a slash.
+if ($output_path ne '' && substr($output_path, -1) ne '/')
+{
+ $output_path .= '/';
+}
+
+# Read all the input files into internal data structures.
+# We pass data file names as arguments and then look for matching
+# headers to parse the schema from.
+my %catalogs;
+my %catalog_data;
+my @catnames;
+foreach my $datfile (@ARGV)
+{
+ $datfile =~ /(.+)\.dat$/
+ or die "Input files need to be data (.dat) files.\n";
+
+ my $header = "$1.h";
+ die "There in no header file corresponding to $datfile"
+ if !-e $header;
+
+ my $catalog = Catalog::ParseHeader($header);
+ my $catname = $catalog->{catname};
+ my $schema = $catalog->{columns};
+
+ push @catnames, $catname;
+ $catalogs{$catname} = $catalog;
+
+ $catalog_data{$catname} = Catalog::ParseData($datfile, $schema, 1);
+}
+
+# Collect all the assigned OIDs in numerical order.
+my @header_files = (glob("pg_*.h"), qw(indexing.h toasting.h));
+my $oids = Catalog::FindAllOidsFromHeaders(@header_files);
+my @oids = sort { $a <=> $b } @$oids;
+
+# Write the data.
+foreach my $catname (@catnames)
+{
+ my $catalog = $catalogs{$catname};
+ my @attnames;
+ my $schema = $catalog->{columns};
+
+ foreach my $column (@$schema)
+ {
+ my $attname = $column->{name};
+ push @attnames, $attname
+ }
+
+ # Write output files to specified directory.
+ my $datfile = "$output_path$catname.dat";
+ open my $dat, '>', $datfile
+ or die "can't open $datfile: $!";
+
+ foreach my $data (@{ $catalog_data{$catname} })
+ {
+ # Hash ref representing a data entry.
+ if (ref $data eq 'HASH')
+ {
+ my %values = %$data;
+
+ $values{oid} = get_lower_oid($values{oid})
+ if defined $values{oid}
+ && $values{oid} >= $first_mapped_oid
+ && $values{oid} <= $last_mapped_oid;
+
+ $values{array_type_oid} = get_lower_oid($values{oid})
+ if defined $values{array_type_oid}
+ && $values{array_type_oid} >= $first_mapped_oid
+ && $values{array_type_oid} <= $last_mapped_oid;
+
+ print $dat Dumper(\%values);
+ print $dat ",\n";
+ }
+
+ # Preserve blank lines.
+ elsif ($data =~ /^\s*$/)
+ {
+ print $dat "\n";
+ }
+
+ # Preserve comments or brackets that are on their own line.
+ elsif ($data =~ /^\s*(\[|\]|#.*?)\s*$/)
+ {
+ print $dat "$1\n";
+ }
+ }
+ close $dat;
+}
+
+# Return the next available OID above $first_target_oid.
+sub get_lower_oid
+{
+ my $old_oid = shift;
+ my $new_oid;
+
+ for (;;)
+ {
+ if (scalar @oids == 0 || $next_oid < $oids[0])
+ {
+ $new_oid = $next_oid;
+ warn sprintf "failed to map OID %d\n", $old_oid
+ if $new_oid >= $first_mapped_oid;
+ $next_oid++;
+ return $new_oid;
+ }
+ elsif ($next_oid > $oids[0])
+ {
+ shift @oids;
+ }
+ elsif ($oids[0] == $next_oid)
+ {
+ shift @oids;
+ $next_oid++;
+ }
+ else
+ {
+ die "unreachable\n";
+ }
+ }
+}
+
+sub usage
+{
+ die <<EOM;
+Usage: renumber_oids.pl [--output <path>] --first-mapped-oid X --last-mapped-oid Y --first-target-oid Z datafile...
+
+Options:
+ --output output directory (default '.')
+ --first-mapped-oid first OID to be mapped
+ --last-mapped-oid last OID to be mapped
+ --first-target-oid first OID to map to
+
+Expects a list of .dat files as arguments.
+
+EOM
+}
base-commit: 203749a8a66096171f808dd8e870d08d8ad57e5e
--
2.17.1