opclasscmds.c
来自「PostgreSQL7.4.6 for Linux」· C语言 代码 · 共 725 行 · 第 1/2 页
C
725 行
if (operators[i] == InvalidOid) continue; referenced.objectId = operators[i]; referenced.objectSubId = 0; recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); } /* dependencies on procedures */ for (i = 0; i < numProcs; i++) { if (procedures[i] == InvalidOid) continue; referenced.classId = RelOid_pg_proc; referenced.objectId = procedures[i]; referenced.objectSubId = 0; recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); } heap_close(rel, RowExclusiveLock);}/* * Dump the operators to pg_amop */static voidstoreOperators(Oid opclassoid, int numOperators, Oid *operators, bool *recheck){ Relation rel; Datum values[Natts_pg_amop]; char nulls[Natts_pg_amop]; HeapTuple tup; int i, j; rel = heap_openr(AccessMethodOperatorRelationName, RowExclusiveLock); for (j = 0; j < numOperators; j++) { if (operators[j] == InvalidOid) continue; for (i = 0; i < Natts_pg_amop; ++i) { nulls[i] = ' '; values[i] = (Datum) NULL; } i = 0; values[i++] = ObjectIdGetDatum(opclassoid); /* amopclaid */ values[i++] = Int16GetDatum(j + 1); /* amopstrategy */ values[i++] = BoolGetDatum(recheck[j]); /* amopreqcheck */ values[i++] = ObjectIdGetDatum(operators[j]); /* amopopr */ tup = heap_formtuple(rel->rd_att, values, nulls); simple_heap_insert(rel, tup); CatalogUpdateIndexes(rel, tup); heap_freetuple(tup); } heap_close(rel, RowExclusiveLock);}/* * Dump the procedures (support routines) to pg_amproc */static voidstoreProcedures(Oid opclassoid, int numProcs, Oid *procedures){ Relation rel; Datum values[Natts_pg_amproc]; char nulls[Natts_pg_amproc]; HeapTuple tup; int i, j; rel = heap_openr(AccessMethodProcedureRelationName, RowExclusiveLock); for (j = 0; j < numProcs; j++) { if (procedures[j] == InvalidOid) continue; for (i = 0; i < Natts_pg_amproc; ++i) { nulls[i] = ' '; values[i] = (Datum) NULL; } i = 0; values[i++] = ObjectIdGetDatum(opclassoid); /* amopclaid */ values[i++] = Int16GetDatum(j + 1); /* amprocnum */ values[i++] = ObjectIdGetDatum(procedures[j]); /* amproc */ tup = heap_formtuple(rel->rd_att, values, nulls); simple_heap_insert(rel, tup); CatalogUpdateIndexes(rel, tup); heap_freetuple(tup); } heap_close(rel, RowExclusiveLock);}/* * RemoveOpClass * Deletes an opclass. */voidRemoveOpClass(RemoveOpClassStmt *stmt){ Oid amID, opcID; char *schemaname; char *opcname; HeapTuple tuple; ObjectAddress object; /* * Get the access method's OID. */ amID = GetSysCacheOid(AMNAME, CStringGetDatum(stmt->amname), 0, 0, 0); if (!OidIsValid(amID)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("access method \"%s\" does not exist", stmt->amname))); /* * Look up the opclass. */ /* deconstruct the name list */ DeconstructQualifiedName(stmt->opclassname, &schemaname, &opcname); if (schemaname) { /* Look in specific schema only */ Oid namespaceId; namespaceId = LookupExplicitNamespace(schemaname); tuple = SearchSysCache(CLAAMNAMENSP, ObjectIdGetDatum(amID), PointerGetDatum(opcname), ObjectIdGetDatum(namespaceId), 0); } else { /* Unqualified opclass name, so search the search path */ opcID = OpclassnameGetOpcid(amID, opcname); if (!OidIsValid(opcID)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("operator class \"%s\" does not exist for access method \"%s\"", opcname, stmt->amname))); tuple = SearchSysCache(CLAOID, ObjectIdGetDatum(opcID), 0, 0, 0); } if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("operator class \"%s\" does not exist for access method \"%s\"", NameListToString(stmt->opclassname), stmt->amname))); opcID = HeapTupleGetOid(tuple); /* Permission check: must own opclass or its namespace */ if (!pg_opclass_ownercheck(opcID, GetUserId()) && !pg_namespace_ownercheck(((Form_pg_opclass) GETSTRUCT(tuple))->opcnamespace, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPCLASS, NameListToString(stmt->opclassname)); ReleaseSysCache(tuple); /* * Do the deletion */ object.classId = get_system_catalog_relid(OperatorClassRelationName); object.objectId = opcID; object.objectSubId = 0; performDeletion(&object, stmt->behavior);}/* * Guts of opclass deletion. */voidRemoveOpClassById(Oid opclassOid){ Relation rel; HeapTuple tup; ScanKeyData skey[1]; SysScanDesc scan; /* * First remove the pg_opclass entry itself. */ rel = heap_openr(OperatorClassRelationName, RowExclusiveLock); tup = SearchSysCache(CLAOID, ObjectIdGetDatum(opclassOid), 0, 0, 0); if (!HeapTupleIsValid(tup)) /* should not happen */ elog(ERROR, "cache lookup failed for opclass %u", opclassOid); simple_heap_delete(rel, &tup->t_self); ReleaseSysCache(tup); heap_close(rel, RowExclusiveLock); /* * Remove associated entries in pg_amop. */ ScanKeyEntryInitialize(&skey[0], 0, Anum_pg_amop_amopclaid, F_OIDEQ, ObjectIdGetDatum(opclassOid)); rel = heap_openr(AccessMethodOperatorRelationName, RowExclusiveLock); scan = systable_beginscan(rel, AccessMethodStrategyIndex, true, SnapshotNow, 1, skey); while (HeapTupleIsValid(tup = systable_getnext(scan))) simple_heap_delete(rel, &tup->t_self); systable_endscan(scan); heap_close(rel, RowExclusiveLock); /* * Remove associated entries in pg_amproc. */ ScanKeyEntryInitialize(&skey[0], 0, Anum_pg_amproc_amopclaid, F_OIDEQ, ObjectIdGetDatum(opclassOid)); rel = heap_openr(AccessMethodProcedureRelationName, RowExclusiveLock); scan = systable_beginscan(rel, AccessMethodProcedureIndex, true, SnapshotNow, 1, skey); while (HeapTupleIsValid(tup = systable_getnext(scan))) simple_heap_delete(rel, &tup->t_self); systable_endscan(scan); heap_close(rel, RowExclusiveLock);}/* * Rename opclass */voidRenameOpClass(List *name, const char *access_method, const char *newname){ Oid opcOid; Oid amOid; Oid namespaceOid; char *schemaname; char *opcname; HeapTuple tup; Relation rel; AclResult aclresult; amOid = GetSysCacheOid(AMNAME, CStringGetDatum(access_method), 0, 0, 0); if (!OidIsValid(amOid)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("access method \"%s\" does not exist", access_method))); rel = heap_openr(OperatorClassRelationName, RowExclusiveLock); /* * Look up the opclass */ DeconstructQualifiedName(name, &schemaname, &opcname); if (schemaname) { namespaceOid = LookupExplicitNamespace(schemaname); tup = SearchSysCacheCopy(CLAAMNAMENSP, ObjectIdGetDatum(amOid), PointerGetDatum(opcname), ObjectIdGetDatum(namespaceOid), 0); if (!HeapTupleIsValid(tup)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("operator class \"%s\" does not exist for access method \"%s\"", opcname, access_method))); opcOid = HeapTupleGetOid(tup); } else { opcOid = OpclassnameGetOpcid(amOid, opcname); if (!OidIsValid(opcOid)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("operator class \"%s\" does not exist for access method \"%s\"", opcname, access_method))); tup = SearchSysCacheCopy(CLAOID, ObjectIdGetDatum(opcOid), 0, 0, 0); if (!HeapTupleIsValid(tup)) /* should not happen */ elog(ERROR, "cache lookup failed for opclass %u", opcOid); namespaceOid = ((Form_pg_opclass) GETSTRUCT(tup))->opcnamespace; } /* make sure the new name doesn't exist */ if (SearchSysCacheExists(CLAAMNAMENSP, ObjectIdGetDatum(amOid), CStringGetDatum(newname), ObjectIdGetDatum(namespaceOid), 0)) { ereport(ERROR, (errcode(ERRCODE_DUPLICATE_OBJECT), errmsg("operator class \"%s\" for access method \"%s\" already exists in schema \"%s\"", newname, access_method, get_namespace_name(namespaceOid)))); } /* must be owner */ if (!pg_opclass_ownercheck(opcOid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPCLASS, NameListToString(name)); /* must have CREATE privilege on namespace */ aclresult = pg_namespace_aclcheck(namespaceOid, GetUserId(), ACL_CREATE); if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, ACL_KIND_NAMESPACE, get_namespace_name(namespaceOid)); /* rename */ namestrcpy(&(((Form_pg_opclass) GETSTRUCT(tup))->opcname), newname); simple_heap_update(rel, &tup->t_self, tup); CatalogUpdateIndexes(rel, tup); heap_close(rel, NoLock); heap_freetuple(tup);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?