46#include "utils/fmgroids.h"
52 Oid amoid,
Oid opfamilyoid,
53 int maxOpNumber,
int maxProcNumber,
56 Oid amoid,
Oid opfamilyoid,
57 int maxOpNumber,
int maxProcNumber,
62 int opclassOptsProcNum);
65 List *operators,
bool isAdd);
67 List *procedures,
bool isAdd);
121 elog(
ERROR,
"cache lookup failed for access method %u", amID);
123 (
errcode(ERRCODE_UNDEFINED_OBJECT),
124 errmsg(
"operator family \"%s\" does not exist for access method \"%s\"",
149 opfID = opfamform->oid;
202 elog(
ERROR,
"cache lookup failed for access method %u", amID);
204 (
errcode(ERRCODE_UNDEFINED_OBJECT),
205 errmsg(
"operator class \"%s\" does not exist for access method \"%s\"",
230 opcID = opcform->oid;
244 Oid namespaceoid,
Oid amoid)
250 bool nulls[Natts_pg_opfamily];
267 errmsg(
"operator family \"%s\" for access method \"%s\" already exists",
268 opfname,
stmt->amname)));
274 memset(nulls,
false,
sizeof(nulls));
277 Anum_pg_opfamily_oid);
294 myself.
classId = OperatorFamilyRelationId;
299 referenced.
classId = AccessMethodRelationId;
305 referenced.
classId = NamespaceRelationId;
346 bool isDefault =
stmt->isDefault;
355 bool nulls[Natts_pg_opclass];
375 (
errcode(ERRCODE_UNDEFINED_OBJECT),
376 errmsg(
"access method \"%s\" does not exist",
386 if (maxOpNumber <= 0)
387 maxOpNumber = SHRT_MAX;
416 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
417 errmsg(
"must be superuser to create an operator class")));
433 if (
stmt->opfamilyname)
480 foreach(l,
stmt->items)
493 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
494 errmsg(
"invalid operator number %d,"
495 " must be between 1 and %d",
496 item->
number, maxOpNumber)));
538 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
539 errmsg(
"invalid function number %d,"
540 " must be between 1 and %d",
541 item->
number, maxProcNumber)));
567 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
568 errmsg(
"storage type specified more than once")));
590 if (storageoid == typeoid)
594 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
595 errmsg(
"storage type cannot be different from data type for access method \"%s\"",
611 errmsg(
"operator class \"%s\" for access method \"%s\" already exists",
612 opcname,
stmt->amname)));
627 if (amoid == GIST_AM_OID &&
628 ((typeoid == INETOID && strcmp(opcname,
"gist_inet_ops") == 0) ||
629 (typeoid == CIDROID && strcmp(opcname,
"gist_cidr_ops") == 0)))
644 Anum_pg_opclass_opcmethod,
655 if (opclass->opcintype == typeoid && opclass->opcdefault)
658 errmsg(
"could not make operator class \"%s\" be default for type %s",
661 errdetail(
"Operator class \"%s\" already is the default.",
672 memset(nulls,
false,
sizeof(nulls));
675 Anum_pg_opclass_oid);
698 foreach(l, operators)
706 foreach(l, procedures)
741 myself.
classId = OperatorClassRelationId;
746 referenced.
classId = NamespaceRelationId;
752 referenced.
classId = OperatorFamilyRelationId;
758 referenced.
classId = TypeRelationId;
766 referenced.
classId = TypeRelationId;
820 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
821 errmsg(
"must be superuser to create an operator family")));
852 (
errcode(ERRCODE_UNDEFINED_OBJECT),
853 errmsg(
"access method \"%s\" does not exist",
863 if (maxOpNumber <= 0)
864 maxOpNumber = SHRT_MAX;
880 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
881 errmsg(
"must be superuser to alter an operator family")));
888 maxOpNumber, maxProcNumber,
stmt->items);
891 maxOpNumber, maxProcNumber, optsProcNumber,
902 int maxOpNumber,
int maxProcNumber,
int optsProcNumber,
929 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
930 errmsg(
"invalid operator number %d,"
931 " must be between 1 and %d",
932 item->
number, maxOpNumber)));
938 (
errcode(ERRCODE_SYNTAX_ERROR),
939 errmsg(
"operator argument types must be specified in ALTER OPERATOR FAMILY")));
979 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
980 errmsg(
"invalid function number %d,"
981 " must be between 1 and %d",
982 item->
number, maxProcNumber)));
1013 (
errcode(ERRCODE_SYNTAX_ERROR),
1014 errmsg(
"STORAGE cannot be specified in ALTER OPERATOR FAMILY")));
1043 operators, procedures);
1051 int maxOpNumber,
int maxProcNumber,
List *
items)
1075 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1076 errmsg(
"invalid operator number %d,"
1077 " must be between 1 and %d",
1078 item->
number, maxOpNumber)));
1091 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1092 errmsg(
"invalid function number %d,"
1093 " must be between 1 and %d",
1094 item->
number, maxProcNumber)));
1120 operators, procedures);
1143 *righttype = *lefttype;
1147 (
errcode(ERRCODE_SYNTAX_ERROR),
1148 errmsg(
"one or two argument types must be specified")));
1171 if (opform->oprkind !=
'b')
1173 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1174 errmsg(
"index operators must be binary")));
1190 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1191 errmsg(
"access method \"%s\" does not support ordering operators",
1199 if (opform->oprresult != BOOLOID)
1201 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1202 errmsg(
"index search operators must return boolean")));
1209 member->
lefttype = opform->oprleft;
1222 int opclassOptsProcNum)
1234 if (member->
number == opclassOptsProcNum)
1241 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1242 errmsg(
"associated data types for operator class options parsing functions must match opclass input type")));
1248 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1249 errmsg(
"left and right associated data types for operator class options parsing functions must match")));
1252 if (procform->prorettype != VOIDOID ||
1253 procform->pronargs != 1 ||
1254 procform->proargtypes.values[0] != INTERNALOID)
1256 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1257 errmsg(
"invalid operator class options parsing function"),
1258 errhint(
"Valid signature of operator class options parsing function is %s.",
1259 "(internal) RETURNS void")));
1274 if (procform->pronargs != 2)
1276 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1277 errmsg(
"ordering comparison functions must have two arguments")));
1278 if (procform->prorettype != INT4OID)
1280 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1281 errmsg(
"ordering comparison functions must return integer")));
1288 member->
lefttype = procform->proargtypes.values[0];
1290 member->
righttype = procform->proargtypes.values[1];
1294 if (procform->pronargs != 1 ||
1295 procform->proargtypes.values[0] != INTERNALOID)
1297 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1298 errmsg(
"ordering sort support functions must accept type \"internal\"")));
1299 if (procform->prorettype != VOIDOID)
1301 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1302 errmsg(
"ordering sort support functions must return void")));
1310 if (procform->pronargs != 5)
1312 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1313 errmsg(
"ordering in_range functions must have five arguments")));
1314 if (procform->prorettype != BOOLOID)
1316 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1317 errmsg(
"ordering in_range functions must return boolean")));
1324 member->
lefttype = procform->proargtypes.values[0];
1326 member->
righttype = procform->proargtypes.values[2];
1330 if (procform->pronargs != 1)
1332 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1333 errmsg(
"ordering equal image functions must have one argument")));
1334 if (procform->prorettype != BOOLOID)
1336 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1337 errmsg(
"ordering equal image functions must return boolean")));
1349 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1350 errmsg(
"ordering equal image functions must not be cross-type")));
1354 if (procform->pronargs != 1 ||
1355 procform->proargtypes.values[0] != INTERNALOID)
1357 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1358 errmsg(
"btree skip support functions must accept type \"internal\"")));
1359 if (procform->prorettype != VOIDOID)
1361 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1362 errmsg(
"btree skip support functions must return void")));
1374 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1375 errmsg(
"btree skip support functions must not be cross-type")));
1382 if (procform->pronargs != 1)
1384 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1385 errmsg(
"hash function 1 must have one argument")));
1386 if (procform->prorettype != INT4OID)
1388 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1389 errmsg(
"hash function 1 must return integer")));
1393 if (procform->pronargs != 2)
1395 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1396 errmsg(
"hash function 2 must have two arguments")));
1397 if (procform->prorettype != INT8OID)
1399 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1400 errmsg(
"hash function 2 must return bigint")));
1407 member->
lefttype = procform->proargtypes.values[0];
1409 member->
righttype = procform->proargtypes.values[0];
1424 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1425 errmsg(
"associated data types must be specified for index support function")));
1449 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1450 errmsg(
"function number %d for (%s,%s) appears more than once",
1456 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1457 errmsg(
"operator number %d for (%s,%s) appears more than once",
1473 List *operators,
bool isAdd)
1477 bool nulls[Natts_pg_amop];
1486 foreach(l, operators)
1503 errmsg(
"operator %d(%s,%s) already exists in operator family \"%s\"",
1513 memset(nulls,
false,
sizeof(nulls));
1534 myself.
classId = AccessMethodOperatorRelationId;
1538 referenced.
classId = OperatorRelationId;
1547 OperatorClassRelationId;
1556 referenced.
classId = TypeRelationId;
1568 referenced.
classId = TypeRelationId;
1580 referenced.
classId = OperatorFamilyRelationId;
1603 List *procedures,
bool isAdd)
1607 bool nulls[Natts_pg_amproc];
1616 foreach(l, procedures)
1632 errmsg(
"function %d(%s,%s) already exists in operator family \"%s\"",
1640 memset(nulls,
false,
sizeof(nulls));
1643 Anum_pg_amproc_oid);
1658 myself.
classId = AccessMethodProcedureRelationId;
1662 referenced.
classId = ProcedureRelationId;
1671 OperatorClassRelationId;
1680 referenced.
classId = TypeRelationId;
1692 referenced.
classId = TypeRelationId;
1738 for (
int i = 0;
i < nargs;
i++)
1740 if (typid == argtypes[
i])
1754 if (typid == lefttype || typid == righttype)
1773 foreach(l, operators)
1786 (
errcode(ERRCODE_UNDEFINED_OBJECT),
1787 errmsg(
"operator %d(%s,%s) does not exist in operator family \"%s\"",
1793 object.classId = AccessMethodOperatorRelationId;
1794 object.objectId = amopid;
1795 object.objectSubId = 0;
1813 foreach(l, procedures)
1826 (
errcode(ERRCODE_UNDEFINED_OBJECT),
1827 errmsg(
"function %d(%s,%s) does not exist in operator family \"%s\"",
1833 object.classId = AccessMethodProcedureRelationId;
1834 object.objectId = amprocid;
1835 object.objectSubId = 0;
1858 errmsg(
"operator class \"%s\" for access method \"%s\" already exists in schema \"%s\"",
1881 errmsg(
"operator family \"%s\" for access method \"%s\" already exists in schema \"%s\"",
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
bool object_ownercheck(Oid classid, Oid objectid, Oid roleid)
void aclcheck_error_type(AclResult aclerr, Oid typeOid)
const IndexAmRoutine * GetIndexAmRoutineByAmId(Oid amoid, bool noerror)
Oid get_index_am_oid(const char *amname, bool missing_ok)
char * get_am_name(Oid amOid)
static Datum values[MAXATTR]
#define OidIsValid(objectId)
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
bool IsPinnedObject(Oid classId, Oid objectId)
void performDeletion(const ObjectAddress *object, DropBehavior behavior, int flags)
int errdetail(const char *fmt,...)
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
void EventTriggerCollectAlterOpFam(AlterOpFamilyStmt *stmt, Oid opfamoid, List *operators, List *procedures)
void EventTriggerCollectCreateOpClass(CreateOpClassStmt *stmt, Oid opcoid, List *operators, List *procedures)
void EventTriggerCollectSimpleCommand(ObjectAddress address, ObjectAddress secondaryObject, Node *parsetree)
#define palloc0_object(type)
void systable_endscan(SysScanDesc sysscan)
HeapTuple systable_getnext(SysScanDesc sysscan)
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
#define HASHSTANDARD_PROC
#define HASHEXTENDED_PROC
Assert(PointerIsAligned(start, uint64))
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
void heap_freetuple(HeapTuple htup)
#define HeapTupleIsValid(tuple)
static void * GETSTRUCT(const HeapTupleData *tuple)
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
List * lappend(List *list, void *datum)
char * get_opname(Oid opno)
Oid get_func_signature(Oid funcid, Oid **argtypes, int *nargs)
RegProcedure get_opcode(Oid opno)
char * get_func_name(Oid funcid)
char * get_namespace_name(Oid nspid)
void op_input_types(Oid opno, Oid *lefttype, Oid *righttype)
void pfree(void *pointer)
void namestrcpy(Name name, const char *str)
Oid OpclassnameGetOpcid(Oid amid, const char *opcname)
char * NameListToString(const List *names)
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Oid QualifiedNameGetCreationNamespace(const List *names, char **objname_p)
void DeconstructQualifiedName(const List *names, char **nspname_p, char **objname_p)
Oid OpfamilynameGetOpfid(Oid amid, const char *opfname)
#define BTEQUALIMAGE_PROC
#define BTSKIPSUPPORT_PROC
#define BTSORTSUPPORT_PROC
#define InvokeObjectPostCreateHook(classId, objectId, subId)
const ObjectAddress InvalidObjectAddress
static void assignOperTypes(OpFamilyMember *member, Oid amoid, Oid typeoid)
static HeapTuple OpFamilyCacheLookup(Oid amID, List *opfamilyname, bool missing_ok)
ObjectAddress DefineOpClass(CreateOpClassStmt *stmt)
static ObjectAddress CreateOpFamily(CreateOpFamilyStmt *stmt, const char *opfname, Oid namespaceoid, Oid amoid)
static void storeProcedures(List *opfamilyname, Oid amoid, Oid opfamilyoid, List *procedures, bool isAdd)
static void storeOperators(List *opfamilyname, Oid amoid, Oid opfamilyoid, List *operators, bool isAdd)
static bool typeDepNeeded(Oid typid, OpFamilyMember *member)
static void dropOperators(List *opfamilyname, Oid amoid, Oid opfamilyoid, List *operators)
static void assignProcTypes(OpFamilyMember *member, Oid amoid, Oid typeoid, int opclassOptsProcNum)
Oid get_opclass_oid(Oid amID, List *opclassname, bool missing_ok)
static void addFamilyMember(List **list, OpFamilyMember *member)
void IsThereOpFamilyInNamespace(const char *opfname, Oid opfmethod, Oid opfnamespace)
static void dropProcedures(List *opfamilyname, Oid amoid, Oid opfamilyoid, List *procedures)
ObjectAddress DefineOpFamily(CreateOpFamilyStmt *stmt)
static void processTypesSpec(List *args, Oid *lefttype, Oid *righttype)
static HeapTuple OpClassCacheLookup(Oid amID, List *opclassname, bool missing_ok)
static void AlterOpFamilyDrop(AlterOpFamilyStmt *stmt, Oid amoid, Oid opfamilyoid, int maxOpNumber, int maxProcNumber, List *items)
Oid AlterOpFamily(AlterOpFamilyStmt *stmt)
Oid get_opfamily_oid(Oid amID, List *opfamilyname, bool missing_ok)
static void AlterOpFamilyAdd(AlterOpFamilyStmt *stmt, Oid amoid, Oid opfamilyoid, int maxOpNumber, int maxProcNumber, int optsProcNumber, List *items)
void IsThereOpClassInNamespace(const char *opcname, Oid opcmethod, Oid opcnamespace)
Oid LookupFuncWithArgs(ObjectType objtype, ObjectWithArgs *func, bool missing_ok)
Oid LookupOperName(ParseState *pstate, List *opername, Oid oprleft, Oid oprright, bool noError, int location)
Oid LookupOperWithArgs(ObjectWithArgs *oper, bool noError)
char * TypeNameToString(const TypeName *typeName)
Oid typenameTypeId(ParseState *pstate, const TypeName *typeName)
#define OPCLASS_ITEM_STORAGETYPE
#define OPCLASS_ITEM_OPERATOR
#define OPCLASS_ITEM_FUNCTION
FormData_pg_am * Form_pg_am
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
void recordDependencyOnCurrentExtension(const ObjectAddress *object, bool isReplace)
#define lfirst_node(type, lc)
static int list_length(const List *l)
FormData_pg_opclass * Form_pg_opclass
FormData_pg_operator * Form_pg_operator
FormData_pg_opfamily * Form_pg_opfamily
FormData_pg_proc * Form_pg_proc
void recordDependencyOnOwner(Oid classId, Oid objectId, Oid owner)
static Datum PointerGetDatum(const void *X)
static Datum Int16GetDatum(int16 X)
static Datum BoolGetDatum(bool X)
static Datum ObjectIdGetDatum(Oid X)
static Datum NameGetDatum(const NameData *X)
static Datum CStringGetDatum(const char *X)
static Datum CharGetDatum(char X)
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
#define BTEqualStrategyNumber
#define ERRCODE_DUPLICATE_OBJECT
amadjustmembers_function amadjustmembers
void ReleaseSysCache(HeapTuple tuple)
HeapTuple SearchSysCache1(int cacheId, Datum key1)
HeapTuple SearchSysCache3(int cacheId, Datum key1, Datum key2, Datum key3)
#define SearchSysCacheExists4(cacheId, key1, key2, key3, key4)
#define SearchSysCacheExists3(cacheId, key1, key2, key3)
#define GetSysCacheOid4(cacheId, oidcol, key1, key2, key3, key4)
void table_close(Relation relation, LOCKMODE lockmode)
Relation table_open(Oid relationId, LOCKMODE lockmode)