1#!/usr/bin/perl
2#----------------------------------------------------------------------
3#
4# unused_oids
5#    Finds blocks of manually-assignable OIDs that have not already been
6#    claimed by previous hackers.  The main use is for finding available
7#    OIDs for new internal functions.  The numbers printed are inclusive
8#    ranges of unused OIDs.
9#
10#    Before using a large empty block, make sure you aren't about
11#    to take over what was intended as expansion space for something
12#    else.
13#
14# Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
15# Portions Copyright (c) 1994, Regents of the University of California
16#
17# src/include/catalog/unused_oids
18#
19#----------------------------------------------------------------------
20
21use strict;
22use warnings;
23
24# Must run in src/include/catalog
25use FindBin;
26chdir $FindBin::RealBin or die "could not cd to $FindBin::RealBin: $!\n";
27
28use lib "$FindBin::RealBin/../../backend/catalog/";
29use Catalog;
30
31my @input_files = glob("pg_*.h");
32
33my $oids = Catalog::FindAllOidsFromHeaders(@input_files);
34
35# Also push FirstGenbkiObjectId to serve as a terminator for the last gap.
36my $FirstGenbkiObjectId =
37  Catalog::FindDefinedSymbol('access/transam.h', '..', 'FirstGenbkiObjectId');
38push @{$oids}, $FirstGenbkiObjectId;
39
40my $prev_oid = 0;
41my @sortedoids = sort { $a <=> $b } @{$oids};
42foreach my $oid (@sortedoids)
43{
44	if ($oid > $prev_oid + 1)
45	{
46		if ($oid > $prev_oid + 2)
47		{
48			printf "%d - %d\n", $prev_oid + 1, $oid - 1;
49		}
50		else
51		{
52			printf "%d\n", $prev_oid + 1;
53		}
54	}
55	$prev_oid = $oid;
56}
57
58my $suggestion;
59do
60{
61	$suggestion = int(8000 + rand(2000));
62} while (grep(/^$suggestion$/, @{$oids}));
63
64my $navailable = 0;
65foreach my $oid (@sortedoids)
66{
67	if ($oid > $suggestion)
68	{
69		$navailable = $oid - $suggestion;
70		last;
71	}
72}
73
74printf "Patches should use a more-or-less consecutive range of OIDs.\n";
75printf
76  "Best practice is to start with a random choice in the range 8000-9999.\n";
77printf
78  "Suggested random unused OID: $suggestion ($navailable consecutive OID(s) available starting here)\n";
79