|
57 | 57 | $output_path .= '/';
|
58 | 58 | }
|
59 | 59 |
|
60 |
| -# Open temp files |
61 |
| -my $tmpext = ".tmp$$"; |
62 |
| -my $bkifile = $output_path . 'postgres.bki'; |
63 |
| -open my $bki, '>', $bkifile . $tmpext |
64 |
| - or die "can't open $bkifile$tmpext: $!"; |
65 |
| -my $schemafile = $output_path . 'schemapg.h'; |
66 |
| -open my $schemapg, '>', $schemafile . $tmpext |
67 |
| - or die "can't open $schemafile$tmpext: $!"; |
68 |
| -my $descrfile = $output_path . 'postgres.description'; |
69 |
| -open my $descr, '>', $descrfile . $tmpext |
70 |
| - or die "can't open $descrfile$tmpext: $!"; |
71 |
| -my $shdescrfile = $output_path . 'postgres.shdescription'; |
72 |
| -open my $shdescr, '>', $shdescrfile . $tmpext |
73 |
| - or die "can't open $shdescrfile$tmpext: $!"; |
74 |
| - |
75 | 60 | # Read all the files into internal data structures.
|
76 | 61 | my @catnames;
|
77 | 62 | my %catalogs;
|
78 | 63 | my %catalog_data;
|
79 | 64 | my @toast_decls;
|
80 | 65 | my @index_decls;
|
| 66 | +my %oidcounts; |
| 67 | + |
81 | 68 | foreach my $header (@input_files)
|
82 | 69 | {
|
83 | 70 | $header =~ /(.+)\.h$/
|
|
94 | 81 | $catalogs{$catname} = $catalog;
|
95 | 82 | }
|
96 | 83 |
|
| 84 | + # While checking for duplicated OIDs, we ignore the pg_class OID and |
| 85 | + # rowtype OID of bootstrap catalogs, as those are expected to appear |
| 86 | + # in the initial data for pg_class and pg_type. For regular catalogs, |
| 87 | + # include these OIDs. (See also Catalog::FindAllOidsFromHeaders |
| 88 | + # if you change this logic.) |
| 89 | + if (!$catalog->{bootstrap}) |
| 90 | + { |
| 91 | + $oidcounts{ $catalog->{relation_oid} }++ |
| 92 | + if ($catalog->{relation_oid}); |
| 93 | + $oidcounts{ $catalog->{rowtype_oid} }++ |
| 94 | + if ($catalog->{rowtype_oid}); |
| 95 | + } |
| 96 | + |
97 | 97 | # Not all catalogs have a data file.
|
98 | 98 | if (-e $datfile)
|
99 | 99 | {
|
100 |
| - $catalog_data{$catname} = Catalog::ParseData($datfile, $schema, 0); |
| 100 | + my $data = Catalog::ParseData($datfile, $schema, 0); |
| 101 | + $catalog_data{$catname} = $data; |
| 102 | + |
| 103 | + # Check for duplicated OIDs while we're at it. |
| 104 | + foreach my $row (@$data) |
| 105 | + { |
| 106 | + $oidcounts{ $row->{oid} }++ if defined $row->{oid}; |
| 107 | + } |
101 | 108 | }
|
102 | 109 |
|
103 | 110 | # If the header file contained toast or index info, build BKI
|
|
108 | 115 | sprintf "declare toast %s %s on %s\n",
|
109 | 116 | $toast->{toast_oid}, $toast->{toast_index_oid},
|
110 | 117 | $toast->{parent_table};
|
| 118 | + $oidcounts{ $toast->{toast_oid} }++; |
| 119 | + $oidcounts{ $toast->{toast_index_oid} }++; |
111 | 120 | }
|
112 | 121 | foreach my $index (@{ $catalog->{indexing} })
|
113 | 122 | {
|
|
116 | 125 | $index->{is_unique} ? 'unique ' : '',
|
117 | 126 | $index->{index_name}, $index->{index_oid},
|
118 | 127 | $index->{index_decl};
|
| 128 | + $oidcounts{ $index->{index_oid} }++; |
119 | 129 | }
|
120 | 130 | }
|
121 | 131 |
|
| 132 | +# Complain and exit if we found any duplicate OIDs. |
| 133 | +# While duplicate OIDs would only cause a failure if they appear in |
| 134 | +# the same catalog, our project policy is that manually assigned OIDs |
| 135 | +# should be globally unique, to avoid confusion. |
| 136 | +my $found = 0; |
| 137 | +foreach my $oid (keys %oidcounts) |
| 138 | +{ |
| 139 | + next unless $oidcounts{$oid} > 1; |
| 140 | + print "Duplicate oids detected:\n" if !$found; |
| 141 | + print "$oid\n"; |
| 142 | + $found++; |
| 143 | +} |
| 144 | +die "found $found duplicate OID(s) in catalog data\n" if $found; |
| 145 | + |
122 | 146 | # Fetch some special data that we will substitute into the output file.
|
123 | 147 | # CAUTION: be wary about what symbols you substitute into the .bki file here!
|
124 | 148 | # It's okay to substitute things that are expected to be really constant
|
|
224 | 248 | pg_type => \%typeoids);
|
225 | 249 |
|
226 | 250 |
|
| 251 | +# Open temp files |
| 252 | +my $tmpext = ".tmp$$"; |
| 253 | +my $bkifile = $output_path . 'postgres.bki'; |
| 254 | +open my $bki, '>', $bkifile . $tmpext |
| 255 | + or die "can't open $bkifile$tmpext: $!"; |
| 256 | +my $schemafile = $output_path . 'schemapg.h'; |
| 257 | +open my $schemapg, '>', $schemafile . $tmpext |
| 258 | + or die "can't open $schemafile$tmpext: $!"; |
| 259 | +my $descrfile = $output_path . 'postgres.description'; |
| 260 | +open my $descr, '>', $descrfile . $tmpext |
| 261 | + or die "can't open $descrfile$tmpext: $!"; |
| 262 | +my $shdescrfile = $output_path . 'postgres.shdescription'; |
| 263 | +open my $shdescr, '>', $shdescrfile . $tmpext |
| 264 | + or die "can't open $shdescrfile$tmpext: $!"; |
| 265 | + |
227 | 266 | # Generate postgres.bki, postgres.description, postgres.shdescription,
|
228 | 267 | # and pg_*_d.h headers.
|
229 | 268 | print "Generating BKI files and symbol definition headers...\n";
|
|
0 commit comments