pg_type.c

来自「PostgreSQL7.4.6 for Linux」· C语言 代码 · 共 542 行 · 第 1/2 页

C
542
字号
	 */	pg_type_desc = heap_openr(TypeRelationName, RowExclusiveLock);	tup = SearchSysCacheCopy(TYPENAMENSP,							 CStringGetDatum(typeName),							 ObjectIdGetDatum(typeNamespace),							 0, 0);	if (HeapTupleIsValid(tup))	{		/*		 * check that the type is not already defined.	It may exist as a		 * shell type, however (but only if assignedTypeOid is not given).		 */		if (((Form_pg_type) GETSTRUCT(tup))->typisdefined ||			assignedTypeOid != InvalidOid)			ereport(ERROR,					(errcode(ERRCODE_DUPLICATE_OBJECT),					 errmsg("type \"%s\" already exists", typeName)));		/*		 * Okay to update existing "shell" type tuple		 */		tup = heap_modifytuple(tup,							   pg_type_desc,							   values,							   nulls,							   replaces);		simple_heap_update(pg_type_desc, &tup->t_self, tup);		typeObjectId = HeapTupleGetOid(tup);		rebuildDeps = true;		/* get rid of shell type's dependencies */	}	else	{		tupDesc = pg_type_desc->rd_att;		tup = heap_formtuple(tupDesc,							 values,							 nulls);		/* preassign tuple Oid, if one was given */		HeapTupleSetOid(tup, assignedTypeOid);		typeObjectId = simple_heap_insert(pg_type_desc, tup);	}	/* Update indexes */	CatalogUpdateIndexes(pg_type_desc, tup);	/*	 * Create dependencies.  We can/must skip this in bootstrap mode.	 */	if (!IsBootstrapProcessingMode())		GenerateTypeDependencies(typeNamespace,								 typeObjectId,								 relationOid,								 relationKind,								 inputProcedure,								 outputProcedure,								 receiveProcedure,								 sendProcedure,								 elementType,								 baseType,								 (defaultTypeBin ?								  stringToNode(defaultTypeBin) :								  (void *) NULL),								 rebuildDeps);	/*	 * finish up	 */	heap_close(pg_type_desc, RowExclusiveLock);	return typeObjectId;}/* * GenerateTypeDependencies: build the dependencies needed for a type * * If rebuild is true, we remove existing dependencies and rebuild them * from scratch.  This is needed for ALTER TYPE, and also when replacing * a shell type. * * NOTE: a shell type will have a dependency to its namespace, and no others. */voidGenerateTypeDependencies(Oid typeNamespace,						 Oid typeObjectId,						 Oid relationOid,		/* only for 'c'atalog												 * types */						 char relationKind,		/* ditto */						 Oid inputProcedure,						 Oid outputProcedure,						 Oid receiveProcedure,						 Oid sendProcedure,						 Oid elementType,						 Oid baseType,						 Node *defaultExpr,						 bool rebuild){	ObjectAddress myself,				referenced;	if (rebuild)		deleteDependencyRecordsFor(RelOid_pg_type,								   typeObjectId);	myself.classId = RelOid_pg_type;	myself.objectId = typeObjectId;	myself.objectSubId = 0;	/* dependency on namespace */	/* skip for relation rowtype, since we have indirect dependency */	if (!OidIsValid(relationOid))	{		referenced.classId = get_system_catalog_relid(NamespaceRelationName);		referenced.objectId = typeNamespace;		referenced.objectSubId = 0;		recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);	}	/* Normal dependencies on the I/O functions */	if (OidIsValid(inputProcedure))	{		referenced.classId = RelOid_pg_proc;		referenced.objectId = inputProcedure;		referenced.objectSubId = 0;		recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);	}	if (OidIsValid(outputProcedure))	{		referenced.classId = RelOid_pg_proc;		referenced.objectId = outputProcedure;		referenced.objectSubId = 0;		recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);	}	if (OidIsValid(receiveProcedure))	{		referenced.classId = RelOid_pg_proc;		referenced.objectId = receiveProcedure;		referenced.objectSubId = 0;		recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);	}	if (OidIsValid(sendProcedure))	{		referenced.classId = RelOid_pg_proc;		referenced.objectId = sendProcedure;		referenced.objectSubId = 0;		recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);	}	/*	 * If the type is a rowtype for a relation, mark it as internally	 * dependent on the relation, *unless* it is a stand-alone composite	 * type relation. For the latter case, we have to reverse the	 * dependency.	 *	 * In the former case, this allows the type to be auto-dropped when the	 * relation is, and not otherwise. And in the latter, of course we get	 * the opposite effect.	 */	if (OidIsValid(relationOid))	{		referenced.classId = RelOid_pg_class;		referenced.objectId = relationOid;		referenced.objectSubId = 0;		if (relationKind != RELKIND_COMPOSITE_TYPE)			recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL);		else			recordDependencyOn(&referenced, &myself, DEPENDENCY_INTERNAL);	}	/*	 * If the type is an array type, mark it auto-dependent on the base	 * type.  (This is a compromise between the typical case where the	 * array type is automatically generated and the case where it is	 * manually created: we'd prefer INTERNAL for the former case and	 * NORMAL for the latter.)	 */	if (OidIsValid(elementType))	{		referenced.classId = RelOid_pg_type;		referenced.objectId = elementType;		referenced.objectSubId = 0;		recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);	}	/* Normal dependency from a domain to its base type. */	if (OidIsValid(baseType))	{		referenced.classId = RelOid_pg_type;		referenced.objectId = baseType;		referenced.objectSubId = 0;		recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);	}	/* Normal dependency on the default expression. */	if (defaultExpr)		recordDependencyOnExpr(&myself, defaultExpr, NIL, DEPENDENCY_NORMAL);}/* * TypeRename *		This renames a type * * Note: any associated array type is *not* renamed; caller must make * another call to handle that case.  Currently this is only used for * renaming types associated with tables, for which there are no arrays. */voidTypeRename(const char *oldTypeName, Oid typeNamespace,		   const char *newTypeName){	Relation	pg_type_desc;	HeapTuple	tuple;	pg_type_desc = heap_openr(TypeRelationName, RowExclusiveLock);	tuple = SearchSysCacheCopy(TYPENAMENSP,							   CStringGetDatum(oldTypeName),							   ObjectIdGetDatum(typeNamespace),							   0, 0);	if (!HeapTupleIsValid(tuple))		ereport(ERROR,				(errcode(ERRCODE_UNDEFINED_OBJECT),				 errmsg("type \"%s\" does not exist", oldTypeName)));	if (SearchSysCacheExists(TYPENAMENSP,							 CStringGetDatum(newTypeName),							 ObjectIdGetDatum(typeNamespace),							 0, 0))		ereport(ERROR,				(errcode(ERRCODE_DUPLICATE_OBJECT),				 errmsg("type \"%s\" already exists", newTypeName)));	namestrcpy(&(((Form_pg_type) GETSTRUCT(tuple))->typname), newTypeName);	simple_heap_update(pg_type_desc, &tuple->t_self, tuple);	/* update the system catalog indexes */	CatalogUpdateIndexes(pg_type_desc, tuple);	heap_freetuple(tuple);	heap_close(pg_type_desc, RowExclusiveLock);}/* * makeArrayTypeName(typeName); *	  - given a base type name, make an array of type name out of it * * the caller is responsible for pfreeing the result */char *makeArrayTypeName(const char *typeName){	char	   *arr;	if (!typeName)		return NULL;	arr = palloc(NAMEDATALEN);	snprintf(arr, NAMEDATALEN,			 "_%.*s", NAMEDATALEN - 2, typeName);	return arr;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?