I wrote: > Also, I fail to understand why fmgr_builtin_oid_index has 10000 entries > anyway. We could easily have fmgrtab.c expose the last actually assigned > builtin function OID (presently 6121) and make the index array only > that big, which just about eliminates the space advantage completely.
Concretely, like the attached. We could make the index table still smaller if we wanted to reassign a couple dozen high-numbered functions down to lower OIDs, but I dunno if it's worth the trouble. It certainly isn't from a performance standpoint, because those unused entry ranges will never be touched in normal usage; but it'd make the server executable a couple KB smaller. regards, tom lane
diff --git a/src/backend/utils/Gen_fmgrtab.pl b/src/backend/utils/Gen_fmgrtab.pl index cafe408..f970940 100644 *** a/src/backend/utils/Gen_fmgrtab.pl --- b/src/backend/utils/Gen_fmgrtab.pl *************** foreach my $datfile (@input_files) *** 80,90 **** $catalog_data{$catname} = Catalog::ParseData($datfile, $schema, 0); } - # Fetch some values for later. - my $FirstGenbkiObjectId = - Catalog::FindDefinedSymbol('access/transam.h', $include_path, - 'FirstGenbkiObjectId'); - # Collect certain fields from pg_proc.dat. my @fmgr = (); --- 80,85 ---- *************** my %bmap; *** 225,230 **** --- 220,226 ---- $bmap{'t'} = 'true'; $bmap{'f'} = 'false'; my @fmgr_builtin_oid_index; + my $last_builtin_oid = 0; my $fmgr_count = 0; foreach my $s (sort { $a->{oid} <=> $b->{oid} } @fmgr) { *************** foreach my $s (sort { $a->{oid} <=> $b-> *** 232,237 **** --- 228,234 ---- " { $s->{oid}, $s->{nargs}, $bmap{$s->{strict}}, $bmap{$s->{retset}}, \"$s->{prosrc}\", $s->{prosrc} }"; $fmgr_builtin_oid_index[ $s->{oid} ] = $fmgr_count++; + $last_builtin_oid = $s->{oid}; if ($fmgr_count <= $#fmgr) { *************** foreach my $s (sort { $a->{oid} <=> $b-> *** 244,274 **** } print $tfh "};\n"; ! print $tfh qq| 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 FirstGenbkiObjectId, ! # as we can't rely on zero initialization as 0 is a valid mapping. ! print $tfh qq| ! const uint16 fmgr_builtin_oid_index[FirstGenbkiObjectId] = { ! |; ! for (my $i = 0; $i < $FirstGenbkiObjectId; $i++) { my $oid = $fmgr_builtin_oid_index[$i]; ! # fmgr_builtin_oid_index is sparse, map nonexistant functions to # InvalidOidBuiltinMapping if (not defined $oid) { $oid = 'InvalidOidBuiltinMapping'; } ! if ($i + 1 == $FirstGenbkiObjectId) { print $tfh " $oid\n"; } --- 241,270 ---- } print $tfh "};\n"; ! printf $tfh qq| const int fmgr_nbuiltins = (sizeof(fmgr_builtins) / sizeof(FmgrBuiltin)); ! ! const Oid fmgr_last_builtin_oid = %u; ! |, $last_builtin_oid; # Create fmgr_builtins_oid_index table. ! printf $tfh qq| ! const uint16 fmgr_builtin_oid_index[%u] = { ! |, $last_builtin_oid + 1; ! for (my $i = 0; $i <= $last_builtin_oid; $i++) { my $oid = $fmgr_builtin_oid_index[$i]; ! # fmgr_builtin_oid_index is sparse, map nonexistent functions to # InvalidOidBuiltinMapping if (not defined $oid) { $oid = 'InvalidOidBuiltinMapping'; } ! if ($i == $last_builtin_oid) { print $tfh " $oid\n"; } diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c index b41649f..506eeef 100644 *** a/src/backend/utils/fmgr/fmgr.c --- b/src/backend/utils/fmgr/fmgr.c *************** fmgr_isbuiltin(Oid id) *** 75,86 **** uint16 index; /* fast lookup only possible if original oid still assigned */ ! if (id >= FirstGenbkiObjectId) return NULL; /* * Lookup function data. If there's a miss in that range it's likely a ! * nonexistant function, returning NULL here will trigger an ERROR later. */ index = fmgr_builtin_oid_index[id]; if (index == InvalidOidBuiltinMapping) --- 75,86 ---- uint16 index; /* fast lookup only possible if original oid still assigned */ ! if (id > fmgr_last_builtin_oid) return NULL; /* * Lookup function data. If there's a miss in that range it's likely a ! * nonexistent function, returning NULL here will trigger an ERROR later. */ index = fmgr_builtin_oid_index[id]; if (index == InvalidOidBuiltinMapping) diff --git a/src/include/utils/fmgrtab.h b/src/include/utils/fmgrtab.h index a778f88..e981f34 100644 *** a/src/include/utils/fmgrtab.h --- b/src/include/utils/fmgrtab.h *************** extern const FmgrBuiltin fmgr_builtins[] *** 36,46 **** extern const int fmgr_nbuiltins; /* number of entries in table */ /* ! * Mapping from a builtin function's oid to the index in the fmgr_builtins ! * array. */ #define InvalidOidBuiltinMapping PG_UINT16_MAX ! extern const uint16 fmgr_builtin_oid_index[FirstGenbkiObjectId]; #endif /* FMGRTAB_H */ --- 36,48 ---- extern const int fmgr_nbuiltins; /* number of entries in table */ + extern const Oid fmgr_last_builtin_oid; /* highest function OID in table */ + /* ! * Mapping from a builtin function's OID to its index in the fmgr_builtins ! * array. This is indexed from 0 through fmgr_last_builtin_oid. */ #define InvalidOidBuiltinMapping PG_UINT16_MAX ! extern const uint16 fmgr_builtin_oid_index[]; #endif /* FMGRTAB_H */