summaryrefslogtreecommitdiff
path: root/src/backend/access/index/amvalidate.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access/index/amvalidate.c')
-rw-r--r--src/backend/access/index/amvalidate.c246
1 files changed, 0 insertions, 246 deletions
diff --git a/src/backend/access/index/amvalidate.c b/src/backend/access/index/amvalidate.c
deleted file mode 100644
index 5a2728502ce..00000000000
--- a/src/backend/access/index/amvalidate.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * amvalidate.c
- * Support routines for index access methods' amvalidate functions.
- *
- * Copyright (c) 2016-2019, PostgreSQL Global Development Group
- *
- *
- * IDENTIFICATION
- * src/backend/access/index/amvalidate.c
- *
- *-------------------------------------------------------------------------
- */
-#include "postgres.h"
-
-#include "access/amvalidate.h"
-#include "access/htup_details.h"
-#include "catalog/pg_am.h"
-#include "catalog/pg_amop.h"
-#include "catalog/pg_amproc.h"
-#include "catalog/pg_opclass.h"
-#include "catalog/pg_operator.h"
-#include "catalog/pg_proc.h"
-#include "parser/parse_coerce.h"
-#include "utils/syscache.h"
-
-
-/*
- * identify_opfamily_groups() returns a List of OpFamilyOpFuncGroup structs,
- * one for each combination of lefttype/righttype present in the family's
- * operator and support function lists. If amopstrategy K is present for
- * this datatype combination, we set bit 1 << K in operatorset, and similarly
- * for the support functions. With uint64 fields we can handle operator and
- * function numbers up to 63, which is plenty for the foreseeable future.
- *
- * The given CatCLists are expected to represent a single opfamily fetched
- * from the AMOPSTRATEGY and AMPROCNUM caches, so that they will be in
- * order by those caches' second and third cache keys, namely the datatypes.
- */
-List *
-identify_opfamily_groups(CatCList *oprlist, CatCList *proclist)
-{
- List *result = NIL;
- OpFamilyOpFuncGroup *thisgroup;
- Form_pg_amop oprform;
- Form_pg_amproc procform;
- int io,
- ip;
-
- /* We need the lists to be ordered; should be true in normal operation */
- if (!oprlist->ordered || !proclist->ordered)
- elog(ERROR, "cannot validate operator family without ordered data");
-
- /*
- * Advance through the lists concurrently. Thanks to the ordering, we
- * should see all operators and functions of a given datatype pair
- * consecutively.
- */
- thisgroup = NULL;
- io = ip = 0;
- if (io < oprlist->n_members)
- {
- oprform = (Form_pg_amop) GETSTRUCT(&oprlist->members[io]->tuple);
- io++;
- }
- else
- oprform = NULL;
- if (ip < proclist->n_members)
- {
- procform = (Form_pg_amproc) GETSTRUCT(&proclist->members[ip]->tuple);
- ip++;
- }
- else
- procform = NULL;
-
- while (oprform || procform)
- {
- if (oprform && thisgroup &&
- oprform->amoplefttype == thisgroup->lefttype &&
- oprform->amoprighttype == thisgroup->righttype)
- {
- /* Operator belongs to current group; include it and advance */
-
- /* Ignore strategy numbers outside supported range */
- if (oprform->amopstrategy > 0 && oprform->amopstrategy < 64)
- thisgroup->operatorset |= ((uint64) 1) << oprform->amopstrategy;
-
- if (io < oprlist->n_members)
- {
- oprform = (Form_pg_amop) GETSTRUCT(&oprlist->members[io]->tuple);
- io++;
- }
- else
- oprform = NULL;
- continue;
- }
-
- if (procform && thisgroup &&
- procform->amproclefttype == thisgroup->lefttype &&
- procform->amprocrighttype == thisgroup->righttype)
- {
- /* Procedure belongs to current group; include it and advance */
-
- /* Ignore function numbers outside supported range */
- if (procform->amprocnum > 0 && procform->amprocnum < 64)
- thisgroup->functionset |= ((uint64) 1) << procform->amprocnum;
-
- if (ip < proclist->n_members)
- {
- procform = (Form_pg_amproc) GETSTRUCT(&proclist->members[ip]->tuple);
- ip++;
- }
- else
- procform = NULL;
- continue;
- }
-
- /* Time for a new group */
- thisgroup = (OpFamilyOpFuncGroup *) palloc(sizeof(OpFamilyOpFuncGroup));
- if (oprform &&
- (!procform ||
- (oprform->amoplefttype < procform->amproclefttype ||
- (oprform->amoplefttype == procform->amproclefttype &&
- oprform->amoprighttype < procform->amprocrighttype))))
- {
- thisgroup->lefttype = oprform->amoplefttype;
- thisgroup->righttype = oprform->amoprighttype;
- }
- else
- {
- thisgroup->lefttype = procform->amproclefttype;
- thisgroup->righttype = procform->amprocrighttype;
- }
- thisgroup->operatorset = thisgroup->functionset = 0;
- result = lappend(result, thisgroup);
- }
-
- return result;
-}
-
-/*
- * Validate the signature (argument and result types) of an opclass support
- * function. Return true if OK, false if not.
- *
- * The "..." represents maxargs argument-type OIDs. If "exact" is true, they
- * must match the function arg types exactly, else only binary-coercibly.
- * In any case the function result type must match restype exactly.
- */
-bool
-check_amproc_signature(Oid funcid, Oid restype, bool exact,
- int minargs, int maxargs,...)
-{
- bool result = true;
- HeapTuple tp;
- Form_pg_proc procform;
- va_list ap;
- int i;
-
- tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
- if (!HeapTupleIsValid(tp))
- elog(ERROR, "cache lookup failed for function %u", funcid);
- procform = (Form_pg_proc) GETSTRUCT(tp);
-
- if (procform->prorettype != restype || procform->proretset ||
- procform->pronargs < minargs || procform->pronargs > maxargs)
- result = false;
-
- va_start(ap, maxargs);
- for (i = 0; i < maxargs; i++)
- {
- Oid argtype = va_arg(ap, Oid);
-
- if (i >= procform->pronargs)
- continue;
- if (exact ? (argtype != procform->proargtypes.values[i]) :
- !IsBinaryCoercible(argtype, procform->proargtypes.values[i]))
- result = false;
- }
- va_end(ap);
-
- ReleaseSysCache(tp);
- return result;
-}
-
-/*
- * Validate the signature (argument and result types) of an opclass operator.
- * Return true if OK, false if not.
- *
- * Currently, we can hard-wire this as accepting only binary operators. Also,
- * we can insist on exact type matches, since the given lefttype/righttype
- * come from pg_amop and should always match the operator exactly.
- */
-bool
-check_amop_signature(Oid opno, Oid restype, Oid lefttype, Oid righttype)
-{
- bool result = true;
- HeapTuple tp;
- Form_pg_operator opform;
-
- tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno));
- if (!HeapTupleIsValid(tp)) /* shouldn't happen */
- elog(ERROR, "cache lookup failed for operator %u", opno);
- opform = (Form_pg_operator) GETSTRUCT(tp);
-
- if (opform->oprresult != restype || opform->oprkind != 'b' ||
- opform->oprleft != lefttype || opform->oprright != righttype)
- result = false;
-
- ReleaseSysCache(tp);
- return result;
-}
-
-/*
- * Is the datatype a legitimate input type for the btree opfamily?
- */
-bool
-opfamily_can_sort_type(Oid opfamilyoid, Oid datatypeoid)
-{
- bool result = false;
- CatCList *opclist;
- int i;
-
- /*
- * We search through all btree opclasses to see if one matches. This is a
- * bit inefficient but there is no better index available. It also saves
- * making an explicit check that the opfamily belongs to btree.
- */
- opclist = SearchSysCacheList1(CLAAMNAMENSP, ObjectIdGetDatum(BTREE_AM_OID));
-
- for (i = 0; i < opclist->n_members; i++)
- {
- HeapTuple classtup = &opclist->members[i]->tuple;
- Form_pg_opclass classform = (Form_pg_opclass) GETSTRUCT(classtup);
-
- if (classform->opcfamily == opfamilyoid &&
- classform->opcintype == datatypeoid)
- {
- result = true;
- break;
- }
- }
-
- ReleaseCatCacheList(opclist);
-
- return result;
-}