aboutsummaryrefslogtreecommitdiff
path: root/src/include
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/include
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/include')
-rw-r--r--src/include/access/amapi.h43
-rw-r--r--src/include/access/amvalidate.h5
-rw-r--r--src/include/access/gin_private.h4
-rw-r--r--src/include/access/gist_private.h4
-rw-r--r--src/include/access/hash.h4
-rw-r--r--src/include/access/nbtree.h4
-rw-r--r--src/include/access/spgist.h4
-rw-r--r--src/include/catalog/opfam_internal.h28
8 files changed, 67 insertions, 29 deletions
diff --git a/src/include/access/amapi.h b/src/include/access/amapi.h
index 4325faa460b..85b4766016f 100644
--- a/src/include/access/amapi.h
+++ b/src/include/access/amapi.h
@@ -54,6 +54,42 @@ typedef enum IndexAMProperty
AMPROP_CAN_INCLUDE
} IndexAMProperty;
+/*
+ * We use lists of this struct type to keep track of both operators and
+ * support functions while building or adding to an opclass or opfamily.
+ * amadjustmembers functions receive lists of these structs, and are allowed
+ * to alter their "ref" fields.
+ *
+ * The "ref" fields define how the pg_amop or pg_amproc entry should depend
+ * on the associated objects (that is, which dependency type to use, and
+ * which opclass or opfamily it should depend on).
+ *
+ * If ref_is_hard is true, the entry will have a NORMAL dependency on the
+ * operator or support func, and an INTERNAL dependency on the opclass or
+ * opfamily. This forces the opclass or opfamily to be dropped if the
+ * operator or support func is dropped, and requires the CASCADE option
+ * to do so. Nor will ALTER OPERATOR FAMILY DROP be allowed. This is
+ * the right behavior for objects that are essential to an opclass.
+ *
+ * If ref_is_hard is false, the entry will have an AUTO dependency on the
+ * operator or support func, and also an AUTO dependency on the opclass or
+ * opfamily. This allows ALTER OPERATOR FAMILY DROP, and causes that to
+ * happen automatically if the operator or support func is dropped. This
+ * is the right behavior for inessential ("loose") objects.
+ */
+typedef struct OpFamilyMember
+{
+ bool is_func; /* is this an operator, or support func? */
+ Oid object; /* operator or support func's OID */
+ int number; /* strategy or support func number */
+ Oid lefttype; /* lefttype */
+ Oid righttype; /* righttype */
+ Oid sortfamily; /* ordering operator's sort opfamily, or 0 */
+ bool ref_is_hard; /* hard or soft dependency? */
+ bool ref_is_family; /* is dependency on opclass or opfamily? */
+ Oid refobjid; /* OID of opclass or opfamily */
+} OpFamilyMember;
+
/*
* Callback function signatures --- see indexam.sgml for more info.
@@ -114,6 +150,12 @@ typedef char *(*ambuildphasename_function) (int64 phasenum);
/* validate definition of an opclass for this AM */
typedef bool (*amvalidate_function) (Oid opclassoid);
+/* validate operators and support functions to be added to an opclass/family */
+typedef void (*amadjustmembers_function) (Oid opfamilyoid,
+ Oid opclassoid,
+ List *operators,
+ List *functions);
+
/* prepare for index scan */
typedef IndexScanDesc (*ambeginscan_function) (Relation indexRelation,
int nkeys,
@@ -224,6 +266,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 */
diff --git a/src/include/access/amvalidate.h b/src/include/access/amvalidate.h
index f3a0e52d84e..149fc75f856 100644
--- a/src/include/access/amvalidate.h
+++ b/src/include/access/amvalidate.h
@@ -1,7 +1,8 @@
/*-------------------------------------------------------------------------
*
* amvalidate.h
- * Support routines for index access methods' amvalidate functions.
+ * Support routines for index access methods' amvalidate and
+ * amadjustmembers functions.
*
* Copyright (c) 2016-2020, PostgreSQL Global Development Group
*
@@ -32,6 +33,8 @@ extern bool check_amproc_signature(Oid funcid, Oid restype, bool exact,
extern bool check_amoptsproc_signature(Oid funcid);
extern bool check_amop_signature(Oid opno, Oid restype,
Oid lefttype, Oid righttype);
+extern Oid opclass_for_family_datatype(Oid amoid, Oid opfamilyoid,
+ Oid datatypeoid);
extern bool opfamily_can_sort_type(Oid opfamilyoid, Oid datatypeoid);
#endif /* AMVALIDATE_H */
diff --git a/src/include/access/gin_private.h b/src/include/access/gin_private.h
index 71eeac205c9..5cb2f72e4cf 100644
--- a/src/include/access/gin_private.h
+++ b/src/include/access/gin_private.h
@@ -407,6 +407,10 @@ extern ItemPointer ginVacuumItemPointers(GinVacuumState *gvs,
/* ginvalidate.c */
extern bool ginvalidate(Oid opclassoid);
+extern void ginadjustmembers(Oid opfamilyoid,
+ Oid opclassoid,
+ List *operators,
+ List *functions);
/* ginbulk.c */
typedef struct GinEntryAccumulator
diff --git a/src/include/access/gist_private.h b/src/include/access/gist_private.h
index 4bfc6280002..02e985549f6 100644
--- a/src/include/access/gist_private.h
+++ b/src/include/access/gist_private.h
@@ -464,6 +464,10 @@ extern bool gistcanreturn(Relation index, int attno);
/* gistvalidate.c */
extern bool gistvalidate(Oid opclassoid);
+extern void gistadjustmembers(Oid opfamilyoid,
+ Oid opclassoid,
+ List *operators,
+ List *functions);
/* gistutil.c */
diff --git a/src/include/access/hash.h b/src/include/access/hash.h
index 7e7b1b73d86..bab4d9f1b05 100644
--- a/src/include/access/hash.h
+++ b/src/include/access/hash.h
@@ -379,6 +379,10 @@ extern IndexBulkDeleteResult *hashvacuumcleanup(IndexVacuumInfo *info,
IndexBulkDeleteResult *stats);
extern bytea *hashoptions(Datum reloptions, bool validate);
extern bool hashvalidate(Oid opclassoid);
+extern void hashadjustmembers(Oid opfamilyoid,
+ Oid opclassoid,
+ List *operators,
+ List *functions);
/* private routines */
diff --git a/src/include/access/nbtree.h b/src/include/access/nbtree.h
index f5274cc7508..65d9698b899 100644
--- a/src/include/access/nbtree.h
+++ b/src/include/access/nbtree.h
@@ -1141,6 +1141,10 @@ extern bool _bt_allequalimage(Relation rel, bool debugmessage);
* prototypes for functions in nbtvalidate.c
*/
extern bool btvalidate(Oid opclassoid);
+extern void btadjustmembers(Oid opfamilyoid,
+ Oid opclassoid,
+ List *operators,
+ List *functions);
/*
* prototypes for functions in nbtsort.c
diff --git a/src/include/access/spgist.h b/src/include/access/spgist.h
index 852d1e2961a..9f2ccc1730f 100644
--- a/src/include/access/spgist.h
+++ b/src/include/access/spgist.h
@@ -220,5 +220,9 @@ extern IndexBulkDeleteResult *spgvacuumcleanup(IndexVacuumInfo *info,
/* spgvalidate.c */
extern bool spgvalidate(Oid opclassoid);
+extern void spgadjustmembers(Oid opfamilyoid,
+ Oid opclassoid,
+ List *operators,
+ List *functions);
#endif /* SPGIST_H */
diff --git a/src/include/catalog/opfam_internal.h b/src/include/catalog/opfam_internal.h
deleted file mode 100644
index d63bd9ffa3c..00000000000
--- a/src/include/catalog/opfam_internal.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * opfam_internal.h
- *
- * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- * src/include/catalog/opfam_internal.h
- *
- *-------------------------------------------------------------------------
- */
-#ifndef OPFAM_INTERNAL_H
-#define OPFAM_INTERNAL_H
-
-/*
- * We use lists of this struct type to keep track of both operators and
- * procedures while building or adding to an opfamily.
- */
-typedef struct
-{
- Oid object; /* operator or support proc's OID */
- int number; /* strategy or support proc number */
- Oid lefttype; /* lefttype */
- Oid righttype; /* righttype */
- Oid sortfamily; /* ordering operator's sort opfamily, or 0 */
-} OpFamilyMember;
-
-#endif /* OPFAM_INTERNAL_H */