aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/spgist
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2020-08-01 17:12:47 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2020-08-01 17:12:47 -0400
commit9f9682783bea74bf8d93cac4f7dd65fa677f5dc7 (patch)
tree5328d55da702250d9da41c3a3b83ce7c1a99d8f1 /src/backend/access/spgist
parente2b37d9e7cabc90633c4bd822e1bcfdd1bda44c4 (diff)
downloadpostgresql-9f9682783bea74bf8d93cac4f7dd65fa677f5dc7.tar.gz
postgresql-9f9682783bea74bf8d93cac4f7dd65fa677f5dc7.zip
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
Diffstat (limited to 'src/backend/access/spgist')
-rw-r--r--src/backend/access/spgist/spgutils.c1
-rw-r--r--src/backend/access/spgist/spgvalidate.c66
2 files changed, 67 insertions, 0 deletions
diff --git a/src/backend/access/spgist/spgutils.c b/src/backend/access/spgist/spgutils.c
index 0efe05e552b..64d3ba82887 100644
--- a/src/backend/access/spgist/spgutils.c
+++ b/src/backend/access/spgist/spgutils.c
@@ -74,6 +74,7 @@ spghandler(PG_FUNCTION_ARGS)
amroutine->amproperty = spgproperty;
amroutine->ambuildphasename = NULL;
amroutine->amvalidate = spgvalidate;
+ amroutine->amadjustmembers = spgadjustmembers;
amroutine->ambeginscan = spgbeginscan;
amroutine->amrescan = spgrescan;
amroutine->amgettuple = spggettuple;
diff --git a/src/backend/access/spgist/spgvalidate.c b/src/backend/access/spgist/spgvalidate.c
index f0cfd8b42b1..d4f5841e265 100644
--- a/src/backend/access/spgist/spgvalidate.c
+++ b/src/backend/access/spgist/spgvalidate.c
@@ -303,3 +303,69 @@ spgvalidate(Oid opclassoid)
return result;
}
+
+/*
+ * Prechecking function for adding operators/functions to an SP-GiST opfamily.
+ */
+void
+spgadjustmembers(Oid opfamilyoid,
+ Oid opclassoid,
+ List *operators,
+ List *functions)
+{
+ ListCell *lc;
+
+ /*
+ * Operator members of an SP-GiST opfamily should never have hard
+ * dependencies, since their connection to the opfamily depends only on
+ * what the support functions think, and that can be altered. For
+ * consistency, we make all soft dependencies point to the opfamily,
+ * though a soft dependency on the opclass would work as well in the
+ * CREATE OPERATOR CLASS case.
+ */
+ foreach(lc, operators)
+ {
+ OpFamilyMember *op = (OpFamilyMember *) lfirst(lc);
+
+ op->ref_is_hard = false;
+ op->ref_is_family = true;
+ op->refobjid = opfamilyoid;
+ }
+
+ /*
+ * Required support functions should have hard dependencies. Preferably
+ * those are just dependencies on the opclass, but if we're in ALTER
+ * OPERATOR FAMILY, we leave the dependency pointing at the whole
+ * opfamily. (Given that SP-GiST opclasses generally don't share
+ * opfamilies, it seems unlikely to be worth working harder.)
+ */
+ foreach(lc, functions)
+ {
+ OpFamilyMember *op = (OpFamilyMember *) lfirst(lc);
+
+ switch (op->number)
+ {
+ case SPGIST_CONFIG_PROC:
+ case SPGIST_CHOOSE_PROC:
+ case SPGIST_PICKSPLIT_PROC:
+ case SPGIST_INNER_CONSISTENT_PROC:
+ case SPGIST_LEAF_CONSISTENT_PROC:
+ /* Required support function */
+ op->ref_is_hard = true;
+ break;
+ case SPGIST_COMPRESS_PROC:
+ case SPGIST_OPTIONS_PROC:
+ /* Optional, so force it to be a soft family dependency */
+ op->ref_is_hard = false;
+ op->ref_is_family = true;
+ op->refobjid = opfamilyoid;
+ break;
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("support function number %d is invalid for access method %s",
+ op->number, "spgist")));
+ break;
+ }
+ }
+}