Hi, On 2018-12-09 18:43:14 -0500, Tom Lane wrote: > Andres Freund <and...@anarazel.de> writes: > > On 2018-12-09 17:14:42 -0500, Tom Lane wrote: > >> Well, that's just a different very-easily-broken assumption. There are > >> a lot of things that make auto-assigned OIDs unstable, and I do not think > >> that we want to guarantee that they'll hold still across a release series. > > > Why wouldn't they be for genbki (rather than initdb) assigned oids? I > > don't think it's reasonable to add new functions or such post release > > that would have move oid assignments for other objects? > > As you've got this set up, we couldn't change *anything* for fear of > it moving auto-assignments; there's no isolation between catalogs.
But there wasn't any previously either? > Another thing I seriously dislike is that this allows people to omit OIDs > from .dat entries in catalogs where we traditionally hand-assign OIDs. That's not new, is it? Sure, now genbki.pl assigns the oid, but previously it'd just have been heap_insert()? bootparse.y/bootstrap.c never enforced that oids are assigned for tables that have oids. > That's not a good idea because it would mean those entries don't have > stable OIDs, whereas the whole point of hand assignment is to ensure > all built-in objects of a particular type have stable OIDs. Now, you > could argue about the usefulness of that policy for any given catalog; > but if we decide that catalog X doesn't need stable OIDs then that should > be an intentional policy change, not something that can happen because > one lazy hacker didn't follow the policy. I think we should change that policy, but I also think that there wasn't any meaningful "assignment policy" change in what I did. So that just seems like a separate argument. Note that changing that for "prominent" catalogs would be a bit more work than just changing the policy, as we'd need to assign oids before the lookup tables are built - although the current behaviour would kind of allow us to implement the "not crazy" policy of allowing auto-assignment as long as the object isn't referenced; but via an imo fairly opaque mechanism. > > I'm fine with adding a distinct range, the earlier version of the patch > > had that. I'd asked for comments if anybody felt a need to keep that, > > nobody replied... I alternatively proposed that we could just start at > > FirstNormalObjectId for those and update the server's oid start value to > > the maximum genbki assigned oid. Do you have preferences around that? > > Yeah, I thought about the latter as well. But it adds complexity to the > bootstrap process and makes it harder to tell what assigned a particular > OID, so I'd rather go with the former, at least until the OID situation > gets too tight to allow for daylight between the ranges. Yea, it doesn't seem perfect, that's basically why I didn't go for it last time. > It looks to me like as of HEAD, genbki.pl is auto-assigning about 1470 > OIDs. Meanwhile, on my RHEL6 machine, initdb is auto-assigning about > 1740 OIDs (what a coincidence); of those, 872 are collation entries > that are absorbed from the system environment. So the second number is > likely to vary a lot from platform to platform. (I don't have ICU > enabled; I wonder how many that typically adds.) > > I'd be inclined to allow say 2000 OIDs for genbki.pl, with 4384 therefore > available for initdb. We could expect to have to raise the boundary > from time to time, but not very often. I've attached a patch implementing that. I'm not particularly in love with FirstGenbkiObjectId as the symbol, but I couldn't think of something more descriptive. I changed the length of fmgr_builtin_oid_index to FirstGenbkiObjectId - until we allow pg_proc oids to be auto-assigned that'd just be wasted memory otherwise? I did *not* change record_plan_function_dependency(), it seems correct that it doesn't track genbki assigned oids, they certainly can't change while a server is running. But I'm not entirely clear to why that's not using FirstNormalObjectId as the cutoff, so perhaps I'm missing something. Similar with logic in predicate.c. I did however change postgres_fdw's is_builtin(), as that says: /* * Return true if given object is one of PostgreSQL's built-in objects. * - * We use FirstBootstrapObjectId as the cutoff, so that we only consider + * We use FirstGenbkiObjectId as the cutoff, so that we only consider * objects with hand-assigned OIDs to be "built in", not for instance any * function or type defined in the information_schema. * @@ -154,7 +154,7 @@ lookup_shippable(Oid objectId, Oid classId, PgFdwRelationInfo *fpinfo) and >= FirstGenbkiObjectId would not be maniually assigned. I added a throwaway "with 9000-9999 tentatively reserved for forks." to transam.h, but I'm not sure we really want that, or whether that's good wording. Greetings, Andres Freund
diff --git a/contrib/postgres_fdw/shippable.c b/contrib/postgres_fdw/shippable.c index 7f2ed0499c0..fb98faa5fd7 100644 --- a/contrib/postgres_fdw/shippable.c +++ b/contrib/postgres_fdw/shippable.c @@ -137,7 +137,7 @@ lookup_shippable(Oid objectId, Oid classId, PgFdwRelationInfo *fpinfo) /* * Return true if given object is one of PostgreSQL's built-in objects. * - * We use FirstBootstrapObjectId as the cutoff, so that we only consider + * We use FirstGenbkiObjectId as the cutoff, so that we only consider * objects with hand-assigned OIDs to be "built in", not for instance any * function or type defined in the information_schema. * @@ -154,7 +154,7 @@ lookup_shippable(Oid objectId, Oid classId, PgFdwRelationInfo *fpinfo) bool is_builtin(Oid objectId) { - return (objectId < FirstBootstrapObjectId); + return (objectId < FirstGenbkiObjectId); } /* diff --git a/src/backend/catalog/Makefile b/src/backend/catalog/Makefile index 0865240f11f..aaa3af7e5a1 100644 --- a/src/backend/catalog/Makefile +++ b/src/backend/catalog/Makefile @@ -88,7 +88,9 @@ generated-header-symlinks: $(top_builddir)/src/include/catalog/header-stamp # instead is cheating a bit, but it will achieve the goal of updating the # version number when it changes. bki-stamp: genbki.pl Catalog.pm $(POSTGRES_BKI_SRCS) $(POSTGRES_BKI_DATA) $(top_srcdir)/configure.in - $(PERL) -I $(catalogdir) $< --set-version=$(MAJORVERSION) $(POSTGRES_BKI_SRCS) + $(PERL) -I $(catalogdir) $< \ + -I $(top_srcdir)/src/include/ --set-version=$(MAJORVERSION) \ + $(POSTGRES_BKI_SRCS) touch $@ # The generated headers must all be symlinked into builddir/src/include/, diff --git a/src/backend/catalog/genbki.pl b/src/backend/catalog/genbki.pl index edc8ea9f533..8e2a2480be6 100644 --- a/src/backend/catalog/genbki.pl +++ b/src/backend/catalog/genbki.pl @@ -22,6 +22,7 @@ use warnings; my @input_files; my $output_path = ''; my $major_version; +my $include_path; # Process command line switches. while (@ARGV) @@ -31,6 +32,10 @@ while (@ARGV) { push @input_files, $arg; } + elsif ($arg =~ /^-I/) + { + $include_path = length($arg) > 2 ? substr($arg, 2) : shift @ARGV; + } elsif ($arg =~ /^-o/) { $output_path = length($arg) > 2 ? substr($arg, 2) : shift @ARGV; @@ -50,6 +55,7 @@ while (@ARGV) # Sanity check arguments. die "No input files.\n" if !@input_files; die "--set-version must be specified.\n" if !defined $major_version; +die "-I, the header include path, must be specified.\n" if !$include_path; # Make sure output_path ends in a slash. if ($output_path ne '' && substr($output_path, -1) ne '/') @@ -133,17 +139,9 @@ foreach my $header (@input_files) # While duplicate OIDs would only cause a failure if they appear in # the same catalog, our project policy is that manually assigned OIDs # should be globally unique, to avoid confusion. -# -# Also use the loop to determine the maximum explicitly assigned oid -# found in the data file, we'll use that for default oid assignments. my $found = 0; -my $maxoid = 0; foreach my $oid (keys %oidcounts) { - if ($oid > $maxoid) - { - $maxoid = $oid; - } next unless $oidcounts{$oid} > 1; print STDERR "Duplicate OIDs detected:\n" if !$found; print STDERR "$oid\n"; @@ -151,6 +149,15 @@ foreach my $oid (keys %oidcounts) } die "found $found duplicate OID(s) in catalog data\n" if $found; + +# Oids not specified in the input files are automatically assigned, +# starting at FirstGenbkiObjectId. +my $FirstGenbkiObjectId = + Catalog::FindDefinedSymbol('access/transam.h', $include_path, + 'FirstGenbkiObjectId'); +my $GenbkiNextOid = $FirstGenbkiObjectId; + + # Fetch some special data that we will substitute into the output file. # 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 @@ -418,8 +425,8 @@ EOM # Assign oid if oid column exists and no explicit assignment in row if ($attname eq "oid" and not defined $bki_values{$attname}) { - $bki_values{$attname} = $maxoid; - $maxoid++; + $bki_values{$attname} = $GenbkiNextOid; + $GenbkiNextOid++; } # Substitute constant values we acquired above. @@ -858,6 +865,7 @@ sub usage Usage: genbki.pl [options] header... Options: + -I include path -o output path --set-version PostgreSQL version number for initdb cross-check diff --git a/src/backend/utils/Gen_fmgrtab.pl b/src/backend/utils/Gen_fmgrtab.pl index ca282913552..ed16737a6a1 100644 --- a/src/backend/utils/Gen_fmgrtab.pl +++ b/src/backend/utils/Gen_fmgrtab.pl @@ -79,9 +79,9 @@ foreach my $datfile (@input_files) } # Fetch some values for later. -my $FirstBootstrapObjectId = +my $FirstGenbkiObjectId = Catalog::FindDefinedSymbol('access/transam.h', $include_path, - 'FirstBootstrapObjectId'); + 'FirstGenbkiObjectId'); my $INTERNALlanguageId = Catalog::FindDefinedSymbolFromData($catalog_data{pg_language}, 'INTERNALlanguageId'); @@ -252,13 +252,13 @@ const int fmgr_nbuiltins = (sizeof(fmgr_builtins) / sizeof(FmgrBuiltin)); # Create fmgr_builtins_oid_index table. # -# Note that the array has to be filled up to FirstBootstrapObjectId, +# Note that the array has to be filled up to FirstGenbkiObjectId, # as we can't rely on zero initialization as 0 is a valid mapping. print $tfh qq| -const uint16 fmgr_builtin_oid_index[FirstBootstrapObjectId] = { +const uint16 fmgr_builtin_oid_index[FirstGenbkiObjectId] = { |; -for (my $i = 0; $i < $FirstBootstrapObjectId; $i++) +for (my $i = 0; $i < $FirstGenbkiObjectId; $i++) { my $oid = $fmgr_builtin_oid_index[$i]; @@ -269,7 +269,7 @@ for (my $i = 0; $i < $FirstBootstrapObjectId; $i++) $oid = 'InvalidOidBuiltinMapping'; } - if ($i + 1 == $FirstBootstrapObjectId) + if ($i + 1 == $FirstGenbkiObjectId) { print $tfh " $oid\n"; } diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c index 73ff48c1963..231bf885989 100644 --- a/src/backend/utils/fmgr/fmgr.c +++ b/src/backend/utils/fmgr/fmgr.c @@ -75,7 +75,7 @@ fmgr_isbuiltin(Oid id) uint16 index; /* fast lookup only possible if original oid still assigned */ - if (id >= FirstBootstrapObjectId) + if (id >= FirstGenbkiObjectId) return NULL; /* diff --git a/src/include/access/transam.h b/src/include/access/transam.h index 83ec3f19797..f979a065f9f 100644 --- a/src/include/access/transam.h +++ b/src/include/access/transam.h @@ -71,18 +71,21 @@ /* ---------- * Object ID (OID) zero is InvalidOid. * - * OIDs 1-9999 are reserved for manual assignment (see the files - * in src/include/catalog/). + * OIDs 1-9999 are reserved for manual assignment (see .dat files in + * src/include/catalog/), with 9000-9999 tentatively reserved for forks. * - * OIDS 10000-16383 are reserved for assignment during initdb - * using the OID generator. (We start the generator at 10000.) + * OIDs 10000-12000 are reserved for assignment by genbki.pl, when the + * .dat files in src/include/catalog/ do not specify oids. + * + * OIDS 12000-16383 are reserved for assignment during initdb + * using the OID generator. (We start the generator at 12000.) * * OIDs beginning at 16384 are assigned from the OID generator * during normal multiuser operation. (We force the generator up to * 16384 as soon as we are in normal operation.) * - * The choices of 10000 and 16384 are completely arbitrary, and can be moved - * if we run low on OIDs in either category. Changing the macros below + * The choices of 10000, 12000 and 16384 are completely arbitrary, and can be + * moved if we run low on OIDs in either category. Changing the macros below * should be sufficient to do this. * * NOTE: if the OID generator wraps around, we skip over OIDs 0-16383 @@ -90,7 +93,8 @@ * reassigning OIDs that might have been assigned during initdb. * ---------- */ -#define FirstBootstrapObjectId 10000 +#define FirstGenbkiObjectId 10000 +#define FirstBootstrapObjectId 12000 #define FirstNormalObjectId 16384 /* diff --git a/src/include/catalog/unused_oids b/src/include/catalog/unused_oids index c5fc378ae34..b5cafe0f3d3 100755 --- a/src/include/catalog/unused_oids +++ b/src/include/catalog/unused_oids @@ -32,11 +32,11 @@ my @input_files = (glob("pg_*.h"), qw(indexing.h toasting.h)); my $oids = Catalog::FindAllOidsFromHeaders(@input_files); -# Also push FirstBootstrapObjectId to serve as a terminator for the last gap. -my $FirstBootstrapObjectId = +# Also push FirstGenbkiObjectId to serve as a terminator for the last gap. +my $FirstGenbkiObjectId = Catalog::FindDefinedSymbol('access/transam.h', '..', - 'FirstBootstrapObjectId'); -push @{$oids}, $FirstBootstrapObjectId; + 'FirstGenbkiObjectId'); +push @{$oids}, $FirstGenbkiObjectId; my $prev_oid = 0; foreach my $oid (sort { $a <=> $b } @{$oids}) diff --git a/src/include/utils/fmgrtab.h b/src/include/utils/fmgrtab.h index 6122ed3e978..72671c38296 100644 --- a/src/include/utils/fmgrtab.h +++ b/src/include/utils/fmgrtab.h @@ -41,6 +41,6 @@ extern const int fmgr_nbuiltins; /* number of entries in table */ * array. */ #define InvalidOidBuiltinMapping PG_UINT16_MAX -extern const uint16 fmgr_builtin_oid_index[FirstBootstrapObjectId]; +extern const uint16 fmgr_builtin_oid_index[FirstGenbkiObjectId]; #endif /* FMGRTAB_H */