1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-16 06:01:02 +03:00

Invent "amadjustmembers" AM method for validating opclass members.

This allows AM-specific knowledge to be applied during creation of
pg_amop and pg_amproc entries.  Specifically, the AM knows better than
core code which entries to consider as required or optional.  Giving
the latter entries the appropriate sort of dependency allows them to
be dropped without taking out the whole opclass or opfamily; which
is something we'd like to have to correct obsolescent entries in
extensions.

This callback also opens the door to performing AM-specific validity
checks during opclass creation, rather than hoping than an opclass
developer will remember to test with "amvalidate".  For the most part
I've not actually added any such checks yet; that can happen in a
follow-on patch.  (Note that we shouldn't remove any tests from
"amvalidate", as those are still needed to cross-check manually
constructed entries in the initdb data.  So adding tests to
"amadjustmembers" will be somewhat duplicative, but it seems like
a good idea anyway.)

Patch by me, reviewed by Alexander Korotkov, Hamid Akhtar, and
Anastasia Lubennikova.

Discussion: https://postgr.es/m/4578.1565195302@sss.pgh.pa.us
This commit is contained in:
Tom Lane
2020-08-01 17:12:47 -04:00
parent e2b37d9e7c
commit 9f9682783b
24 changed files with 646 additions and 112 deletions

View File

@ -143,6 +143,7 @@ typedef struct IndexAmRoutine
amproperty_function amproperty; /* can be NULL */
ambuildphasename_function ambuildphasename; /* can be NULL */
amvalidate_function amvalidate;
amadjustmembers_function amadjustmembers; /* can be NULL */
ambeginscan_function ambeginscan;
amrescan_function amrescan;
amgettuple_function amgettuple; /* can be NULL */
@ -502,7 +503,48 @@ amvalidate (Oid opclassoid);
the access method can reasonably do that. For example, this might include
testing that all required support functions are provided.
The <function>amvalidate</function> function must return false if the opclass is
invalid. Problems should be reported with <function>ereport</function> messages.
invalid. Problems should be reported with <function>ereport</function>
messages, typically at <literal>INFO</literal> level.
</para>
<para>
<programlisting>
void
amadjustmembers (Oid opfamilyoid,
Oid opclassoid,
List *operators,
List *functions);
</programlisting>
Validate proposed new operator and function members of an operator family,
so far as the access method can reasonably do that, and set their
dependency types if the default is not satisfactory. This is called
during <command>CREATE OPERATOR CLASS</command> and during
<command>ALTER OPERATOR FAMILY ADD</command>; in the latter
case <parameter>opclassoid</parameter> is <literal>InvalidOid</literal>.
The <type>List</type> arguments are lists
of <structname>OpFamilyMember</structname> structs, as defined
in <filename>amapi.h</filename>.
Tests done by this function will typically be a subset of those
performed by <function>amvalidate</function>,
since <function>amadjustmembers</function> cannot assume that it is
seeing a complete set of members. For example, it would be reasonable
to check the signature of a support function, but not to check whether
all required support functions are provided. Any problems can be
reported by throwing an error.
The dependency-related fields of
the <structname>OpFamilyMember</structname> structs are initialized by
the core code to create hard dependencies on the opclass if this
is <command>CREATE OPERATOR CLASS</command>, or soft dependencies on the
opfamily if this is <command>ALTER OPERATOR FAMILY ADD</command>.
<function>amadjustmembers</function> can adjust these fields if some other
behavior is more appropriate. For example, GIN, GiST, and SP-GiST
always set operator members to have soft dependencies on the opfamily,
since the connection between an operator and an opclass is relatively
weak in these index types; so it is reasonable to allow operator members
to be added and removed freely. Optional support functions are typically
also given soft dependencies, so that they can be removed if necessary.
</para>