⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lsyscache.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 3 页
字号:
{	HeapTuple	typeTuple;	Form_pg_type type;	Datum		datum;	bool		isNull;	Node	   *expr;	typeTuple = SearchSysCache(TYPEOID,							   ObjectIdGetDatum(typid),							   0, 0, 0);	if (!HeapTupleIsValid(typeTuple))		elog(ERROR, "cache lookup failed for type %u", typid);	type = (Form_pg_type) GETSTRUCT(typeTuple);	/*	 * typdefault and typdefaultbin are potentially null, so don't try to	 * access 'em as struct fields. Must do it the hard way with	 * SysCacheGetAttr.	 */	datum = SysCacheGetAttr(TYPEOID,							typeTuple,							Anum_pg_type_typdefaultbin,							&isNull);	if (!isNull)	{		/* We have an expression default */		expr = stringToNode(DatumGetCString(DirectFunctionCall1(textout,																datum)));	}	else	{		/* Perhaps we have a plain literal default */		datum = SysCacheGetAttr(TYPEOID,								typeTuple,								Anum_pg_type_typdefault,								&isNull);		if (!isNull)		{			char	   *strDefaultVal;			/* Convert text datum to C string */			strDefaultVal = DatumGetCString(DirectFunctionCall1(textout,																datum));			/* Convert C string to a value of the given type */			datum = OidFunctionCall3(type->typinput,									 CStringGetDatum(strDefaultVal),								 ObjectIdGetDatum(getTypeIOParam(typeTuple)),									 Int32GetDatum(-1));			/* Build a Const node containing the value */			expr = (Node *) makeConst(typid,									  type->typlen,									  datum,									  false,									  type->typbyval);			pfree(strDefaultVal);		}		else		{			/* No default */			expr = NULL;		}	}	ReleaseSysCache(typeTuple);	return expr;}/* * getBaseType *		If the given type is a domain, return its base type; *		otherwise return the type's own OID. */OidgetBaseType(Oid typid){	/*	 * We loop to find the bottom base type in a stack of domains.	 */	for (;;)	{		HeapTuple	tup;		Form_pg_type typTup;		tup = SearchSysCache(TYPEOID,							 ObjectIdGetDatum(typid),							 0, 0, 0);		if (!HeapTupleIsValid(tup))			elog(ERROR, "cache lookup failed for type %u", typid);		typTup = (Form_pg_type) GETSTRUCT(tup);		if (typTup->typtype != 'd')		{			/* Not a domain, so done */			ReleaseSysCache(tup);			break;		}		typid = typTup->typbasetype;		ReleaseSysCache(tup);	}	return typid;}/* * get_typavgwidth * *	  Given a type OID and a typmod value (pass -1 if typmod is unknown), *	  estimate the average width of values of the type.  This is used by *	  the planner, which doesn't require absolutely correct results; *	  it's OK (and expected) to guess if we don't know for sure. */int32get_typavgwidth(Oid typid, int32 typmod){	int			typlen = get_typlen(typid);	int32		maxwidth;	/*	 * Easy if it's a fixed-width type	 */	if (typlen > 0)		return typlen;	/*	 * type_maximum_size knows the encoding of typmod for some datatypes;	 * don't duplicate that knowledge here.	 */	maxwidth = type_maximum_size(typid, typmod);	if (maxwidth > 0)	{		/*		 * For BPCHAR, the max width is also the only width.  Otherwise we		 * need to guess about the typical data width given the max. A sliding		 * scale for percentage of max width seems reasonable.		 */		if (typid == BPCHAROID)			return maxwidth;		if (maxwidth <= 32)			return maxwidth;	/* assume full width */		if (maxwidth < 1000)			return 32 + (maxwidth - 32) / 2;	/* assume 50% */		/*		 * Beyond 1000, assume we're looking at something like		 * "varchar(10000)" where the limit isn't actually reached often, and		 * use a fixed estimate.		 */		return 32 + (1000 - 32) / 2;	}	/*	 * Ooops, we have no idea ... wild guess time.	 */	return 32;}/* * get_typtype * *		Given the type OID, find if it is a basic type, a complex type, etc. *		It returns the null char if the cache lookup fails... */charget_typtype(Oid typid){	HeapTuple	tp;	tp = SearchSysCache(TYPEOID,						ObjectIdGetDatum(typid),						0, 0, 0);	if (HeapTupleIsValid(tp))	{		Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);		char		result;		result = typtup->typtype;		ReleaseSysCache(tp);		return result;	}	else		return '\0';}/* * get_typ_typrelid * *		Given the type OID, get the typrelid (InvalidOid if not a complex *		type). */Oidget_typ_typrelid(Oid typid){	HeapTuple	tp;	tp = SearchSysCache(TYPEOID,						ObjectIdGetDatum(typid),						0, 0, 0);	if (HeapTupleIsValid(tp))	{		Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);		Oid			result;		result = typtup->typrelid;		ReleaseSysCache(tp);		return result;	}	else		return InvalidOid;}/* * get_element_type * *		Given the type OID, get the typelem (InvalidOid if not an array type). * * NB: this only considers varlena arrays to be true arrays; InvalidOid is * returned if the input is a fixed-length array type. */Oidget_element_type(Oid typid){	HeapTuple	tp;	tp = SearchSysCache(TYPEOID,						ObjectIdGetDatum(typid),						0, 0, 0);	if (HeapTupleIsValid(tp))	{		Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);		Oid			result;		if (typtup->typlen == -1)			result = typtup->typelem;		else			result = InvalidOid;		ReleaseSysCache(tp);		return result;	}	else		return InvalidOid;}/* * get_array_type * *		Given the type OID, get the corresponding array type. *		Returns InvalidOid if no array type can be found. * * NB: this only considers varlena arrays to be true arrays. */Oidget_array_type(Oid typid){	HeapTuple	tp;	tp = SearchSysCache(TYPEOID,						ObjectIdGetDatum(typid),						0, 0, 0);	if (HeapTupleIsValid(tp))	{		Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);		char	   *array_typename;		Oid			namespaceId;		array_typename = makeArrayTypeName(NameStr(typtup->typname));		namespaceId = typtup->typnamespace;		ReleaseSysCache(tp);		tp = SearchSysCache(TYPENAMENSP,							PointerGetDatum(array_typename),							ObjectIdGetDatum(namespaceId),							0, 0);		pfree(array_typename);		if (HeapTupleIsValid(tp))		{			Oid			result;			typtup = (Form_pg_type) GETSTRUCT(tp);			if (typtup->typlen == -1 && typtup->typelem == typid)				result = HeapTupleGetOid(tp);			else				result = InvalidOid;			ReleaseSysCache(tp);			return result;		}	}	return InvalidOid;}/* * getTypeInputInfo * *		Get info needed for converting values of a type to internal form */voidgetTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam){	HeapTuple	typeTuple;	Form_pg_type pt;	typeTuple = SearchSysCache(TYPEOID,							   ObjectIdGetDatum(type),							   0, 0, 0);	if (!HeapTupleIsValid(typeTuple))		elog(ERROR, "cache lookup failed for type %u", type);	pt = (Form_pg_type) GETSTRUCT(typeTuple);	if (!pt->typisdefined)		ereport(ERROR,				(errcode(ERRCODE_UNDEFINED_OBJECT),				 errmsg("type %s is only a shell",						format_type_be(type))));	if (!OidIsValid(pt->typinput))		ereport(ERROR,				(errcode(ERRCODE_UNDEFINED_FUNCTION),				 errmsg("no input function available for type %s",						format_type_be(type))));	*typInput = pt->typinput;	*typIOParam = getTypeIOParam(typeTuple);	ReleaseSysCache(typeTuple);}/* * getTypeOutputInfo * *		Get info needed for printing values of a type */voidgetTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena){	HeapTuple	typeTuple;	Form_pg_type pt;	typeTuple = SearchSysCache(TYPEOID,							   ObjectIdGetDatum(type),							   0, 0, 0);	if (!HeapTupleIsValid(typeTuple))		elog(ERROR, "cache lookup failed for type %u", type);	pt = (Form_pg_type) GETSTRUCT(typeTuple);	if (!pt->typisdefined)		ereport(ERROR,				(errcode(ERRCODE_UNDEFINED_OBJECT),				 errmsg("type %s is only a shell",						format_type_be(type))));	if (!OidIsValid(pt->typoutput))		ereport(ERROR,				(errcode(ERRCODE_UNDEFINED_FUNCTION),				 errmsg("no output function available for type %s",						format_type_be(type))));	*typOutput = pt->typoutput;	*typIsVarlena = (!pt->typbyval) && (pt->typlen == -1);	ReleaseSysCache(typeTuple);}/* * getTypeBinaryInputInfo * *		Get info needed for binary input of values of a type */voidgetTypeBinaryInputInfo(Oid type, Oid *typReceive, Oid *typIOParam){	HeapTuple	typeTuple;	Form_pg_type pt;	typeTuple = SearchSysCache(TYPEOID,							   ObjectIdGetDatum(type),							   0, 0, 0);	if (!HeapTupleIsValid(typeTuple))		elog(ERROR, "cache lookup failed for type %u", type);	pt = (Form_pg_type) GETSTRUCT(typeTuple);	if (!pt->typisdefined)		ereport(ERROR,				(errcode(ERRCODE_UNDEFINED_OBJECT),				 errmsg("type %s is only a shell",						format_type_be(type))));	if (!OidIsValid(pt->typreceive))		ereport(ERROR,				(errcode(ERRCODE_UNDEFINED_FUNCTION),				 errmsg("no binary input function available for type %s",						format_type_be(type))));	*typReceive = pt->typreceive;	*typIOParam = getTypeIOParam(typeTuple);	ReleaseSysCache(typeTuple);}/* * getTypeBinaryOutputInfo * *		Get info needed for binary output of values of a type */voidgetTypeBinaryOutputInfo(Oid type, Oid *typSend, bool *typIsVarlena){	HeapTuple	typeTuple;	Form_pg_type pt;	typeTuple = SearchSysCache(TYPEOID,							   ObjectIdGetDatum(type),							   0, 0, 0);	if (!HeapTupleIsValid(typeTuple))		elog(ERROR, "cache lookup failed for type %u", type);	pt = (Form_pg_type) GETSTRUCT(typeTuple);	if (!pt->typisdefined)		ereport(ERROR,				(errcode(ERRCODE_UNDEFINED_OBJECT),				 errmsg("type %s is only a shell",						format_type_be(type))));	if (!OidIsValid(pt->typsend))		ereport(ERROR,				(errcode(ERRCODE_UNDEFINED_FUNCTION),				 errmsg("no binary output function available for type %s",						format_type_be(type))));	*typSend = pt->typsend;	*typIsVarlena = (!pt->typbyval) && (pt->typlen == -1);	ReleaseSysCache(typeTuple);}/*				---------- STATISTICS CACHE ----------					 *//* * get_attavgwidth * *	  Given the table and attribute number of a column, get the average *	  width of entries in the column.  Return zero if no data available. */int32get_attavgwidth(Oid relid, AttrNumber attnum){	HeapTuple	tp;	tp = SearchSysCache(STATRELATT,						ObjectIdGetDatum(relid),						Int16GetDatum(attnum),						0, 0);	if (HeapTupleIsValid(tp))	{		int32		stawidth = ((Form_pg_statistic) GETSTRUCT(tp))->stawidth;		ReleaseSysCache(tp);		if (stawidth > 0)			return stawidth;	}	return 0;}/* * get_attstatsslot * *		Extract the contents of a "slot" of a pg_statistic tuple. *		Returns TRUE if requested slot type was found, else FALSE. * * Unlike other routines in this file, this takes a pointer to an * already-looked-up tuple in the pg_statistic cache.  We do this since * most callers will want to extract more than one value from the cache * entry, and we don't want to repeat the cache lookup unnecessarily. * * statstuple: pg_statistics tuple to be examined. * atttype: type OID of attribute (can be InvalidOid if values == NULL). * atttypmod: typmod of attribute (can be 0 if values == NULL). * reqkind: STAKIND code for desired statistics slot kind. * reqop: STAOP value wanted, or InvalidOid if don't care. * values, nvalues: if not NULL, the slot's stavalues are extracted. * numbers, nnumbers: if not NULL, the slot's stanumbers are extracted. * * If assigned, values and numbers are set to point to palloc'd arrays. * If the attribute type is pass-by-reference, the values referenced by * the values array are themselves palloc'd.  The palloc'd stuff can be * freed by calling free_attstatsslot. */boolget_attstatsslot(HeapTuple statstuple,				 Oid atttype, int32 atttypmod,				 int reqkind, Oid reqop,				 Datum **values, int *nvalues,				 float4 **numbers, int *nnumbers){	Form_pg_statistic stats = (Form_pg_statistic) GETSTRUCT(statstuple);	int			i,				j;	Datum		val;	bool		isnull;	ArrayType  *statarray;	int			narrayelem;	HeapTuple	typeTuple;	Form_pg_type typeForm;	for (i = 0; i < STATISTIC_NUM_SLOTS; i++)	{		if ((&stats->stakind1)[i] == reqkind &&			(reqop == InvalidOid || (&stats->staop1)[i] == reqop))			break;	}	if (i >= STATISTIC_NUM_SLOTS)		return false;			/* not there */	if (values)	{		val = SysCacheGetAttr(STATRELATT, statstuple,							  Anum_pg_statistic_stavalues1 + i,							  &isnull);		if (isnull)			elog(ERROR, "stavalues is null");		statarray = DatumGetArrayTypeP(val);		/* Need to get info about the array element type */		typeTuple = SearchSysCache(TYPEOID,								   ObjectIdGetDatum(atttype),								   0, 0, 0);		if (!HeapTupleIsValid(typeTuple))			elog(ERROR, "cache lookup failed for type %u", atttype);		typeForm = (Form_pg_type) GETSTRUCT(typeTuple);		/* Deconstruct array into Datum elements */		deconstruct_array(statarray,						  atttype,						  typeForm->typlen,						  typeForm->typbyval,						  typeForm->typalign,						  values, nvalues);		/*		 * If the element type is pass-by-reference, we now have a bunch of		 * Datums that are pointers into the syscache value.  Copy them to		 * avoid problems if syscache decides to drop the entry.		 */		if (!typeForm->typbyval)		{			for (j = 0; j < *nvalues; j++)			{				(*values)[j] = datumCopy((*values)[j],										 typeForm->typbyval,										 typeForm->typlen);			}		}		ReleaseSysCache(typeTuple);		/*		 * Free statarray if it's a detoasted copy.		 */		if ((Pointer) statarray != DatumGetPointer(val))			pfree(statarray);	}	if (numbers)	{		val = SysCacheGetAttr(STATRELATT, statstuple,							  Anum_pg_statistic_stanumbers1 + i,							  &isnull);		if (isnull)			elog(ERROR, "stanumbers is null");		statarray = DatumGetArrayTypeP(val);		/*		 * We expect the array to be a 1-D float4 array; verify that. We don't		 * need to use deconstruct_array() since the array data is just going		 * to look like a C array of float4 values.		 */		narrayelem = ARR_DIMS(statarray)[0];		if (ARR_NDIM(statarray) != 1 || narrayelem <= 0 ||			ARR_ELEMTYPE(statarray) != FLOAT4OID)			elog(ERROR, "stanumbers is not a 1-D float4 array");		*numbers = (float4 *) palloc(narrayelem * sizeof(float4));		memcpy(*numbers, ARR_DATA_PTR(statarray), narrayelem * sizeof(float4));		*nnumbers = narrayelem;		/*		 * Free statarray if it's a detoasted copy.		 */		if ((Pointer) statarray != DatumGetPointer(val))			pfree(statarray);	}	return true;}/* * free_attstatsslot *		Free data allocated by get_attstatsslot * * atttype need be valid only if values != NULL. */voidfree_attstatsslot(Oid atttype,				  Datum *values, int nvalues,				  float4 *numbers, int nnumbers){	if (values)	{		if (!get_typbyval(atttype))		{			int			i;			for (i = 0; i < nvalues; i++)				pfree(DatumGetPointer(values[i]));		}		pfree(values);	}	if (numbers)		pfree(numbers);}/*				---------- PG_NAMESPACE CACHE ----------				 *//* * get_namespace_name *		Returns the name of a given namespace * * Returns a palloc'd copy of the string, or NULL if no such namespace. */char *get_namespace_name(Oid nspid){	HeapTuple	tp;	tp = SearchSysCache(NAMESPACEOID,						ObjectIdGetDatum(nspid),						0, 0, 0);	if (HeapTupleIsValid(tp))	{		Form_pg_namespace nsptup = (Form_pg_namespace) GETSTRUCT(tp);		char	   *result;		result = pstrdup(NameStr(nsptup->nspname));		ReleaseSysCache(tp);		return result;	}	else		return NULL;}/*				---------- PG_AUTHID CACHE ----------					 *//* * get_roleid *	  Given a role name, look up the role's OID. *	  Returns InvalidOid if no such role. */Oidget_roleid(const char *rolname){	return GetSysCacheOid(AUTHNAME,						  PointerGetDatum(rolname),						  0, 0, 0);}/* * get_roleid_checked *	  Given a role name, look up the role's OID. *	  ereports if no such role. */Oidget_roleid_checked(const char *rolname){	Oid			roleid;	roleid = get_roleid(rolname);	if (!OidIsValid(roleid))		ereport(ERROR,				(errcode(ERRCODE_UNDEFINED_OBJECT),				 errmsg("role \"%s\" does not exist", rolname)));	return roleid;}

⌨️ 快捷键说明

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