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;
354 bool nulls[Natts_pg_opclass];
374 (
errcode(ERRCODE_UNDEFINED_OBJECT),
375 errmsg(
"access method \"%s\" does not exist",
385 if (maxOpNumber <= 0)
386 maxOpNumber = SHRT_MAX;
415 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
416 errmsg(
"must be superuser to create an operator class")));
432 if (
stmt->opfamilyname)
479 foreach(l,
stmt->items)
492 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
493 errmsg(
"invalid operator number %d,"
494 " must be between 1 and %d",
495 item->
number, maxOpNumber)));
537 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
538 errmsg(
"invalid function number %d,"
539 " must be between 1 and %d",
540 item->
number, maxProcNumber)));
566 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
567 errmsg(
"storage type specified more than once")));
589 if (storageoid == typeoid)
593 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
594 errmsg(
"storage type cannot be different from data type for access method \"%s\"",
610 errmsg(
"operator class \"%s\" for access method \"%s\" already exists",
611 opcname,
stmt->amname)));
624 Anum_pg_opclass_opcmethod,
635 if (opclass->opcintype == typeoid && opclass->opcdefault)
638 errmsg(
"could not make operator class \"%s\" be default for type %s",
641 errdetail(
"Operator class \"%s\" already is the default.",
652 memset(nulls,
false,
sizeof(nulls));
655 Anum_pg_opclass_oid);
678 foreach(l, operators)
686 foreach(l, procedures)
721 myself.
classId = OperatorClassRelationId;
726 referenced.
classId = NamespaceRelationId;
732 referenced.
classId = OperatorFamilyRelationId;
738 referenced.
classId = TypeRelationId;
746 referenced.
classId = TypeRelationId;
800 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
801 errmsg(
"must be superuser to create an operator family")));
832 (
errcode(ERRCODE_UNDEFINED_OBJECT),
833 errmsg(
"access method \"%s\" does not exist",
843 if (maxOpNumber <= 0)
844 maxOpNumber = SHRT_MAX;
860 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
861 errmsg(
"must be superuser to alter an operator family")));
868 maxOpNumber, maxProcNumber,
stmt->items);
871 maxOpNumber, maxProcNumber, optsProcNumber,
882 int maxOpNumber,
int maxProcNumber,
int optsProcNumber,
909 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
910 errmsg(
"invalid operator number %d,"
911 " must be between 1 and %d",
912 item->
number, maxOpNumber)));
918 (
errcode(ERRCODE_SYNTAX_ERROR),
919 errmsg(
"operator argument types must be specified in ALTER OPERATOR FAMILY")));
959 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
960 errmsg(
"invalid function number %d,"
961 " must be between 1 and %d",
962 item->
number, maxProcNumber)));
993 (
errcode(ERRCODE_SYNTAX_ERROR),
994 errmsg(
"STORAGE cannot be specified in ALTER OPERATOR FAMILY")));
1023 operators, procedures);
1031 int maxOpNumber,
int maxProcNumber,
List *
items)
1055 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1056 errmsg(
"invalid operator number %d,"
1057 " must be between 1 and %d",
1058 item->
number, maxOpNumber)));
1071 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1072 errmsg(
"invalid function number %d,"
1073 " must be between 1 and %d",
1074 item->
number, maxProcNumber)));
1100 operators, procedures);
1123 *righttype = *lefttype;
1127 (
errcode(ERRCODE_SYNTAX_ERROR),
1128 errmsg(
"one or two argument types must be specified")));
1151 if (opform->oprkind !=
'b')
1153 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1154 errmsg(
"index operators must be binary")));
1172 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1173 errmsg(
"access method \"%s\" does not support ordering operators",
1181 if (opform->oprresult != BOOLOID)
1183 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1184 errmsg(
"index search operators must return boolean")));
1191 member->
lefttype = opform->oprleft;
1204 int opclassOptsProcNum)
1216 if (member->
number == opclassOptsProcNum)
1223 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1224 errmsg(
"associated data types for operator class options parsing functions must match opclass input type")));
1230 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1231 errmsg(
"left and right associated data types for operator class options parsing functions must match")));
1234 if (procform->prorettype != VOIDOID ||
1235 procform->pronargs != 1 ||
1236 procform->proargtypes.values[0] != INTERNALOID)
1238 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1239 errmsg(
"invalid operator class options parsing function"),
1240 errhint(
"Valid signature of operator class options parsing function is %s.",
1241 "(internal) RETURNS void")));
1252 else if (amoid == BTREE_AM_OID)
1256 if (procform->pronargs != 2)
1258 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1259 errmsg(
"btree comparison functions must have two arguments")));
1260 if (procform->prorettype != INT4OID)
1262 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1263 errmsg(
"btree comparison functions must return integer")));
1270 member->
lefttype = procform->proargtypes.values[0];
1272 member->
righttype = procform->proargtypes.values[1];
1276 if (procform->pronargs != 1 ||
1277 procform->proargtypes.values[0] != INTERNALOID)
1279 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1280 errmsg(
"btree sort support functions must accept type \"internal\"")));
1281 if (procform->prorettype != VOIDOID)
1283 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1284 errmsg(
"btree sort support functions must return void")));
1292 if (procform->pronargs != 5)
1294 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1295 errmsg(
"btree in_range functions must have five arguments")));
1296 if (procform->prorettype != BOOLOID)
1298 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1299 errmsg(
"btree in_range functions must return boolean")));
1306 member->
lefttype = procform->proargtypes.values[0];
1308 member->
righttype = procform->proargtypes.values[2];
1312 if (procform->pronargs != 1)
1314 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1315 errmsg(
"btree equal image functions must have one argument")));
1316 if (procform->prorettype != BOOLOID)
1318 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1319 errmsg(
"btree equal image functions must return boolean")));
1331 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1332 errmsg(
"btree equal image functions must not be cross-type")));
1335 else if (amoid == HASH_AM_OID)
1339 if (procform->pronargs != 1)
1341 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1342 errmsg(
"hash function 1 must have one argument")));
1343 if (procform->prorettype != INT4OID)
1345 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1346 errmsg(
"hash function 1 must return integer")));
1350 if (procform->pronargs != 2)
1352 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1353 errmsg(
"hash function 2 must have two arguments")));
1354 if (procform->prorettype != INT8OID)
1356 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1357 errmsg(
"hash function 2 must return bigint")));
1364 member->
lefttype = procform->proargtypes.values[0];
1366 member->
righttype = procform->proargtypes.values[0];
1381 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1382 errmsg(
"associated data types must be specified for index support function")));
1406 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1407 errmsg(
"function number %d for (%s,%s) appears more than once",
1413 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1414 errmsg(
"operator number %d for (%s,%s) appears more than once",
1430 List *operators,
bool isAdd)
1434 bool nulls[Natts_pg_amop];
1443 foreach(l, operators)
1460 errmsg(
"operator %d(%s,%s) already exists in operator family \"%s\"",
1470 memset(nulls,
false,
sizeof(nulls));
1491 myself.
classId = AccessMethodOperatorRelationId;
1495 referenced.
classId = OperatorRelationId;
1504 OperatorClassRelationId;
1513 referenced.
classId = TypeRelationId;
1525 referenced.
classId = TypeRelationId;
1537 referenced.
classId = OperatorFamilyRelationId;
1560 List *procedures,
bool isAdd)
1564 bool nulls[Natts_pg_amproc];
1573 foreach(l, procedures)
1589 errmsg(
"function %d(%s,%s) already exists in operator family \"%s\"",
1597 memset(nulls,
false,
sizeof(nulls));
1600 Anum_pg_amproc_oid);
1615 myself.
classId = AccessMethodProcedureRelationId;
1619 referenced.
classId = ProcedureRelationId;
1628 OperatorClassRelationId;
1637 referenced.
classId = TypeRelationId;
1649 referenced.
classId = TypeRelationId;
1695 for (
int i = 0;
i < nargs;
i++)
1697 if (typid == argtypes[
i])
1711 if (typid == lefttype || typid == righttype)
1730 foreach(l, operators)
1743 (
errcode(ERRCODE_UNDEFINED_OBJECT),
1744 errmsg(
"operator %d(%s,%s) does not exist in operator family \"%s\"",
1750 object.classId = AccessMethodOperatorRelationId;
1751 object.objectId = amopid;
1752 object.objectSubId = 0;
1770 foreach(l, procedures)
1783 (
errcode(ERRCODE_UNDEFINED_OBJECT),
1784 errmsg(
"function %d(%s,%s) does not exist in operator family \"%s\"",
1790 object.classId = AccessMethodProcedureRelationId;
1791 object.objectId = amprocid;
1792 object.objectSubId = 0;
1815 errmsg(
"operator class \"%s\" for access method \"%s\" already exists in schema \"%s\"",
1838 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)
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 Assert(condition)
#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)
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
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
void heap_freetuple(HeapTuple htup)
#define HeapTupleIsValid(tuple)
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
List * lappend(List *list, void *datum)
char * get_opname(Oid opno)
char * get_namespace_name(Oid nspid)
Oid get_func_signature(Oid funcid, Oid **argtypes, int *nargs)
RegProcedure get_opcode(Oid opno)
char * get_func_name(Oid funcid)
void op_input_types(Oid opno, Oid *lefttype, Oid *righttype)
void pfree(void *pointer)
void * palloc0(Size size)
void namestrcpy(Name name, const char *str)
Oid OpclassnameGetOpcid(Oid amid, const char *opcname)
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)
char * NameListToString(const List *names)
Oid OpfamilynameGetOpfid(Oid amid, const char *opfname)
#define BTEQUALIMAGE_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)