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 + -
显示快捷键?