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);
120 elog(
ERROR,
"cache lookup failed for access method %u", amID);
122 (
errcode(ERRCODE_UNDEFINED_OBJECT),
123 errmsg(
"operator family \"%s\" does not exist for access method \"%s\"",
148 opfID = opfamform->oid;
201 elog(
ERROR,
"cache lookup failed for access method %u", amID);
203 (
errcode(ERRCODE_UNDEFINED_OBJECT),
204 errmsg(
"operator class \"%s\" does not exist for access method \"%s\"",
229 opcID = opcform->oid;
243 Oid namespaceoid,
Oid amoid)
249 bool nulls[Natts_pg_opfamily];
266 errmsg(
"operator family \"%s\" for access method \"%s\" already exists",
267 opfname,
stmt->amname)));
273 memset(nulls,
false,
sizeof(nulls));
276 Anum_pg_opfamily_oid);
293 myself.
classId = OperatorFamilyRelationId;
298 referenced.
classId = AccessMethodRelationId;
304 referenced.
classId = NamespaceRelationId;
353 bool nulls[Natts_pg_opclass];
373 (
errcode(ERRCODE_UNDEFINED_OBJECT),
374 errmsg(
"access method \"%s\" does not exist",
384 if (maxOpNumber <= 0)
385 maxOpNumber = SHRT_MAX;
414 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
415 errmsg(
"must be superuser to create an operator class")));
431 if (
stmt->opfamilyname)
478 foreach(l,
stmt->items)
491 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
492 errmsg(
"invalid operator number %d,"
493 " must be between 1 and %d",
494 item->
number, maxOpNumber)));
536 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
537 errmsg(
"invalid function number %d,"
538 " must be between 1 and %d",
539 item->
number, maxProcNumber)));
565 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
566 errmsg(
"storage type specified more than once")));
588 if (storageoid == typeoid)
592 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
593 errmsg(
"storage type cannot be different from data type for access method \"%s\"",
609 errmsg(
"operator class \"%s\" for access method \"%s\" already exists",
610 opcname,
stmt->amname)));
623 Anum_pg_opclass_opcmethod,
634 if (opclass->opcintype == typeoid && opclass->opcdefault)
637 errmsg(
"could not make operator class \"%s\" be default for type %s",
640 errdetail(
"Operator class \"%s\" already is the default.",
651 memset(nulls,
false,
sizeof(nulls));
654 Anum_pg_opclass_oid);
677 foreach(l, operators)
685 foreach(l, procedures)
720 myself.
classId = OperatorClassRelationId;
725 referenced.
classId = NamespaceRelationId;
731 referenced.
classId = OperatorFamilyRelationId;
737 referenced.
classId = TypeRelationId;
745 referenced.
classId = TypeRelationId;
799 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
800 errmsg(
"must be superuser to create an operator family")));
831 (
errcode(ERRCODE_UNDEFINED_OBJECT),
832 errmsg(
"access method \"%s\" does not exist",
842 if (maxOpNumber <= 0)
843 maxOpNumber = SHRT_MAX;
859 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
860 errmsg(
"must be superuser to alter an operator family")));
867 maxOpNumber, maxProcNumber,
stmt->items);
870 maxOpNumber, maxProcNumber, optsProcNumber,
881 int maxOpNumber,
int maxProcNumber,
int optsProcNumber,
908 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
909 errmsg(
"invalid operator number %d,"
910 " must be between 1 and %d",
911 item->
number, maxOpNumber)));
917 (
errcode(ERRCODE_SYNTAX_ERROR),
918 errmsg(
"operator argument types must be specified in ALTER OPERATOR FAMILY")));
958 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
959 errmsg(
"invalid function number %d,"
960 " must be between 1 and %d",
961 item->
number, maxProcNumber)));
992 (
errcode(ERRCODE_SYNTAX_ERROR),
993 errmsg(
"STORAGE cannot be specified in ALTER OPERATOR FAMILY")));
1022 operators, procedures);
1030 int maxOpNumber,
int maxProcNumber,
List *
items)
1054 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1055 errmsg(
"invalid operator number %d,"
1056 " must be between 1 and %d",
1057 item->
number, maxOpNumber)));
1070 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1071 errmsg(
"invalid function number %d,"
1072 " must be between 1 and %d",
1073 item->
number, maxProcNumber)));
1099 operators, procedures);
1122 *righttype = *lefttype;
1126 (
errcode(ERRCODE_SYNTAX_ERROR),
1127 errmsg(
"one or two argument types must be specified")));
1150 if (opform->oprkind !=
'b')
1152 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1153 errmsg(
"index operators must be binary")));
1171 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1172 errmsg(
"access method \"%s\" does not support ordering operators",
1180 if (opform->oprresult != BOOLOID)
1182 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1183 errmsg(
"index search operators must return boolean")));
1190 member->
lefttype = opform->oprleft;
1203 int opclassOptsProcNum)
1215 if (member->
number == opclassOptsProcNum)
1222 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1223 errmsg(
"associated data types for operator class options parsing functions must match opclass input type")));
1229 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1230 errmsg(
"left and right associated data types for operator class options parsing functions must match")));
1233 if (procform->prorettype != VOIDOID ||
1234 procform->pronargs != 1 ||
1235 procform->proargtypes.values[0] != INTERNALOID)
1237 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1238 errmsg(
"invalid operator class options parsing function"),
1239 errhint(
"Valid signature of operator class options parsing function is %s.",
1240 "(internal) RETURNS void")));
1251 else if (amoid == BTREE_AM_OID)
1255 if (procform->pronargs != 2)
1257 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1258 errmsg(
"btree comparison functions must have two arguments")));
1259 if (procform->prorettype != INT4OID)
1261 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1262 errmsg(
"btree comparison functions must return integer")));
1269 member->
lefttype = procform->proargtypes.values[0];
1271 member->
righttype = procform->proargtypes.values[1];
1275 if (procform->pronargs != 1 ||
1276 procform->proargtypes.values[0] != INTERNALOID)
1278 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1279 errmsg(
"btree sort support functions must accept type \"internal\"")));
1280 if (procform->prorettype != VOIDOID)
1282 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1283 errmsg(
"btree sort support functions must return void")));
1291 if (procform->pronargs != 5)
1293 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1294 errmsg(
"btree in_range functions must have five arguments")));
1295 if (procform->prorettype != BOOLOID)
1297 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1298 errmsg(
"btree in_range functions must return boolean")));
1305 member->
lefttype = procform->proargtypes.values[0];
1307 member->
righttype = procform->proargtypes.values[2];
1311 if (procform->pronargs != 1)
1313 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1314 errmsg(
"btree equal image functions must have one argument")));
1315 if (procform->prorettype != BOOLOID)
1317 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1318 errmsg(
"btree equal image functions must return boolean")));
1330 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1331 errmsg(
"btree equal image functions must not be cross-type")));
1334 else if (amoid == HASH_AM_OID)
1338 if (procform->pronargs != 1)
1340 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1341 errmsg(
"hash function 1 must have one argument")));
1342 if (procform->prorettype != INT4OID)
1344 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1345 errmsg(
"hash function 1 must return integer")));
1349 if (procform->pronargs != 2)
1351 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1352 errmsg(
"hash function 2 must have two arguments")));
1353 if (procform->prorettype != INT8OID)
1355 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1356 errmsg(
"hash function 2 must return bigint")));
1363 member->
lefttype = procform->proargtypes.values[0];
1365 member->
righttype = procform->proargtypes.values[0];
1380 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1381 errmsg(
"associated data types must be specified for index support function")));
1405 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1406 errmsg(
"function number %d for (%s,%s) appears more than once",
1412 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1413 errmsg(
"operator number %d for (%s,%s) appears more than once",
1429 List *operators,
bool isAdd)
1433 bool nulls[Natts_pg_amop];
1442 foreach(l, operators)
1459 errmsg(
"operator %d(%s,%s) already exists in operator family \"%s\"",
1469 memset(nulls,
false,
sizeof(nulls));
1490 myself.
classId = AccessMethodOperatorRelationId;
1494 referenced.
classId = OperatorRelationId;
1503 OperatorClassRelationId;
1513 referenced.
classId = OperatorFamilyRelationId;
1536 List *procedures,
bool isAdd)
1540 bool nulls[Natts_pg_amproc];
1549 foreach(l, procedures)
1565 errmsg(
"function %d(%s,%s) already exists in operator family \"%s\"",
1573 memset(nulls,
false,
sizeof(nulls));
1576 Anum_pg_amproc_oid);
1591 myself.
classId = AccessMethodProcedureRelationId;
1595 referenced.
classId = ProcedureRelationId;
1604 OperatorClassRelationId;
1632 foreach(l, operators)
1645 (
errcode(ERRCODE_UNDEFINED_OBJECT),
1646 errmsg(
"operator %d(%s,%s) does not exist in operator family \"%s\"",
1652 object.classId = AccessMethodOperatorRelationId;
1653 object.objectId = amopid;
1654 object.objectSubId = 0;
1672 foreach(l, procedures)
1685 (
errcode(ERRCODE_UNDEFINED_OBJECT),
1686 errmsg(
"function %d(%s,%s) does not exist in operator family \"%s\"",
1692 object.classId = AccessMethodProcedureRelationId;
1693 object.objectId = amprocid;
1694 object.objectSubId = 0;
1717 errmsg(
"operator class \"%s\" for access method \"%s\" already exists in schema \"%s\"",
1740 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)
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)
RegProcedure get_opcode(Oid opno)
char * get_func_name(Oid funcid)
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 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)