lsyscache.c

来自「postgresql8.3.4源码,开源数据库」· C语言 代码 · 共 2,698 行 · 第 1/5 页

C
2,698
字号
			 * Get the matching support function(s).  Failure probably			 * shouldn't happen --- it implies a bogus opfamily --- but			 * continue looking if so.			 */			if (lhs_procno)			{				*lhs_procno = get_opfamily_proc(aform->amopfamily,												aform->amoplefttype,												aform->amoplefttype,												HASHPROC);				if (!OidIsValid(*lhs_procno))					continue;				/* Matching LHS found, done if caller doesn't want RHS */				if (!rhs_procno)				{					result = true;					break;				}				/* Only one lookup needed if given operator is single-type */				if (aform->amoplefttype == aform->amoprighttype)				{					*rhs_procno = *lhs_procno;					result = true;					break;				}			}			if (rhs_procno)			{				*rhs_procno = get_opfamily_proc(aform->amopfamily,												aform->amoprighttype,												aform->amoprighttype,												HASHPROC);				if (!OidIsValid(*rhs_procno))				{					/* Forget any LHS function from this opfamily */					if (lhs_procno)						*lhs_procno = InvalidOid;					continue;				}				/* Matching RHS found, so done */				result = true;				break;			}		}	}	ReleaseSysCacheList(catlist);	return result;}/* * get_op_btree_interpretation *		Given an operator's OID, find out which btree opfamilies it belongs to, *		and what strategy number it has within each one.  The results are *		returned as an OID list and a parallel integer list. * * In addition to the normal btree operators, we consider a <> operator to be * a "member" of an opfamily if its negator is an equality operator of the * opfamily.  ROWCOMPARE_NE is returned as the strategy number for this case. */voidget_op_btree_interpretation(Oid opno, List **opfamilies, List **opstrats){	CatCList   *catlist;	bool		op_negated;	int			i;	*opfamilies = NIL;	*opstrats = NIL;	/*	 * Find all the pg_amop entries containing the operator.	 */	catlist = SearchSysCacheList(AMOPOPID, 1,								 ObjectIdGetDatum(opno),								 0, 0, 0);	/*	 * If we can't find any opfamily containing the op, perhaps it is a <>	 * operator.  See if it has a negator that is in an opfamily.	 */	op_negated = false;	if (catlist->n_members == 0)	{		Oid			op_negator = get_negator(opno);		if (OidIsValid(op_negator))		{			op_negated = true;			ReleaseSysCacheList(catlist);			catlist = SearchSysCacheList(AMOPOPID, 1,										 ObjectIdGetDatum(op_negator),										 0, 0, 0);		}	}	/* Now search the opfamilies */	for (i = 0; i < catlist->n_members; i++)	{		HeapTuple	op_tuple = &catlist->members[i]->tuple;		Form_pg_amop op_form = (Form_pg_amop) GETSTRUCT(op_tuple);		Oid			opfamily_id;		StrategyNumber op_strategy;		/* must be btree */		if (op_form->amopmethod != BTREE_AM_OID)			continue;		/* Get the operator's btree strategy number */		opfamily_id = op_form->amopfamily;		op_strategy = (StrategyNumber) op_form->amopstrategy;		Assert(op_strategy >= 1 && op_strategy <= 5);		if (op_negated)		{			/* Only consider negators that are = */			if (op_strategy != BTEqualStrategyNumber)				continue;			op_strategy = ROWCOMPARE_NE;		}		*opfamilies = lappend_oid(*opfamilies, opfamily_id);		*opstrats = lappend_int(*opstrats, op_strategy);	}	ReleaseSysCacheList(catlist);}/* * ops_in_same_btree_opfamily *		Return TRUE if there exists a btree opfamily containing both operators. *		(This implies that they have compatible notions of equality.) */boolops_in_same_btree_opfamily(Oid opno1, Oid opno2){	bool		result = false;	CatCList   *catlist;	int			i;	/*	 * We search through all the pg_amop entries for opno1.	 */	catlist = SearchSysCacheList(AMOPOPID, 1,								 ObjectIdGetDatum(opno1),								 0, 0, 0);	for (i = 0; i < catlist->n_members; i++)	{		HeapTuple	op_tuple = &catlist->members[i]->tuple;		Form_pg_amop op_form = (Form_pg_amop) GETSTRUCT(op_tuple);		/* must be btree */		if (op_form->amopmethod != BTREE_AM_OID)			continue;		if (op_in_opfamily(opno2, op_form->amopfamily))		{			result = true;			break;		}	}	ReleaseSysCacheList(catlist);	return result;}/*				---------- AMPROC CACHES ----------						 *//* * get_opfamily_proc *		Get the OID of the specified support function *		for the specified opfamily and datatypes. * * Returns InvalidOid if there is no pg_amproc entry for the given keys. */Oidget_opfamily_proc(Oid opfamily, Oid lefttype, Oid righttype, int16 procnum){	HeapTuple	tp;	Form_pg_amproc amproc_tup;	RegProcedure result;	tp = SearchSysCache(AMPROCNUM,						ObjectIdGetDatum(opfamily),						ObjectIdGetDatum(lefttype),						ObjectIdGetDatum(righttype),						Int16GetDatum(procnum));	if (!HeapTupleIsValid(tp))		return InvalidOid;	amproc_tup = (Form_pg_amproc) GETSTRUCT(tp);	result = amproc_tup->amproc;	ReleaseSysCache(tp);	return result;}/*				---------- ATTRIBUTE CACHES ----------					 *//* * get_attname *		Given the relation id and the attribute number, *		return the "attname" field from the attribute relation. * * Note: returns a palloc'd copy of the string, or NULL if no such attribute. */char *get_attname(Oid relid, AttrNumber attnum){	HeapTuple	tp;	tp = SearchSysCache(ATTNUM,						ObjectIdGetDatum(relid),						Int16GetDatum(attnum),						0, 0);	if (HeapTupleIsValid(tp))	{		Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);		char	   *result;		result = pstrdup(NameStr(att_tup->attname));		ReleaseSysCache(tp);		return result;	}	else		return NULL;}/* * get_relid_attribute_name * * Same as above routine get_attname(), except that error * is handled by elog() instead of returning NULL. */char *get_relid_attribute_name(Oid relid, AttrNumber attnum){	char	   *attname;	attname = get_attname(relid, attnum);	if (attname == NULL)		elog(ERROR, "cache lookup failed for attribute %d of relation %u",			 attnum, relid);	return attname;}/* * get_attnum * *		Given the relation id and the attribute name, *		return the "attnum" field from the attribute relation. * *		Returns InvalidAttrNumber if the attr doesn't exist (or is dropped). */AttrNumberget_attnum(Oid relid, const char *attname){	HeapTuple	tp;	tp = SearchSysCacheAttName(relid, attname);	if (HeapTupleIsValid(tp))	{		Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);		AttrNumber	result;		result = att_tup->attnum;		ReleaseSysCache(tp);		return result;	}	else		return InvalidAttrNumber;}/* * get_atttype * *		Given the relation OID and the attribute number with the relation, *		return the attribute type OID. */Oidget_atttype(Oid relid, AttrNumber attnum){	HeapTuple	tp;	tp = SearchSysCache(ATTNUM,						ObjectIdGetDatum(relid),						Int16GetDatum(attnum),						0, 0);	if (HeapTupleIsValid(tp))	{		Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);		Oid			result;		result = att_tup->atttypid;		ReleaseSysCache(tp);		return result;	}	else		return InvalidOid;}/* * get_atttypmod * *		Given the relation id and the attribute number, *		return the "atttypmod" field from the attribute relation. */int32get_atttypmod(Oid relid, AttrNumber attnum){	HeapTuple	tp;	tp = SearchSysCache(ATTNUM,						ObjectIdGetDatum(relid),						Int16GetDatum(attnum),						0, 0);	if (HeapTupleIsValid(tp))	{		Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);		int32		result;		result = att_tup->atttypmod;		ReleaseSysCache(tp);		return result;	}	else		return -1;}/* * get_atttypetypmod * *		A two-fer: given the relation id and the attribute number, *		fetch both type OID and atttypmod in a single cache lookup. * * Unlike the otherwise-similar get_atttype/get_atttypmod, this routine * raises an error if it can't obtain the information. */voidget_atttypetypmod(Oid relid, AttrNumber attnum,				  Oid *typid, int32 *typmod){	HeapTuple	tp;	Form_pg_attribute att_tup;	tp = SearchSysCache(ATTNUM,						ObjectIdGetDatum(relid),						Int16GetDatum(attnum),						0, 0);	if (!HeapTupleIsValid(tp))		elog(ERROR, "cache lookup failed for attribute %d of relation %u",			 attnum, relid);	att_tup = (Form_pg_attribute) GETSTRUCT(tp);	*typid = att_tup->atttypid;	*typmod = att_tup->atttypmod;	ReleaseSysCache(tp);}/*				---------- CONSTRAINT CACHE ----------					 *//* * get_constraint_name *		Returns the name of a given pg_constraint entry. * * Returns a palloc'd copy of the string, or NULL if no such constraint. * * NOTE: since constraint name is not unique, be wary of code that uses this * for anything except preparing error messages. */char *get_constraint_name(Oid conoid){	HeapTuple	tp;	tp = SearchSysCache(CONSTROID,						ObjectIdGetDatum(conoid),						0, 0, 0);	if (HeapTupleIsValid(tp))	{		Form_pg_constraint contup = (Form_pg_constraint) GETSTRUCT(tp);		char	   *result;		result = pstrdup(NameStr(contup->conname));		ReleaseSysCache(tp);		return result;	}	else		return NULL;}/*				---------- OPCLASS CACHE ----------						 *//* * get_opclass_family * *		Returns the OID of the operator family the opclass belongs to. */Oidget_opclass_family(Oid opclass){	HeapTuple	tp;	Form_pg_opclass cla_tup;	Oid			result;	tp = SearchSysCache(CLAOID,						ObjectIdGetDatum(opclass),						0, 0, 0);	if (!HeapTupleIsValid(tp))		elog(ERROR, "cache lookup failed for opclass %u", opclass);	cla_tup = (Form_pg_opclass) GETSTRUCT(tp);	result = cla_tup->opcfamily;	ReleaseSysCache(tp);	return result;}/* * get_opclass_input_type * *		Returns the OID of the datatype the opclass indexes. */Oidget_opclass_input_type(Oid opclass){	HeapTuple	tp;	Form_pg_opclass cla_tup;	Oid			result;	tp = SearchSysCache(CLAOID,						ObjectIdGetDatum(opclass),						0, 0, 0);	if (!HeapTupleIsValid(tp))		elog(ERROR, "cache lookup failed for opclass %u", opclass);	cla_tup = (Form_pg_opclass) GETSTRUCT(tp);	result = cla_tup->opcintype;	ReleaseSysCache(tp);	return result;}/*				---------- OPERATOR CACHE ----------					 *//* * get_opcode * *		Returns the regproc id of the routine used to implement an *		operator given the operator oid. */RegProcedureget_opcode(Oid opno){	HeapTuple	tp;	tp = SearchSysCache(OPEROID,						ObjectIdGetDatum(opno),						0, 0, 0);	if (HeapTupleIsValid(tp))	{		Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);		RegProcedure result;		result = optup->oprcode;		ReleaseSysCache(tp);		return result;	}	else		return (RegProcedure) InvalidOid;}/* * get_opname *	  returns the name of the operator with the given opno * * Note: returns a palloc'd copy of the string, or NULL if no such operator. */char *get_opname(Oid opno){	HeapTuple	tp;	tp = SearchSysCache(OPEROID,						ObjectIdGetDatum(opno),						0, 0, 0);	if (HeapTupleIsValid(tp))	{		Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);		char	   *result;		result = pstrdup(NameStr(optup->oprname));		ReleaseSysCache(tp);		return result;	}	else		return NULL;}/* * op_input_types * *		Returns the left and right input datatypes for an operator *		(InvalidOid if not relevant). */voidop_input_types(Oid opno, Oid *lefttype, Oid *righttype){	HeapTuple	tp;	Form_pg_operator optup;	tp = SearchSysCache(OPEROID,						ObjectIdGetDatum(opno),						0, 0, 0);	if (!HeapTupleIsValid(tp))	/* shouldn't happen */		elog(ERROR, "cache lookup failed for operator %u", opno);	optup = (Form_pg_operator) GETSTRUCT(tp);	*lefttype = optup->oprleft;	*righttype = optup->oprright;	ReleaseSysCache(tp);}/* * op_mergejoinable * * Returns true if the operator is potentially mergejoinable.  (The planner * will fail to find any mergejoin plans unless there are suitable btree * opfamily entries for this operator and associated sortops.  The pg_operator * flag is just a hint to tell the planner whether to bother looking.) */boolop_mergejoinable(Oid opno){	HeapTuple	tp;	bool		result = false;	tp = SearchSysCache(OPEROID,						ObjectIdGetDatum(opno),						0, 0, 0);	if (HeapTupleIsValid(tp))

⌨️ 快捷键说明

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