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