summaryrefslogtreecommitdiff
path: root/src/backend/access/index/indexam.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access/index/indexam.c')
-rw-r--r--src/backend/access/index/indexam.c77
1 files changed, 73 insertions, 4 deletions
diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c
index a5210d0b342..f7e4c65d99f 100644
--- a/src/backend/access/index/indexam.c
+++ b/src/backend/access/index/indexam.c
@@ -45,17 +45,23 @@
#include "access/amapi.h"
#include "access/heapam.h"
+#include "access/reloptions.h"
#include "access/relscan.h"
#include "access/tableam.h"
#include "access/transam.h"
#include "access/xlog.h"
#include "catalog/index.h"
+#include "catalog/pg_amproc.h"
#include "catalog/pg_type.h"
+#include "commands/defrem.h"
+#include "nodes/makefuncs.h"
#include "pgstat.h"
#include "storage/bufmgr.h"
#include "storage/lmgr.h"
#include "storage/predicate.h"
+#include "utils/ruleutils.h"
#include "utils/snapmgr.h"
+#include "utils/syscache.h"
/* ----------------------------------------------------------------
@@ -767,9 +773,9 @@ index_getprocid(Relation irel,
nproc = irel->rd_indam->amsupport;
- Assert(procnum > 0 && procnum <= (uint16) nproc);
+ Assert(procnum >= 0 && procnum <= (uint16) nproc);
- procindex = (nproc * (attnum - 1)) + (procnum - 1);
+ procindex = ((nproc + 1) * (attnum - 1)) + procnum;
loc = irel->rd_support;
@@ -797,13 +803,15 @@ index_getprocinfo(Relation irel,
{
FmgrInfo *locinfo;
int nproc;
+ int optsproc;
int procindex;
nproc = irel->rd_indam->amsupport;
+ optsproc = irel->rd_indam->amoptsprocnum;
- Assert(procnum > 0 && procnum <= (uint16) nproc);
+ Assert(procnum >= 0 && procnum <= (uint16) nproc);
- procindex = (nproc * (attnum - 1)) + (procnum - 1);
+ procindex = ((nproc + 1) * (attnum - 1)) + procnum;
locinfo = irel->rd_supportinfo;
@@ -832,6 +840,17 @@ index_getprocinfo(Relation irel,
procnum, attnum, RelationGetRelationName(irel));
fmgr_info_cxt(procId, locinfo, irel->rd_indexcxt);
+
+ if (procnum != optsproc)
+ {
+ /* Initialize locinfo->fn_expr with opclass options Const */
+ bytea **attoptions = RelationGetIndexAttOptions(irel, false);
+ MemoryContext oldcxt = MemoryContextSwitchTo(irel->rd_indexcxt);
+
+ set_fn_opclass_options(locinfo, attoptions[attnum - 1]);
+
+ MemoryContextSwitchTo(oldcxt);
+ }
}
return locinfo;
@@ -906,3 +925,53 @@ index_store_float8_orderby_distances(IndexScanDesc scan, Oid *orderByTypes,
}
}
}
+
+/* ----------------
+ * index_opclass_options
+ *
+ * Parse opclass-specific options for index column.
+ * ----------------
+ */
+bytea *
+index_opclass_options(Relation indrel, AttrNumber attnum, Datum attoptions,
+ bool validate)
+{
+ int amoptsprocnum = indrel->rd_indam->amoptsprocnum;
+ Oid procid = index_getprocid(indrel, attnum, amoptsprocnum);
+ FmgrInfo *procinfo;
+ local_relopts relopts;
+
+ if (!OidIsValid(procid))
+ {
+ Oid opclass;
+ Datum indclassDatum;
+ oidvector *indclass;
+ bool isnull;
+
+ if (!DatumGetPointer(attoptions))
+ return NULL; /* ok, no options, no procedure */
+
+ /*
+ * Report an error if the opclass's options-parsing procedure does not
+ * exist but the opclass options are specified.
+ */
+ indclassDatum = SysCacheGetAttr(INDEXRELID, indrel->rd_indextuple,
+ Anum_pg_index_indclass, &isnull);
+ Assert(!isnull);
+ indclass = (oidvector *) DatumGetPointer(indclassDatum);
+ opclass = indclass->values[attnum - 1];
+
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("operator class %s has no options",
+ generate_opclass_name(opclass))));
+ }
+
+ init_local_reloptions(&relopts, 0);
+
+ procinfo = index_getprocinfo(indrel, attnum, amoptsprocnum);
+
+ (void) FunctionCall1(procinfo, PointerGetDatum(&relopts));
+
+ return build_local_reloptions(&relopts, attoptions, validate);
+}