From 3ae7f95d9cf61c1327fabcd1c75fd530d1d0c379 Mon Sep 17 00:00:00 2001 From: John Naylor Date: Sun, 11 Mar 2018 18:34:01 +0700 Subject: [PATCH] Implement OID macro lookups Teach genbki.pl to do the necessary OID lookups to turn the macros introduced in last commit back into numeric OIDs when writing postgres.bki. Since all the lookup tables are now built before we start writing the data to BKI files, genbki.pl can be less stringent about the order the catalogs are processed -- the only ordering constraints are those imposed by the bootstrap code. --- src/backend/catalog/Catalog.pm | 4 + src/backend/catalog/README | 1 - src/backend/catalog/genbki.pl | 137 +++++++++++++++++++++++++++++------ src/include/catalog/genbki.h | 5 +- src/include/catalog/pg_aggregate.h | 22 +++--- src/include/catalog/pg_am.h | 2 +- src/include/catalog/pg_amop.h | 12 +-- src/include/catalog/pg_amproc.h | 19 +++-- src/include/catalog/pg_cast.h | 4 +- src/include/catalog/pg_opclass.h | 16 ++-- src/include/catalog/pg_operator.h | 16 ++-- src/include/catalog/pg_opfamily.h | 7 +- src/include/catalog/pg_proc.h | 4 +- src/include/catalog/pg_range.h | 23 ++++-- src/include/catalog/pg_ts_parser.h | 27 +++++-- src/include/catalog/pg_ts_template.h | 15 +++- src/include/catalog/pg_type.h | 16 ++-- 17 files changed, 238 insertions(+), 92 deletions(-) diff --git a/src/backend/catalog/Catalog.pm b/src/backend/catalog/Catalog.pm index 0a88c08..6fe5566 100644 --- a/src/backend/catalog/Catalog.pm +++ b/src/backend/catalog/Catalog.pm @@ -174,6 +174,10 @@ sub ParseHeader { $column{default} = $1; } + elsif ($attopt =~ /BKI_LOOKUP\((\S+)\)/) + { + $column{lookup} = $1; + } else { die diff --git a/src/backend/catalog/README b/src/backend/catalog/README index aa0785e..447fce6 100644 --- a/src/backend/catalog/README +++ b/src/backend/catalog/README @@ -129,7 +129,6 @@ CATALOG_HEADERS variable, as these cannot be created through the standard heap_create_with_catalog process, because it needs these tables to exist already. The list of files this currently includes is: pg_proc.h pg_type.h pg_attribute.h pg_class.h -Within this list, pg_type.h must come before pg_attribute.h. Also, indexing.h must be last, since the indexes can't be created until all the tables are in place, and toasting.h should probably be next-to-last (or at least after all the tables that need toast tables). There are diff --git a/src/backend/catalog/genbki.pl b/src/backend/catalog/genbki.pl index 9f67a24..fe83f3b 100644 --- a/src/backend/catalog/genbki.pl +++ b/src/backend/catalog/genbki.pl @@ -121,6 +121,83 @@ my $BOOTSTRAP_SUPERUSERID my $PG_CATALOG_NAMESPACE = Catalog::FindDefinedSymbolFromData($catalog_data{pg_namespace}, 'PG_CATALOG_NAMESPACE'); +# Build lookup tables for OID macro substitutions and for pg_attribute +# copies of pg_type values. + +# index access method OID lookup +my %amoids; +foreach my $row (@{ $catalog_data{pg_am} }) +{ + $amoids{$row->{amname}} = $row->{oid}; +} + +# operator OID lookup +my %operoids; +foreach my $row (@{ $catalog_data{pg_operator} }) +{ + # There is no unique name, so we need to invent one that contains + # the relevant type names. + my $key = sprintf "%s(%s,%s)", + $row->{oprname}, $row->{oprleft}, $row->{oprright}; + $operoids{$key} = $row->{oid}; +} + +# opclass OID lookup +my %opcoids; +foreach my $row (@{ $catalog_data{pg_opclass} }) +{ + # There is no unique name, so we need to combine access method + # and opclass name. + my $key = sprintf "%s/%s", + $row->{opcmethod}, $row->{opcname}; + $opcoids{$key} = $row->{oid}; +} + +# opfamily OID lookup +my %opfoids; +foreach my $row (@{ $catalog_data{pg_opfamily} }) +{ + # There is no unique name, so we need to combine access method + # and opfamily name. + my $key = sprintf "%s/%s", + $row->{opfmethod}, $row->{opfname}; + $opfoids{$key} = $row->{oid}; +} + +# procedure OID lookup +my %procoids; +foreach my $row (@{ $catalog_data{pg_proc} }) +{ + if (defined($procoids{ $row->{proname} })) + { + $procoids{ $row->{proname} } = 'MULTIPLE'; + } + else + { + $procoids{ $row->{proname} } = $row->{oid}; + } +} + +# type lookups +my %typeoids; +my %types; +foreach my $row (@{ $catalog_data{pg_type} }) +{ + $typeoids{ $row->{typname} } = $row->{oid}; + $types{ $row->{typname} } = $row; +} + +# Map catalog name to OID lookup. +my %lookup_kind = ( + pg_am => \%amoids, + pg_operator => \%operoids, + pg_opclass => \%opcoids, + pg_opfamily => \%opfoids, + pg_proc => \%procoids, + pg_type => \%typeoids +); + + # Generate postgres.bki, postgres.description, and postgres.shdescription # version marker for .bki file @@ -129,8 +206,6 @@ print $bki "# PostgreSQL $major_version\n"; # vars to hold data needed for schemapg.h my %schemapg_entries; my @tables_needing_macros; -my %regprocoids; -my %types; # produce output, one catalog at a time foreach my $catname (@catnames) @@ -225,8 +300,6 @@ EOM } # For pg_attribute.h, we generate data entries ourselves. - # NB: pg_type.h must come before pg_attribute.h in the input list - # of catalog names, since we use info from pg_type.h here. if ($catname eq 'pg_attribute') { gen_pg_attribute($schema); @@ -248,38 +321,54 @@ EOM $bki_values{$attname} =~ s/\bPGUID\b/$BOOTSTRAP_SUPERUSERID/g; $bki_values{$attname} =~ s/\bPGNSP\b/$PG_CATALOG_NAMESPACE/g; - # Replace regproc columns' values with OIDs. - # If we don't have a unique value to substitute, - # just do nothing (regprocin will complain). - if ($atttype eq 'regproc') + # Replace OID macros with OIDs. + # If we don't have a unique value to substitute, just do + # nothing. This should only happen in the case for functions, + # in which case regprocin will complain. + if ($column->{lookup}) { - my $procoid = $regprocoids{ $bki_values{$attname} }; - $bki_values{$attname} = $procoid - if defined($procoid) && $procoid ne 'MULTIPLE'; + my $lookup = $lookup_kind{ $column->{lookup} } + if defined $column->{lookup}; + my $lookupoid = $lookup->{ $bki_values{$attname} }; + $bki_values{$attname} = $lookupoid + if defined($lookupoid) && $lookupoid ne 'MULTIPLE'; } } - # Save pg_proc oids for use in later regproc substitutions. - # This relies on the order we process the files in! + # We can't always do type lookups in a general way for + # pg_proc, so do special handling here. if ($catname eq 'pg_proc') { - if (defined($regprocoids{ $bki_values{proname} })) + + # proargtypes + if ($bki_values{proargtypes}) { - $regprocoids{ $bki_values{proname} } = 'MULTIPLE'; + my @argtypenames = split /\s+/, $bki_values{proargtypes}; + my @argtypeoids; + foreach my $argtypename (@argtypenames) + { + my $argtypeoid = $typeoids{$argtypename}; + push @argtypeoids, $argtypeoid; + } + $bki_values{proargtypes} = join(' ', @argtypeoids); } - else + + # proallargtypes + if ($bki_values{proallargtypes} ne '_null_') { - $regprocoids{ $bki_values{proname} } = $bki_values{oid}; + $bki_values{proallargtypes} =~ s/[{}]//g; + my @argtypenames = split /,/, $bki_values{proallargtypes}; + my @argtypeoids; + foreach my $argtypename (@argtypenames) + { + my $argtypeoid = $typeoids{$argtypename}; + push @argtypeoids, $argtypeoid; + } + $bki_values{proallargtypes} = + sprintf "{%s}", join(',', @argtypeoids); } } - # Save pg_type info for pg_attribute processing below - if ($catname eq 'pg_type') - { - my %type = %bki_values; - $types{ $type{typname} } = \%type; - } - # Write to postgres.bki print_bki_insert(\%bki_values, $schema); diff --git a/src/include/catalog/genbki.h b/src/include/catalog/genbki.h index 4702932..9566b44 100644 --- a/src/include/catalog/genbki.h +++ b/src/include/catalog/genbki.h @@ -28,11 +28,14 @@ #define BKI_WITHOUT_OIDS #define BKI_ROWTYPE_OID(oid) #define BKI_SCHEMA_MACRO + +/* Options that may appear after an attribute (on the same line) */ #define BKI_FORCE_NULL #define BKI_FORCE_NOT_NULL - /* Specifies a default value for a catalog field */ #define BKI_DEFAULT(value) +/* Indicates where to perform OID lookups for OID macros */ +#define BKI_LOOKUP(kind) /* The following are never defined; they are here only for documentation. */ diff --git a/src/include/catalog/pg_aggregate.h b/src/include/catalog/pg_aggregate.h index 74f2b27..0fe6b03 100644 --- a/src/include/catalog/pg_aggregate.h +++ b/src/include/catalog/pg_aggregate.h @@ -57,22 +57,22 @@ CATALOG(pg_aggregate,2600) BKI_WITHOUT_OIDS regproc aggfnoid; char aggkind BKI_DEFAULT(n); int16 aggnumdirectargs BKI_DEFAULT(0); - regproc aggtransfn; - regproc aggfinalfn BKI_DEFAULT(-); - regproc aggcombinefn BKI_DEFAULT(-); - regproc aggserialfn BKI_DEFAULT(-); - regproc aggdeserialfn BKI_DEFAULT(-); - regproc aggmtransfn BKI_DEFAULT(-); - regproc aggminvtransfn BKI_DEFAULT(-); - regproc aggmfinalfn BKI_DEFAULT(-); + regproc aggtransfn BKI_LOOKUP(pg_proc); + regproc aggfinalfn BKI_DEFAULT(-) BKI_LOOKUP(pg_proc); + regproc aggcombinefn BKI_DEFAULT(-) BKI_LOOKUP(pg_proc); + regproc aggserialfn BKI_DEFAULT(-) BKI_LOOKUP(pg_proc); + regproc aggdeserialfn BKI_DEFAULT(-) BKI_LOOKUP(pg_proc); + regproc aggmtransfn BKI_DEFAULT(-) BKI_LOOKUP(pg_proc); + regproc aggminvtransfn BKI_DEFAULT(-) BKI_LOOKUP(pg_proc); + regproc aggmfinalfn BKI_DEFAULT(-) BKI_LOOKUP(pg_proc); bool aggfinalextra BKI_DEFAULT(f); bool aggmfinalextra BKI_DEFAULT(f); char aggfinalmodify BKI_DEFAULT(r); char aggmfinalmodify BKI_DEFAULT(r); - Oid aggsortop BKI_DEFAULT(0); - Oid aggtranstype; + Oid aggsortop BKI_DEFAULT(0) BKI_LOOKUP(pg_operator); + Oid aggtranstype BKI_LOOKUP(pg_type); int32 aggtransspace BKI_DEFAULT(0); - Oid aggmtranstype BKI_DEFAULT(0); + Oid aggmtranstype BKI_DEFAULT(0) BKI_LOOKUP(pg_type); int32 aggmtransspace BKI_DEFAULT(0); #ifdef CATALOG_VARLEN /* variable-length fields start here */ diff --git a/src/include/catalog/pg_am.h b/src/include/catalog/pg_am.h index 4004c96..193711b 100644 --- a/src/include/catalog/pg_am.h +++ b/src/include/catalog/pg_am.h @@ -31,7 +31,7 @@ CATALOG(pg_am,2601) { NameData amname; /* access method name */ - regproc amhandler; /* handler function */ + regproc amhandler BKI_LOOKUP(pg_proc); /* handler function */ char amtype; /* see AMTYPE_xxx constants below */ } FormData_pg_am; diff --git a/src/include/catalog/pg_amop.h b/src/include/catalog/pg_amop.h index e638c30..c99530d 100644 --- a/src/include/catalog/pg_amop.h +++ b/src/include/catalog/pg_amop.h @@ -56,13 +56,13 @@ CATALOG(pg_amop,2602) { /* the index opfamily this entry is for */ - Oid amopfamily; + Oid amopfamily BKI_LOOKUP(pg_opfamily); /* operator's left input data type */ - Oid amoplefttype; + Oid amoplefttype BKI_LOOKUP(pg_type); /* operator's right input data type */ - Oid amoprighttype; + Oid amoprighttype BKI_LOOKUP(pg_type); /* operator strategy number */ int16 amopstrategy; @@ -71,13 +71,13 @@ CATALOG(pg_amop,2602) char amoppurpose BKI_DEFAULT(s); /* the operator's pg_operator OID */ - Oid amopopr; + Oid amopopr BKI_LOOKUP(pg_operator); /* the index access method this entry is for */ - Oid amopmethod; + Oid amopmethod BKI_LOOKUP(pg_am); /* ordering opfamily OID, or 0 if search op */ - Oid amopsortfamily BKI_DEFAULT(0); + Oid amopsortfamily BKI_DEFAULT(0) BKI_LOOKUP(pg_opfamily); } FormData_pg_amop; /* ---------------- diff --git a/src/include/catalog/pg_amproc.h b/src/include/catalog/pg_amproc.h index 66e1cdc..1db7db5 100644 --- a/src/include/catalog/pg_amproc.h +++ b/src/include/catalog/pg_amproc.h @@ -44,11 +44,20 @@ CATALOG(pg_amproc,2603) { - Oid amprocfamily; /* the index opfamily this entry is for */ - Oid amproclefttype; /* procedure's left input data type */ - Oid amprocrighttype; /* procedure's right input data type */ - int16 amprocnum; /* support procedure index */ - regproc amproc; /* OID of the proc */ + /* the index opfamily this entry is for */ + Oid amprocfamily BKI_LOOKUP(pg_opfamily); + + /* procedure's left input data type */ + Oid amproclefttype BKI_LOOKUP(pg_type); + + /* procedure's right input data type */ + Oid amprocrighttype BKI_LOOKUP(pg_type); + + /* support procedure index */ + int16 amprocnum; + + /* OID of the proc */ + regproc amproc; } FormData_pg_amproc; /* ---------------- diff --git a/src/include/catalog/pg_cast.h b/src/include/catalog/pg_cast.h index 6d98213..d980c25 100644 --- a/src/include/catalog/pg_cast.h +++ b/src/include/catalog/pg_cast.h @@ -32,8 +32,8 @@ CATALOG(pg_cast,2605) { - Oid castsource; /* source datatype for cast */ - Oid casttarget; /* destination datatype for cast */ + Oid castsource BKI_LOOKUP(pg_type); /* source datatype for cast */ + Oid casttarget BKI_LOOKUP(pg_type); /* destination datatype for cast */ Oid castfunc; /* cast function; 0 = binary coercible */ char castcontext; /* contexts in which cast can be used */ char castmethod; /* cast method */ diff --git a/src/include/catalog/pg_opclass.h b/src/include/catalog/pg_opclass.h index 6d0fed8..9c41aab 100644 --- a/src/include/catalog/pg_opclass.h +++ b/src/include/catalog/pg_opclass.h @@ -50,8 +50,11 @@ CATALOG(pg_opclass,2616) { - Oid opcmethod; /* index access method opclass is for */ - NameData opcname; /* name of this opclass */ + /* index access method opclass is for */ + Oid opcmethod BKI_LOOKUP(pg_am); + + /* name of this opclass */ + NameData opcname; /* namespace of this opclass */ Oid opcnamespace BKI_DEFAULT(PGNSP); @@ -59,14 +62,17 @@ CATALOG(pg_opclass,2616) /* opclass owner */ Oid opcowner BKI_DEFAULT(PGUID); - Oid opcfamily; /* containing operator family */ - Oid opcintype; /* type of data indexed by opclass */ + /* containing operator family */ + Oid opcfamily BKI_LOOKUP(pg_opfamily); + + /* type of data indexed by opclass */ + Oid opcintype BKI_LOOKUP(pg_type); /* T if opclass is default for opcintype */ bool opcdefault BKI_DEFAULT(t); /* type of data in index, or InvalidOid */ - Oid opckeytype BKI_DEFAULT(0); + Oid opckeytype BKI_DEFAULT(0) BKI_LOOKUP(pg_type); } FormData_pg_opclass; /* ---------------- diff --git a/src/include/catalog/pg_operator.h b/src/include/catalog/pg_operator.h index e111914..0962c39 100644 --- a/src/include/catalog/pg_operator.h +++ b/src/include/catalog/pg_operator.h @@ -51,14 +51,14 @@ CATALOG(pg_operator,2617) char oprkind BKI_DEFAULT(b); bool oprcanmerge BKI_DEFAULT(f); bool oprcanhash BKI_DEFAULT(f); - Oid oprleft; - Oid oprright; - Oid oprresult; - Oid oprcom BKI_DEFAULT(0); - Oid oprnegate BKI_DEFAULT(0); - regproc oprcode; - regproc oprrest BKI_DEFAULT(-); - regproc oprjoin BKI_DEFAULT(-); + Oid oprleft BKI_LOOKUP(pg_type); + Oid oprright BKI_LOOKUP(pg_type); + Oid oprresult BKI_LOOKUP(pg_type); + Oid oprcom BKI_DEFAULT(0) BKI_LOOKUP(pg_operator); + Oid oprnegate BKI_DEFAULT(0) BKI_LOOKUP(pg_operator); + regproc oprcode BKI_LOOKUP(pg_proc); + regproc oprrest BKI_DEFAULT(-) BKI_LOOKUP(pg_proc); + regproc oprjoin BKI_DEFAULT(-) BKI_LOOKUP(pg_proc); } FormData_pg_operator; /* ---------------- diff --git a/src/include/catalog/pg_opfamily.h b/src/include/catalog/pg_opfamily.h index 571615d..8cf5d17 100644 --- a/src/include/catalog/pg_opfamily.h +++ b/src/include/catalog/pg_opfamily.h @@ -30,8 +30,11 @@ CATALOG(pg_opfamily,2753) { - Oid opfmethod; /* index access method opfamily is for */ - NameData opfname; /* name of this opfamily */ + /* index access method opfamily is for */ + Oid opfmethod BKI_LOOKUP(pg_am); + + /* name of this opfamily */ + NameData opfname; /* namespace of this opfamily */ Oid opfnamespace BKI_DEFAULT(PGNSP); diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index d181d67..01dadd4 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -67,7 +67,7 @@ CATALOG(pg_proc,1255) BKI_BOOTSTRAP BKI_ROWTYPE_OID(81) BKI_SCHEMA_MACRO float4 procost BKI_DEFAULT(1); float4 prorows BKI_DEFAULT(0); Oid provariadic BKI_DEFAULT(0); - regproc protransform BKI_DEFAULT(0); + regproc protransform BKI_DEFAULT(0) BKI_LOOKUP(pg_proc); char prokind BKI_DEFAULT(f); bool prosecdef BKI_DEFAULT(f); bool proleakproof BKI_DEFAULT(f); @@ -77,7 +77,7 @@ CATALOG(pg_proc,1255) BKI_BOOTSTRAP BKI_ROWTYPE_OID(81) BKI_SCHEMA_MACRO char proparallel BKI_DEFAULT(u); int16 pronargs; int16 pronargdefaults BKI_DEFAULT(0); - Oid prorettype; + Oid prorettype BKI_LOOKUP(pg_type); /* * variable-length fields start here, but we allow direct access to diff --git a/src/include/catalog/pg_range.h b/src/include/catalog/pg_range.h index 4c806fd..2046441 100644 --- a/src/include/catalog/pg_range.h +++ b/src/include/catalog/pg_range.h @@ -30,12 +30,23 @@ CATALOG(pg_range,3541) BKI_WITHOUT_OIDS { - Oid rngtypid; /* OID of owning range type */ - Oid rngsubtype; /* OID of range's element type (subtype) */ - Oid rngcollation; /* collation for this range type, or 0 */ - Oid rngsubopc; /* subtype's btree opclass */ - regproc rngcanonical; /* canonicalize range, or 0 */ - regproc rngsubdiff; /* subtype difference as a float8, or 0 */ + /* OID of owning range type */ + Oid rngtypid BKI_LOOKUP(pg_type); + + /* OID of range's element type (subtype) */ + Oid rngsubtype BKI_LOOKUP(pg_type); + + /* collation for this range type, or 0 */ + Oid rngcollation; + + /* subtype's btree opclass */ + Oid rngsubopc BKI_LOOKUP(pg_opclass); + + /* canonicalize range, or 0 */ + regproc rngcanonical BKI_LOOKUP(pg_proc); + + /* subtype difference as a float8, or 0 */ + regproc rngsubdiff BKI_LOOKUP(pg_proc); } FormData_pg_range; /* ---------------- diff --git a/src/include/catalog/pg_ts_parser.h b/src/include/catalog/pg_ts_parser.h index 3baaef0..8274ff0 100644 --- a/src/include/catalog/pg_ts_parser.h +++ b/src/include/catalog/pg_ts_parser.h @@ -30,13 +30,26 @@ CATALOG(pg_ts_parser,3601) { - NameData prsname; /* parser's name */ - Oid prsnamespace; /* name space */ - regproc prsstart; /* init parsing session */ - regproc prstoken; /* return next token */ - regproc prsend; /* finalize parsing session */ - regproc prsheadline; /* return data for headline creation */ - regproc prslextype; /* return descriptions of lexeme's types */ + /* parser's name */ + NameData prsname; + + /* name space */ + Oid prsnamespace; + + /* init parsing session */ + regproc prsstart BKI_LOOKUP(pg_proc); + + /* return next token */ + regproc prstoken BKI_LOOKUP(pg_proc); + + /* finalize parsing session */ + regproc prsend BKI_LOOKUP(pg_proc); + + /* return data for headline creation */ + regproc prsheadline BKI_LOOKUP(pg_proc); + + /* return descriptions of lexeme's types */ + regproc prslextype BKI_LOOKUP(pg_proc); } FormData_pg_ts_parser; typedef FormData_pg_ts_parser *Form_pg_ts_parser; diff --git a/src/include/catalog/pg_ts_template.h b/src/include/catalog/pg_ts_template.h index 7ea6e15..0cb5f9f 100644 --- a/src/include/catalog/pg_ts_template.h +++ b/src/include/catalog/pg_ts_template.h @@ -30,10 +30,17 @@ CATALOG(pg_ts_template,3764) { - NameData tmplname; /* template name */ - Oid tmplnamespace; /* name space */ - regproc tmplinit; /* initialization method of dict (may be 0) */ - regproc tmpllexize; /* base method of dictionary */ + /* template name */ + NameData tmplname; + + /* name space */ + Oid tmplnamespace; + + /* initialization method of dict (may be 0) */ + regproc tmplinit BKI_LOOKUP(pg_proc); + + /* base method of dictionary */ + regproc tmpllexize BKI_LOOKUP(pg_proc); } FormData_pg_ts_template; typedef FormData_pg_ts_template *Form_pg_ts_template; diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h index b52e677..ad04fdb 100644 --- a/src/include/catalog/pg_type.h +++ b/src/include/catalog/pg_type.h @@ -117,21 +117,23 @@ CATALOG(pg_type,1247) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71) BKI_SCHEMA_MACRO /* * I/O conversion procedures for the datatype. */ - regproc typinput; /* text format (required) */ - regproc typoutput; - regproc typreceive; /* binary format (optional) */ - regproc typsend; + /* text format (required) */ + regproc typinput BKI_LOOKUP(pg_proc); + regproc typoutput BKI_LOOKUP(pg_proc); + /* binary format (optional) */ + regproc typreceive BKI_LOOKUP(pg_proc); + regproc typsend BKI_LOOKUP(pg_proc); /* * I/O functions for optional type modifiers. */ - regproc typmodin BKI_DEFAULT(-); - regproc typmodout BKI_DEFAULT(-); + regproc typmodin BKI_DEFAULT(-) BKI_LOOKUP(pg_proc); + regproc typmodout BKI_DEFAULT(-) BKI_LOOKUP(pg_proc); /* * Custom ANALYZE procedure for the datatype (0 selects the default). */ - regproc typanalyze BKI_DEFAULT(-); + regproc typanalyze BKI_DEFAULT(-) BKI_LOOKUP(pg_proc); /* ---------------- * typalign is the alignment required when storing a value of this -- 2.7.4