📄 plancat.c
字号:
Costrestriction_selectivity(Oid functionObjectId, Oid operatorObjectId, Oid relationObjectId, AttrNumber attributeNumber, char *constValue, int32 constFlag){ float64 result; result = (float64) fmgr(functionObjectId, (char *) operatorObjectId, (char *) relationObjectId, (char *) (int) attributeNumber, (char *) constValue, (char *) constFlag, NULL); if (!PointerIsValid(result)) elog(ERROR, "RestrictionClauseSelectivity: bad pointer"); if (*result < 0.0 || *result > 1.0) elog(ERROR, "RestrictionClauseSelectivity: bad value %lf", *result); return (Cost) *result;}/* * join_selectivity * Similarly, this routine is merged with JoinClauseSelectivity in * plancat.c * * Returns the selectivity of an operator, given the join clause * information. * * XXX The assumption in the selectivity procedures is that if the * relation OIDs or attribute numbers are -1, then the clause * isn't of the form (op var var). */Costjoin_selectivity(Oid functionObjectId, Oid operatorObjectId, Oid relationObjectId1, AttrNumber attributeNumber1, Oid relationObjectId2, AttrNumber attributeNumber2){ float64 result; result = (float64) fmgr(functionObjectId, (char *) operatorObjectId, (char *) relationObjectId1, (char *) (int) attributeNumber1, (char *) relationObjectId2, (char *) (int) attributeNumber2, NULL); if (!PointerIsValid(result)) elog(ERROR, "JoinClauseSelectivity: bad pointer"); if (*result < 0.0 || *result > 1.0) elog(ERROR, "JoinClauseSelectivity: bad value %lf", *result); return (Cost) *result;}/* * find_all_inheritors * * Returns a LISP list containing the OIDs of all relations which * inherits from the relation with OID 'inhparent'. */List *find_inheritance_children(Oid inhparent){ static ScanKeyData key[1] = { {0, Anum_pg_inherits_inhparent, F_OIDEQ} }; HeapTuple inheritsTuple; Relation relation; HeapScanDesc scan; List *list = NIL; Oid inhrelid; fmgr_info(F_OIDEQ, &key[0].sk_func); key[0].sk_nargs = key[0].sk_func.fn_nargs; key[0].sk_argument = ObjectIdGetDatum((Oid) inhparent); relation = heap_openr(InheritsRelationName); scan = heap_beginscan(relation, 0, SnapshotNow, 1, key); while (HeapTupleIsValid(inheritsTuple = heap_getnext(scan, 0))) { inhrelid = ((Form_pg_inherits) GETSTRUCT(inheritsTuple))->inhrel; list = lappendi(list, inhrelid); } heap_endscan(scan); heap_close(relation); return list;}#ifdef NOT_USED/* * VersionGetParents * * Returns a LISP list containing the OIDs of all relations which are * base relations of the relation with OID 'verrelid'. */List *VersionGetParents(Oid verrelid){ static ScanKeyData key[1] = { {0, Anum_pg_version_verrelid, F_OIDEQ} }; HeapTuple versionTuple; Relation relation; HeapScanDesc scan; Oid verbaseid; List *list = NIL; fmgr_info(F_OIDEQ, &key[0].sk_func); key[0].sk_nargs = key[0].sk_func.fn_nargs; relation = heap_openr(VersionRelationName); key[0].sk_argument = ObjectIdGetDatum(verrelid); scan = heap_beginscan(relation, 0, SnapshotNow, 1, key); while (HeapTupleIsValid(versionTuple = heap_getnext(scan, 0))) { verbaseid = ((Form_pg_version) GETSTRUCT(versionTuple))->verbaseid; list = lconsi(verbaseid, list); key[0].sk_argument = ObjectIdGetDatum(verbaseid); heap_rescan(scan, 0, key); } heap_endscan(scan); heap_close(relation); return list;}#endif/***************************************************************************** * *****************************************************************************//* * IdexSelectivity * * Retrieves the 'amopnpages' and 'amopselect' parameters for each * AM operator when a given index (specified by 'indexrelid') is used. * These two parameters are returned by copying them to into an array of * floats. * * Assumption: the attribute numbers and operator ObjectIds are in order * WRT to each other (otherwise, you have no way of knowing which * AM operator class or attribute number corresponds to which operator. * * 'varAttributeNumbers' contains attribute numbers for variables * 'constValues' contains the constant values * 'constFlags' describes how to treat the constants in each clause * 'nIndexKeys' describes how many keys the index actually has * * Returns 'selectivityInfo' filled with the sum of all pages touched * and the product of each clause's selectivity. * */static voidIndexSelectivity(Oid indexrelid, Oid indrelid, int32 nIndexKeys, Oid *AccessMethodOperatorClasses, /* XXX not used? */ Oid *operatorObjectIds, int32 *varAttributeNumbers, char **constValues, int32 *constFlags, float *idxPages, float *idxSelec){ int i, n; HeapTuple indexTuple, amopTuple, indRel; Form_pg_index index; Form_pg_amop amop; Oid indclass; float64data npages, select; float64 amopnpages, amopselect; Oid relam; bool nphack = false; float64data fattr_select = 1.0; indRel = SearchSysCacheTuple(RELOID, ObjectIdGetDatum(indexrelid), 0, 0, 0); if (!HeapTupleIsValid(indRel)) elog(ERROR, "IndexSelectivity: index %u not found", indexrelid); relam = ((Form_pg_class) GETSTRUCT(indRel))->relam; indexTuple = SearchSysCacheTuple(INDEXRELID, ObjectIdGetDatum(indexrelid), 0, 0, 0); if (!HeapTupleIsValid(indexTuple)) elog(ERROR, "IndexSelectivity: index %u not found", indexrelid); index = (Form_pg_index) GETSTRUCT(indexTuple); /* * Hack for non-functional btree npages estimation: npages = * index_pages * selectivity_of_1st_attr_clause(s) - vadim 04/24/97 */ if (relam == BTREE_AM_OID && varAttributeNumbers[0] != InvalidAttrNumber) nphack = true; npages = 0.0; select = 1.0; for (n = 0; n < nIndexKeys; ++n) { /* * Find the AM class for this key. * * If the first attribute number is invalid then we have a functional * index, and AM class is the first one defined since functional * indices have exactly one key. */ indclass = (varAttributeNumbers[0] == InvalidAttrNumber) ? index->indclass[0] : InvalidOid; i = 0; while ((i < nIndexKeys) && (indclass == InvalidOid)) { if (varAttributeNumbers[n] == index->indkey[i]) { indclass = index->indclass[i]; break; } i++; } if (!OidIsValid(indclass)) { /* * Presumably this means that we are using a functional index * clause and so had no variable to match to the index key ... * if not we are in trouble. */ elog(NOTICE, "IndexSelectivity: no key %d in index %u", varAttributeNumbers[n], indexrelid); continue; } amopTuple = SearchSysCacheTuple(AMOPOPID, ObjectIdGetDatum(indclass), ObjectIdGetDatum(operatorObjectIds[n]), ObjectIdGetDatum(relam), 0); if (!HeapTupleIsValid(amopTuple)) elog(ERROR, "IndexSelectivity: no amop %u %u", indclass, operatorObjectIds[n]); amop = (Form_pg_amop) GETSTRUCT(amopTuple); if (!nphack) { amopnpages = (float64) fmgr(amop->amopnpages, (char *) operatorObjectIds[n], (char *) indrelid, (char *) varAttributeNumbers[n], (char *) constValues[n], (char *) constFlags[n], (char *) nIndexKeys, (char *) indexrelid);#ifdef NOT_USED/* * So cool guys! Npages for x > 10 and x < 20 is twice as * npages for x > 10! - vadim 04/09/97 */ npages += PointerIsValid(amopnpages) ? *amopnpages : 0.0; if ((i = npages) < npages) /* ceil(npages)? */ npages += 1.0;#endif npages += PointerIsValid(amopnpages) ? *amopnpages : 0.0; } amopselect = (float64) fmgr(amop->amopselect, (char *) operatorObjectIds[n], (char *) indrelid, (char *) varAttributeNumbers[n], (char *) constValues[n], (char *) constFlags[n], (char *) nIndexKeys, (char *) indexrelid); if (nphack && varAttributeNumbers[n] == index->indkey[0]) fattr_select *= PointerIsValid(amopselect) ? *amopselect : 1.0; select *= PointerIsValid(amopselect) ? *amopselect : 1.0; } /* * Estimation of npages below is hack of course, but it's better than * it was before. - vadim 04/09/97 */ if (nphack) { npages = fattr_select * ((Form_pg_class) GETSTRUCT(indRel))->relpages; *idxPages = ceil((double) npages); } else { if (nIndexKeys > 1) npages = npages / (1.0 + nIndexKeys); *idxPages = ceil((double) (npages / nIndexKeys)); } *idxSelec = select;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -